Rigidbody钢体移动时抖动问题
Posted 小紫苏xw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Rigidbody钢体移动时抖动问题相关的知识,希望对你有一定的参考价值。
Rigidbody移动时抖动问题
撞墙抖动
Unity中物体移动有非常多的方式;
比如:
transform.position += dir*speed*Time.deltaTime;
transform.Translate(pos, Space.World);
但是这种方式与碰撞结合时,是先位移在判断碰撞,会导致撞墙抖动;
而钢体中修改速度,或是添加力,是先判断碰撞在移动,有效解决撞墙抖动问题;
RigidBody rig;
rig.AddForce(dir*speed);
rig.velocity = new Vector3(pos.x, 0, pos.z) * speed * Time.fixedDeltaTime;
众所周知,人物移动时乘以Time.fixedDeltaTime,相当于逻辑在FixedUpade中调用,每个0.02s移动一次;
移动抖动
如果你的摄像机跟随人物移动,一般会将摄像机逻辑写在LateUpdate中处理,保证每一帧的最后调用,有效保护游戏的公平性;
但这样钢体移动和摄像机移动不同步,会导致移动时屏幕不断抖动;
所谓这里的摄像机逻辑建议都写在FixedUpdate周期中;
public class CameraController : MonoBehaviour
{
public Transform hero;
private float distacne = 6.5f;
private float height = 6.3f;
public void FixedUpdate()
{
transform.LookAt(hero);
transform.position = hero.position + new Vector3(distacne,height,0);
}
}
移动鼠标时抖动
【中文标题】移动鼠标时抖动【英文标题】:Jittering when moving mouse 【发布时间】:2011-11-27 16:06:24 【问题描述】:我有一个 opengl 程序,我正在使用 SDL 来创建窗口/事件处理等。现在,当我移动鼠标重新定位相机偏航/俯仰角时,我得到一个抖动的图像,旧位置闪烁在屏幕上停留片刻。
现在我认为这可能是我重新定位鼠标的方式的问题。在重新定位结束时,我将其设置回屏幕的中心。这是上述代码:
void handleMouseMove(int mouseX, int mouseY)
GLfloat vertMouseSensitivity = 10.0f;
GLfloat horizMouseSensitivity = 10.0f;
int horizMovement = mouseX - midWindowX;
int vertMovement = mouseY - midWindowY;
camXRot += vertMovement / vertMouseSensitivity;
camYRot += horizMovement / horizMouseSensitivity;
if (camXRot < -90.0f)
camXRot = -90.0f;
if (camXRot > 90.0f)
camXRot = 90.0f;
if (camYRot < -180.0f)
camYRot += 360.0f;
if (camYRot > 180.0f)
camYRot -= 360.0f;
// Reset the mouse to center of screen
SDL_WarpMouse(midWindowX, midWindowY);
现在,在我的主 while 循环中,这里是调用此函数的 SDL 代码:
while( SDL_PollEvent( &event ) )
if( event.type == SDL_KEYDOWN )
if( event.key.keysym.sym == SDLK_ESCAPE )
Game.running = false;
if( event.type == SDL_MOUSEMOTION )
int mouse_x, mouse_y;
SDL_GetMouseState(&mouse_x, &mouse_y);
handleMouseMove(mouse_x, mouse_y);
我发现获取像 event.motion.x
和 event.motion.x
这样的坐标导致的这种影响较小。
对如何避免这种“抖动”图像有什么想法吗?
【问题讨论】:
你绘制的表面是双缓冲的吗? 【参考方案1】:当您SDL_WarpMouse
时,会生成另一个您正在处理的鼠标移动事件。您必须忽略第二个。
为了让事情变得更复杂,并不是每个运动事件都跟着一个由SDL_WarpMouse
引起的相反方向的事件。事件可能来自例如两个运动和一个由扭曲到屏幕中间产生的运动。我已经编写了适合我的代码:
void motion(SDL_MouseMotionEvent *mme)
static bool initializing = true; // For the first time
static int warpMotionX = 0, warpMotionY = 0; // accumulated warp motion
if (initializing)
if (mme->x == midWindowX && mme->y == midWindowY)
initializing = false;
else
SDL_WarpMouse(midWindowX, midWindowY);
else if (mme->xrel != -warpMotionX || mme->yrel != -warpMotionY)
/****** Mouse moved by mme->xrel and mme->yrel ******/
warpMotionX += mme->xrel;
warpMotionY += mme->yrel;
SDL_WarpMouse(midWindowX, midWindowY);
else // if event motion was negative of accumulated previous moves,
// then it is generated by SDL_WarpMotion
warpMotionX = warpMotionY = 0;
void processEvents()
SDL_Event e;
while (SDL_PollEvent(&e))
switch (e.type)
case SDL_MOUSEMOTION:
motion(&e.motion);
break;
default:
break;
请注意,我本人对-mme->yrel
比mme->yrel
更感兴趣,这就是为什么它在原始代码中的原因,无论我在哪里使用它都将其否定(我在上面发布的代码中将其删除)
我写/****** Mouse moved by mme->xrel and mme->yrel ******/
的地方是你想要对鼠标动作进行操作的地方。其他代码是忽略SDL_WarpMouse
产生的运动
【讨论】:
这很有意义。关于如何解决这个问题的任何建议? 当我添加handleMouseMove(mme->xrel, mme->yrel);
代替您的评论时,当我移动鼠标时,它直接指向上方,然后卡在那里.. 有什么想法吗?
您的 handleMouseMove 获取绝对鼠标位置。 xrel 和 yrel 是鼠标的运动,表示鼠标移动了多少。
啊,当然。好的,我得到了那个工作,但是它对抖动没有任何影响:/。但是,我会让你纠正,因为你已经针对我的问题。谢谢!
那么抖动肯定是别的东西! :-?如果没有看到代码,我真的无法判断,但是您是否有机会在每次事件处理后绘制或处理所有然后绘制一次?以上是关于Rigidbody钢体移动时抖动问题的主要内容,如果未能解决你的问题,请参考以下文章