Fix CharacterController still colliding after being disabled at runtime
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user