A component that reacts to collisions like a heavy anvil. When a collision exceeds a speed threshold it optionally plays an impact sound, applies an upward/away impulse to a CharacterController, and applies a physics impulse to a Rigidbody on the other object.
using Sandbox;
public sealed class HeavyAnvil : Component, Component.ICollisionListener
{
[Property] public float PushResistanceMultiplier { get; set; } = 0.25f;
[Property] public float CrushSpeedThreshold { get; set; } = 300f;
[Property] public float CrushImpactForce { get; set; } = 75000f;
[Property] public SoundEvent ImpactSound { get; set; }
public void OnCollisionStart( Collision collision )
{
if ( collision.Contact.Speed.Length < CrushSpeedThreshold ) return;
var targetObj = collision.Other.GameObject?.Root;
if ( !targetObj.IsValid() || targetObj == GameObject.Root ) return;
if ( ImpactSound != null )
{
Sound.Play( ImpactSound, WorldPosition );
}
var cc = targetObj.Components.Get<CharacterController>();
if ( cc.IsValid() )
{
var dir = (targetObj.WorldPosition - WorldPosition).Normal;
dir.z = 0.5f;
cc.Velocity += dir * 900f;
}
var rb = targetObj.Components.Get<Rigidbody>();
if ( rb.IsValid() )
{
var dir = (targetObj.WorldPosition - WorldPosition).Normal;
dir.z = 0.5f;
rb.ApplyImpulse( dir * CrushImpactForce );
}
}
}