Unity2D-----动画沿AnimationCurve曲线移动、缩放、旋转

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Ro969668074/article/details/80336842

同一场景中,可能需要多个动画在运行时能够移动、缩放、旋转,要么手动在Animation窗口中给动画添加AnchoredPosition等属性,要么每个动画都要写一个脚本来控制变化,操作起来各种麻烦。花了一点时间简化了下,如果你有更简洁的,欢迎大家留言。

在菜单工具栏中添加AboutMoveOrScaleOrRotate来移动、缩放或旋转需要改变的预制体。


代码如下:

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

public class AboutMoveOrScaleOrRotate : EditorWindow
{
    GameObject PrefabGo;
    //是否移动
    bool isMove = false;
    float rate_Position_X;
    float rate_Position_Y;
    AnimationCurve CurvePosition_X = AnimationCurve.Linear(0, 0, 10, 10);
    AnimationCurve CurvePosition_Y = AnimationCurve.Linear(0, 0, 10, 10);
    //是否缩放
    bool isScale = false;
    float rate_Scale;
    AnimationCurve CurveScale = AnimationCurve.Linear(0, 0, 10, 10);
    //是否旋转
    bool isRotate = false;
    float rate_Rotate_X;
    float rate_Rotate_Y;
    AnimationCurve CurveRotate_X = AnimationCurve.Linear(0, 0, 10, 10);
    AnimationCurve CurveRotate_Y = AnimationCurve.Linear(0, 0, 10, 10);

    //定义弹出当前窗口的菜单位置
    [MenuItem("Tools/AboutMoveOrScaleOrRotate")]
    static void Init()
    {
        //弹出窗口
        EditorWindow.GetWindow(typeof(AboutMoveOrScaleOrRotate));
    }
    void OnGUI()
    {
        int num = 0;
        PrefabGo = (GameObject)EditorGUILayout.ObjectField("预制体:", PrefabGo, typeof(GameObject));
        isMove = EditorGUILayout.Toggle("是否移动", isMove);
        if (isMove)
        {
            rate_Position_X = EditorGUILayout.FloatField("X轴移动距离倍率:", rate_Position_X);
            CurvePosition_X = (AnimationCurve)EditorGUILayout.CurveField("X轴移动曲线", CurvePosition_X);
            rate_Position_Y = EditorGUILayout.FloatField("Y轴移动距离倍率:", rate_Position_Y);
            CurvePosition_Y = (AnimationCurve)EditorGUILayout.CurveField("Y轴移动曲线", CurvePosition_Y);
            num += 4;
        }
        isScale = EditorGUILayout.Toggle("是否缩放", isScale);
        if (isScale)
        {
            CurveScale = (AnimationCurve)EditorGUILayout.CurveField("缩放曲线", CurveScale);
            rate_Scale = EditorGUILayout.FloatField("缩放大小倍率:", rate_Scale);
            num += 2;
        }
        isRotate = EditorGUILayout.Toggle("是否旋转", isRotate);
        if (isRotate)
        {
            rate_Rotate_X = EditorGUILayout.FloatField("X轴旋转角度倍率:", rate_Rotate_X);
            CurveRotate_X = (AnimationCurve)EditorGUILayout.CurveField("X轴旋转曲线", CurveRotate_X);
            rate_Rotate_Y = EditorGUILayout.FloatField("Y轴旋转角度倍率:", rate_Rotate_Y);
            CurveRotate_Y = (AnimationCurve)EditorGUILayout.CurveField("Y轴旋转曲线", CurveRotate_Y);
            num += 4;
        }
        if (GUI.Button(new Rect(Screen.width / 4, 80 + num * 20, Screen.width / 2, 30), "确   定"))
        {
            SureChange();
        }
    }
    void SureChange()
    {
        if ((!isMove && !isScale && !isRotate) || PrefabGo == null)
        {
            Debug.LogError("没有选择需要更改的项目或预制体");
            return;
        }
        if (isMove || isScale || isRotate)
        {
            AboutAnimationCurve comp = PrefabGo.AddComponent<AboutAnimationCurve>();
            if (isMove)
            {
                if (rate_Position_X != 0)
                {
                    comp.CurvePosition_X = CurvePosition_X;
                    comp.Position_rateX = rate_Position_X;
                }
                if (rate_Position_Y != 0)
                {
                    comp.Position_rateY = rate_Position_Y;
                    comp.CurvePosition_Y = CurvePosition_Y;
                }
            }

            if (isScale)
            {
                comp.CurveScale = CurveScale;
                comp.Scale_rate = rate_Scale;
            }
            else
            {
                comp.Scale_rate = 1.0f;
            }
            if (isRotate)
            {
                if (rate_Rotate_X != 0)
                {
                    comp.CurveRotate_X = CurveRotate_X;
                    comp.Rotate_rateX = rate_Rotate_X;
                }
                if (rate_Rotate_Y != 0)
                {
                    comp.Rotate_rateY = rate_Rotate_Y;
                    comp.CurveRotate_Y = CurveRotate_Y;
                }
            }

        }
    }
}

Curve窗口中的横坐标是时间轴,纵坐标是物体改变的X轴或Y轴。如物体需要横向平移,0-10秒从0移动到10,10-20秒再从10移动到0,以此循环。移动距离是由倍率和纵坐标的起点和终点决定的。修改倍率和曲线就可实现物体上下左右移动、缩小放大以及旋转

using UnityEngine;
using System.Collections;

public class AboutAnimationCurve : MonoBehaviour
{
    public float Position_rateX;
    public AnimationCurve CurvePosition_X;
    public float Position_rateY;
    public AnimationCurve CurvePosition_Y;
    public float Scale_rate;
    public AnimationCurve CurveScale;
    public float Rotate_rateX;
    public AnimationCurve CurveRotate_X;
    public float Rotate_rateY;
    public AnimationCurve CurveRotate_Y;
    void Update()
    {
        if (CurvePosition_X != null || CurvePosition_Y!=null)
        {
            transform.position = new Vector3(CurvePosition_X.Evaluate(Time.time) * Position_rateX, CurvePosition_Y.Evaluate(Time.time) * Position_rateY, 0);
        }
        if (CurveScale != null && Scale_rate!=1)
        {
            transform.localScale = new Vector3(CurveScale.Evaluate(Time.time) * Scale_rate, CurveScale.Evaluate(Time.time) * Scale_rate, 0);
        }
        if (CurveRotate_X != null || CurveRotate_Y != null)
        {
            transform.rotation = Quaternion.Euler(new Vector3(CurveRotate_X.Evaluate(Time.time) * Rotate_rateX, CurveRotate_Y.Evaluate(Time.time) * Rotate_rateY, 0));
        }
    }
}

展开阅读全文

没有更多推荐了,返回首页