用触摸拖动对象并轻弹以抛出它?

时间:2015-10-11 01:07:27

标签: unity3d physics

我试图允许用户通过触摸在屏幕上拖动对象并抬起手指让对象“飞走”#34;在他们被移动的方向。

这就是我的尝试。

    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
        }

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

知道如何顺利​​完成这项工作吗?

修改

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

3 个答案:

答案 0 :(得分:2)

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

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();
    }
}

答案 1 :(得分:0)

如果你的意思是&#34;发布&#34;通过&#34;摧毁&#34;它,使用

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

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

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

答案 2 :(得分:0)

您可以使用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