在Unity

时间:2017-07-26 05:39:52

标签: c# unity3d

我需要一个物体根据动态时间上下移动。确切的位置存储在名为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这样的高峰时,应该没有多少漂移。

另请注意,其他内容(例如更改颜色和检查用户行为)需要同时进行,请参阅我的other question

3 个答案:

答案 0 :(得分:1)

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

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

您已收到currentPoint并正在更新。

currentPoint作为moveSpeedArray的索引。

像;

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

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

希望这有帮助!干杯!

答案 1 :(得分:0)

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

enter image description here

示例代码:

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

答案 2 :(得分:0)

解决方案的路径是this answer,它显示了随时间推移GameObject的功能。

掌握该功能后,您可以启动协程,循环遍历包含List的{​​{1}}。在每个循环内部,您应该有一个变量,用于确定在每次循环后是否应该向上向下。在我的例子中,我命名了变量beatsTimer。此变量将决定使用upDownMoveDecider数组的哪个索引。(我假设索引 0 1 只有两个点。)

此外,您每次都可以在patrolPoints循环内调用moveToX函数。确保for它以便在转到下一个函数之前等待yield函数完成或返回。

下面应该是这样的:

moveToX

public Transform[] patrolPoints; //contains top and bottom position List<float> beatsTimer = new List<float>(); 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