【Unity(C#)】Oculus Integrationで手のマテリアル切り替え
デモ
オブジェクトに触れると手のマテリアルが触れたオブジェクトと同じものに変わります。
この情報だけでコードが頭の中に完成してしまう人も少なくないかと思いますが、
なぜか、望んだ結果が得られず原因特定に時間を要したのでメモしておきます。
望んだ結果が得られなかったコード
public class HandTriggerEnterEvent : MonoBehaviour
{
private MeshRenderer _meshRenderer;
private void Start()
{
_mshRenderer = this.gameObject.GetComponent<MeshRenderer>();
}
private void OnTriggerEnter(Collider other)
{
//この書き方については今回の本題ではないのでスルー安定
SkinnedMeshRenderer skinnedMeshRenderer = other.gameObject.transform.parent.parent.parent.GetComponent<SkinnedMeshRenderer>();
if (skinnedMeshRenderer != null)
{
Debug.Log("Get Color");
//マテリアルを手に適用
skinnedMeshRenderer.material = _meshRenderer.material;
}
else
{
Debug.Log("skinnedMeshRenderer is Null");
}
}
}
一見すると触れられたらマテリアルを手に反映させる
ただそれだけのコードで問題ないように思えますが、
マテリアルは変化しません。
原因
原因はOVRHandPrefab
にアタッチされたOVRMeshRenderer
のUpdate内のコードにありました。
private void Update()
{
IsDataValid = false;
IsDataHighConfidence = false;
ShouldUseSystemGestureMaterial = false;
if (IsInitialized)
{
bool shouldRender = false;
if (_dataProvider != null)
{
var data = _dataProvider.GetMeshRendererData();
IsDataValid = data.IsDataValid;
IsDataHighConfidence = data.IsDataHighConfidence;
ShouldUseSystemGestureMaterial = data.ShouldUseSystemGestureMaterial;
shouldRender = data.IsDataValid && data.IsDataHighConfidence;
}
if (_confidenceBehavior == ConfidenceBehavior.ToggleRenderer)
{
if (_skinnedMeshRenderer != null && _skinnedMeshRenderer.enabled != shouldRender)
{
_skinnedMeshRenderer.enabled = shouldRender;
}
}
if (_systemGestureBehavior == SystemGestureBehavior.SwapMaterial)
{
if (_skinnedMeshRenderer != null)
{
if (ShouldUseSystemGestureMaterial && _systemGestureMaterial != null && _skinnedMeshRenderer.sharedMaterial != _systemGestureMaterial)
{
_skinnedMeshRenderer.sharedMaterial = _systemGestureMaterial;
}
else if (!ShouldUseSystemGestureMaterial && _originalMaterial != null && _skinnedMeshRenderer.sharedMaterial != _originalMaterial)
{
_skinnedMeshRenderer.sharedMaterial = _originalMaterial;
}
}
}
}
#if UNITY_EDITOR
else
{
if (OVRInput.IsControllerConnected(OVRInput.Controller.Hands))
{
Initialize();
}
}
#endif
}
SystemGestureBehavior.SwapMaterial
というステートに設定している場合、
マテリアルが変更されてもすぐに_originalMaterial
に戻されてしまいます。
なので、Inspectorでデフォルト設定されているSystem Gesture Behavior
のSwapMaterial
をNone
に変更すればOKでした。
余談ですが、Confidence Behavior
は
デフォルトでToggle Renderer
に設定されているパラメーターで、
手のトラッキング状況に応じてRendererをオンオフして切り替えてくれます。
SystemGestureBehavior
System Gesture Behavior
は、OculusQuestのハンドトラッキング機能に
デフォルトで備わっている
"ホーム画面に戻るジェスチャーの予備動作(手のひらを自身に向ける)"に関わる機能です。
SwapMaterial
を設定している場合、
"ホーム画面に戻るジェスチャーの予備動作(手のひらを自身に向ける)"を行うと
手のマテリアルがSystem Gesture Material
に設定したマテリアルに変更されます。
もし、このSystem Gesture Behavior
のSwapMaterial
も利用しつつ
他のマテリアルとの入れ替えも実装したいとなった場合、
下記のように少しコードを書き換える必要があります。
if (_systemGestureBehavior == SystemGestureBehavior.SwapMaterial)
{
if (_skinnedMeshRenderer != null)
{
if (ShouldUseSystemGestureMaterial && _systemGestureMaterial != null && _skinnedMeshRenderer.sharedMaterial != _systemGestureMaterial)
{
Debug.Log("Get Current Material");
_originalMaterial = GetComponent<SkinnedMeshRenderer>().sharedMaterial;
_skinnedMeshRenderer.sharedMaterial = _systemGestureMaterial;
}
else if (!ShouldUseSystemGestureMaterial && _originalMaterial != null && _skinnedMeshRenderer.sharedMaterial == _systemGestureMaterial)
{
_skinnedMeshRenderer.sharedMaterial = _originalMaterial;
}
}
}
参考リンク
SkinnedMeshRenderer material from OVRHand prefab is overwritten every frame
Author And Source
この問題について(【Unity(C#)】Oculus Integrationで手のマテリアル切り替え), 我々は、より多くの情報をここで見つけました https://qiita.com/OKsaiyowa/items/2f8d18050a78acad5971著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .