2DShooter Part5

From Unify Community Wiki
Jump to: navigation, search

By Eric Haines (a.k.a. Eric5h5)

Scripting the trigger

Create a script called EnemyTrigger in the same way that you did for Enemy, and then load it.

@HideInInspector
var enemy : Transform;
private var myTransform : Transform;
private var script : Enemy;

The "enemy" variable is a reference to the Transform of the enemy object that spawned this trigger object (see previous section). Since it's assigned by the Enemy script and we don't need to see it in the inspector, again we use "@HideInInspector" to reduce clutter.

"myTransform" will be a reference to the Transform of this trigger.

"script" will be a reference to the script of the enemy object that spawned this trigger object (we're using type Enemy, the name of its script).

function Start() {
    myTransform = transform;
    script = enemy.GetComponent(Enemy);
 
    var others = GameObject.FindGameObjectsWithTag("enemy");
    for (other in others) {
        Physics.IgnoreCollision(collider, other.collider);
    }
 
    this.enabled = false;
}

First thing is to set myTransform to the transform of this trigger (see the previous section for an explanation of why we're bothering with this instead of just using transform). Then we set the variable "script" to the script called "Enemy", which belongs to the variable "enemy" (this is assigned by the Enemy script, and refers to the enemy object). We need this reference so we can send information to it (namely, the Transform of the player's ship).

We don't want to have other enemy objects interact with this trigger (we only want the player's ship to activate it), so we ignore the colliders of any other objects with the "enemy" tag, in the same way that the enemy object ignores all triggers. This includes the turrets, since they also have the "enemy" tag, but as it happens, they would be ignored anyway. That's because this trigger is made from a normal collider (without a rigidbody), and the turrets are also non-rigidbody colliders, and the two don't interact. You can see a chart of which types of colliders and triggers interact with other colliders in the Collider reference page of the documentation.

Finally, we disable this script, for the same reasons as before; i.e., no point in the Update function running unless the player comes near. But wait--don't we want the OnTriggerEnter function to be activated? If we disable the script, how's that going to work? Well, actually, disabling the script doesn't disable all functions. OnTriggerEnter and others will continue to work. It functions this way for this very reason: often you don't want enemies taking up CPU time unless the player is nearby, but you still want to be able to have triggers wake them up, or respond to other collisions.

function OnTriggerEnter(other : Collider) {
    if (other.tag != "Player") {return;}
    script.enabled = this.enabled = true;
    script.ship = other.transform;
}

When something does enter this trigger, first we check to see if the tag is "Player", which is what the tag on the player's ship is called. If not, then we return from the function without doing anything. If you looked through the scripts for the various objects, you might think this is unnecessary, since theoretically all other objects are ignoring the enemy's trigger anyway. However, we want to be 100% sure that only the player's ship actually activates the trigger (and not have the enemy accidentally go chasing after a stray bullet or something), rather than just assuming that we haven't made any mistakes in any other code.

If it does happen that the player has entered the trigger, then we enable the "script" variable, which is a reference to the script on the enemy object that spawned this trigger, so its Update function will run. We also enable this script so this Update function will run too. Since both variables are being assigned "true", we might as well assign it to both at once to save a little typing.

Now we need to tell the enemy object what transform entered this trigger, so the enemy can go after it. You'll notice that, when we started this function, we've defined a local variable called "other" of type Collider. Since the Transform of "other" must be the player's ship, we assign it to the variable "ship" (which is also a Transform) on the enemy object's script.

function Update() {
    myTransform.position = enemy.position;
}

Since the trigger isn't a child of the enemy object (for reasons discussed in Part 2), normally it would just stay put when the enemy object goes after the player. That's not what we want, though--the trigger has activated the enemy object, but we still need it to determine if the player goes out of range. So we simply assign the position of the enemy's Transform to this Transform's position every frame. (Since "enemy" is defined as a Transform, we don't need to write "enemy.transform.position".)

function OnTriggerExit(other : Collider) {
    if (other.tag != "Player") {return;}
    script.enabled = this.enabled = false;
}

This is the end! All we need now is to disable the Update functions on this script and the enemy object's script, in the event that the player has gone outside the trigger. Again, we check the tag to be 100% sure it's only the player that can do this.

Here's the whole thing:

@HideInInspector
var enemy : Transform;
private var myTransform : Transform;
private var script : Enemy;
 
function Start() {
    myTransform = transform;
    script = enemy.GetComponent(Enemy);
 
    var others = GameObject.FindGameObjectsWithTag("enemy");
    for (other in others) {
        Physics.IgnoreCollision(collider, other.collider);
    }
 
    this.enabled = false;
}
 
function OnTriggerEnter(other : Collider) {
    if (other.tag != "Player") {return;}
    script.enabled = this.enabled = true;
    script.ship = other.transform;
}
 
function Update() {
    myTransform.position = enemy.position;
}
 
function OnTriggerExit(other : Collider) {
    if (other.tag != "Player") {return;}
    script.enabled = this.enabled = false;
}

Save the script, find the EnemyTrigger prefab in the Project pane, and click on it. Go to the Component menu and choose Scripts -> EnemyTrigger. That's it: you can now run the game, and your enemy will chase after your ship when you come close enough. It's moving kind of slow, however...maybe you want it to be more of a challenge. So stop the game, click on the Enemy prefab, and change the "MoveSpeed" variable to a higher number. Run the game again, and the enemies will go faster. If you pause the game and change MoveSpeed, the change will revert to the original value as soon as you stop the game. You can use this to quickly test different values, but make sure you remember to change the value to your desired number after the game is stopped. Happy blasting!

If you want to try some additional scripting to make the enemy more interesting, see the next section for some suggestions.


2D Shooter Index : Previous Part : Next Part

Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox