使用滑动控件和transform.position问题播放动画Unity

时间:2019-04-16 13:39:04

标签: c# visual-studio unity3d

我已经设置了滑动控件来向左/右/上/下变换播放器,并且将移动限制在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 :(得分:0)

修改您的代码,而不仅仅是使用

transform.position = newPosition;

在所有位置使用

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

其中的smooth是float变量,将其指定为0.5f或所需的任何值

注意:实际作用是使游戏对象在每一帧的平滑值基础上移动很少

答案 1 :(得分:0)

请注意,我们不知道您的动画师设置。如果在这些动画剪辑中任何位置都有关键帧,那么动画师将始终否决脚本所做的一切!


您可以将CoroutineStartCoroutine一起使用,而不是立即设置新位置(也可以修复某些编码样式)

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))中,以模拟PC上的触摸。)

enter image description here