[英]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.