- 投稿日:2020-10-13T21:45:25+09:00
【Unity】NRSDK1.3.0のInput-VirtualControllerシーンを読んでみる(Inputシーン編3/3)【Nreal】
はじめに
Input-VirtualControllerシーンについて
シーン構成
シーン構成 NRCameraRig NRInput Directional Light TargetModelDisplayCtrl [Tip:----------------------------] [Drag " NRVirtualDisplayer" Prefab Here] [Then Breake Prefab Instance And Make] [Your Custom Virtual Controller. ] CustomVirtualDisplayer NRCameraRig、NRInput
Nrealに対応したカメラ、入力システム
別のサンプルシーンで読んでます。
NrealSDK1.3.0のHelloMRシーンを読んでみるDirectional Light
Unity製のライト。
TargetModelDisplayCtrl
[Tip:----------------------------]
このオブジェクト以下はTipを記載しているらしい。
読んでみよう。Drag " NRVirtualDisplayer" Prefab Here
Then Breake Prefab Instance And Make
Your Custom Virtual Controller.NRVirtualDisplayerのプレハブをHierarchyにドラッグして
カスタムの仮装コントローラーを作れるらしい
(既存のNRVirtualDisplayerに同期されてしまうので、プレハブ化を無効にするってことですね)え、便利!!
もう少し理解するため、公式ページを覗いてみた。
以下Nreal公式リファレンス引用Nreal電話コントローラーの優れた点の1つは、UIインターレースを簡単にカスタマイズできることです。Nreal電話コントローラーを使用する2つの方法は次のとおりです。
・デフォルトの方法 「NRInput」プレハブをシーンにドラッグするだけです。次に、デバイスでアプリを実行すると、デフォルトの仮想コントローラー( "NRVirtualDisplayer"プレハブ)が自動的にロードされます。3つの一般的なコントローラーボタン(トリガー、ホーム、アプリ)があります。この仮想コントローラーは、NrealLightコントローラーと非常によく似ています。
・カスタム方法 「NRInput」プレハブをシーンにドラッグします。次に、「NRVirtualDisplayer」プレハブをシーンにドラッグし、必要に応じて変更します。たとえば、アプリケーションに合わせて、いくつかの新しいボタンを追加したり、コントローラーUIのスタイルを変更したりします。
引用:https://developer.nreal.ai/develop/unity/customize-phone-controller
Nreal Lightでは、グラスにスマートフォンをコントローラーとして接続するので、それに使うようです。
デフォルトだと、2つのボタンとタッチ、ドラッグを検出する場所のみなので、
その他必要なUI等をカスタムできると、、、そういう話か。CustomVirtualDisplayer
カスタムされたコントローラーを子に持つオブジェクト
スクリプト名 役割 NRVirtualDisplayer NRInputクラスのEmulateVirtualDisplayInEditorの結果によって、仮装コントローラーの表示を行なっていたり、タッチした座標の更新を行なっている。各ボタンの状態はMultiScreenControllerで管理して流している。プレハブ内にあるBaseControllerPanelがデフォルトのコントローラー CustomVirtualControlerUI これがカスタムした仮装コントローラー。VirtualDisplayerの子にUIを配置することで、コントローラーを作ることができる。 各色でNrealのロゴの色を変更
スライダーで大きさの変更
Resetボタンはそのままリセットって感じで。簡易的ながら、UIを複数配置できるのはいいですね。
Nreal Developer Kit で実行してみた
コントローラーを指でタッチしながら、黄色矢印方向に動かすとロゴが回転する仕組み
Developer Kitでは何も変化がないですね(NrealLight買うか、、
まとめ
UIの処理のみで仮装コントローラーが作れるのは大変ありがたいです!
とすると、Developer KitよりNreal Lightを買ったほうがより良いショートカットなどを作れて大変便利なのでは!?
NRVirtualDisplayerはUnityEditor上で確認できるのでDeveloper Kitでもよく使うことになると思います。さいごに
NrealのInputが一通り理解できました。
最近(2020/09末)NRSDKが更新され、Inputで取得できる情報が追加されたようですね
(今後も増えていくのだろうか)
今後も更新を追いかけつつ、Nrealに関する記事を投稿していきたいと思います。
- 投稿日:2020-10-13T17:06:38+09:00
Unity初心者が思ったアレコレ。
Uniyを勉強していて思ったこと一覧。
思っただけで、実用的かは不明。[Transform関係]
・オブジェクトの回転角はtransform.eulerAngleで取得する。
・オブジェクトの回転はtransform.rotationで行う。(Quaternionを使うべし)
・transform.Rotateはなるべく使用しない。[Rigidbody関係]
・オブジェクトへの力をかける方法はAddForce()よりvelocity。[Animation関係]
・アニメーションの遷移はanimator.Play()を極力使わない。
・paramaterを設定して、animator.SetFloat()などを用いて遷移を行う。
・アニメーションの終了確認はanimator.GetCurrentAnimatorStateInfo().normalizedTimeで比較する。
・目的のアニメーション名かはanimator.GetCurrentAnimatorStateInfo().IsName()で確認する。
- 投稿日:2020-10-13T15:37:54+09:00
【Unity】FungusのLuaでキャラクターを表示する方法
前の記事の続きになります。
前提条件としてHierarchyにFlowchart、LuaEnvironment、LuaScriptの3つの配置が必要です。
ステップ1 HierarchyにCharacterを配置する
Tools > Fungus > Create > Character
を選択し、HierarchyにCharacterを配置します。ステップ2 CharacterのNameText、Portraitsの設定
配置したCharacterのNameTextで名前を変更し、Portraitsにキャラクターの画像を追加します。
Portraitsは複数配置でき、表情の差分を登録できます。ステップ3 HierarchyにLuaBindingsを配置する
Tools > Fungus > Create > LuaBindings
を選択し、HierarchyにLuaBindingsを配置します。ステップ4 LuaBindingsにCharacterを登録する
ステップ3で追加したLuaBindingsのObjectBindingsにステップ2で配置したCharacterを登録します。
Key名を任意の名称に変更してください。この名前でLuaからキャラクターを表示します。また、ObjectBindingsのComponentをFungus.Characterに変更してください。
ステップ5 Luaからキャラクターを呼び出す方法
Luaからsetcharacter関数を呼び出します。
setcharacter(tesuko, "Actor4_0_0_L00")第一引数はステップ4で登録したObjectBindingsのKey
第二引数はステップ2で登録したPortraitsのElementにあるSprite名を文字列
で指定してください。第二引数を変更することで表情の差分を切り替えることができます。
うまくいけば下の画像のようにキャラクターが表示されます。
- 投稿日:2020-10-13T15:37:54+09:00
【Unity】Fungusのキャラクター表示をLuaで操作する方法
前の記事の続きになります。
前提条件としてHierarchyにFlowchart、LuaEnvironment、LuaScriptの3つの配置が必要です。
ステップ1 HierarchyにCharacterを配置する
Tools > Fungus > Create > Character
を選択し、HierarchyにCharacterを配置します。ステップ2 CharacterのNameText、Portraitsの設定
配置したCharacterのNameTextで名前を変更し、Portraitsにキャラクターの画像を追加します。
Portraitsは複数配置でき、表情の差分を登録できます。ステップ3 HierarchyにLuaBindingsを配置する
Tools > Fungus > Create > LuaBindings
を選択し、HierarchyにLuaBindingsを配置します。ステップ4 LuaBindingsにCharacterを登録する
ステップ3で追加したLuaBindingsのObjectBindingsにステップ2で配置したCharacterを登録します。
Key名を任意の名称に変更してください。この名前でLuaからキャラクターを表示します。また、ObjectBindingsのComponentをFungus.Characterに変更してください。
ステップ5 Luaからキャラクターを呼び出す方法
Luaからsetcharacter関数を呼び出します。
setcharacter(tesuko, "Actor4_0_0_L00")第一引数はステップ4で登録したObjectBindingsのKey
第二引数はステップ2で登録したPortraitsのElementにあるSprite名を文字列
で指定してください。第二引数を変更することで表情の差分を切り替えることができます。
うまくいけば下の画像のようにキャラクターが表示されます。
- 投稿日:2020-10-13T14:46:46+09:00
【Unity】特定のLayerだけPostProcessを適用する
こんにちはっ?八ツ橋まろんです
今回はUnityで『特定のレイヤーだけPostProcessを適用する』方法の解説です。
対象は
・PostProcessingStack
・Layer
がわかる人です。概説
そもそも特定のLayerだけPostProcessを適用したい時ってどんな時よ?って人向けの画像は以下です↓↓↓↓↓↓↓↓
ここでは眼とペンダント以外の全てのオブジェクトにPostProcessをかけて見た目をグレースケールにしています。かっこいい✨!!
UnityのPostProcessingStackはとても便利で使いやすいですが、基本的には「描画した全てのオブジェクトに対して適用されるもの」なので、特定のオブジェクトだけに適用することはできないのですが、CameraとLayerを使うことで疑似的に実現していきます。
やり方
?Cameraを3つ用意します。以下のように、どれか一つを親にして残りを子にしておくと後で楽です。
・1つめ:通常描画用のCamera
Clear Flags: Don't Clear
Culling Mask: PostProcessをかけたいオブジェクト以外を描画
Depth: 1・2つめ:PostProcess適用する用のCamera
Clear Flags: Don't Clear
Culling Mask: PostProcessをかけたいオブジェクトのみを描画
Depth: 0
PostProcessgLayer Componentを付ける・3つめ:Skybox描画用のCamera
Clear Flags: Skybox
Culling Mask: Nothing
Depth: 指定なし
Target Texture: 1920x1080など、Game画面に合わせた適当なRenderTextureを選択?Canvas (Raw Image)を用意します。Skybox描画用です。
・Raw Image:上記のRenderTextureを指定し、サイズはGame画面と同じに。
・Canvas:Render Mode: Screen Space-Cameraで1つ目のカメラを指定?PostProcessingVolumeを用意します。設定は自由です。
これで準備は完了です。2つ目のカメラに映るオブジェクトだけがPostProcessの影響を受けます。
解説
・Game画面に映るのはHierarchyにあるCameraに映るものをDepthの小さい順に並べた映像になります。
・Cameraが2個以上ある場合、デフォルトではClear FlagsがSkyboxなので、Depthの値が最も大きいCameraの映像のSkyboxによってそれ以外のCamera映像は上書きされ、Game画面に映りません。
・Clear FlagsがDon't ClearのCameraの映像は背景が透過した映像になるので、Game画面にはDepthの小さいCameraの映像も一緒に映ります。
・今回は2つ目のカメラにPostProcessが付いているため、それ以下のDepth値のCameraに映るオブジェクトは全てPostProcessが適用されます。
(Depthが-3,-2,-1,0のCameraがあったとして、-1のCameraにPostProcessが適用される場合、Depthの小さい順に描画するため-1のCamera描画時には-3と-2の映像は既に描画されており、その映像と-1のCamera映像をまるっと含めてPostProcessが適用される)・その性質上、SkyboxはDepthが最も小さいCameraで描画しないといけないですが、そうするとどうしてもPostProcessに影響されてしまうので、RenderTextureに描画して、Canvasを使ってDepthの高いCameraのScreenSpaceに描画することで、Depthが高く且つPostProcessよりも後に描画するという回避を行っています。
解説は以上となります。
その他応用
・親子構造にしたため、CinemachineなどでCameraを動かしたい場合、親のCameraを動かすことで子も一緒に追従するので便利です。
・CameraのField of viewなどのパラメータを変更したいとき、3つのCameraを全て変更しないといけませんが、以下のようなスクリプトを書けば親の変更が子に適用されるので便利です。([ExecuteAlways]のためEditor上でも動きます)CameraParamSync.csusing System.Collections; using System.Collections.Generic; using UnityEngine; [ExecuteAlways] public class CameraParamSync : MonoBehaviour { [SerializeField] Camera ParentCamera; [SerializeField] Camera[] ChildCamera; void Update() { if (ParentCamera != null && ChildCamera != null) { for (int i = 0; i < ChildCamera.Length; i++) { ChildCamera[i].fieldOfView = ParentCamera.fieldOfView; ChildCamera[i].nearClipPlane = ParentCamera.nearClipPlane; ChildCamera[i].farClipPlane = ParentCamera.farClipPlane; } } } }・HDRPの場合、Clear Flags: Don't Clearがないためこのままのやり方は適用できませんが、RenderTextureを複数枚使うことで上手く動かせると思います。
以上『特定のLayerだけPostProcessを適用する』でしたっ?
- 投稿日:2020-10-13T10:16:19+09:00
Unityでマイクから取得した音をVFX Graphで使用する
Unityでマイクから取得した音をVFX Graphで使用してみます。
基本的にはAudioSourceにマイクを設定し、そこから取得できる波形とスペクトラムを動的に生成したテクスチャに書き込んでVFX Graphのプロパティに渡すという流れになります。
マイクからの音の入力と解析に関しては以下の記事を参考にしました。
- Unity:マイクの音量を取得する(2) - Qiita
- Unity のオーディオの再生・エフェクト・解析周りについてまとめてみた - 凹みTips
- Unityでマイク入力からピッチ検出をするまで - Qiita
スクリプトでテクスチャを動的に生成してVFX Graphに渡す方法に関しては私が以前に書いた記事も参考にしてみてください。
使用したUnity等のバージョンは以下のようになっています。
- Unity: 2020.1.4f1 Personal
- Universal RP: 8.2.0
- Visual Effect Graph: 8.2.0
C#スクリプト
以下、C#スクリプトです。これをAudioSourceコンポーネントとVisualEffectコンポーネントを持つGameObjectに追加します。
using UnityEngine; using UnityEngine.VFX; [RequireComponent(typeof(AudioSource), typeof(VisualEffect))] public class VfxSoundSample : MonoBehaviour { AudioSource audioSource; VisualEffect visualEffect; // 波形データ長 // AudioSource.GetOutputDataから2の累乗である必要がある int outputLength = 256; // スペクトラムデータ長 // AudioSource.GetSpectrumDataから2の累乗である必要がある int spectrumLength = 256; // 波形データを格納する配列 float[] outputSamples; // スペクトラムデータを格納する配列 float[] spectrumSamples; // VFX Graphに渡す波形データを格納するテクスチャ Texture2D outputMap; // VFX Graphに渡すスペクトラムデータを格納するテクスチャ Texture2D spectrumMap; // 波形データのテクスチャ更新時に使用する配列 Color[] outputColors; // スペクトラムデータのテクスチャ更新時に使用する配列 Color[] spectrumColors; void Start() { audioSource = GetComponent<AudioSource>(); visualEffect = GetComponent<VisualEffect>(); // 配列の初期化 outputSamples = new float[outputLength]; spectrumSamples = new float[spectrumLength]; outputColors = new Color[outputLength]; spectrumColors = new Color[spectrumLength]; // 波形データのテクスチャの作成 outputMap = new Texture2D(outputLength, 1, TextureFormat.RFloat, false); outputMap.filterMode = FilterMode.Bilinear; outputMap.wrapMode = TextureWrapMode.Clamp; // スペクトラムデータのテクスチャの作成 spectrumMap = new Texture2D(spectrumLength, 1, TextureFormat.RFloat, false); spectrumMap.filterMode = FilterMode.Bilinear; spectrumMap.wrapMode = TextureWrapMode.Clamp; // 波形データのテクスチャをVFX Graphの「Output Map」というプロパティに設定 visualEffect.SetTexture("Output Map", outputMap); // スペクトラムデータのテクスチャをVFX Graphの「Spectrum Map」というプロパティに設定 visualEffect.SetTexture("Spectrum Map", spectrumMap); // AudioSourceにマイクを設定する audioSource.clip = Microphone.Start(null, true, 10, 44100); audioSource.loop = true; while(!(Microphone.GetPosition(null) > 0)) {} // 開始後すぐにマイク入力が取得できるように待つ audioSource.Play(); } void Update() { // 波形データの取得 audioSource.GetOutputData(outputSamples, 0); // スペクトラムデータの取得 audioSource.GetSpectrumData(spectrumSamples, 0, FFTWindow.Hamming); // 波形データのテクスチャを更新 for (var i = 0; i < outputLength; i++) { outputColors[i].r = outputSamples[i]; } outputMap.SetPixels(outputColors); outputMap.Apply(); // スペクトラムデータのテクスチャを更新 for (var i = 0; i < spectrumLength; i++) { spectrumColors[i].r = spectrumSamples[i]; } spectrumMap.SetPixels(spectrumColors); spectrumMap.Apply(); } }VFX Graph
使用したVFX Graphです。今回は単純に波形とスペクトラムを線グラフっぽくビジュアライズしています。スクリプトから設定するために
Output Map
とSpectrum Map
という名前のTexture2D形式のプロパティが必要になります。このテクスチャから横方向の位置をもとにサンプリングし、高さにと色に反映しています。上が波形データ、下がスペクトラムデータに対応しています。表示の都合上、スクリーンショットを分割していますが、実際には一つのVFX Graphの中に作成しています。結果
- 投稿日:2020-10-13T09:34:29+09:00
【Unity(Shader)】そろそろShaderをやるパート1 Unite 2017の動画を見る(基礎知識~フラグメントシェーダーで色を変える)
そろそろShaderをやります
そろそろShaderをやります。そろそろShaderをやりたいからです。
パート100までダラダラ頑張ります。10年かかってもいいのでやります。
100記事分くらい学べば私レベルの初心者でもまあまあ理解できるかなと思っています。※初心者がメモレベルで記録するので
技術記事としてはお力になれないかもしれません。下準備
いつの間にかShaderのサポートがてんこ盛りになってました。
【参考リンク】:Riderがサポートするシェーダー周りの機能メモ正直、強力な入力補間機能が無いことを言い訳にしてました。
完ぺきではないようですが、勝手に入力補間もコード整形もやってくれるらしいです。Unite 2017の動画
会社の強い人に入門動画を教えてもらいました。
少し古い動画ですが、たぶん大丈夫だと思います。【Unite 2017 Tokyo】シェーダープログラミング入門!カスタムシェーダー、作るで!
こんな人におすすめ
・シェーダーを使用してビジュアル改良方法を学びたいプログラマー
・Unityのグラフィックスの仕組みやカスタムシェーダーで何が達成できるか知りたいアーティスト
・シェーダーの基本構造と使用方法を理解したい学生受講者が得られる知見
・Unityのグラフィックス・パイプラインの仕組みとUnity シェーダーの基本構造
・カスタムシェーダーの作成方法
・頂点シェーダーとフラグメントシェーダーで使用される基本的な数学的コンセプト今回はフラグメントシェーダーを書き換えて色を変更するところまでやります。
Shaderの定義
A set of instructions that runs on the GPU
GPU上で実行されるインストラクション(プログラム)の集合 と講演では定義していました。
Vertex Shaders(頂点シェーダー)
頂点の位置を変えたり、頂点に情報を付加したりすることできます。
Input
頂点シェーダーはまずジオメトリから
複数の頂点の情報(座標、法線、色など)を受け取ります。ジオメトリとは、物質の形状、物質、可視属性、配置を定めたもの。3DCGでは、表示図形の座標計算部分のこと。
【参考リンク】:ジオメトリ
Output
新しい頂点座標、およびそのほかの情報を返します。
Fragment Shaders(ピクセルシェーダー)
ピクセルの色をスクリーンのオブジェクトに介して変えます。
Input
ピクセルとなるフラグメントを受け取ります。
フラグメントは、シェーディングしているピクセルの周りの3つの頂点の寄与から与えられる単純なデータです。
【参考リンク】:3Dグラフィックプログラミングのフラグメントとは何ですか?
Output
ピクセルの色、透明度を返します。
扱う言語
・CG(C for Graphics)
・ShaderLabC言語に似てるそうです。(C言語知らない)
精度に応じてfloat
、half
、fixed
を使い分けましょうとのことでした。扱うデータの大きさ?に応じて数字が後ろに付くそうです。
//カラーを扱いたい RGBA float4 color = float4(1,1,0,1); //法線ベクトルを扱いたい float3 normal = float3(0.2,0.5,0.3);Shaderサンプル
//Shaderの名前 Shader "UniteAsia/Shader01" { //サブシェーダー シェーダの中身を書くとこらしい 複数書けるとのこと //実行できない場合は最後にFallback "○○" と書いとけば○○で実行される SubShader { //パス Shader本体を書くとこらしい 複数書ける Pass { //タグ 透明度とか設定できるらしい Tags { "RenderType"="Opaque" } //こっから書きますよ みたいな宣言 CGPROGRAM //vertexシェーダーとfragmentシェーダーの関数がどれなのか伝える //実行モードにしなくても定義したらUnityが勝手に呼びだしてくれる #pragma vertex vert //vertという名前の関数がvertexシェーダーです と宣言している ※① #pragma fragment frag //fragという名前の関数がfragmentシェーダーです と宣言している ※② //便利関数詰め合わせセットらしい #include "UnityCG.cginc" //v2fという構造体を定義 Vertex to Fragment の略 //文字通りvertexシェーダーとfragmentシェーダーの間におけるデータのやりとりで使う //vertexシェーダーの結果をfragmentシェーダーに渡す struct v2f { //位置情報 ":" 以降の大文字はセマンティクスと言って必要なものだけ受け取るために用意されているらしい float4 pos : SV_POSITION; }; //①で "これがvertexシェーダーです" と宣言した関数 v2f vert(appdata_base v) //頂点の情報が引数に渡ってくる { //先ほど宣言した構造体のオブジェクトを作る v2f o; //"3Dの世界での座標は2D(スクリーン)においてはこの位置になりますよ" という変換を関数を使って行っている o.pos = UnityObjectToClipPos(v.vertex); //変換した座標を返す return o; } //②で "これがfragmentシェーダーです" と宣言した関数 half4 frag(v2f i) : COLOR //頂点シェーダからの入力(input)が引数に渡ってくる COLORは今はSV_Targetらしい { //色情報を返す R G B A return half4(1, 0, 0, 1); } //ここで終わりの宣言 ENDCG } } }適用したら赤くなりました。
フラグメントシェーダー内で返す色情報を変えると、
half4 frag(v2f i) : COLOR { //色情報を返す R G B A return half4(1, 1, 0, 1); }色が変わりました。
参考リンク
- 投稿日:2020-10-13T04:13:41+09:00
UnityにMixamoから取り込んだキャラクターのアニメーションを別のキャラクターに割り当てて動かす方法
なんで動かないのかな、と無駄に時間を消費してしまっていて理由がやっとわかったので、同じミスをまたしてしまう可能性があるのでここにまとめておきました。
結論から言うと、RigをHumanoidに変更していなくて別のキャラクターに割り当てられなかった、と言うのが答えです。
流れを見ていきましょう1:mixamoでアニメーションを割り当てたUnity用のfbxファイルをダウンロードする
<1>
.
.
.
.Assets > import New Assetからダウンロードファイルにダウンロードした先ほどのファイルを取り込む
<2>
.
.
.
.取り込んだばかりのファイルはRigがGenericになっており、他のオブジェクトに対してもアニメーションを割り当てたい時に使えるようにHumanoidに切り替える
<3-1>
.
.
.
..
.
.
.そうすると、存在しなかったアバターファイルがfbxファイルの子要素として生成されてるのを確認する
<4>
.
.
.
.他のキャラクターに対してもmixamoから取り込んだキャラクターに割り当てたアニメーションを使用できるようにAnimator Controllerを新規作成する
<5>
.
.
.
.Animator Controllerのタブから新規にアニメーションを割り当てて作成する
<6>
.
.
.
.startから矢印を引っ張ってアニメーションのルートを作る
<7>
.
.
.
.InspectorのMotionにmixamoからとりこんだキャラクターのアニメーションを割り当てる
<8>
.
.
.
.ループ再生にするためにアニメーションを割り当てたstateに対してMake Transitonで同じStateをクリックし、TransitionのSoloにチェックを入れる
<9>
.
.
.
..
.
.
.