Google VR SDKの入力クラスをZenjectで抽象化する
はじめに
Google VR SDKではGvrControllerInput
というクラスを通してstaticに入力を取得できます。
https://developers.google.com/vr/unity/reference/class/GvrControllerInput
例えばボタンのクリックは以下のように検知できます。
using UnityEngine;
public class Test : MonoBehaviour
{
void Update()
{
if (GvrControllerInput.ClickButton)
{
Debug.Log("ボタンがクリックされた");
}
}
}
今回はこの入力をZenjectを用いて抽象化することで、Google VR SDK以外の入力も扱えるようにしました。
実装
抽象クラスの定義
まずは入力の抽象クラスを定義します。
GoogleVRで拾える入力をそのまま抜き出した形です。
using UnityEngine;
public interface IHandController
{
Vector3 Position { get; }
Quaternion Orientation { get; }
Vector3 Gyro { get; }
Vector3 Accel { get; }
bool IsTouching { get; }
bool TouchDown { get; }
bool TouchUp { get; }
Vector2 TouchPos { get; }
Vector2 TouchPosCentered { get; }
bool Recentered { get; }
bool ClickButton { get; }
bool ClickButtonDown { get; }
bool ClickButtonUp { get; }
bool AppButton { get; }
bool AppButtonDown { get; }
bool AppButtonUp { get; }
bool HomeButtonDown { get; }
bool HomeButtonState { get; }
}
次に、GvrControllerInput
を直接呼び出していた実装を抽象クラスで置き換えます。
using UnityEngine;
using Zenject;
public class Test : MonoBehaviour
{
[Inject]
IHandController HandController = null;
void Update()
{
// 書き換え前
// if (GvrControllerInput.ClickButton)
// 書き換え後
if (HandController.ClickButton)
{
Debug.Log("ボタンがクリックされた");
}
}
}
GvrControllerInput
に依存しない状態になりました。
抽象クラスにZenjectで値を流しこむ
では実際にIHandController
に任意の入力を流し込んでみましょう。
まずは流し込みたい入力をIHandController
を継承して定義します。
以下はGvrControllerInput
を用いて実装した例です。
public class GvrHandController : IHandController
{
Transform controller = null;
public Vector3 Position { get { return (controller ?? (controller = GameObject.FindObjectOfType<GvrTrackedController>().transform)).position; } }
public Quaternion Orientation { get { return GvrControllerInput.Orientation; } }
public Vector3 Gyro { get { return GvrControllerInput.Gyro; } }
public Vector3 Accel { get { return GvrControllerInput.Accel; } }
public bool IsTouching { get { return GvrControllerInput.IsTouching; } }
public bool TouchDown { get { return GvrControllerInput.TouchDown; } }
public bool TouchUp { get { return GvrControllerInput.TouchUp; } }
public Vector2 TouchPos { get { return GvrControllerInput.TouchPos; } }
public Vector2 TouchPosCentered { get { return GvrControllerInput.TouchPosCentered; } }
public bool Recentered { get { return GvrControllerInput.Recentered; } }
public bool ClickButton { get { return GvrControllerInput.ClickButton; } }
public bool ClickButtonDown { get { return GvrControllerInput.ClickButtonDown; } }
public bool ClickButtonUp { get { return GvrControllerInput.ClickButtonUp; } }
public bool AppButton { get { return GvrControllerInput.AppButton; } }
public bool AppButtonDown { get { return GvrControllerInput.AppButtonDown; } }
public bool AppButtonUp { get { return GvrControllerInput.AppButtonUp; } }
public bool HomeButtonDown { get { return GvrControllerInput.HomeButtonDown; } }
public bool HomeButtonState { get { return GvrControllerInput.HomeButtonState; } }
}
これをIHandControllerとして呼び出せる形(Injectできる形)にする必要があります。
先ほどのTest.cs
クラスでいうと、この部分にGvrHandController
を流し込んでいきます。
[Inject]
IHandController HandController = null;
Zenjectの紹介記事ではよくZenjectBinding
が利用されていますが、今回はMonoBehavior
を継承していないクラスなので、コード上で紐づけを行います。
MonoInstaller
を継承したInstallerクラスで以下のようにBindすることができます。
Container.Bind<[抽象クラス]>().To<[派生クラス]>().AsSingle();
AsSingle()
は全てのInjectで再利用されるようにする指定です。
参考: #Binding - Zenject READMEの日本語訳 - Qiita
今回の実装例はこちらです。
using Zenject;
public class HandControllerInstaller : MonoInstaller<HandControllerInstaller>
{
public override void InstallBindings()
{
Container.Bind<IHandController>().To<GvrHandController>().AsSingle();
}
}
これをSceneContext
クラスを用いて呼び出します。
SceneContext
はScript Execute Orderで必ず初めに呼び出されるようになっているので、確実にInjectを実行することができます。
以上の作業で、抽象化した入力クラスに入力の定義を流し込むことが出来るようになりました。
おまけ:Oculusでの実装
GvrControllerInput
とは少し勝手が違いますが、こんな感じで行けると思います。
public class OvrHandController : IHandController
{
// public bool ClickButton { get { return GvrControllerInput.ClickButton; } }
public bool ClickButton { get { return OVRInput.Get(OVRInput.Button.PrimaryTouchpad); } }
}
参考: Oculus Goのコントローラ入力の取得まとめ - Qiita
まとめ
Zenjectで綺麗な設計やっていきましょう
Author And Source
この問題について(Google VR SDKの入力クラスをZenjectで抽象化する), 我々は、より多くの情報をここで見つけました https://qiita.com/nkjzm/items/06dfeccca506808b1cbf著者帰属:元の著者の情報は、元の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 .