iPhone上不规则的iOS触摸率



我三天前发布了这个问题,但收到的反馈是问题不清楚,所以我想再问一次。此外,随着我进一步研究,问题的范围也发生了变化(没有Unity问题!)

我正在为iOS制作一个游戏,你可以通过触摸屏幕的左侧或右侧来左右旋转对象。只要触摸显示器,对象就会旋转,并且在触摸结束时停止旋转。当我在实际的iPad/iPhone上运行游戏一段时间时,每隔几次触摸,对象的旋转就会停顿大约2秒。这种情况发生在大约5%的触球中。所有其他触摸都非常流畅。所有其他游戏动作在设定的60帧/秒的帧速率下运行良好。唯一移动不流畅的是旋转的对象,而游戏的其余部分都非常流畅。我试着把这个问题形象化在所附的图片上。参见此处

从视觉上看,触摸刷新率冻结了两秒钟。

造成这种情况的原因是什么?我该如何解决?

我用游戏引擎Unity创建了这个游戏。我使用以下版本:-Unity:2019.3.15f1-X代码:11-设备:iPhone x-iOS版本:13.5.1

经过大量研究,我发现这与团结无关。此外,在安卓设备上构建游戏时也没有问题。

复制步骤:

int rotation
private void FixedUpdate(){
for (int i = 0; i < Input.touchCount; i++)
{
Vector3 touchPos = Camera.main.ScreenToWorldPoint(Input.touches[i].position);
if (touchPos.x < 0)
{
rotation += 10;
}
else if (touchPos.x > 0)
{
rotation -= 10;
}
}
transform.Rotate(0, 0, rotation);
rotation = 0;
}
  1. 通过Unity中的c#对触摸输入进行编码(见上文)

  2. 在iOS平台上构建项目(创建xcodeproject)

  3. 在XCode中打开项目并在iPhone 上运行

有人能解决这个问题吗?

任何"输入";类应该在Update()中调用,而不是FixedUpdate()。

如果您试图在FixedUpdate()中获取输入数据,则会出现输入数据丢失。

例如,FixedUpdate可以在一个帧中执行两次,也可以在一帧中跳过。这就是它导致数据丢失或不准确的原因。

正确的解决办法是如下。

int rotation
private void Update()
{
for (int i = 0; i < Input.touchCount; i++)
{
Vector3 touchPos = Camera.main.ScreenToWorldPoint(Input.touches[i].position);
if (touchPos.x < 0)
{
rotation += 10 * time.deltaTime;
}
else if (touchPos.x > 0)
{
rotation -= 10 * time.deltaTime;
}
}
transform.Rotate(0, 0, rotation);
rotation = 0;
}

请注意,您当前的旋转方向是由相机的光线投射决定的。

如果你想按屏幕空间向左/向右旋转,这应该会更好。

private void Update()
{
int rotation = 0;
for (int i = 0; i < Input.touchCount; i++)
{
if (Input.touches[i].position.x < Screen.width/2)
{
rotation += 10 * time.deltaTime;
}
else
{
rotation -= 10 * time.deltaTime;
}
}
transform.Rotate(0, 0, rotation);
}

一般来说,我更喜欢通过检查最后一次触摸来进行简单的旋转脚本。

private void Update()
{
if(Input.touchCount > 0)
{
if (Input.touches[Input.touchCount-1].position.x < Screen.width/2)
{
transform.Rotate(0, 0, 10f * time.deltaTime);
}
else
{
transform.Rotate(0, 0, -10f * time.deltaTime);
}
}
}

或者,如果你真的想用FixedUpdate()同步输入,你可以做下面这样的事情。

bool HasTouch = false;
float SpeedRot = 0;
private void Update()
{
if(Input.touchCount > 0)
{
HasTouch = true;
if (Input.touches[Input.touchCount-1].position.x < Screen.width/2)
{
SpeedRot = 10f;
}
else
{
SpeedRot = -10f;
}
}
else
{
HasTouch = false;
}
}
private void FixedUpdate()
{
if(HasTouch) transform.Rotate(0, 0, SpeedRot * Time.fixedDeltaTime);
}

最新更新