Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: No Physics Shapes On The CharacterComponent Causes Unhandled Exception #2410

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions sources/engine/Stride.Physics/Elements/CharacterComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.ComponentModel;
using System.Diagnostics;
using Stride.Core;
using Stride.Core.Mathematics;
using Stride.Engine;
Expand All @@ -26,7 +27,8 @@ public void Jump(Vector3 jumpDirection)
{
if (KinematicCharacter == null)
{
throw new InvalidOperationException("Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.");
LogPhysicsFunctionError();
return;
}
BulletSharp.Math.Vector3 bV3 = jumpDirection;
KinematicCharacter.Jump(ref bV3);
Expand All @@ -39,7 +41,8 @@ public void Jump()
{
if (KinematicCharacter == null)
{
throw new InvalidOperationException("Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.");
LogPhysicsFunctionError();
return;
}
KinematicCharacter.Jump();
}
Expand Down Expand Up @@ -209,7 +212,8 @@ public void Teleport(Vector3 targetPosition)
{
if (KinematicCharacter == null)
{
throw new InvalidOperationException("Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.");
LogPhysicsFunctionError();
return;
}

//we assume that the user wants to teleport in world/entity space
Expand All @@ -230,7 +234,8 @@ public void Move(Vector3 movement)
{
if (KinematicCharacter == null)
{
throw new InvalidOperationException("Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.");
LogPhysicsFunctionError();
return;
}

KinematicCharacter.SetWalkDirection(movement);
Expand All @@ -246,7 +251,8 @@ public void SetVelocity(Vector3 velocity)
{
if (KinematicCharacter == null)
{
throw new InvalidOperationException("Attempted to call a Physics function that is available only when the Entity has been already added to the Scene.");
LogPhysicsFunctionError();
return;
}

KinematicCharacter.SetWalkDirection(velocity * Simulation.FixedTimeStep);
Expand Down Expand Up @@ -305,5 +311,16 @@ protected override void OnDetach()

base.OnDetach();
}

/// <summary>
/// Run specific error when physics functions are called on components that do not have proper setup.
/// Captures good tracing info for debugging purposes.
/// </summary>
private void LogPhysicsFunctionError()
{
StackFrame frame = new StackTrace(true).GetFrame(2);
logger.Error($"Component:[{this}] attempted to call a Physics function that is available only when the Entity has been already added to the Scene. " +
$"This may be due to a {this} without any physical shapes.\nLocation: {frame.GetFileName()} at Line Number: {frame.GetFileLineNumber()} from Method: {frame.GetMethod().Name} ");
}
}
}
16 changes: 10 additions & 6 deletions sources/engine/Stride.Physics/Engine/PhysicsComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,12 @@ internal void Attach(PhysicsProcessor.AssociatedData data)
{
Data = data;

if (ColliderShapes.Count == 0 && ColliderShape == null)
{
logger.Error($"Entity {{Entity.Name}} has a PhysicsComponent without any collider shape.");
return; //no shape no purpose
}

//this is mostly required for the game studio gizmos
if (Simulation.DisableSimulation)
{
Expand All @@ -651,12 +657,7 @@ internal void Attach(PhysicsProcessor.AssociatedData data)
//this is not optimal as UpdateWorldMatrix will end up being called twice this frame.. but we need to ensure that we have valid data.
Entity.Transform.UpdateWorldMatrix();

if (ColliderShapes.Count == 0 && ColliderShape == null)
{
logger.Error($"Entity {Entity.Name} has a PhysicsComponent without any collider shape.");
return; //no shape no purpose
}
else if (ColliderShape == null)
if (ColliderShape == null)
{
ComposeShape();
if (ColliderShape == null)
Expand Down Expand Up @@ -700,6 +701,9 @@ internal void Detach()
}
}

/// <summary>
/// Called whenever an entity with this component is added to scene.
/// </summary>
protected virtual void OnAttach()
{
//set pre-set post deserialization properties
Expand Down