简体   繁体   English

随着时间的推移移动游戏对象

[英]Move GameObject over time

I am learning Unity from a Swift SpriteKit background where moving a sprite's x Position is as straight forward as an running an action as below:我正在从 Swift SpriteKit 背景中学习 Unity,其中移动精灵的 x Position 就像运行如下操作一样简单:

let moveLeft = SKAction.moveToX(self.frame.width/5, duration: 1.0)
let delayAction = SKAction.waitForDuration(1.0)
let handSequence = SKAction.sequence([delayAction, moveLeft])
sprite.runAction(handSequence)

I would like to know an equivalent or similar way of moving a sprite to a specific position for a specific duration (say, a second) with a delay that doesn't have to be called in the update function.我想知道将精灵移动到特定 position 特定持续时间(例如一秒)的等效或类似方法,延迟不必在更新 function 中调用。

gjttt1's answer is close but is missing important functions and the use of WaitForSeconds() for moving GameObject is unacceptable. gjttt1 的答案很接近,但缺少重要功能,并且使用WaitForSeconds()移动GameObject是不可接受的。 You should use combination of Lerp , Coroutine and Time.deltaTime .您应该结合使用LerpCoroutineTime.deltaTime You must understand these stuff to be able to do animation from Script in Unity.您必须了解这些内容才能在 Unity 中通过 Script 制作动画。

public GameObject objectectA;
public GameObject objectectB;

void Start()
{
    StartCoroutine(moveToX(objectectA.transform, objectectB.transform.position, 1.0f));
}


bool isMoving = false;

IEnumerator moveToX(Transform fromPosition, Vector3 toPosition, float duration)
{
    //Make sure there is only one instance of this function running
    if (isMoving)
    {
        yield break; ///exit if this is still running
    }
    isMoving = true;

    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;
    }

    isMoving = false;
}

Similar Question: SKAction.scaleXTo类似问题: SKAction.scaleXTo

The answer of git1 is good but there is another solution if you do not want to use couritines. git1 的答案很好,但如果您不想使用 couritines,还有另一种解决方案。

You can use InvokeRepeating to repeatedly trigger a function.您可以使用InvokeRepeating重复触发一个函数。

float duration; //duration of movement
float durationTime; //this will be the value used to check if Time.time passed the current duration set

void Start()
{
    StartMovement();
}

void StartMovement()
{
    InvokeRepeating("MovementFunction", Time.deltaTime, Time.deltaTime); //Time.deltaTime is the time passed between two frames
    durationTime = Time.time + duration; //This is how long the invoke will repeat
}

void MovementFunction()
{
    if(durationTime > Time.time)
    {
        //Movement
    } 
    else 
    {
        CancelInvoke("MovementFunction"); //Stop the invoking of this function
        return;
    }
}

You can use co-routines to do this.您可以使用协同程序来做到这一点。 To do this, create a function that returns type IEnumerator and include a loop to do what you want:为此,请创建一个返回类型IEnumerator的函数并包含一个循环来执行您想要的操作:

private IEnumerator foo()
{
    while(yourCondition) //for example check if two seconds has passed
    {
        //move the player on a per frame basis.
        yeild return null;
    }
}

Then you can call it by using StartCoroutine(foo())然后你可以使用StartCoroutine(foo())调用它

This calls the function every frame but it picks up where it left off last time.这会在每一帧调用该函数,它会从上次停止的地方开始。 So in this example it stops at yield return null on one frame and then starts again on the next: thus it repeats the code in the while loop every frame.所以在这个例子中,它在一帧的yield return null处停止,然后在下一帧再次开始:因此它每帧重复while循环中的代码。

If you want to pause for a certain amount of time then you can use yield return WaitForSeconds(3) to wait for 3 seconds.如果你想暂停一段时间,那么你可以使用yield return WaitForSeconds(3)等待 3 秒。 You can also yield return other co-routines!你也可以yield return其他协程! This means the current routine will pause and run a second coroutine and then pick up again once the second co-routine has finished.这意味着当前例程将暂停并运行第二个协程,然后在第二个协程完成后再次启动。

I recommend checking the docs as they do a far superior job of explaining this than I could here我建议检查文档,因为它们在解释这一点方面做得比我在这里要好得多

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM