用触摸和轻弹拖动一个物体来扔掉它?

Drag an object with touch and flick to throw it?

我试图让用户通过触摸将对象拖过屏幕并抬起手指使对象 "fly away" 沿移动方向移动。

这就是我正在尝试的。

    Vector3 touchPosition = Camera.main.ScreenToWorldPoint (Input.mousePosition);
    Vector3 newPosition = new Vector3 (touchPosition.x, touchPosition.y, transform.position.z);
    velocity = newPosition - transform.position;

    // User is dragging the object around
    if(Input.GetMouseButton(0)) {
        transform.position = Vector2.Lerp(transform.position, newPosition, Time.deltaTime * 25f);
    }

    // User lifts finger
    if (Input.GetMouseButtonUp (0)){
            transform.GetComponent<Rigidbody2D>().AddForce(velocity, ForceMode2D.Force); // Also tried with transform.GetComponent<Rigidbody2D>().velocity = velocity; and transform.position += velocity; // The later works but doesn't allow for physics later on
        }

使用这种方法,对象在拖动时似乎帧率较低。此外,当 swiping/flicking 对象并不总是保持正确的方向并且它飞得非常慢(我可能必须将它乘以与每秒更新相关的因子但我不确定)。

知道如何使这项工作顺利进行吗?

编辑

我通过使用对象最后几帧的平均速度校正了轻弹对象时的方向,但我仍然无法获得正确的速度。拖动时帧率仍然很低(这可以通过使用物理方法而不是直接写入位置来纠正吗?)

如果你用 "destroying" 表示 "release",请使用

gameObject.SetActive(false); //Or 
Destroy(gameObject);

如果您希望保持当前移动速度:

rigidbody.velocity = new Vector3(x,y,z); //or alternatively:
rigidbody.AddRelativeForce (new Vector(x,y,z));

您可以在拖动对象时计算速度,并在释放对象后继续应用它。

Vector3 velocity;
..
void Update() {  
    if(Input.GetMouseButton(0)){
        Vector3 touchPosition = Camera.main.ScreenToWorldPoint (Input.mousePosition);
        velocity = new Vector3 (touchPosition.x, touchPosition.y, transform.position.z) - transform.position;
    }
    transform.position += velocity;
}

编辑:

如果你想让你的对象在被拖动时只受触摸位置的影响,你可以在刚体上设置isKinematic = true并设置它的位置 直接地。否则,您可以更新速度,使对象向触摸位置移动。 最后在 MouseButtonUp 上将速度设置为最后一帧的平均速度(如果拖动持续超过 10 帧,则最大值为 10)。

..        
    private PositionQueue pastPositions; 
    void Awake(){
        pastPositions = new PositionQueue(10);
    }

    void Update(){
        Vector3 touchPosition = Camera.main.ScreenToWorldPoint (Input.mousePosition);
        Vector3 newPosition = new Vector3 (touchPosition.x, touchPosition.y, transform.position.z);

        if(Input.GetMouseButtonDown(0)){
            //transform.GetComponent<Rigidbody2D>().isKinematic=true;  
            pastPositions.Clear();
        }
        // User is dragging the object around
        if(Input.GetMouseButton(0)) {   
            pastPositions.Enqueue(newPosition);
            //transform.position = newPosition;                      
            //transform.position = Vector2.Lerp(transform.position, newPosition, Time.deltaTime * 25f);
            transform.GetComponent<Rigidbody2D>().velocity = (newPosition - transform.position) * 10;
        }
        if (Input.GetMouseButtonUp (0)){
            //transform.GetComponent<Rigidbody2D>().isKinematic = false;   
            velocity = (newPosition - pastPositions.Peek()) / pastPositions.Count;
            transform.GetComponent<Rigidbody2D>().velocity = velocity * 20; // Also tried with transform.GetComponent<Rigidbody2D>().velocity = velocity; and transform.position += velocity; // The later works but doesn't allow for physics later on
        }
    }
}

class PositionQueue{
    private Queue<Vector3> _queue;
    private int _maxSize;
    public int Count {
        get {
            return _queue.Count;
        }
    }
    public PositionQueue(int maxSize){
        _maxSize = maxSize;
        _queue = new Queue<Vector3>();
    }
    public void Enqueue(Vector3 v){
        if(_queue.Count>=_maxSize){
            _queue.Dequeue();
        }
        _queue.Enqueue(v);
    }
    public Vector3 Peek(){
        return _queue.Peek();
    }
    public void Clear(){
        _queue.Clear();
    }
}

您可以使用 Input.GetTouch(i) 中的信息根据手指移动来移动对象,然后应用速度。

根据手指移动移动和轻弹场景对象

[SerializeField] float speedMultiplier = 1f;

void Update() {

    for (var i = 0; i < Input.touchCount; i++) {

        Touch touch = Input.GetTouch(i);

        if (touch.phase == TouchPhase.Moved) {

            transform.position = touch.position;

        } else if (touch.phase = TouchPhase.Ended) {

            velocity = touch.deltaPosition.magnitude / touch.deltaTime * speedMultiplier;

        }

    }    

}

来源:http://docs.unity3d.com/ScriptReference/Input.GetTouch.html