Воспроизведение анимации с помощью прокрутки и проблемы с transform.position Unity - PullRequest
0 голосов
/ 16 апреля 2019

Я настроил свои прокрутки для преобразования моего игрока влево / вправо / вверх / вниз, и я ограничил движение на 3 линии; -1, 0, 1. Все работает нормально, но движение совсем не плавное, и игрок, похоже, «телепортируется» из одной позиции в другую. Я хотел сгладить движение, воспроизводя анимацию, но в результате анимация воспроизводилась после того, как игрок изменил свою позицию. Есть ли способ воспроизвести анимацию, когда игрок меняет свою позицию, или способ сгладить движение, чтобы оно выглядело правильно?

Я перепробовал все, и теперь я застрял с проблемой, пожалуйста, помогите

Вот мой код

  public class SwipeControls : MonoBehaviour {

    public float speed = 5.0f;
    private Vector3 startpos;  // start position
    private Vector3 endpos; //end position
    public int pozioma = 0;
    public int pionowa = 0;

    Animator anim;


    void Start() {
      GetComponent<Animator>();
    }

    void Update() {

      foreach (Touch touch in Input.touches) {

        Vector3 newPosition;
        if (touch.phase == TouchPhase.Began) {
          startpos = touch.position;
          endpos = touch.position;
        }

        if (touch.phase == TouchPhase.Moved) {
          endpos = touch.position;
        }

        if (touch.phase == TouchPhase.Ended) {
          newPosition = transform.position;

          if (Mathf.Abs(startpos.y - endpos.y) > Mathf.Abs(startpos.x - endpos.x)) {
            if ((startpos.y - endpos.y) > 100 && pionowa > -1) //swipe down
            {
              pionowa--;
              newPosition.y -= speed;
              transform.position = newPosition;
              anim.SetTrigger("Flydown");
            }

            if ((startpos.y - endpos.y) < -100 && pionowa < 1) //swipe up
            {
              pionowa++;
              newPosition.y += speed;
              transform.position = newPosition;
              anim.SetTrigger("Flyup");
            }
          }
          else {
            if ((startpos.x - endpos.x) > 100 && pozioma > -1)  //swipe left
            {
              pozioma--;
              newPosition.z -= speed;
              transform.position = newPosition;
              anim.SetTrigger("Flyleft");
            }
          }

          if ((startpos.x - endpos.x) < -100 && pozioma < 1) //swipe right
          {
            pozioma++;
            newPosition.z += speed;
            transform.position = newPosition;
            anim.SetTrigger("Flyright");
          }
        }
      }
    }
  }

Ответы [ 2 ]

0 голосов
/ 16 апреля 2019

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


Вместо немедленной установки новой позиции вы можете использовать Coroutine с StartCoroutine, как (также исправляя некоторые стили кодирования)

public class SwipeControls : MonoBehaviour
{
    // Flag for ignoring input until current animation finished
    private bool routineRunning;

    // Configure in the Inspector distance to swipe
    // in unity units
    [SerializeField] private float swipeDistance = 5;

    // configure this in the Inspector
    // How long should the swiping take in seconds
    [SerializeField] private float swipeDuration = 1;

    private Vector3 _startpos;  // start position
    private Vector3 _endpos; //end position

    public int pozioma = 0;
    public int pionowa = 0;

    private Animator _anim;


    private void Start()
    {
        GetComponent<Animator>();
    }

    private void Update()
    {
        // Ignore any Input while a routine is running
        if (routineRunning) return;

        foreach (var touch in Input.touches)
        {
            switch (touch.phase)
            {
                case TouchPhase.Began:
                    _startpos = touch.position;
                    _endpos = touch.position;
                    break;

                case TouchPhase.Moved:
                    _endpos = touch.position;
                    break;

                case TouchPhase.Ended:
                    if (Mathf.Abs(_startpos.y - _endpos.y) > Mathf.Abs(_startpos.x - _endpos.x))
                    {
                        if (_startpos.y - _endpos.y > 100 && pionowa > -1) //swipe down
                        {
                            pionowa--;
                            StartCoroutine(MoveSmooth(Vector3.up * -1, swipeDuration));
                            _anim.SetTrigger("Flydown");
                        }
                        else if (_startpos.y - _endpos.y < -100 && pionowa < 1) //swipe up
                        {
                            pionowa++;
                            StartCoroutine(MoveSmooth(Vector3.up, swipeDuration));
                            _anim.SetTrigger("Flyup");
                        }
                    }
                    else
                    {
                        if (_startpos.x - _endpos.x > 100 && pozioma > -1) //swipe left
                        {
                            pozioma--;
                            StartCoroutine(MoveSmooth(Vector3.forward * -1, swipeDuration));
                            _anim.SetTrigger("Flyleft");
                        }
                        else if (_startpos.x - _endpos.x < -100 && pozioma < 1) //swipe right
                        {
                            pozioma++;
                            StartCoroutine(MoveSmooth(Vector3.forward, swipeDuration));
                            _anim.SetTrigger("Flyright");
                        }
                    }
                    break;
            }
        }
    }

    private IEnumerator MoveSmooth(Vector3 direction, float duration)
    {
        routineRunning = true;

        var currentPosition = transform.localPosition;
        var targetPosition = currentPosition + direction * swipeDistance;

        var timePassed = 0f;
        do
        {
            // Additionally add some ease in and out to the movement to get 
            // even smoother movement
            var lerpFactor = Mathf.SmoothStep(0, 1, timePassed / duration);

            // Interpolate the position between currentPosition and targetPosition
            // using the factor between 0 and 1
            transform.localPosition = Vector3.Lerp(currentPosition, targetPosition, lerpFactor);

            // increase by time since last frame
            timePassed += Time.deltaTime;
            // let this frame render and go on from
            // here in the next frame
            yield return null;
        } while (timePassed <= duration);

        // To avoid over or undershooting in the end set a fixed value
        transform.localPosition = targetPosition;

        routineRunning = false;
    }
}

Я не знаю, почему вы используете y+= и z+= ... мне кажется, что это означает, что камера стоит в вашей сцене слева, например. с rotation = 0, -90, 0 и, например, position = 10, 0, 0 чем это должно быть в результате ( Примечание Я скопировал тот же код в if(GetMouseButtonDown(0)) и т. Д. Для имитации касания на ПК.)

enter image description here

0 голосов
/ 16 апреля 2019

Измените ваш код, вместо использования просто

transform.position = newPosition;

во всех позициях. Используйте

transform.position = Vector3.Lerp(transform.position, newPosition, smooth * Time.deltaTime);

, где smooth - переменная с плавающей запятой, присвойте ей требуемое значение, равное 0,5f или как вам угодно

Примечание: на самом деле он заставляет игровой объект двигаться немного в зависимости от сглаженного значения, каждый кадр

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...