美文网首页Unity技术分享程序员首页推荐
「Unity3D」(8)Rigidbody2D卡顿问题和重心旋转

「Unity3D」(8)Rigidbody2D卡顿问题和重心旋转

作者: 飞机王 | 来源:发表于2017-12-13 22:41 被阅读51次

本文主要讨论,在Unity中使用物理引擎Physics2D的三个方面的内容:

  • 如何让Rigidbody2D物理模拟看起来更加的顺滑。
  • 介绍几个造成运动卡顿的原因和解决方法。
  • 针对Rigidbody2D的重心旋转模拟。

让运动更加顺滑

最直接的方法,就是设置Rigidbody2D的Interpolate属性,面板属性提供了下拉选项,有None,Interpolate,Extrapolate。官方文档介绍的很清晰,这是物理模拟在Update过程中的运动插值计算,用来解决运动生涩(卡顿)的问题。

  • None 不进行平滑插值。
  • Interpolate 运动插值基于前几帧的位置。在一个相对平稳的运动环境里是有很好效果的。但如果是颠簸,崎岖的运动环境,前几帧的插值并不能很好的反应未来的趋势。
  • Extrapolate 运动插值基于后几帧的预测位置。根据物理公式和地形预测,可以很好的估算出未来几帧的情况,但遇到突然的碰撞或外力影响,就无法得到很好的效果。

经过测试发现,如果Rigidbody2D的所有的父节点是固定不动的(没有手动控制),Interpolate 和 Extrapolate 一样顺滑,并且要比None来的流畅。如果Rigidbody2D的父节点有运动(手动控制),Interpolate会有明显的卡顿,Extrapolate 和 None 差不多,但是依然是不流畅的。

卡顿问题

抛开性能问题,我遇到的卡顿来自于两个原因。第一,就是上面所说的Rigidbody2D的父节点发生了运动,造成了物理运动有明显的生涩感。第二,就是手动设置了Rigidbody2D的transform属性,如Position,Rotation,Scale等。

其实,这两个问题是同一个原因,就是不要手动设置和Rigidbody2D相关的transform属性,包括父类链的所有节点。物理引擎会接管一切运动模拟,引擎会有自己的算法预测,手动设置会造成冲突。

经过测试发现,哪怕使用了Rigidbody2D的Constraints约束,Freeze Position 或 Freeze Rotation 之后,依然不能去手动设置锁住的属性,否则依旧会造成卡顿。

那如果遇到了必须要手动设置的需求,应该怎么办呢 ? 这时候可以使用Rigidbody2D暴露的接口去控制。

Rigidbody2D.position
Rigidbody2D.rotation
Rigidbody2D.MovePosition
Rigidbody2D.MoveRotation

Rigidbody2D 暴露了两个属性和两个方法,用来设置position和rotation。经过测试发现,设置属性依然卡顿,但使用Move方法就消除了卡顿的现象。所以,手动改变Rigidbody2D的position和rotation使用其暴露的Move方法是最好的办法。

重心旋转

在使用Rigidbody2D的过程中,期望能够实现,因为重心在运动中产生自发旋转的效果,比如弓箭的飞行模拟。

开始使用了centerOfMass,强行把刚体的质心移动到物体边缘或外部,期望质心能够在重力作用下,形成旋转力,结果不尽人意,自由落体的时候作用很小,反而碰撞接触了产生了很大的效用。

后来,使用了Rigidbody2D的angularVelocity角速度设置,并且Freeze Rotation锁住了刚体本身的旋转模拟,让angularVelocity无干扰的发挥作用。其结果是可以工作,但是效果不够真实,angularVelocity并没有衰减而且是一个固定的速率,难道还需要每帧去模拟angularVelocity的变化,太过繁琐。

最终,使用了每帧去计算rotation的数值,并Freeze Rotation锁住旋转,得到了很好的效果。大概实现如下:

private void FixedUpdate()
{
    if (this.body2D.bodyType == RigidbodyType2D.Dynamic)
    {
        var deltaTime = Time.fixedDeltaTime * 0.5f * this.transform.localScale.x > 0 ? 1.0f : -1.0f;
        var v2        = this.body2D.velocity;
        // s = (v0 + v1) * t / 2
        this.body2D.MoveRotation(Mathf.Atan2(v2.y * deltaTime, v2.x * deltaTime) * Mathf.Rad2Deg);
    }
}

根据当前刚体的速度,计算一帧的xy方向的运动距离,通过Atan2来计算出旋转角度,在FixedUpdate中手动设置给刚体,当然要使用MoveRotation来得到流畅的旋转效果。


「Extrapolate」

相关文章

  • 「Unity3D」(8)Rigidbody2D卡顿问题和重心旋转

    本文主要讨论,在Unity中使用物理引擎Physics2D的三个方面的内容: 如何让Rigidbody2D物理模拟...

  • 应用卡顿问题分析

    1.应用卡顿原理分析 卡顿问题的表现启动卡顿:启动白屏和启动动画卡顿运行卡顿:点击相应慢,列表滑动卡,动画卡顿 原...

  • android继承RadioGroup实现添加小红点 旋转dra

    github.com源码库 实现了加小红点,以及解决原来的drawableTop旋转 不能调节速度问题,卡顿问题 ...

  • Android性能优化-App卡顿

    目录 1.卡顿简介 2.检测Jank:介绍监测卡顿的方法 3.修复卡顿问题:介绍如何修复卡顿问题; 4.卡顿通常的...

  • 一文读懂直播卡顿优化那些事儿

    希望本文可以带给大家一个相对全局的视角看待卡顿问题,认识到卡顿是什么、卡顿的成因、卡顿的分类、卡顿的优化和一些经验...

  • 如何避免卡顿掉帧

    本次初步讨论两个问题: Native 卡顿 网页卡顿 Native卡顿 iOS客户端卡顿已经是老生常谈的问题了,解...

  • 深入卡顿优化

    前言 我们经常会遇到卡顿问题 而且卡顿问题往往很难解决与复现 非常的依赖卡顿现场 所以我们来深入分析一下卡顿优化 ...

  • 21-性能优化

    一、CPU和GPU 二、卡顿产生的原因和优化 卡顿优化-CPU 卡顿优化-GPU 卡顿监测 监控卡顿的demo:推...

  • CABasicAnimation 旋转动画

    使用CABasicAnimation 进行旋转动画时,如果进行断续操作,在启动的瞬间,可能会出现旋转卡顿现象,其问...

  • webstrom 卡顿问题

    wenstrom官网 : http://www.jetbrains.com/webstorm/webstorm强大...

网友评论

    本文标题:「Unity3D」(8)Rigidbody2D卡顿问题和重心旋转

    本文链接:https://www.haomeiwen.com/subject/tbhtwxtx.html