首页 > 解决方案 > 为什么字符从不旋转?

问题描述

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

public class AnimatorController : MonoBehaviour
{
    [Header("Animators")]
    public Animator[] animators;
    [Space(5)]
    [Header("Movement Settings")]
    public Transform target;
    public float movingSpeed = 1f;
    public bool slowDown = false;
    [Space(5)]
    [Header("Rotation Settings")]
    public float rotationSpeed;

    private bool endRotation = false;
    private Vector3 targetCenter;
    private bool startWaitingAnim = true;

    // Use this for initialization
    void Start()
    {
        targetCenter = target.GetComponent<Renderer>().bounds.center;

        for (int i = 0; i < animators.Length; i++)
        {
            animators[i].SetFloat("Walking Speed", movingSpeed);
        }
    }

    // Update is called once per frame
    void Update()
    {
        float distanceFromTarget = Vector3.Distance(animators[2].transform.position, target.position);
        animators[2].transform.position = Vector3.MoveTowards(animators[2].transform.position, targetCenter, 0);

        if (slowDown)
        {
            if (distanceFromTarget < 10)
            {
                float speed = (distanceFromTarget / 10) / 1;
                for (int i = 0; i < animators.Length; i++)
                {
                    animators[i].SetFloat("Walking Speed", speed);
                }
            }
        }

        if (distanceFromTarget < 5f)
        {
            for (int i = 0; i < animators.Length; i++)
            {
                //animators[i].SetFloat("Walking Speed", 0);
                animators[i].SetBool("Idle", true);

                if (startWaitingAnim == true)
                {
                    StartCoroutine(WaitForAnimation());
                    startWaitingAnim = false;
                }
            }

            if (waitinganimation == true)
            {
                RotateAll(new Quaternion(0, -90, 0, 0),
                    Vector3.down, "Magic Pack", animators[2]);
            }

            RotateAll(new Quaternion(0, 180, 0, 0),
                    Vector3.up, "Rifle Aiming Idle",  animators[0]);

            RotateAll(new Quaternion(0, 180, 0, 0),
                    Vector3.down, "Rifle Aiming Idle", animators[1]);
        }
    }

    private void ApplyRotation(Quaternion goalRotation,
         Vector3 axis, string AnimationName, Animator anim)
    {
        if (!endRotation)
        {
            float angleToGoal = Quaternion.Angle(
                    goalRotation,
                    anim.transform.localRotation);
            float angleThisFrame = Mathf.Min(angleToGoal, 100 * Time.deltaTime);

            anim.transform.Rotate(axis, angleThisFrame);

            endRotation = Mathf.Approximately(angleThisFrame, angleToGoal);
        }
        else
        {
            anim.SetBool(AnimationName, true);
        }
    }

    void RotateAll(Quaternion rotation,
        Vector3 axis,
        string AnimationName, params Animator[] anims)
    {
        foreach (var anim in anims)
            ApplyRotation(rotation, axis, AnimationName, anim); // However you want to actually apply the rotation
    }

    bool waitinganimation = false;
    IEnumerator WaitForAnimation()
    {
        yield return new WaitForSeconds(3);
        waitinganimation = true;
    }
}

第一个问题是没有动画师在旋转。没有错误或异常,它只是不旋转。

我用断点检查了它是否进入:

if (!endRotation)

然后它到达 else 并播放动画播放动画很好,但它之前没有进行旋转。

这个想法是动画师中的每个动画师都会旋转到另一个轴/角度/方向。同时或取决于其他条件,如动画师[2],应该首先等待 waitinganimation 为真。

另一个问题是 animators[0] 和 [1] 的两行:

RotateAll(new Quaternion(0, 180, 0, 0),
                        Vector3.up, "Rifle Aiming Idle",  animators[0]);

                RotateAll(new Quaternion(0, 180, 0, 0),
                        Vector3.down, "Rifle Aiming Idle", animators[1]);

两者都旋转相同的角度但不同的轴。也许有一种方法可以扩展动画参数:

params Animator[] anims

所以我将能够写出类似的东西:

RotateAll(new Quaternion(0, 180, 0, 0),
           "Rifle Aiming Idle",  animators[0, Vector3.Up], animators[1, Vector3.Down]);

而是为每个轴更改添加一条线。

标签: c#unity3d

解决方案


使用欧拉角生成Quaternions 时,使用Quaternion.Euler.

一般来说,Quaternion除非您非常熟悉四元数数学,否则不要使用构造函数!

在您的特定情况下,使用Quaternion.Euler(0f, 180f, 0f)代替new Quaternion(0, 180, 0, 0)Quaternion.Euler(0f, -90f, 0f)代替new Quaternion(0, -90, 0, 0)


推荐阅读