Casting the ray

In the PlayerCollisions script, move your cursor a couple of lines down from the opening of the Update() function. We will place the Raycast operation inside the Update() function because we need to technically cast our ray forward every frame, as the player's direction may change at any time. For optimization, you might want to restrict this call to 1 time on 10 loops or something like this, to avoid CPU overhead but I will leave this code tweak to you as an exercise. Now, add the following code within the Update method:

RaycastHit hit; 

if(Physics.Raycast (transform.position, transform.forward, out hit, 3))
{
if(hit.collider.gameObject.tag=="playerDoor")
{
currentDoor = hit.collider.gameObject;
currentDoor.SendMessage("DoorCheck");
}
}

At the outset, a ray is created by establishing a local variable called hit, which is of the RaycastHit type. Note that it does not need to be made private in order to not be seen in the Inspector, it is not seen because it is a local variable (declared inside a function). This will be used to store information on the ray when it intersects colliders. Whenever we refer to the ray, we use this variable.

Then, we use two if statements. The parent if is in charge of casting the ray and uses the variable we created. As we place the casting of the ray (the Physics.Raycast() function) into an if statement, we are able to only call the nested if statement if the ray hits an object, making the script more efficient.

Our first if statement contains Physics.Raycast(), the actual function that casts the ray. This function has four arguments within its own brackets:

Note that in C#, we must use a precursor out parameter before the hit variable in order to get the function to assign data to it; this is done implicitly in JavaScript by simply naming the variable to use.

Then, we have a nested if statement that first checks the hit variable for collision with colliders in the game world, specifically whether we have hit a collider belonging to a GameObject tagged playerDoor,  we will write:

hit.collider.gameObject.tag == "PlayerDoor" 

Once both the if statements' conditions are met, we simply set the currentDoor variable to the object stored in the collision hit collection and then call the DoorCheck() function using the SendMessage() method.

Using SendMessage, we can call a method on a GameObject without a reference to the particular script, simply by naming the function:

currentDoor.SendMessage("DoorCheck");

SendMessage() here simply checks any scripts attached to the object assigned to the currentDoor variable, finds the DoorCheck() function, and calls it.

For more information on SendMessage(), see the Unity script reference at http://unity3d.com/support/documentation/ScriptReference/GameObject.SendMessage.html.

Save your script and return to Unity now. All that is left is to apply our DoorManager to the door. Ensure that the outPost parent object is expanded in the Hierarchy so that you can see the door child object and then drag and drop your DoorManager script from the Project view onto the door child object in the Hierarchy.

Assign the door_open and door_shut audio clips to the public variables on the script component in the Inspector, as you did previously when they were members of the PlayerCollisions component.