如何让移动的GameObject顺利推动CharacterController?

问题描述 投票:0回答:1

我有一个名为 Player 的游戏对象,附加有具有以下设置的 CharacterController 组件。


Player 还附有一个名为

PlayerController
的脚本。
重力通过以下函数应用于CharacterController,该函数在
Update()
中调用。

private void ApplyGravity()
{
    if (!characterController.isGrounded)
    {
        moveDirection.y -= gravity * Time.deltaTime;
    }
}

Player有一个名为PlayerModel的子游戏对象,它只附加了一个默认的CapsuleCollider。

PlayerController
还有一个附加功能,称为
MoveAround()
,在
Update()
中也有调用;如果这与问题有关。

public void MoveAround()
{
    Vector2 moveInput = playerInputActions.Player.Move.ReadValue<Vector2>();

    currentInput = new Vector2(moveInput.y, moveInput.x);

    float moveDirectionY = moveDirection.y;

    float speed = isSprinting ? sprintSpeed : walkSpeed;

    moveDirection = (transform.forward * currentInput.x + transform.right * currentInput.y) + boatController.boatRigidbody.velocity;

    moveDirection.y = moveDirectionY;

    moveDirection.Normalize();

    moveDirection *= speed;
}


我有一个名为 Boat 的游戏对象,它附加了默认的 BoxCollider、Rigidbody 和

BoatController
脚本; Rigidbody 有以下设置。

漂浮在水面上,因此上下移动。
玩家 位于 的表面。
Boat 漂浮起来时,Player 也随之被向上推。当它向下浮动时,会调用

ApplyGravity()
函数,从而使 Player 随之返回。

场景设置如下所示。

问题是这个过程并不顺利。
玩家被推上来时和落下时会在碰撞点抖动。

我尝试尝试将 Player 位置捕捉到 Boat 的表面,但这会导致同样的问题。
在此基础上,我还尝试使用

Physics.Raycast()
Vector3.Lerp()
的组合来抓取表面位置,并将 Player 分别平滑地移动到该位置;这导致了一些奇怪的错误(但我可能错误地实现了它)。

非常感谢任何有关如何解决此问题的建议。

c# unity-game-engine game-physics
1个回答
0
投票

这是正常的,因为你没有考虑框架的演变。通常要根据帧进行平滑,最好的解决方案是乘以

UnityEngine.Time.deltaTime
。由于这是一个物理函数,所以最好的选择是使用
UnityEngine.Time.fixedDeltaTime
,但应该调用相对的
FixedUpdate()
而不是
Update()
事件。

尝试:

moveDirection *= speed * Time.fixedDeltaTime;

但请确保您的堆栈跟踪是从

FixedUpdate()
启动的。当涉及物理时,这是帧更新事件的首选版本。是的,你也可以使用
Update()
,但精度不一样。

© www.soinside.com 2019 - 2024. All rights reserved.