我在Unity 6中遇到一个奇怪的运动抖动问题。
我的玩家运动是完全在FixedUpdate()方法中处理的。控制器速度是在那里累积的,我调用:
controller.Move(velocity * Time.fixedDeltaTime);
相机(CineMachine)不是问题。通过:
- 不移动鼠标,
- 将游戏速度降低到
Time.timeScale = 0.2, - 观察玩家运动时使用阻尼。
当游戏速度降低时,我可以清晰地看到玩家以小块的跳跃方式前进,而不是平滑地移动。
运动是使用自定义Quake/Source风格加速系统与CharacterController实现的。代码:
private void FixedUpdate()
{
Move();
ApplyCounterMovement();
ApplyFriction();
ApplyGravity();
motor.Move(Time.fixedDeltaTime);
}
private void Move()
{
Vector2 moveInput = input.MoveInput;
Vector3 wishDirection = GetWishDirection(moveInput);
if (wishDirection.sqrMagnitude < 0.0001f)
return;
wishDirection.Normalize();
float wishSpeed = isGrounded ? walkWishSpeed : airWishSpeed;
float accel = isGrounded ? walkAcceleration : airAcceleration;
Accelerate(wishDirection, wishSpeed, accel);
}
private void Accelerate(Vector3 wishDirection, float wishSpeed, float accel)
{
Vector3 horizontalVelocity = GetHorizontalVelocity();
float currentSpeed = Vector3.Dot(horizontalVelocity, wishDirection);
float addSpeed = wishSpeed - currentSpeed;
if (addSpeed <= 0f)
return;
float accelSpeed = accel * Time.fixedDeltaTime * wishSpeed;
accelSpeed = Mathf.Min(accelSpeed, addSpeed);
motor.AddVelocity(wishDirection * accelSpeed);
}
private void ApplyCounterMovement()
{
if (!isGrounded)
return;
if (input.MoveInput.sqrMagnitude < 0.01f)
return;
Vector3 wishDirection = GetWishDirection(input.MoveInput).normalized;
Vector3 horizontalVelocity = GetHorizontalVelocity();
Vector3 unwantedVelocity =
horizontalVelocity -
Vector3.Project(horizontalVelocity, wishDirection);
motor.AddVelocity(
-unwantedVelocity *
counterMovement *
Time.fixedDeltaTime);
}
private void ApplyFriction()
{
if (!isGrounded)
return;
if (input.MoveInput.sqrMagnitude > 0.01f)
return;
Vector3 horizontalVelocity = GetHorizontalVelocity();
float speed = horizontalVelocity.magnitude;
float drop = groundFriction * Time.fixedDeltaTime;
speed = Mathf.Max(speed - drop, 0f);
horizontalVelocity = horizontalVelocity.normalized * speed;
motor.SetVelocity(new Vector3(
horizontalVelocity.x,
motor.Velocity.y,
horizontalVelocity.z));
}
private void ApplyGravity()
{
Vector3 velocity = motor.Velocity;
if (isGrounded && velocity.y < 0f)
{
motor.SetVelocity(new Vector3(
velocity.x,
-groundStickVelocity,
velocity.z));
return;
}
motor.AddVelocity(Vector3.down * gravity * Time.fixedDeltaTime);
}
PlayerMotor.Move()方法仅仅调用:
public CollisionFlags Move(float deltaTime)
{
Vector3 moveVelocity = Velocity;
if (IsGrounded && moveVelocity.y < 0f)
moveVelocity.y = -2f;
return controller.Move(moveVelocity * deltaTime);
}
评论 (0)