2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Unityで学ぶDecoratorパターン ~三人称視点のカメラを作る~

Last updated at Posted at 2018-09-30

前の記事 ― 目次

Zenjectが流行ってるけど、UnityのInspectorをDIコンテナに見立てて、デコレータパターンを実装する考察

作るもの

キャラクターの周りを旋回する三人称カメラを作成する。

通常はマウスの動きに合わせてカメラが動く。しかし、イベントリを表示するなどGUIを操作する際は動かしたくないので、それに備えてカメラが動く条件を装飾できるようにする。

準備

こんな感じでシーンを用意。

image.png

準備の説明は面倒なので、Githubで配布してます。

05-Decorator-FirstPerson-Base

コンポーネントの作成

デコレータパターンを実装するための、4つのコンポーネントを作ります。

CameraRotationBase

継承させて使う雛形のコンポーネント。
Rotationメソッドでゲームオブジェクトを回転させますが、値が0なので動かないです。

CameraRotationBase.cs
using UnityEngine;

public class CameraRotationBase : MonoBehaviour {
    
    virtual public float XValue { get { return 0; } }
    
    virtual public float YValue { get { return 0; } }

    public virtual void Rotation()
    {
        transform.localEulerAngles += new Vector3(YValue, XValue, 0);
    }
    
}

CameraRotationMouse

さきほどのコンポーネントを継承します。
値をマウスの動きでオーバーライドします。

CameraRotationMouse.cs
using UnityEngine;

public class CameraRotationMouse : CameraRotationBase
{
    override public float XValue { get { return Input.GetAxis("Mouse X"); } }
    
    override public float YValue { get { return Input.GetAxis("Mouse Y"); } }
    
}

CameraRotationClickDecorator

デコレータ用コンポーネント。
Rotationメソッドを右クリックを押していないと、呼ばれないようにデコレーションします。

ParameterPresenter.cs
using UnityEngine;

public class CameraRotationClickDecorator : CameraRotationBase
{
    public CameraRotationBase decorator;

    public int buttonIndex = 1;

    public override void Rotation()
    {
        if (Input.GetMouseButton(buttonIndex))
        {
            decorator.Rotation();
        }
    }
}

CameraControl

RotationメソッドをUpdateメソッドで呼び出すコンポーネントです。

cameraRotationはCameraRotationMouseかCameraRotationClickDecoratorを登録できます。

CameraControl.cs
using UnityEngine;

public class CameraControl : MonoBehaviour
{
    public CameraRotationBase cameraRotation;
    
    void Update()
    {
        cameraRotation.Rotation();
    }

}

完成

CameraControlのcameraRotationに登録するコンポーネントによって挙動が変わります。

CameraRotationMouseを登録した場合は常にマウスの動きに合わせてカメラが動くようになります。

image.png

CameraRotationClickDecoratorを登録した場合は右クリックを押していないとカメラが動きません。

image.png

比較のデモを記事上で披露できれば良いですが、ちょっと難しい。
完成版プロジェクトはこちら

06-Decorator-FirstPerson

まとめ

デコレータパターンで既にある機能に何かを加える例を紹介しました。

自分が書いたコードを誰かに改編される際に、
デコレータパターンで変更可能なコードにしておけば、既にあるコードを崩されずに処理を変えられます。

本来のデコレータパターンはinterfaceとか使って作るんだけど
inspectorの仕組み考慮したら、Unityではこんな感じで作ると良いかもしれない。

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?