Игрок не двигается медленно (плавно) - PullRequest
1 голос
/ 13 мая 2019

У меня есть вопрос, пожалуйста, в моей игре, когда я пишу «ВЛЕВО» в поле ввода и нажимаю на кнопку пользовательского интерфейса, куб перемещается «ВЛЕВО» и есть монеты (то же самое для вверх, вниз, вправо), моя проблема заключается в том, когда янаписал этот код ниже, игрок двигался, но не медленно, скорее исчезать, чем появляться в позиции, которая объявляет его

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, UP цикл while не будет работать должным образом, когда я вызываю функцию в первой строке.извините за мой английский

Game image

1 Ответ

2 голосов
/ 13 мая 2019

Вы получите одновременные сопрограммы.

Похоже, что вы на самом деле спрашиваете, как составлять несколько команд и обрабатывать их одну за другой.Это становится немного сложнее, но звучит как идеальный вариант использования для 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;
}

Для самого прыгающего:

Я бы не сталвот так вот.Это начинает движение очень быстро и, в конце концов, замедляется, но никогда не достигает целевой позиции.Если это то, что вы хотите, оставьте это, но я бы лучше порекомендовал сделать что-то вроде

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 вы бы вместо этого установили время в секундах, которое должен занимать в целом прыжок.На мой взгляд, это дает вам больше контроля.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 единицу единства.


Я не знаю ваших точных настроек для целей курса, но вот как это будет выглядеть с целями, прикрепленными к игроку (поэтому они двигаются вместе с ним)

enter image description here

...