2012-06-03

【Unity】GUIでテクスチャの回転

これ、GUITextureクラスじゃできないらしいってことでメモ。
(GUITextureは拡縮程度ならできるんだけどなー)

ちなみに、GUIになるので、Translateは使えない。
直接GUI.matrixに作用させて描画をする必要がある。

が、そこはUnityさん。わざわざ行列作らないくとも、


GUIUtility.RotateAroundPivot

を使えば行列生成してくれる模様。
そのあとは、
GUI.DrawTexture
すればいいだけ。

GUI.matrixに変更がかかってしまうの、matrixを一時保存してから戻すとしてみるテスト。

public class UICompass : MonoBehaviour {

    [SerializeField]
    private Texture guiCompass;

    private Matrix4x4 tmpMat;
    private float angle;

    void Start () 
    {
        angleY = 0.0f;
    }

    public void SetAngle( float angle_ )
    {
        angle = angle_;
    }

    void OnGUI()
    {
        // テクスチャの回転はGUIUtility.RotateAroundPivotではないと回転できない
        tmpMat = GUI.matrix;    // 一時退避
        {
            Vector2 point = new Vector2(Screen.width * 0.5f, (float)Screen.height);
            GUIUtility.RotateAroundPivot(angle, point);
            GUI.DrawTexture(new Rect(Screen.width * 0.5f - guiCompass.width * 0.5f,
                                        Screen.height - guiCompass.height * 0.5f,
                                        (float)guiCompass.width,
                                        (float)guiCompass.height), guiCompass);
        }
        GUI.matrix = tmpMat;    // 戻す
    }
}

で、このクラスをてきとーなところにつけておいておいて、
これをプレイヤー側から、

private UICompass uiCompass;

    void Start () 
    {
        GameObject uiObj = GameObject.Find("/UI");
        if (uiObj) { 
            uiCompass = uiObj.GetComponent<UICompass>();
        }
    }

    void RotatePlayer() 
    {
        deltaRot = Quaternion.Euler(rotVec * Time.deltaTime);
        rigidbody.MoveRotation(rigidbody.rotation * deltaRot);
        uiCompass.SetAngle(transform.localEulerAngles.y);
    }


みたいな感じでやれば、追従して回ってくれる感じ。

わざわざSendMessageするほどのものでもないかなーと思って、
コンポーネントから引っ張りだして参照を保存しておく。

UICompassをPlayerのコンポーネントにしてもいいんだけど、
他の調整用スクリプトがくっついていたりしてインスペクタがみにくてしょうがない。
なので、UI系は空のGameObejctにまとめて記述することにした。

これでなんとなくすっきり。満足。

0 件のコメント: