How to send a signal when something stops happening?

When my character controller is pushing a crate, the pushing script calls the PlayPushingSound() function on the crate to play a dragging sound… But how can I tell it when I’ve stopped pushing the crate, thus ceasing the sound playback?

I could just add an update function that’s always running on the crate script but seems kinda inefficient. Is there a better way?

(Simplified):

function OnControllerColliderHit (hit : ControllerColliderHit) {
	var body : Rigidbody = hit.collider.attachedRigidbody;

	// Calculate push direction from move direction, we only push objects to the sides
	// never up and down
	var pushDir = Vector3 (hit.moveDirection.x, 0, hit.moveDirection.z);
	
	// push with move speed but never more than half runspeed
	body.velocity = pushDir * pushPower * Mathf.Min (controller.GetSpeed (), controller.movement.runSpeed/2);
	
	hit.gameObject.GetComponent(PushingSoundEffect).PushingSound();
}

Script attached to crate:

function PushingSound() {
	// Don't restart audio clip
	if (audio.isPlaying)
		return;
	
	audio.Play();
}
@script RequireComponent(AudioSource)

I am pretty sure this would work…

function OnCollisionExit () {
         audio.Stop() //or whatever it is
        }

If the crate can slide for a while after you stop pushing it and you want the sound to play until it comes to a rest,
just check repeatedly ( but not every frame in Update ) if the rigidbody is sleeping:

var myRB : Rigidbody // drag on in inspector, don't repeatedly call GetComponent

function OnCollisionEnter()
{
InvokeRepeating("AmIMoving", 0.0, 0.3); //precise enough but much cheaper than Update() 
}

function AmIMoving()
{
if (myRB.IsSleeping)
    {
    audio.Stop();
    Debug.Log("Crate has come to rest.")
    CancelInvoke("AmIMoving");
    }
}

I dunno; I don’t entirely trust the CharacterController enough to want to use it. IMHO it feels like something the Unity team cooked up primarily to make the built-in tutorial examples seem as if scripting gameplay in Unity is easier than it is in real life and not something they actually expect you to use in your game. If you can work out your own character control script from scratch you’ll have a full understanding of how to make it do what you want it to do.