【发布时间】:2019-01-11 04:54:12
【问题描述】:
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 并播放动画/s 播放动画很好,但之前没有进行旋转。
这个想法是动画师中的每个动画师都会旋转到另一个轴/角度/方向。同时或取决于其他条件,如动画师[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]);
而是为每个轴更改添加一条线。
【问题讨论】:
-
确保这是一个非常基本的场景,只有这个脚本的一个实例,如果你有这个脚本的多个实例,那么其中一些实例可能会遇到其他情况,因此你是进入其他地方。
-
除非你非常熟悉四元数数学,否则不要使用
Quaternion构造函数。请改用Quaternion.Euler。如果您使用Quaternion.Euler(0f,180f,0f)而不是new Quaternion(0, 180, 0, 0)和Quaternion.Euler(0f,-90f,0f)而不是new Quaternion(0, -90,0,0),会发生什么? -
@Ruzihm 我现在试试。
-
@Ruzihm 非常感谢它正在使用 Euler