Function that Runs Once?

I have a scene where if a player steps on a switch, a gate is destroyed, and if he steps off, it is recreated. When the function starts, the player is not stepping on the switch, and hence the gate is being created; the problem is that the gate is being created infinitely because it is under the Update function. My question is, how do I make it so that the gate is created only once, and then destroyed when the player steps on the switch, and recreated again once the player steps off?

Here are the scripts I have so far.

static var press = false;
function OnTriggerEnter (trigger : Collider){
	if (trigger.gameObject.tag == "Player"){
		press = true;
		
	}
}	
function OnTriggerExit (trigger : Collider){
	if (trigger.gameObject.tag == "Player"){
		press = false;
	}
}			

var block : Rigidbody;
public var blockclone: Rigidbody;

function Update () {
	if(Trigger.press == false){
		var blockclone = Instantiate(block, transform.position, transform.rotation);
}

	if(Trigger.press == true){
		Destroy(blockclone);
}	

}

Instantiate and destroy the gate prefab from your GateTriggerScript.js script. Then you don’t need the static press variable, and you can just do it from OnTriggerEnter() and OnTriggerExit(), as shown below.

Without the static press variable, you can reuse your GateTriggerScript.js for any number of gate triggers and any number of gates and gate position markers.

- - - - GateTriggerScript.js

// create a gate trigger object in the scene, and assign this script to it
// create an empty object in the scene that marks the spot for the position and rotation of a gate
// create a prefab for a gate

var gateMarker: Transform;  // set this to the gate marker
var gatePrefab : RigidBody;  // set this to a prefab of the gate
var initiallyUp: boolean;  // set this to true if the gate is to be initially up

var gate : RigidBody;  // this is a reference to the gate most recently instantiated by this script

function Start() {
    gate = null;
    if (initiallyUp) PutGateUp(); 
}

function OnTriggerEnter (trigger : Collider){
    if (trigger.gameObject.tag == "Player"){
       TakeGateDown();
    }
}   

function OnTriggerExit (trigger : Collider){
    if (trigger.gameObject.tag == "Player"){
       PutGateUp();
    }
}      

function PutGateUp() {
    if (!gate) gate = Instantiate(gatePrefab, gateMarker.position, gateMarker.rotation);
    // also may want to signal an event that this has happened
}

function TakeGateDown() {
    if (gate) Destroy(gate);
    gate = null;
    // also may want to signal an event
}

As noted, you may want to do other things when triggers like this happen besides just opening or closing a gate. One of my favorite patterns is to have a global singleton event manager object, for a given scene, that keeps track of listeners for named events. The event manager just has a few functions: RegisterListener(eventname, listener), UnregisterListener(eventname, listener), and RaiseEvent(eventname, args).

Listener functions for events are registered and unregistered when it makes sense for them to be, then from any where at any time, I can raise a named event, and pass a hash with any arbitrary string-named variables in it that I want, and the various listeners for that event (if there happen to be any at the time) will get called by the event manager, and the code in them only needs to pay attention to the hash members they care about.

For example, say you have ghosts that sometimes wander around, and when they do, you want them to manifest if they happen to be near by when a gate is triggered. Well, the Ghost script’s StartWandering() function can call EventManager.RegisterListener(‘gatetriggered’, this.OnGateTriggered), and it’s StopWandering() function can call EventManager.Unregister(‘gatetriggered’, this.OnGateTriggered), and a trigger object’s OnTriggerEnter() function can call EventManager.Raise(‘gatetriggered’, {‘gate’: gate}); and the Ghost’s OnGateTriggered(eventArgs) function can examine eventArgs[‘gate’] to see if the gate is near by, and if it is, then call it’s own Manifest() function.

I personally find it to be a very useful pattern. I haven’t done this yet in UnityScript, but I’ve done in it Objective C and regular JavaScript, and Python and in C++ and probably some others that I’m not remembering at the moment. If there’s interest in it, maybe I’ll see if I can post a UnityScript implementation to the wiki or something.

I like it better than C#'s events (with their delegate functions and all that) because… you don’t have to have any object that knows about both the sender and the receiver’s classes. With C# events, you have to have some object that knows about the particular sender class and the particular receiver class in order to add a receiver’s event handler to a sender’s event listener list.

A global singleton event manager doesn’t need to know or care about a sender’s class or a listener’s class. All listener functions have the same signature; they take a mapping of string keys to void pointers (or whatever the appropriate replacement for a void pointer is in the given language.) That’s it. And that’s all the event manager knows or cares about. So at any time, from any place that it makes sense to, I can raise any event I want. And any and all listeners that are registered for that event at the time will get fired.

Strings aren’t super fast and misspellings can be a pain, so sometimes I’ll use hex integers and define centralized lists of named constants instead of using string names for events. Then the centralized lists can help me document what events I’ve raised or listened for, and my IDE can help me with the spelling issue.

I lose any strong typing benefit for the event arguments, I know, but this is an example of a context within which duck typing really shines, imo. And if I need to, I can recast a particular hash key’s value as a particular class or struct in order to recover some strong typing benefits.

Try this…

function Update () {
    if(press == false){
       var blockclone = Instantiate(block, transform.position, transform.rotation);
}

    if(press == true){
       Destroy(blockclone);
}

press itself is a variable, not associated with the trigger event itself. I think that should work but be sure to check back. Far more experienced people might say different.