在Unity中动态更改对象的速度

我需要一个物体根据动态时间上下移动。 确切的位置存储在名为Timings的List()中。 这将包含排序的条目,如0.90 1.895 2.64 3.98 …这些时间是相对于音乐的播放,所以它们可以与TheMusic.time进行比较。 (TheMusic是我的AudioSource)。

现在(见下面的代码),它使用moveSpeed静态上下移动。 我怎样才能这样做,或者在预定义的时间达到顶点和底点? 当它到达时间列表的末尾时,运动应该停止。

public class Patrol : MonoBehaviour { public Transform[] patrolPoints; //contains top and bottom position public float moveSpeed; //needs to be changed dynamically private int currentPoint; // Initialization void Start () { transform.position = patrolPoints [0].position; currentPoint = 0; } // Update is called once per frame void Update () { print (currentPoint); if (currentPoint >= patrolPoints.Length) { currentPoint = 0; } if (transform.position == patrolPoints [currentPoint].position) { currentPoint++; } transform.position = Vector3.MoveTowards (transform.position, patrolPoints[currentPoint].position, moveSpeed * Time.deltaTime); } } 

重要的是不要偏离绝对时间点。 例如,当计时到达1009这样的高峰时,应该没有多少漂移。

另请注意,其他事情(例如更改颜色和检查用户行为)需要同时发生,请参阅我的其他问题 。

解决方案的路径就是这个答案,它显示了随着时间的推移移动GameObject的function。

有了这个function,你可以启动一个协同程序,循环遍历包含beatsTimerList 。 在每个循环中,你应该有一个变量来确定你是否应该在每个循环后上升下降 。 在我的例子中,我将该变量命名为upDownMoveDecider 。 这个变量将决定使用patrolPoints数组的哪个索引。(我假设索引01只有两个点)。

此外,您可以每次调用for循环中的moveToX函数。 确保yield它以便在进入下一个函数之前等待moveToX函数完成或返回。


以下是应该是这样的:

 public Transform[] patrolPoints; //contains top and bottom position List beatsTimer = new List(); public Transform objectToMove; void Start() { //For testing purposes beatsTimer.Add(0.90f); beatsTimer.Add(1.895f); beatsTimer.Add(2.64f); beatsTimer.Add(3.98f); //Start the moveobject StartCoroutine(beginToMove()); } IEnumerator beginToMove() { // 0 = move up, 1 = move down int upDownMoveDecider = 0; //Loop through the timers for (int i = 0; i < beatsTimer.Count; i++) { if (upDownMoveDecider == 0) { //Move up Debug.Log("Moving Up with time: " + beatsTimer[i] + " in index: " + i); //Start Moving and wait here until move is complete(moveToX returns) yield return StartCoroutine(moveToX(objectToMove, patrolPoints[upDownMoveDecider].position, beatsTimer[i])); //Change direction to 1 for next move upDownMoveDecider = 1; } else { //Move down Debug.Log("Moving Down with time: " + beatsTimer[i] + " in index: " + i); //Start Moving and wait here until move is complete(moveToX returns) yield return StartCoroutine(moveToX(objectToMove, patrolPoints[upDownMoveDecider].position, beatsTimer[i])); //Change direction to 0 for next move upDownMoveDecider = 0; } } } IEnumerator moveToX(Transform fromPosition, Vector3 toPosition, float duration) { float counter = 0; //Get the current position of the object to be moved Vector3 startPos = fromPosition.position; while (counter < duration) { counter += Time.deltaTime; fromPosition.position = Vector3.Lerp(startPos, toPosition, counter / duration); yield return null; } } 

for循环中的代码很长,但更容易理解。 这是没有if/else语句的较短版本。

 //Loop through the timers for (int i = 0; i < beatsTimer.Count; i++) { //Move up/Down depening on the upDownMoveDecider variable string upDown = (upDownMoveDecider == 0) ? "Up" : "Down"; Debug.Log("Moving " + upDown + " with time: " + beatsTimer[i] + " in index: " + i); //Start Moving and wait here until move is complete(moveToX returns) yield return StartCoroutine(moveToX(objectToMove, patrolPoints[upDownMoveDecider].position, beatsTimer[i])); //Change direction upDownMoveDecider = (upDownMoveDecider == 1) ? 0 : 1; } 

添加一个float数组让我们说public float[] moveSpeedArray;

您可以根据需要在Start()或编辑器中填充此数组。

您已经获得了currentPoint并进行了更新。

将该currentPoint作为moveSpeedArray索引。

喜欢;

 transform.position = Vector3.MoveTowards (transform.position, patrolPoints[currentPoint].position, moveSpeedArray[currentPoint] * Time.deltaTime); 

因此,您可以将对象移动到不同预定义时间的位置。

希望这可以帮助! 干杯!

不要重新发明轮子。 使用补间库,例如iTween 。 为您定义了20多种缓动类型:

在此处输入图像描述

示例代码:

 iTween.MoveBy(gameObject,iTween.Hash( "x" , 2, "time", 0.2f ));