【发布时间】:2019-02-21 14:45:39
【问题描述】:
我的 CharacterController 与刚体交互时遇到问题。它有点工作,但只有 60 fps 并且当我打开垂直同步或帧速率低/非常高时会出现奇怪的行为。我有一些用于 CharacterController 和刚体之间交互的代码,并且我创建了一个名为 PushStates 的函数,它被加载到 Update 函数中。
void OnControllerColliderHit(ControllerColliderHit hit)
{
Rigidbody body = hit.collider.attachedRigidbody;
if (body == null || body.isKinematic)
return;
if (hit.moveDirection.y < -.3f)
return;
Vector3 pushDirection = new Vector3(hit.moveDirection.x, 0, hit.moveDirection.z);
body.velocity = pushForce * pushDirection * Time.deltaTime;
}
这里有一些与我的推送机制相关的代码。另一件尚未奏效的事情是当玩家停止移动时从刚体中移除所有力。这会导致 pushableObject 仍然远离玩家几厘米,我也不确定它为什么不起作用。
public void PushStates() {
// Creating the raycast origin Vector3's
Vector3 forward = transform.TransformDirection(Vector3.forward) * distanceForPush;
Vector3 middle = controller.transform.position - new Vector3(0, -controller.height / 2, 0);
// Inspector bool
if (pushRay)
{
Debug.DrawRay(middle, forward, Color.cyan);
}
// Force the pushForce and movementSpeed to normal when the player is not pushing
pushForce = 0f;
movementSpeed = walkSpeed;
// Draws a raycast in front of the player to check if the object in front of the player is a pushable object
if (Physics.Raycast(middle, forward, out hit, distanceForPush))
{
if (InputManager.BButton() && playerIsInPushingTrigger)
{
PushableInfo();
playerIsPushing = true;
anim.SetBool("isPushing", true);
if (hit.collider.tag == "PushableLight")
{
pushForce = playerPushForceLight;
movementSpeed = pushSpeedLight;
}
else if (hit.collider.tag == "PushableHeavy")
{
pushForce = playerPushForceHeavy;
movementSpeed = pushSpeedHeavy;
}
// Checks the players speed now instead off movement. This is neccesary when the player is pushing a pushable into a collider.
// The player and pushable never stop moving because of force.
if (currentSpeed < 0.15f)
{
//Removes all remaining velocity, when the player stops pushing
pushableObjectRB.velocity = Vector3.zero;
pushableObjectRB.angularVelocity = Vector3.zero;
anim.SetFloat("pushSpeedAnim", 0f);
}
else
{
// Calls a rotation method
PushingRot();
if (hit.collider.tag == "PushableLight")
{
anim.SetFloat("pushSpeedAnim", pushSpeedAnimLight);
}
else if (hit.collider.tag == "PushableHeavy")
{
anim.SetFloat("pushSpeedAnim", pushSpeedAnimHeavy);
}
}
}
else
{
anim.SetBool("isPushing", false);
pushForce = 0f;
movementSpeed = walkSpeed;
playerIsPushing = false;
}
}
else
{
anim.SetBool("isPushing", false);
playerIsPushing = false;
}
// Setting the time it takes to rotate when pushing
AnimatorStateInfo stateInfo = anim.GetCurrentAnimatorStateInfo(0);
if (stateInfo.fullPathHash == pushStateHash)
{
turnSmoothTime = maxTurnSmoothTimePushing;
}
else
{
turnSmoothTime = 0.1f;
}
}
【问题讨论】:
-
如果你在
FixedUpdate而不是Update中调用你的代码会发生什么? -
你是说 pushStates 函数?编辑:快速测试,我现在只能推动半个单位,然后停止/卡住。
-
你不应该在
OnControllerColliderHit中乘以Time.deltaTime。 The documentation for that function 涵盖了您在此处尝试执行的操作。 -
我确实确实添加了 Time.deltaTime 到它,然后删除它并更改一些值就可以了!非常感谢。
标签: c# unity3d game-physics rigid-bodies