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.xevent.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-&gt;yrelmme-&gt;yrel 更感兴趣,这就是为什么它在原始代码中的原因,无论我在哪里使用它都将其否定(我在上面发布的代码中将其删除)

我写/****** Mouse moved by mme-&gt;xrel and mme-&gt;yrel ******/ 的地方是你想要对鼠标动作进行操作的地方。其他代码是忽略SDL_WarpMouse产生的运动

【讨论】:

这很有意义。关于如何解决这个问题的任何建议? 当我添加handleMouseMove(mme-&gt;xrel, mme-&gt;yrel); 代替您的评论时,当我移动鼠标时,它直接指向上方,然后卡在那里.. 有什么想法吗? 您的 handleMouseMove 获取绝对鼠标位置。 xrel 和 yrel 是鼠标的运动,表示鼠标移动了多少。 啊,当然。好的,我得到了那个工作,但是它对抖动没有任何影响:/。但是,我会让你纠正,因为你已经针对我的问题。谢谢! 那么抖动肯定是别的东西! :-?如果没有看到代码,我真的无法判断,但是您是否有机会在每次事件处理后绘制或处理所有然后绘制一次?

以上是关于Rigidbody钢体移动时抖动问题的主要内容,如果未能解决你的问题,请参考以下文章

我的角色 Sprite Node 移动时抖动,为啥?

Unity坑之 加了Rigidbody后主角反而朝天上飞?

相机跟随刚体抖动每隔几秒与背景对象

如何让 Rigidbody2D.MovePosition 在本地空间中移动游戏对象?

Unity中的物体移动-Rigidbody方法

unity2D物理引擎之-Rigidbody 2D