2012年4月21日土曜日

Unity アニメーションイベント

マテリアルのシェーダーは Transparent/Diffuse を使用

TestGL2_b.cs

using UnityEngine;
//using System.Collections;
 
//[RequireComponent(typeof(Animation))]
public class TestGL2_b : MonoBehaviour {
    Vector3[]       m_VtxArray;                 // 頂点の配列
    Vector2[]       m_UvArray;                  // UVの配列
    Vector2         m_uvOffset = Vector2.zero;  // UVのオフセット

    public Material m_Mtl;                      // マテリアル

    AnimationCurve  m_animCurve;                // アニメカーブ

    AnimationEvent  m_animEvtStart;             // 開始イベント
    AnimationEvent  m_animEvtEnd;               // 終了イベント

    AnimationClip   m_animClip;                 // アニメクリップ
    string          m_animName = "anim1";       // アニメ名

    int             m_loopCount = 0;            // ループ回数

    public void Start () {
        // アニメコンポーネントを追加
        Animation anim = GetComponent();
        if(null == anim) anim = gameObject.AddComponent();
        
        // 頂点とUVの作成
        m_VtxArray = new Vector3[4];
        m_UvArray = new Vector2[4];

        m_VtxArray[0] = new Vector3(0.0f, 0.0f, 0.0f);  // BottomLeft
        m_VtxArray[1] = new Vector3(0.0f, 1.0f, 0.0f);  // TopLeft
        m_VtxArray[2] = new Vector3(1.0f, 0.85f, 0.0f); // TopRight
        m_VtxArray[3] = new Vector3(1.0f, 0.0f, 0.0f);  // BottomRight

        m_UvArray[0] = new Vector2(0.0f, 0.0f);
        m_UvArray[1] = new Vector2(0.0f, 1.0f);
        m_UvArray[2] = new Vector2(1.0f, 1.0f);
        m_UvArray[3] = new Vector2(1.0f, 0.0f);

        CreateAnim();
    }

    void OnRenderObject() {
        // フェードイン、アウトをループさせるテスト
        // マテリアルの色変更
        Color color = m_Mtl.GetColor("_Color");
        // アニメの時間取得
        float time = animation[m_animName].time;    // アニメーションの経過時間になる
        
        time -= m_loopCount * animation[m_animName].length;
        // アニメカーブの値を取得
        float value = m_animCurve.Evaluate(time);
        color.a = value;

        // マテリアルの色セット
        m_Mtl.SetColor("_Color", color);

        // 四角形を描画
        DrawQuad();
    }

    // アニメーションを作成
    void CreateAnim() {
        float startTime = 0.0f;
        float endTime = 5.0f;
        float midTime = (endTime - startTime) * 0.5f;

        // アニメカーブを作成
        m_animCurve = new AnimationCurve();

        // アルファ値のキーフレームを追加
        m_animCurve.AddKey( new Keyframe(startTime, 0.0f) );
        m_animCurve.AddKey( new Keyframe(midTime, 1.0f) );
        m_animCurve.AddKey( new Keyframe(endTime, 0.0f) );

        // アニメーションクリップを作成
        m_animClip = new AnimationClip();
        m_animClip.wrapMode = WrapMode.Loop;
        m_animClip.SetCurve("", typeof(Material), "_Color.a", m_animCurve);

        // アニメーションイベントを作成
        m_animEvtStart = new AnimationEvent();
        m_animEvtStart.time = startTime;
        m_animEvtStart.intParameter = 987;
        m_animEvtStart.stringParameter = "start";
        m_animEvtStart.functionName = "AnimEventStart";

        m_animEvtEnd = new AnimationEvent();
        m_animEvtEnd.time = endTime;
        m_animEvtEnd.intParameter = 123;
        m_animEvtEnd.stringParameter = "end";
        m_animEvtEnd.functionName = "AnimEventEnd";

        // クリップにイベントを追加
        m_animClip.AddEvent(m_animEvtStart);
        m_animClip.AddEvent(m_animEvtEnd);

        // アニメーションにクリップを追加
        animation.AddClip(m_animClip, m_animName);
        // アニメーションの再生開始
        animation.Play(m_animName);
    }

    // パラメータ数は 0個か1個 2個だと実行時にエラー
    void AnimEventStart(string s) {
        print("AnimEventStart() " + s);
    }

    void AnimEventEnd(string s) {
        m_loopCount++;
        print("AnimEventEnd() " + s);
    }

    void DrawQuad() {
        m_Mtl.SetPass(0);

        GL.PushMatrix();
        GL.LoadOrtho();
        // 左下が 0, 0, 0
        GL.Begin(GL.QUADS);
        for(int i = 0; i < 4; i++) {
            GL.TexCoord(m_UvArray[i] + m_uvOffset);
            GL.Vertex(m_VtxArray[i]);
        }
        GL.End();
        GL.PopMatrix();
        m_uvOffset.x -= 0.001f;
        m_uvOffset.y -= 0.001f;
    }
}