SpringPad.cs

A SpringPad component that listens for trigger enters and launches touching objects upward. It applies an instant velocity change to CharacterController components and an impulse to Rigidbody components, and optionally plays a sound and spawns a particle game object.

Native Interop
using Sandbox;

public sealed class SpringPad : Component, Component.ITriggerListener
{
    [Property] public float PlayerBounceForce { get; set; } = 1100f;
    [Property] public float PhysicsBounceForce { get; set; } = 65000f;
    [Property] public SoundEvent BounceSound { get; set; }
    [Property] public GameObject BounceParticle { get; set; }

    public void OnTriggerEnter( Collider other )
    {
        if ( !other.GameObject.IsValid() ) return;

        var targetObj = other.GameObject.Root;
        if ( targetObj == GameObject.Root ) return;

        var launched = false;
        var launchDir = WorldTransform.Up;

        var cc = targetObj.Components.Get<CharacterController>();
        if ( cc.IsValid() )
        {
            var currentVel = cc.Velocity;
            currentVel.z = 0;
            cc.Velocity = currentVel + launchDir * PlayerBounceForce;
            launched = true;
        }

        var rb = targetObj.Components.Get<Rigidbody>();
        if ( rb.IsValid() )
        {
            rb.Velocity = Vector3.Zero;
            rb.ApplyImpulse( launchDir * PhysicsBounceForce );
            launched = true;
        }

        if ( launched )
        {
            if ( BounceSound != null )
            {
                Sound.Play( BounceSound, WorldPosition );
            }

            if ( BounceParticle.IsValid() )
            {
                BounceParticle.Clone( WorldPosition );
            }
        }
    }
}