Unity关于飞行效果的小思路(下)

之前讲了自己分解成不同的数学模型来实现,但是可随意性更改尺度不大,所以思考着用AnimationCurve实现,并简单搞了个编辑插件,方便让策划自己进行调整;这个也是参考了谁的,具体也忘记了,多谢那位大大;

以下是插件代码,能推导出具体实现,我就不贴具体实现代码了;

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class EditorCurves : EditorWindow
{
    private float xTime = 0;
    private float yTime = 0;
    private float startTime = 0;
    private bool bShowAni = false;
    private Vector3 startPos;
    public string actIdxStr = "15";

    AnimationCurve curveX = AnimationCurve.Linear(0, 0, 2, 2);
    AnimationCurve curveY = AnimationCurve.Linear(0, 0, 2, 2);

    [MenuItem("AniCurve/GenCurve")]
    static void Init()
    {
        EditorWindow window = GetWindow(typeof(EditorCurves));
        window.position = new Rect(200, 200, 340, 360);
        window.Show();
    }

    void OnGUI()
    {
        curveX = EditorGUI.CurveField(new Rect(3, 3, position.width - 6, 25), "Animation on X", curveX);

        curveY = EditorGUI.CurveField(new Rect(3, 43, position.width - 6, 25), "Animation on Y", curveY);

        GUI.Label(new Rect(3, 80, 200, 25), "Role Show Action Index");
        actIdxStr = GUI.TextField(new Rect(153, 80, position.width / 2, 25), actIdxStr);

        if (GUI.Button(new Rect(3, 120, position.width - 6, 30), "Generate And Show Curve"))
        {
            if (Selection.activeGameObject)
            {
                int actIdx = int.Parse(actIdxStr);
                FollowAnimationCurveShow comp = Selection.activeGameObject.GetComponent<FollowAnimationCurveShow>();
                if (comp == null)
                {
                    comp = Selection.activeGameObject.AddComponent<FollowAnimationCurveShow>();
                }
                curveX.postWrapMode = WrapMode.Once;
                curveX.preWrapMode = WrapMode.Once;
                curveY.postWrapMode = WrapMode.Once;
                curveY.preWrapMode = WrapMode.Once;
                comp.SetCurves(curveX, curveY, actIdx);
            }
            else
            {
                Debug.LogError("No Game Object selected for adding an animation curve");
            }
        }

        if (GUI.Button(new Rect(3, 160, position.width - 6, 30), "Print Curve Param"))
        {
            SetCurves();
        }
    }

    void SetCurves()
    {
        Debug.Log("水平动画曲线============================");
        int len = curveX.keys.Length;
        for (int i = 0; i < len; i++)
        {
            Keyframe key = curveX.keys[i];
            Debug.Log("time:" + key.time + "   value:" + key.value + "   inTangent:" + key.inTangent + "   outTangent:" + key.outTangent + "   tangentMode:" + key.tangentMode);
        }
        Debug.Log("============================");
        Debug.Log(" ");

        Debug.Log("垂直动画曲线============================");
        len = curveY.keys.Length;
        for (int i = 0; i < len; i++)
        {
            Keyframe key = curveY.keys[i];
            Debug.Log("time:" + key.time + "   value:" + key.value + "   inTangent:" + key.inTangent + "   outTangent:" + key.outTangent + "   tangentMode:" + key.tangentMode);
        }
        Debug.Log("============================");
    }
}

public class FollowAnimationCurveShow : MonoBehaviour
{
    public AnimationCurve curveX;
    public AnimationCurve curveY;

    private bool bShowAni = false;
    private float xTime = 0;
    private float yTime = 0;
    private float startTime = 0;
    private Vector3 startPos;
    private Vector3 endPos;
    private float endTime = 0;

    public void SetCurves(AnimationCurve tmpCurveX, AnimationCurve tmpCurveY, int showIdx)
    {
        if (bShowAni)
        {
            Debug.LogError("animation curve is begining, waitting a monment");
            return;
        }

        bShowAni = true;
        curveX = tmpCurveX;
        int len = tmpCurveX.keys.Length;
        for (int i = 0; i < len; i++)
        {
            Keyframe key = tmpCurveX.keys[i];
            xTime = key.time;
        }

        curveY = tmpCurveY;
        len = tmpCurveY.keys.Length;
        for (int i = 0; i < len; i++)
        {
            Keyframe key = tmpCurveY.keys[i];
            yTime = key.time;
        }
        startTime = Time.realtimeSinceStartup;
        startPos = transform.position;

        Animator []ani = transform.GetComponents<Animator>();
        if (ani != null && ani.Length > 0)
        {
            for (int i = 0; i < ani.Length; i ++)
            {
                ani[i].SetInteger("action", showIdx);
            }
        }
        
    }

    void Update()
    {
        if (! bShowAni)
        {
            if (Time.realtimeSinceStartup - endTime < 1)
            {
                transform.parent.transform.position = endPos;
            }
            else
            {
                transform.parent.transform.position = startPos;
            }
            return;
        }

        float h = 0;
        float d = 0;
        bool bEnd = true;
        float dt = Time.realtimeSinceStartup - startTime;
        if (curveX != null && dt <= xTime)
        {
            bEnd = false;
            d = curveX.Evaluate(dt) * 10;
        }

        if (curveY != null && dt <= yTime)
        {
            bEnd = false;
            h = curveY.Evaluate(dt) * 10;
        }
        
        if (bEnd)
        {
            endTime = Time.realtimeSinceStartup;
            bShowAni = false;
            Animator[] ani = transform.GetComponents<Animator>();
            if (ani != null && ani.Length > 0)
            {
                for (int i = 0; i < ani.Length; i++)
                {
                    ani[i].SetInteger("action", 0);
                }
            }
            return;
        }

        endTime = 0;
        float rotAngle = (90 - transform.eulerAngles.y) * Mathf.PI / 180;
        float posx = startPos.x + d * Mathf.Cos(rotAngle);
        float posy = startPos.y + h;
        float posz = startPos.z + d * Mathf.Sin(rotAngle);
        endPos = new Vector3(posx, posy, posz);
        transform.parent.transform.position = endPos;
    }
}

输出的参数填写到配置,然后根据配置的keys实现曲线运动轨迹效果,而且还可以增加其它变化,比如朝向啊之类的。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值