有更好的移动方式吗?

时间:2017-02-26 15:14:10

标签: c# unity3d

现在我这就是我的动作:

foreach (var touch in Input.touches) {
    if (touch.phase == TouchPhase.Began) {
        startPos = touch.position;
        endPos = touch.position;
    }
    if (touch.phase == TouchPhase.Moved) {
        endPos = touch.position;
    }

    if(touch.phase == TouchPhase.Ended){
        //Left
        if ((startPos.x - endPos.x) > 30) {
            Move (new Vector3 (-1, 0, 0));
        }
        //Right
        else if ((endPos.x - startPos.x) > 30) {
            Move (new Vector3 (1, 0, 0));
        }
        //Down
        else if ((startPos.y - endPos.y) > 30) {
            Move (new Vector3 (0, 0, -1));
        }
        //Up
        else {
            Move (new Vector3 (0, 0, 1));
        }
    }
}

这大部分时间都有效,但有时会走向错误的方向。我想通过向右滑动向左移动,向左滑动向左移动,向下滑动向后移动,向前移动或向前滑动向前移动。有没有更好的方法呢?

2 个答案:

答案 0 :(得分:0)

如果您只是想基于一次触摸移动,那么只需实现Unity的example,并在if(directionChosen)的位中,你只需要输入类似于以下处理前进。

    if (directionChosen) {
        Vector3 desiredVector = Vector3.zero
        if (direction.magnitude < 30){
            desiredVector = new Vector3(0,0,1);
        } else {
            desiredVector = new Vector3(direction.x,0,direction.y).normalized;
        }
        Move(desiredVector);
    }

但是,如果您希望跟踪所有触摸,并在其中一个触摸抬起时移动变换,则需要更复杂的解决方案。这是实现一些函数式编程原则的好机会,主要是:closure(ctrl + f“Closures”)。

这将允许您为每个Touch创建一个独特的功能,以跟踪所有必要的变量。一个示例实现就像是这样(它编译但我没有测试,因为我没有必要的设备。跳转它传达了这个想法):

using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TouchMover : MonoBehaviour {

    private float _speed;
    private Dictionary<int,Func<Touch, Vector3>> _touchFuncDict; 

    void Awake(){
        _touchFuncDict = new Dictionary<int,Func<Touch, Vector3>>();
    }

    void Update(){
        //Clean _touchFuncDict of any functions that reference a touch that is not active
       int[] touchIds = (int[])Input.touches.Select( x => x.fingerId);
       var keysToRemove = _touchFuncDict.Keys.Except(touchIds).ToList();
       foreach (var key in keysToRemove)
           _touchFuncDict.Remove(key);

        // Iterate through touches, and evaluate it's associate GetTouchVelocity function.
        // If we haven't created a function for it yet, then do so;
        foreach (var touch in Input.touches){
            Func<Touch,Vector3> getTouchVelocity = null;
            if (!_touchFuncDict.TryGetValue(touch.fingerId, out getTouchVelocity)){
                getTouchVelocity = GenerateTouchVelocityFunc(30);
                _touchFuncDict.Add(touch.fingerId,getTouchVelocity);
            }
            transform.position = transform.position + getTouchVelocity(touch) * _speed * Time.deltaTime;
        }
    }

    // Generates a function that requires a Touch parameter and will return a Vector3
    Func<Touch, Vector3> GenerateTouchVelocityFunc(int buffer){
        Vector2 startPos = Vector2.zero;
        Vector2 moveDelta = Vector2.zero;
        Vector3 desiredVelocity = Vector3.zero;

        Func<Touch, Vector3> getTouchVelocity = delegate(Touch touch){
            switch(touch.phase){
                case TouchPhase.Began:
                    startPos = touch.position;
                break;
                case TouchPhase.Moved:
                    moveDelta = touch.position - startPos;
                break;
                case TouchPhase.Ended:
                    if (moveDelta.magnitude > buffer){
                        desiredVelocity = new Vector3(moveDelta.x,0,moveDelta.y).normalized;
                    } else {
                       // this is your move forward on tap;
                       desiredVelocity = new Vector3(0,0,1);
                    }
                break;
            }
            return desiredVelocity;
        };  
        return getTouchVelocity;
    }

}

答案 1 :(得分:0)

如果你想沿着你开始的方向前进,你可以做类似下面的事情

        if (Input.touchCount > 0)
        {
            var touch = Input.GetTouch(0);

            switch (touch.phase)
            {
                case TouchPhase.Began:
                    startPos = touch.position;
                    break;
                case TouchPhase.Ended:
                    var swipeDistX = touch.position.x - startPos.x;
                    var swipeDistY = touch.position.y - startPos.y;

                    if (Mathf.Abs(swipeDistX) > Mathf.Abs(swipeDistY))
                    {
                        var swipeDirection = Mathf.Sign(swipeDistX);
                        if (swipeDirection > 0)
                        {
                            //swipe right
                        }
                        else
                        {
                            //swipe left
                        }
                    }
                    else
                    {
                        var swipeDirection = Mathf.Sign(swipeDistY);
                        if (swipeDirection > 0)
                        {
                            //swipe up
                        }
                        else
                        {
                            //swipe down
                        }
                    }
                    break;
            }
        }