I need to get the gibs from the prop OnBreak event to do things like apply the velocity of the parent to them.
Currently I cannot figure out how to do this in a sensible way.
The callback is invoked before they are created.
Currently I cannot figure out how to do this in a sensible way.
The callback is invoked before they are created.
void OnBreak()
{
OnPropBreak?.Invoke();
PlayBreakSound();
NetworkCreateGibs();
CreateExplosion();
}
NetworkCreateGibs() does not return the list of gibs so I think that there is probably something I'm missing or a way to get the gibs from a network event?
I ended up writing some really hacky code to find them like this async function to wait one frame.
async void ApplyImpulseToGibs(GameObject obj, Vector3 point, Vector3 impulse)
{
var scene = Scene;
var prop = obj.GetComponentInParent<Prop>();
if ( !prop.IsValid() ) return;
var objectName = obj.Name;
var gibName = $"{objectName} (gib)";
var wait = TaskSource.Create();
try
{
await wait.Frame();
}
catch ( TaskCanceledException )
{
return;
}
if ( !scene.IsValid() )
return;
var gibs = scene.GetAllComponents<Gib>();
foreach ( var gib in gibs )
{
if ( !gib.IsValid() || gib.GameObject.Name != gibName )
continue;
var rb = gib.GetComponent<Rigidbody>();
if ( rb.IsValid() ) {
rb.ApplyImpulseAt(point, impulse);
}
}
}
Or this component that fudges the prop health and handles the events manual.
public sealed class Gibbable : Component, Component.IDamageable, IDestructible
{
[Property] public float Health { get; set; } = 100f;
[Property] public Prop Prop { get; private set; }
protected override void OnStart()
{
Prop ??= GetComponent<Prop>();
if ( Prop.IsValid() )
Prop.Health = 1_000_000f; // Prop never auto-breaks
}
public void OnDamage( in DamageInfo damage )
{
Health -= damage.Damage;
Prop.Health += damage.Damage;
if ( Health <= 0f )
Break( damage.Position, (damage.Position - Transform.World.Position).Normal * 1200f );
}
public void TakeImpact( GameObject hitObject, Vector3 point, Vector3 impulse, float damage_scale )
{
if ( hitObject != GameObject ) return;
Health -= impulse.Length * damage_scale;
if ( Health <= 0f )
Break( point, impulse );
}
private void Break( Vector3 point, Vector3 impulse )
{
if ( !Prop.IsValid() ) return;
var gibs = Prop.CreateGibs();
Prop.NetworkCreateGibs();
foreach ( var gib in gibs )
{
if ( !gib.IsValid() ) continue;
var rb = gib.GetComponent<Rigidbody>();
if ( rb.IsValid() )
rb.ApplyImpulseAt( point, impulse );
}
GameObject.Destroy();
}
}In conclusion how do I get the gibs from a prop that breaks.
Any help is appreciated.