【问题标题】:Player don't move slowly ( smoothly)玩家不要缓慢移动(平稳)
【发布时间】:2019-05-13 01:34:52
【问题描述】:

当我在 InputField 中写“LEFT”并单击 UI 按钮时,我的游戏中有一个问题,立方体移动“LEFT”并吃硬币(向上、向下、向右相同)我的问题是当我将这段代码写在玩家移动的下方,但不是慢慢地消失,而不是出现在声明它的位置

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

public class GameManager : MonoBehaviour
{
    public InputField mainInputField;
    //public float speed;

    public GameObject Player;
    public Button Click_me;

    public float smoothing = 1f;
    public Transform TargetRight1;
    public Transform TargetRight2;
    public Transform TargetUP;

    // Start is called before the first frame update
    void Start()
    {

    }

    public void SubmitName()
    {
        string[] lines = mainInputField.text.Split('\n');
        for (int i = 0; i < lines.Length; i++)
        {
            if (lines[i] == "UP")
            {
                // moveUP();
                StartCoroutine(MyCoroutineUP(TargetUP));
            }
            else if (lines[i] == "DOWN")
            {
                //MoveDown();
            }
            else if (lines[i] == "LEFT")
            {
                //MoveLeft();
            }
            else if (lines[i] == "RIGHT")
            {
                StartCoroutine(MyCoroutineUP(TargetRight1));
            }
        }
        // Click_me.interactable = false;
    }

    IEnumerator MyCoroutineUP(Transform target)
    {
        while (Vector3.Distance(Player.transform.position, target.position) > 0.05f)
        {
            Player.transform.position = Vector3.Lerp(Player.transform.position, target.position, smoothing * Time.deltaTime);       
        }

        yield return null;
    }  
}

知道我是否将 yield return null; 像这样放在 while 循环中

while (Vector3.Distance(Player.transform.position, target.position) > 0.05f)
{
    Player.transform.position = Vector3.Lerp(Player.transform.position, target.position, smoothing * Time.deltaTime);
    yield return null;
}

玩家缓慢移动并获得硬币,但如果我有超过 2 法分,例如我写了 LEFT ,当我在第一行调用函数时,向上的 while 循环将无法正常工作。对不起我的英语

【问题讨论】:

  • 您的 TargetRight、TargetUp 到底是什么?它们是静止点还是一些硬币的位置?
  • TaargetUP ,TargetRight 是一个空的游戏对象,我希望玩家去它的特定位置

标签: c# unity3d coroutine


【解决方案1】:

你会得到并发的协程。

听起来您实际上要问的是如何堆叠多个命令并逐个处理它们。这有点复杂,但听起来像是 Queue 的完美用例

private readonly Queue<Transform> _commands = new Queue<Transform>();

public void SubmitName()
{
    var lines = mainInputField.text.Split('\n');
    mainInputField.text = "";
    foreach (var line in lines)
    {
        switch (line)
        {
            case "UP":
                // adds a new item to the end of the Queue
                _commands.Enqueue(TargetUp);
                break;

            case "DOWN":
                _commands.Enqueue(TargetDown);
                break;

            case "LEFT":
                _commands.Enqueue(TargetLeft);
                break;

            case "RIGHT":
                _commands.Enqueue(TargetRight);
                break;
        }
    }

    StartCoroutine(WorkCommands());
}

private IEnumerator WorkCommands()
{
    // block input
    Click_me.interactable = false;

    // run this routine until all commands are handled
    while (_commands.Count > 0)
    {
        // returns the first element and at the same time removes it from the queue
        var target = _commands.Dequeue();

        // you can simply yield another IEnumerator
        // this makes it execute and at the same time waits until it finishes
        yield return MovementCoroutine(target);
    }

    // when done allow input again
    Click_me.interactable = true;
}

致 lerping 本身:

我不会那样做的。这开始运动非常快,最后变慢,但从未真正到达目标位置。如果这就是你想要的离开它,但我宁愿建议做类似的事情

private IEnumerator MovementCoroutine(Transform target)
{
    var startPos = transform.position;
    var targetPos = target.position;

    var timePassed = 0f;

    do
    {
        var lerpFactor = Mathf.SmoothStep(0, 1, timePassed / smoothing);
        transform.position = Vector3.Lerp(startPos, targetPos, lerpFactor);

        timePassed += Time.deltaTime;
        yield return null;
    }
    while(timePassed < smoothing);

    // just to be sure there is no over or undershooting
    // in the end set the correct target position
    transform.position = targetPos;
}

smoothing 中,您将改为设置 lerping 应该花费的总时间(以秒为单位)。在我看来,这给了你更多的控制权。 SmoothStep 使运动仍在缓进缓出。

如果您愿意,您还可以另外考虑当前距离,以便通过添加/更改目标位置始终以或多或少相同的速度移动,无论目标位置有多近或多远

    var distance = Vector3.Distance(startPos, targetPos);
    var duration = smoothing * distance;

    do
    {
        var lerpFactor = Mathf.SmoothStep(0, 1, timePassed / duration);

        ...
    }
    while (timePassed < duration);

现在在smoothing 中,您希望以秒为单位设置对象移动 1 个 Unity 单位所需的时间。


当然我不知道你对目标的确切设置,但这就是目标附加到播放器时的样子(因此它们会随之移动)

【讨论】:

  • 好答案,如何在stackoverflow中添加gif?
  • @IgnacioAlorre 就像任何其他图像一样,只要它小于 2Mb ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-17
相关资源
最近更新 更多