Fix CharacterController still colliding after being disabled at runtime

This commit is contained in:
Wojtek Figat
2021-05-31 13:30:45 +02:00
parent 8eadd912f7
commit d436b71ef5
2 changed files with 74 additions and 42 deletions

View File

@@ -30,6 +30,11 @@ CharacterController::CharacterController(const SpawnParams& params)
static_assert(sizeof(_filterData) == sizeof(PxFilterData), "Invalid filter data size.");
}
float CharacterController::GetRadius() const
{
return _radius;
}
void CharacterController::SetRadius(const float value)
{
if (Math::NearEqual(value, _radius))
@@ -41,6 +46,11 @@ void CharacterController::SetRadius(const float value)
UpdateBounds();
}
float CharacterController::GetHeight() const
{
return _height;
}
void CharacterController::SetHeight(const float value)
{
if (Math::NearEqual(value, _height))
@@ -52,6 +62,11 @@ void CharacterController::SetHeight(const float value)
UpdateBounds();
}
float CharacterController::GetSlopeLimit() const
{
return _slopeLimit;
}
void CharacterController::SetSlopeLimit(float value)
{
value = Math::Clamp(value, 0.0f, 89.0f);
@@ -100,6 +115,11 @@ void CharacterController::SetUpDirection(const Vector3& up)
_upDirection = up;
}
float CharacterController::GetMinMoveDistance() const
{
return _minMoveDistance;
}
Vector3 CharacterController::GetUpDirection() const
{
return _controller ? P2C(_controller->getUpDirection()) : _upDirection;
@@ -115,6 +135,16 @@ Vector3 CharacterController::GetVelocity() const
return _controller ? P2C(_controller->getActor()->getLinearVelocity()) : Vector3::Zero;
}
bool CharacterController::IsGrounded() const
{
return (static_cast<int>(_lastFlags) & static_cast<int>(CollisionFlags::Below)) != 0;
}
CharacterController::CollisionFlags CharacterController::GetFlags() const
{
return _lastFlags;
}
CharacterController::CollisionFlags CharacterController::SimpleMove(const Vector3& speed)
{
const float deltaTime = Time::GetCurrentSafe()->DeltaTime.GetTotalSeconds();
@@ -178,7 +208,7 @@ void CharacterController::OnDebugDrawSelected()
#endif
void CharacterController::CreateActor()
void CharacterController::CreateController()
{
ASSERT(_controller == nullptr && _shape == nullptr);
@@ -218,6 +248,18 @@ void CharacterController::CreateActor()
UpdateBounds();
}
void CharacterController::DeleteController()
{
if (_controller)
{
_shape->userData = nullptr;
_controller->getActor()->userData = nullptr;
_controller->release();
_controller = nullptr;
}
_shape = nullptr;
}
void CharacterController::UpdateSize() const
{
if (_controller)
@@ -313,7 +355,8 @@ void CharacterController::UpdateLayerBits()
void CharacterController::BeginPlay(SceneBeginData* data)
{
CreateActor();
if (IsActiveInHierarchy())
CreateController();
// Skip collider base
Actor::BeginPlay(data);
@@ -325,26 +368,28 @@ void CharacterController::EndPlay()
Actor::EndPlay();
// Remove controller
if (_controller)
{
_shape->userData = nullptr;
_controller->getActor()->userData = nullptr;
_controller->release();
_controller = nullptr;
}
_shape = nullptr;
DeleteController();
}
void CharacterController::OnActiveInTreeChanged()
{
// Skip collider base
Actor::OnActiveInTreeChanged();
}
// Clear velocities and the forces on disabled
if (!IsActiveInHierarchy() && _controller)
{
// TODO: sleep actor? clear forces?
}
void CharacterController::OnEnable()
{
if (_controller == nullptr)
CreateController();
Collider::OnEnable();
}
void CharacterController::OnDisable()
{
Collider::OnDisable();
DeleteController();
}
void CharacterController::OnParentChanged()

View File

@@ -71,15 +71,11 @@ private:
uint32 _filterData[4];
public:
/// <summary>
/// Gets the radius of the sphere, measured in the object's local space. The sphere radius will be scaled by the actor's world scale.
/// </summary>
API_PROPERTY(Attributes="EditorOrder(100), DefaultValue(50.0f), EditorDisplay(\"Collider\")")
FORCE_INLINE float GetRadius() const
{
return _radius;
}
float GetRadius() const;
/// <summary>
/// Sets the radius of the sphere, measured in the object's local space. The sphere radius will be scaled by the actor's world scale.
@@ -90,10 +86,7 @@ public:
/// Gets the height of the capsule, measured in the object's local space. The capsule height will be scaled by the actor's world scale.
/// </summary>
API_PROPERTY(Attributes="EditorOrder(110), DefaultValue(150.0f), EditorDisplay(\"Collider\")")
FORCE_INLINE float GetHeight() const
{
return _height;
}
float GetHeight() const;
/// <summary>
/// Sets the height of the capsule, measured in the object's local space. The capsule height will be scaled by the actor's world scale.
@@ -104,10 +97,7 @@ public:
/// Gets the slope limit (in degrees). Limits the collider to only climb slopes that are less steep (in degrees) than the indicated value.
/// </summary>
API_PROPERTY(Attributes="EditorOrder(210), DefaultValue(45.0f), Limit(0, 100), EditorDisplay(\"Character Controller\")")
FORCE_INLINE float GetSlopeLimit() const
{
return _slopeLimit;
}
float GetSlopeLimit() const;
/// <summary>
/// Sets the slope limit (in degrees). Limits the collider to only climb slopes that are less steep (in degrees) than the indicated value.
@@ -151,10 +141,7 @@ public:
/// Gets the minimum move distance of the character controller. The minimum traveled distance to consider. If traveled distance is smaller, the character doesn't move. This is used to stop the recursive motion algorithm when remaining distance to travel is small.
/// </summary>
API_PROPERTY(Attributes="EditorOrder(230), DefaultValue(0.0f), Limit(0, 1000), EditorDisplay(\"Character Controller\")")
FORCE_INLINE float GetMinMoveDistance() const
{
return _minMoveDistance;
}
float GetMinMoveDistance() const;
/// <summary>
/// Sets the minimum move distance of the character controller.The minimum traveled distance to consider. If traveled distance is smaller, the character doesn't move. This is used to stop the recursive motion algorithm when remaining distance to travel is small.
@@ -171,18 +158,12 @@ public:
/// <summary>
/// Gets a value indicating whether this character was grounded during last move call grounded.
/// </summary>
API_PROPERTY() FORCE_INLINE bool IsGrounded() const
{
return (static_cast<int>(_lastFlags) & static_cast<int>(CollisionFlags::Below)) != 0;
}
API_PROPERTY() bool IsGrounded() const;
/// <summary>
/// Gets the current collision flags. Tells which parts of the character capsule collided with the environment during the last move call. It can be used to trigger various character animations.
/// </summary>
API_PROPERTY() FORCE_INLINE CollisionFlags GetFlags() const
{
return _lastFlags;
}
API_PROPERTY() CollisionFlags GetFlags() const;
public:
@@ -203,7 +184,6 @@ public:
/// <summary>
/// Gets the native PhysX rigid actor object.
/// </summary>
/// <returns>The PhysX dynamic rigid actor.</returns>
PxRigidDynamic* GetPhysXRigidActor() const;
protected:
@@ -211,7 +191,12 @@ protected:
/// <summary>
/// Creates the physics actor.
/// </summary>
void CreateActor();
void CreateController();
/// <summary>
/// Deletes the physics actor.
/// </summary>
void DeleteController();
/// <summary>
/// Updates the character height and radius.
@@ -248,6 +233,8 @@ protected:
void DrawPhysicsDebug(RenderView& view) override;
#endif
void OnActiveInTreeChanged() override;
void OnEnable() override;
void OnDisable() override;
void OnParentChanged() override;
void OnTransformChanged() override;
};