Hey everyone, I'm Jeremy Gibson Bond and welcome back to the Unity Certified Programmer exam preparation course. In this video, we're going to be looking at your next challenge, which I've called the environmental interactions challenge. There's a lot going on here, a lot of little things that tie into this, I guess kind of an API that I put together for you, that has to do with player actions and player interactions. Well, let's start by looking at the completed version and seeing all the different things that you're going to implement in this challenge. So, here we are in Unity, and you see that I have the game manager selected in the inspector. And I've actually locked the inspector using the lock in the top right, because I want to be able to click on other things and not have this change, because I'm going to need to turn this test alert trigger off several times. So, the alert mode manager script is the only thing on the game manager game object right now. And what it does, is it just manages when we go into or out of alert mode, and notifying things that need to know that we're an alert mode. Later, you will add things in the next course that react to alert mode, and you'll have things like the enemy chasing you and the lighting changing, and all these kinds of things. But right now, we just need to set whether we're in alert mode or not. Let's play and take a look at what's going on here. All right. Let's press play in Unity and get started here. You can see that now I've got this security camera that is panning back and forth. One of the aspects of what you'll want to do for this challenge, is set up this panning back and forth. We'll talk about that a lot more later, because it uses something called timeline playables, they are really really cool. And there's something that a lot of people I don't think have discovered yet, so I really encourage you to take a look at those, as part of this challenge. The other aspect of this security camera, is that when the light touches the player, boom, we get an alert. The alert mode changed to true here, so that is built into the light cone on the camera, that volumetric light-cone, meaning a light cone you can actually see through space, rather than just a light that you see shining on the ground. To show you what I mean about a volumetric light cone, you can see I'm here in the light cone that is attached to the security camera. And if I turn off the mesh renderer, then you'll see that I just get the light itself. This cone really helps the player understand where the security camera can see at any time, so that's why I put it in there. It's a little script I wrote, it's not perfect, but it does give a pretty good effect for what we're looking for. Moving on from the security camera, I'm going to turn off the alert right now, so alert mode is changed back to false. And now, I'm going to walk up through the security gate, and as soon as I walked through it, boom, the alert mode gets set back to true. That's another thing that can set the alert mode, that can set off alarms in my stealth game. I'm going to turn that off again, and I'm going to show you the next thing you need to implement, which is the security desk here. When I walk up to the security desk, you can see that when I'm within the area of the security desk where I can affect it, it glows with this green glow, telling me that I can do something. If I hit space, it turns off the security gate. And now if I walk through the security gate, no alarms are set off. And then the last thing, this is going to use the same implementation as that on the security camera, is this light cone on the bot here, when it sweeps across me, also will set off the alarm. You see it there, it set the alarm to true. That's what you need to implement for this challenge. Let's take a look at how I've set it up for you in the starter project. Here we are in the starter project for this challenge. And the most important thing I've added here, is this player interaction folder within the scripts folder over in the project pane. You can see that there are several different scripts there that all amount to a way that I want you to approach this problem. Let's break it down into the various elements. The first thing that is actually outside of this, is the alert mode manager, which you can see is on the game manager. Now this alert mode manager, all it does is get called whenever you want to set the alert to true or false, and then notify all the things that need to know about it. You can see that there's a delegate, that's the alert mode status change delegate, that you attach things to if you want them to be notified whenever you turn the alert on or off. Now this delegate could be changed into an event, which will be a little bit more secure, that honestly might have been a better way to do it, but I showed you events in another course I wanted to show you, just raw delegate here. Now, you can see that I've got this alert mode public property that deals with the underscore alert mode private bool there. And this public property whenever it is set, if it's setting it to a different value than it currently is, we'll call that delegate to fire out information about the new alert mode to all the things that you need to know about it. Down at the bottom of the script, is the static method switch to alert mode, which defaults to true. That is what can be called by anything in the game to turn the alert mode on. That allows you to add new things that fire off the alert mode pretty easily. To show you an example of how to use the delegate, I've put in this private void logged to console method inside the alert mode manager. You can see all it does is pass that alert mode change message to the console. But what's interesting about it, is I attach it to the delegate here on line 46. If for some reason you didn't want to use this, then you can turn off the pound define up at the top that defines the console log alert mode change value there. Let's look at an example of where this is called. I've actually already implemented the security gate for you. Now you can click on security gate beams to see how it works, and again, I'm trying to get you to approach this problem in the same way I did, because it ties into a lot of stuff that is really useful to know, in terms of programming and stuff for this exam. This is the player interactable script. And what this does, is it looks for a game object with the interacting player component attached to it, to walk into a trigger on the same game object as this player interactable. You can see that on these on-trigger enter and on-trigger exit methods here. It gets triggered, looks for interacting player component on that game object. And if it's there, it sets player within trigger to true, and if it is on exit, it sets player within trigger to false. This does assume that you only have one player, or maybe I guess you get a multiplayer game and each player would trigger this in the same way. But for now, we're looking at it as if there's one player. When player within trigger is set to true, it just sets the hidden protected value underscore player within trigger. But this is what's a little bit interesting about this, is the getter here. If there are no actions stored on this player interactable as things that should be called when the player is within the trigger, then it returns false when we ask if the player's within the trigger. And that's just kind of a way of protecting it from trying to call things that aren't there, or from giving us false positives. Here in the update is the meat of where this actually happens and calls these actions. You can see that if the players within the trigger, which again is only true if there are actions to be called, then if there's no triggering key, if that's just set to blank or none, it will just execute the action. As soon as the player walks into the security gate, it executes that action. On the other hand, if there is a triggering key and on this update the player pressed that triggering key, which will be for the desk where we have to press the space bar, then it will execute the actions. Here's this Execute Action Script, it goes through the list of actions that need to be executed, and it calls act on them. Now when an action is executed, it decrements the time left to activate if they're greater than zero. If any times left to activate then becomes zero, that action is removed from the list of actions that can take place. I'll talk about that more when I get into the actions. Times left to activate can be set to negative one, which is the default, which means it just activates all the time. But if you give it a set number of times, when those number of times gets down to zero, it is removed from the action list. And then, the final method here is the register method, that allows you to register a player action. And when you register a player action, it just adds it to that list of player actions. Let's look at player action, and the first thing you'll notice is that player action is a child class of player action abstract. Let's take a look at that. Here, we are in the player action abstract class, which is an abstract class, meaning you can never create an instance of this class. You can only subclass it with other classes. Similarly, public abstract void act is an abstract method, meaning that it must be overridden in sub-classes. The thing that this allows us to do is override it in a final way. If we go into player action, you can see that act here is sealed, meaning that it can never be overridden by it's sub-classes. I wanted to ensure that act was a thing that was inviolable, right? So it could not be changed by sub-classes, and that's why I set up the abstract class and then the player action class, and made this public overwrites sealed void act. If you take a look at the player action script, you'll see that it manages the times left to activate itself. On awake, it registers itself with any player interactable component that is on the same game object, and it has a public abstract void action method, which again, must be overridden by sub classes, and that action is what is called in the subclass. Finally going back to player action underscore trigger alarm, you can see that I have overridden that action method that needed to be overridden because it was abstract, and that's what I call, switch to alert mode. Now that you understand that, let's take a look at the desk and how the desk is supposed to work. So, you can see the desk here has a trigger and this trigger has a player interactable script on it. So, what I want you to do for the desk is create a PlayerAction_disableGameObject, and this will be in your problem set definitions. That will disable a game object when the player interacts with this object. So, the player walks up to the desk, enters this box trigger collider here, and then presses the triggering key, the spacebar, and that will fire off the PlayerAction_disableGameObject to disable the security gate by selecting security gate beams and setting its active to false. So, that's how that is supposed to work there. Looking at the light cone on the security camera, I want you to do the same thing. However, there is no collider on the security camera. So, you need to sense that the player is within the security camera in a different way. So, let's take a look at what this light cone actually does and how it's doing this volumetric trick. You can see that when I select it, I get a simulation of kind of where the light cone is going to be, and this shows you how it works. You can see that it sends out re-cast and when they collide with something, the line stops, and it kind of builds a mesh from that. If I move my player into here, and then go back to that light cone, you can see that the player is now blocking some of those re-cast hits, and that does the same thing when it's actually playing. Except, instead of just 16 gizmo wedges, it uses 360 wedges. I can actually set this to 360 as well, and you can see the same thing happening here. You can see when I move the player, select her here, select somewhere here and then select the light cone that she is interacting with and blocking those rays with her capsule collider. So, setting the light cone back to 16 gizmo wedges and pressing play, you can see that the effect with the player is actually pretty nice. When I click on the player, I can move her around and you see that she kind of casts a shadow. Now again, it's not perfect but it does feel like a volumetric light. So that's what I was going for, and it allows us to get information from it on collisions. So, each one of those rays of the mesh. So, you can go through the array of recast hits that you get from get re-cast it, and see if the root of the collider that was hit is the same as the root of the interacting player component, and that will give you that information. Let's look at interacting player to see what I'm talking about here. So, this is where I said there can only be one player for now. Interacting player has a singleton. So, you can get the interacting player at any time and from that get its root. Now, why am I talking about getting the root transform rather than just say GET component and parents for the collider that was hit by the re-cast? It's because GET component is a relatively slow action but getting the root transform is really pretty fast, and so for all those different rays, getting the retransform is a much better idea than trying to get component in parents. So now, once you've got the light cone set up with your PlayerInteractable_LightCone script, that's a child of player interactable and works the same way it does, then you can just drop on this PlayerAction_TriggerAlarm and that will work, and you will be able to trigger an alarm with this light cone and then apply the same two things to the light cone under enemy, which you can see is here, deep down. It is probably easiest to just search for LightCone and you'll find it, and select it, and then stop searching, and well, I picked the wrong one but you'll pick the right one, so there you go. There are two more things to clarify with this challenge. One is setting up the movement of the security camera. You can see if I select SecurityCamera here, I've got the anchor, and if I were to rotate this, that doesn't look very good. That's not how this should work. So, instead you want to select Camera_Cam and rotate that around the y axis, which looks a lot more like an actual security camera rotating. Now, the way I want you to do this is, is to use a timeline playable which is a new thing in Unity. But they're really cool and a really useful way to do simple animations inside of Unity, so you don't have to hop into Maya, or Max, or something like that to do your animations. To get started with that, you want to go under Window to Timeline, with the Camera _Cam selected, and then here it says, "To begin a new timeline with Camera_Cam, create a Director component and a Timeline asset." If you click Create here, it will automatically, I'll just go ahead and put this in the Timeline and Playables. This attaches the playable director and the animator components that you need to the Camera_Cam. So, you're probably going to want to set the Ret mode to loop, you're definitely going to do that, and you may want to click Avatar here, and set the Avatar to be the security camera Avatar. That just makes sure that the animator understands the kind of thing it's animating and it's not trying to animate a regular person or something like that. Then within the Timeline/Playable's Window, you can actually set up the rotation about the y axis for this camera. So the way I want this camera to work, is I want it to start panned about 45 degrees this way, right? So, it starts at about 45 degrees, waits two seconds, then spends four seconds panning back to this side. So, it's about 45 degrees this way, spends two seconds there and then spends four seconds rotating back to the original position. If you loop this, it'll take 12 seconds and it'll give us a nice such light pattern that our player can easily avoid, which is what we're looking for. So the last thing you need to do, is that pulsating glow on the desk when the player's within that trigger here. So, you can see the player's not within the trigger. Basically, when she gets to here, we want this green glow on the desk to pulsate, and that will happen by changing the value of border size in the shader. So, that's a thing where you need to go into the shader and change that value, and you can get a nice sort of pulsing thing. I'd usually base it on a sine wave or a cosine wave, to get that nice pulse. So, that's it for the environmental interactions challenge. As you can see, this, like I said, is a bunch of different things but they're all related, they're all part of the security system and they'll have to do with these player interaction scripts that I set up for you. These scripts mean that this is less open-ended than some of the other challenges that I've given you. But I do think that it is setup to better prepare you for the exam. So, I hope you have fun with this and I'll see you in the next video. Thanks.