LoginSignup
3
6

More than 5 years have passed since last update.

Unityでウディタのキャラクタ画像の向きと3Dオブジェクトの回転を連携させる

Posted at

前回、せっかくウディタ画像を利用できるようになったので、3D空間内でいいかんじに向き変更をやってみようと思う。

カメラを回転させる

オブジェクトを回転させる方法はいくつかあるようだけれど、今回は回転用のオブジェクトとカメラを別のオブジェクトにすることで責務の分担を試みる。
以下のように、Pivotオブジェクトを作って回転用スクリプト(Rotator)を新規作成、Pivotの子要素にカメラを置く。

image

Rotator.cs
using UnityEngine;

public class Rotator : MonoBehaviour {
    void Update () {
        gameObject.transform.Rotate(new Vector3(0f, 1f));
    }
}

結果。3Dと2Dの融合した不思議な世界。
elfsan.gif

スプライトの向きをオブジェクトに追随させる

次にスプライトがカメラに対して正面(というと変な言い方だけど)を向けるようにする。
これは超簡単。下のようなスクリプトをSpriteにアタッチして、TargetにさっきのPivotオブジェクトを指定すればいい。

DirectionFollower.cs
using UnityEngine;
public class DirectionFollower : MonoBehaviour {
    public GameObject Target;
    // Update is called once per frame
    void Update () {
        gameObject.transform.rotation = Target.transform.rotation;
    }
}

こうなる。
elfsan.gif

オブジェクトのrotateからキャラクタの向きを算出する

あとは前回のスクリプトに手を加えて、向きによって画像が変わるようにすればOK。

DirectionalSprite.cs
using UnityEngine;

public class DirectionalSprite : MonoBehaviour
{

    public enum Directions { N = 18, S = 0, E = 12, W = 6, NW = 15, NE = 21, SW = 3, SE = 9 }
    //
    public string Name;
    public SpriteRenderer SpriteRenderer;
    public Directions Direction;
    //
    private string _lastSpriteName = "";
    private Sprite[] _subsprites;
    // 
    void Start() {
        SetName(Name);
    }
    void LateUpdate() {
        // 現在のスプライトを得る
        string name = SpriteRenderer.sprite.name;
        // 向きが変化したか、スプライトが変化したならば画像を変更
        if (Compute2DDirection() == true || _lastSpriteName != name) {
            int idx = name.IndexOf('_');
            if (idx >= 0) {
                int id = int.Parse(name.Substring(idx + 1)) + (int)(Direction);
                SpriteRenderer.sprite = _subsprites[id];
            }
            _lastSpriteName = SpriteRenderer.sprite.name;
        }
    }
    // 名前からスプライトを作成
    public void SetName(string name) {
        Name = name;
        _subsprites = Resources.LoadAll<Sprite>("Units/" + name);
    }
    // 角度ごとの向き
    static readonly Directions[] dlist = {
        Directions.N, Directions.NW, Directions.W, Directions.SW,
        Directions.S, Directions.SE, Directions.E, Directions.NE };
    // Directionを算出する
    bool Compute2DDirection() {
        int idx = (int)(((transform.rotation.eulerAngles.y + 22.5f + 360f) % 360f) / 45f);
        bool return_val = (Direction != dlist[idx] ? true : false);
        Direction = dlist[idx];
        return return_val;
    }
}

こんな感じ。これはあくまでカメラの角度に追随しているだけなので、ゲームで動かすならさらにキャラクタの向きの情報を足しこむ必要がある。
elfsan.gif

3
6
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
3
6