繁体   English   中英

适用于移动设备的 Unity 2D 轨迹预测

[英]Unity 2D Trajectory prediction for mobile

我需要移动轨迹预测方面的帮助。

我可以使用鼠标在 PC 上执行此操作,但无法使用移动设备上的触摸功能执行此操作。

我有我在开始时复制的点,当我拖动球时,我想计算我的轨迹。

触摸结束后我会摧毁这些点。

正如我所说,我可以使用Input.GetMouseButton /Up/Down 来做到这一点,但我无法使用触摸功能来做到这一点。

这是我的代码:

 private void Update()
{
    //if (Input.touchCount > 0)
    //{


        Touch touch = Input.GetTouch(0);

        if (touch.phase == TouchPhase.Began)
        {
            startPosition = Input.GetTouch(0).position;


            for (int i = 0; i < number; i++)
            {
                trajectoryDots[i] = Instantiate(trajectoryDot, gameObject.transform);

            } 

        }

        if (Input.touchCount > 0)
        {

            for (int i = 0; i < number; i++)
            {
                trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
            }
        }

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

            for (int i = 0; i < number; i++)
            {
                Destroy(trajectoryDots[i]);
            }

            endPoisiton = Input.GetTouch(0).position;
            force = startPosition - endPoisiton;
            ballRigid.gravityScale = 1;
            ballRigid.velocity = new Vector2(force.x * power, force.y * power);

        }

    //}
}

private Vector2 calculatePosition(float elapsedTime)
{

    return new Vector2(endPoisiton.x, endPoisiton.y) +
        new Vector2(force.x * power, force.y * power) * elapsedTime +
        0.5f * Physics2D.gravity * elapsedTime * elapsedTime;


}

我用于鼠标输入的代码

 if (Input.GetMouseButtonDown(0))
    { //click
        startPos = gameObject.transform.position;
        for (int i = 0; i < number; i++)
        {
            trajectoryDots[i] = Instantiate(trajectoryDot, gameObject.transform);
        }

    }
    if (Input.GetMouseButton(0))
    { //drag
        endPos = Camera.main.ScreenToWorldPoint(Input.mousePosition) + new Vector3(0, 0, 10);
        gameObject.transform.position = endPos;
        forceAtPlayer = endPos - startPos;
        for (int i = 0; i < number; i++)
        {
            trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
        }
    }
    if (Input.GetMouseButtonUp(0))
    { //leave
        rigidbody.gravityScale = 1;
        rigidbody.velocity = new Vector2(-forceAtPlayer.x * forceFactor, -forceAtPlayer.y * forceFactor);
        for (int i = 0; i < number; i++)
        {
            Destroy(trajectoryDots[i]);
        }
    }

所以经过一些小改动后,情况好多了,我越来越接近我想要的东西了,我猜仍然有一些故障是因为触摸。移动所以当我用手指显示并且只做一些小动作时,球在屏幕上跳跃这是代码

    private void Update()
{
    if (Input.touchCount > 0)
    {
        var touch = Input.GetTouch(0);
        switch (touch.phase)
        {
            case TouchPhase.Began:
                initPosition = gameObject.transform.position;
                startPosition = cam.ScreenToWorldPoint(touch.position) + new Vector3(0, 0, 10);
                for (int i = 0; i < number; i++)
                {
                    trajectoryDots[i] = Instantiate(trajectoryDot, gameObject.transform);
                    trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
                }

                break;

            case TouchPhase.Moved:

                endPosition = Camera.main.ScreenToWorldPoint(touch.position) + new Vector3(0, 0, 10);
                gameObject.transform.position = initPosition;
                force = startPosition - endPosition;
                for (int i = 0; i < number; i++)
                {
                    trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
                }
                break;

            case TouchPhase.Ended:
                ballRigid.gravityScale = 1;
                ballRigid.velocity = new Vector2(force.x * power, force.y * power);

                for (int i = 0; i < number; i++)
                {
                    Destroy(trajectoryDots[i]);
                }
                break;
        }
    }
}

private Vector2 calculatePosition(float elapsedTime)
{
    return new Vector2(initPosition.x, initPosition.y) +
    new Vector2(force.x * power, force.y * power) * elapsedTime +
    0.5f * Physics2D.gravity * elapsedTime * elapsedTime;
}

好的,我有最后的解决方案,它工作正常

    private void Update()
{
    if (Input.touchCount > 0)
    {
        var touch = Input.GetTouch(0);
        switch (touch.phase)
        {
            case TouchPhase.Began:
                initPosition = gameObject.transform.position;
                startPosition = cam.ScreenToWorldPoint(touch.position) + new Vector3(0, 0, 10);
                for (int i = 0; i < number; i++)
                {
                    trajectoryDots[i] = Instantiate(trajectoryDot, gameObject.transform);
                    trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
                }
                break;

            case TouchPhase.Ended:
                ballRigid.gravityScale = 1;
                ballRigid.velocity = new Vector2(force.x * power, force.y * power);

                for (int i = 0; i < number; i++)
                {
                    Destroy(trajectoryDots[i]);
                }
                break;
        }

        endPosition = Camera.main.ScreenToWorldPoint(touch.position) + new Vector3(0, 0, 10);
        gameObject.transform.position = initPosition;
        force = startPosition - endPosition;
        for (int i = 0; i < number; i++)
        {
            trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
        }
    }
}

private Vector2 calculatePosition(float elapsedTime)
{
    return new Vector2(initPosition.x, initPosition.y) +
    new Vector2(force.x * power, force.y * power) * elapsedTime +
    0.5f * Physics2D.gravity * elapsedTime * elapsedTime;
}

所以只要把你的鼠标代码转换成触摸代码,它可能看起来像

if(Input.touchCount > 0)
{
    var touch = Input.GetTouch(0);
    switch(touch.phase)
    {
        case TouchPhase.Began:
            // Note: to be more accurate you actually probably would 
            // rather also here use ScreenToWorldPoint on the touch.position
            // same way as later. Otherwise you might allways get a force even if touch wasn't moved at all
            //startPos = transform.position;
            startPos = Camera.main.ScreenToWorldPoint(touch.position) + new Vector3(0, 0, 10);
            for (int i = 0; i < number; i++)
            {
                trajectoryDots[i] = Instantiate(trajectoryDot, gameObject.transform);
                trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
            }

           break;

        case TouchPhase.Moved:
            // These were missing in your touch version
            // You did it only in the end so there were no preview trajectory
            // And note that also touch is in pixel screenspace so if you
            // want to use world positions you need to convert them just the same as for mouse input!
            endPos = Camera.main.ScreenToWorldPoint(touch.position) + new Vector3(0, 0, 10);
            transform.position = endPos;
            force = endPos - startPos;
            for (int i = 0; i < number; i++)
            {
                 trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
            }
            break;

        case TouchPhase.Ended:
            rigidbody.gravityScale = 1;
            // Not sure why but in your mouse code you used a negative force here 
            // but in this case your trajectory would have been wrong since there you didn't use negative values...
            rigidbody.velocity = force * forceFactor;

            for (int i = 0; i < number; i++)
            {
                Destroy(trajectoryDots[i]);
            }
            break;
    }
}

顺便说一句,计算方法变得更好读

private Vector2 calculatePosition(float elapsedTime)
{  
    return endPoisiton 
        + force * power * elapsedTime 
        + Physics2D.gravity * 0.5f * elapsedTime * elapsedTime;
}

注意:在智能手机上输入,但我希望这个想法变得清晰

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM