Point & Click Game Development Unity & Playmaker: No Code! | Romi Fauzi | Skillshare

Playback Speed


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Point & Click Game Development Unity & Playmaker: No Code!

teacher avatar Romi Fauzi, Game Developer, 3D Artist & VFX Artist

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

    • 1.

      Introduction

      1:18

    • 2.

      01 Project Setup

      6:03

    • 3.

      02 Pathfinding Setup

      6:55

    • 4.

      03 Click to Move Behaviour

      14:49

    • 5.

      04 Base Interactable FSM

      16:34

    • 6.

      05 Base Action FSM

      18:27

    • 7.

      06 Dialog Manager UI Setup

      7:51

    • 8.

      07 Dialog Manager FSM Setup

      16:05

    • 9.

      08 Send Dialog Action

      18:31

    • 10.

      09 Dialog Options

      21:23

    • 11.

      10 Activate Deactivate Multiple FSM

      17:28

    • 12.

      11 Item Definition and Inventory

      9:09

    • 13.

      12 Give Item Template

      9:47

    • 14.

      13 Take Item Template

      10:10

    • 15.

      14 Tidying FSM

      3:35

    • 16.

      15 NPC Move Action

      7:05

    • 17.

      16 Add Model and Animation to NPC

      6:57

    • 18.

      17 Replace Player Model and Add Animation

      4:49

    • 19.

      18 Inventory UI Panel Setup

      7:49

    • 20.

      19 Inventory Panel UI Functionality

      37:00

    • 21.

      20 Save and Load Concept

      7:57

    • 22.

      21 Setup Save Manager

      46:09

    • 23.

      22 Record Entity State

      16:06

    • 24.

      23 Load Entity State

      21:55

    • 25.

      24 Record Inventory

      15:15

    • 26.

      25 Audio and Animation Action

      11:59

    • 27.

      26 Camera Manager

      22:59

    • 28.

      27 Switch Scene FSM

      21:39

    • 29.

      28 Door Swing and Transparent Wall

      17:18

    • 30.

      29 Cursor Manager

      18:31

    • 31.

      30 City Scene Story

      19:30

    • 32.

      31 Club Hallway Story

      19:11

    • 33.

      32 Keep States Between Scenes

      19:51

    • 34.

      33 Park Scene Story Part 1

      32:51

    • 35.

      34 Park Scene Story Part 2

      28:57

    • 36.

      35 Connecting City to Park Scene

      11:35

    • 37.

      36 Saving Loaded Scene

      16:31

    • 38.

      Bug Fixing: NPC Move Template Fix

      7:10

    • 39.

      Bug Fixing: Player Movement Fix

      5:02

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

41

Students

--

Project

About This Class

Join this comprehensive course and learn how to create captivating point and click adventure games without coding using Unity and Playmaker! Whether you're a beginner or an experienced game developer, this course will equip you with the skills to bring your game ideas to life.

Through hands-on instruction, you'll delve into Playmaker, a powerful visual scripting tool for Unity, and gain proficiency in creating Finite State Machines (FSMs) to handle game logic and player interactions. Discover how to leverage FSM templates and custom actions for efficient game mechanics and behaviors. Plus, dive into NPC States saving and loading, as well as Inventory and Item mechanics.

You'll also master complex save mechanics for persistent player data, implement additive scene management for seamless transitions between game scenes, and utilize Unity's Timeline tool for creating professional cut scenes. With a focus on practical application, this course provides you with the tools and knowledge to create engaging point and click games that will captivate players.

Whether you're a beginner or an experienced game developer, this course is designed for:

  • Aspiring Game Developers: If you've always wanted to create your own games but don't have coding experience, this course is perfect for you! Learn how to bring your game ideas to life with Unity and Playmaker's visual scripting, and create engaging point and click adventures.

  • Unity Developers: If you're already familiar with Unity but want to expand your skillset and create point and click games, this course is a great fit! Discover how to utilize Playmaker to create custom game mechanics, save systems, and cut scenes.

  • Visual Scripting Enthusiasts: If you enjoy visual scripting and want to learn a new tool, this course is for you! Explore Playmaker's powerful visual scripting capabilities and create complex game logic and interactions without writing code.

  • Indie Game Developers: If you're an indie game developer looking for efficient and no-code solutions to create point and click games, this course is tailored for you! Learn how to create engaging games with Playmaker's FSMs, save mechanics, scene management, and cut scenes.

  • Game Designers: If you're a game designer looking to expand your skillset and learn how to create point and click games, this course is a valuable resource! Gain hands-on experience with Unity and Playmaker, and bring your game design ideas to life.

Enroll now and unlock your creativity with Unity and Playmaker - no coding required! Get ready to embark on an exciting game development journey and bring your unique game ideas to life.

What you'll learn

  • Create a fully playable Point and Click Adventure game in Unity with Playmaker.
  • Getting comfortable with using the powerful FSM Templates in Playmaker.
  • Utilize Scriptable Object, to create custom Item definition to be used with Playmaker.
  • Create complex save data structure in Playmaker, that is applicable to different game genre types.

Requirements

  • Basic Unity essentials knowledge is helpful but not required.
  • An installed Unity Editor (any version that is or above 2020).
  • A seat of Playmaker add-ons license for Unity

Who this course is for:

  • Intended for aspiring game developers, beginners or experienced, interested in creating point and click adventure games without coding using Unity and Playmaker.

Meet Your Teacher

Teacher Profile Image

Romi Fauzi

Game Developer, 3D Artist & VFX Artist

Teacher

Hi there, I'm Romi, a self taught 3d artist and game developer with more than 10 years of experiences in the industry.

See full profile

Level: Beginner

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. Introduction: Welcome to the Complete Point and click Adventure Game Development course, No Code with Unity and playmaker. I'm Rome Fozi, a game developer and a Tre D artist with over ten years of experience. I have self published a Google Play game and worked on various client projects using Unity. In this course, you will learn how to master game development using playmaker, a powerful unity add on that eliminates the need for coding. Topics covered include using FSM templates as custom actions or reusable FSMs with input and output values, creating an inventory system, using scriptable objects for custom data types, building a complex safe system to save inventory PC state scene states and more, implementing animations and setting up simple audio, utilizing timelines to create cinematic experience in your game. If you have any questions during the course, feel free to ask. I'm quite active in the QN A section and committed to providing trough answers. Join us to level up your playmaker skills and unlock new possibilities in game development. 2. 01 Project Setup: Hey, in this video, we are going to prepare the new project for creating the Point and click game using playmaker. So now here, I have this Unity Hub opened, and let's create a new project, and I'm going to pick Unity 2021 0.1 0.7. You can use other version, and if you have the same unity version installed, that will be best. And for now, let's just use a three DD templates. And for the locations, I already prepared a location here. And I'm going to call this playmaker coin and click. Okay. So now we have Unity opened. Let's prepare the project by importing a couple of assets. So first, I'm going to reset the layouts, so it is easier. And then we need to import a couple of assets. I already have the assets imported, but I'm going to share the link, and I'm going to open the package manager. Okay. The first thing that we need to import is playmaker. Of course, I'm going to import playmaker. And let's just import all of them. And here, under the guide window, let's just press Install playmaker and then install playmaker here. Okay. Now we are done with playmaker, Let's download another assets, which is the character asset that we are going to use in this project. It's called tiny two knee db here. I think it's this one here. Yeah. And I'm going to share the link so you can also add it to your assets. And I'm going to do here. And once it's finished downloading, let's press the import button. Okay. So that one is done, and the other thing that we need to download is the animation pack. So I'm going to download, I think it's called simple animation peg or every day. Yeah. It's called everyday motion pack free. And I will also share the link to this asset page. Just press download here. And once it's finished, press the import button again. Okay. Now we are done with importing the assets from Package Manager. Next, let's add a custom add on for playmaker called ecosystem, and this will help us customs actions that are not available by default on playmaker and created by other peoples or third parties that are collect that together in the ecosystem Github. So you can press this button to open the page if you want, and go to the ecosystem borrowser here and download the package. I've already downloaded that, so I'm going to import it right away. And to import this, I need to go to the assets menu under the import package, pick custom package. And let's browse to the folder where you download the files. So it's going to be here on my PC, and then press import. Okay. Now, ecosystem has been downloaded and to access ecosystem, we can go to the play Macer menu under add ons and then press this ecosystem and open the ecosystem browser. And if you install it the first time, we will have this window, but if you want to use it, just press use the ecosystem button, and it will show this bar, and we can type anything. Okay. So now let's just close this for now, and there are another two assets that we need to download, and this is the asset that I created myself, so I'm going to share the files in the resource part of this course. The first one is an audio file, so I'm going to drag the audio files folder and put it here. And once we import this audio files, we will have a couple of audio that we can use in our game. And then I need to also import a package that consists of treaty models for the environment that we are going to use in this project. So let's go to the asset menu, press import package, custom package, and I'm going to go to the folder where I saved those package file here. And then import it. And here, it will be under the point and click folder, and there will be a lot of FBX files and also material and textures. So let's just press import. And now we are pretty much done with the projects. I'm going to clean up a bit here. For example, on the project page, I'm going to change the view to a very small icon so we can see the name of the folder at its full length to make it easier to know which folder, So, yeah, I think we are pretty much done in this video. And the next video, we are going to start working on our game. 3. 02 Pathfinding Setup: In this video, we are going to continue our game project, and we have set up the projects in the previous video. So now here on our sample scene, let's just create a couple of objects that we can use to test our FSM. So I'm going to create a two d object, and this is going to be the ground. I'm going to reset its transform, so it's at 000. And for the scale, I'm going to make this slightly bigger like 20 units on the side. And I'm going to set its height to a very low value, which is 0.1, and this will be the ground of our test environment. And here, let's create a couple of materials that we can use. So I'm going to go to the point and click folder materials, and let's create a new subfolder inside of it, and this is going to be the prototype materials. And here inside this folder. Let's create a new material, and let's just call this ground proto. So we know this is for the ground prototype object. And let's just track this to the object here. Now it's assigned to the measure render of this cube game object. We can change its color. Let's just change the color to a slightly darker gray. So it's not as bright as before. And now the other thing that we want to create is a capsule object. So let's go to the three D game object and create capsule. And this is going to be the character that are going to move around. I'm going to move the position to one on the y axis. So it aligns with our ground here. And I think we can lift this now. And the next thing that we want to do is we need to create the naviigation mesh so the character can move around the scene and can avoid any obstacles that are already considered as obstacles in the navigation mesh. So in order to do that, this tests, let's create a couple of other game objects, another cube, for example, and let's put it somewhere here. And I'm going to scale this on the z axis. So it's wider. And let's just duplicate this cube here by pressing control D, and then we can move the object to other position. So we have created some sort of obstacles here. And let's create an empty game object, and let's call this environment. And let's just reset the transform. And now I'm going to put all of the environment game object, which is the ground, the obstacles as a child of this anti game object. Just to make the scene much cleaner and easier to look at also to navigate. So let's just select all of the cube game object and then drag this to the environment game object. Now it's a child of this game object, and we can easily hide it to isolate the player, for example. Okay. So the next thing that we want to do is we want to generate the navigation mass. In order to do that, we need to make sure that all of these game objects is marked to static. And you can change the static options here on the top right of the inspector, where we have the name of the game object. On the right side, it will shows this check mark for checking the object as a static object. You can select all of this game object and then do that to all of the three game object, or we can select the parent game object, and we mark the parent game object as static, and Unity will as if we want to change the children also to a static game object. So I'm going to pick yes here. And now if we select the child game object, you see all of them are marked to static. So let's save our scene, and now in order to bake the navigation mesh, let's go to the window here and under the AI, let's open the navigation window. And basically, navigation mesh is a way to create a path finding for a game object in unity. Usually, it's being used for creating a movement for enemies that can move around like patrolling and avoiding any obstacles. But in this case, we want to use this for our player movement because we want to move the player whenever we click to a certain area. So in order to create those automatic path finding, we need to use the naviigation system from unity. So now we have the navigation window opened. Let's go to the baked tab here and this press bake. And this will automatically bake the scene. And now, as you can see here, we already have this blue mesh, and this is called Navigation mesh. This is the area where our player can move around. So if we click in this area later, we can set the player to go to that destinations and it will move to that point with a certain speed. And if we click to this area, for example, it will move to this point here, and then it will try to avoid the obstacles by calculating the shorter route to that point that we click. This is make a very good system for point and click movement. Okay, now we have set up the navigation mesh. Let's pick our capsule game object and go to the inspector here, change the name to player. So it's easier to see on our scene here, on the hierarchy, we will know right away, this is the player game object. And then we want to add a NAF mesh agent component. And this will drive the movement of the player. And here we have options like speed, angular speed, and other stuff like acceleration, stopping distance, and obstacle avoidance. Now we have set up the scene. In the next video, we are going to start creating the FSM for move the player around. 4. 03 Click to Move Behaviour: In this video, we are going to continue our game development, and we are going to implement the click to Move Mechanics using playmaker. So first, in order to do that, let's open the playmaker editor window under the playmaker menu here. Click the playmaker editor, and they should open the playmaker editor. I'm going to close this. Welcome to Play Maker Window and drag the playmaker editor window by its name here by the tab name, and then drag this to be on the side of Console. And make this bigger. And here we can start creating the behavior for the click to move movement. I've already created some sort of a notes as a guideline on how we want to do the click to move mechanics here. So basically, we need to click a couple of states, and the first one would be the wait for click. So let's just select the player again here and then right click and then add an FSM. This will create a new FSMs with one state as the start state. On the site here, we can rename the FSM or we can rename the FSM from this tab here. So let's just call this click to move, and this should make it easier later when we are debugging things or when we are organizing things in our scene. The first state, let's just call this wait for click. The state is basically going to wait for a user click, and then it will act upon on it. The next state that we need to do is the defined destination state. Let's create another state, and let's call this define destination. Basically, on the start state, we want to get mouse button down state, and then we want to go to another state based on those clicks. First, I'm going to create a custom event that we can use to transition between state. I'm going to call this mouse down. And we can add that transition to the first state here to the wait for click state, and we can drag this connection to the defined destination. And here inside the wait for click state, we want to use the GT mouse button down action. And if the left button is clicked, then we want to send the mouse down event. And this will trigger the transition whenever mouse is clicked. And here on the define destination. We want to use the mouse pick action. And mouse pick action basically performs a mouse peck on the scene from the main camera and store the result. And we can use a couple of other options with this action. Basically, it will detect if a ray from our mouse click is hitting something on the scene, then we can use that information. Let's just add the action to state here. And we want to store the value whenever this mouse pick pick an object. And basically, store this object is a bulion, so we can just create a new variable, and let's just call this valid click. Once we create this new variable, you see that we have this false value, and if we go to the variables, we know that it's a type of b. This can be true or false. And if the mouse pick hits something, this value will be true, but if it doesn't hit anything, then it will be false. For example, if we click on an empty area here, then the valid click value will be false. But if we click on top of a object that has clyder on it, then this will be true. And we want to set a layer mask. So I'm going to add a layer mask here, and we can add a layer. But right now we don't have that layer now. So in order to do that, we can open the environment here and select the first cube. And under the layer options, let's just click Add layer, and I'm going to use the user layer six, and let's just call this ground. Go back to the first cube object here, and we can change its layer to ground. Now let's say the scene and go back to the player game object. And let's set the layer mass element zero to ground. This will filter out any clicks. So if we click on other objects that is not the ground, then it won't be registered as a valid click. And we need to also start a point here. So point is basically a vector tree value, so we can just create a new variable, and let's just call this target position, or target pause. And now we are done basically with our mouse pick action. We need to check if the valid click is true or false. So let's just use a bull test. Action, and as the name just send an event based on the value of a Bulion variable. Let's just add this one here. And then we can use the valid click Bulion, and if it's true, then we want to set a destination. Here, we can see that if the click is not valid, we want to go back to wait for click, but if it's valid, then we want to go to another new state called Set destination. And this will set the navigation M destinations. So we need to create a custom event for this. I'm going to call this go to target position pus. And at the transition, go to target pus and also finish. And finish is when the valid click is false, then we want to go back to the wait for click. So now if it's true, then we want to go to the target position, and if it's false, we want to pick the finish transition. Okay. So that's all with the bull test here. And let's disconnect the finish back to the wait for click state. And we can create a new state by right clicking and open the context menu and then add state here or to make things faster. I will let you know for some tip here, if you hold control on the keyboard and then drag the transition from the target pose here. If you release this, it will automatically create a new state. And for the state here, we can call this set destination. So let's just type it. This new name here, set destination. And now inside the set destinations, we need to add the Nu mesh agent action, but we don't have this by default. So in order to download it, we can go to the playmaker menu under the add ons, open the ecosystem browser, and then search with keyword path finding. Just press the search button. Once it shows the result, we can press the get button, and this will download the package. Now here, let's just press the import button, and they should import custom actions for path finding, and once it's finished compiling, we can add that action. Let's close the ecosystem browser. And now if we go to the action browser, we can search for agent, and this shows a lot of NAM agents related actions that we can use. And here, the action that we want to use is the SAT agent destination. Let's just use this here. And now we have the target position variable. If the valid click is true, then this should store some value. We can use that for the destination. So here, right now, we are going to use the owner. And for the destinations, we can press this equal sign, and this should expose the variable field, and we can use the target position. And we don't need to do anything on this done event here, the path pending De event, but I want to add a next frame event. And this will delay the transition, which is the finished transition that we are going to add now. And on the next frame event here, we want to send that finish event. So this will delay the finish transition by one frame after we are setting the destinations. And this is need to be done because basically, on the next date, we are going to check if the agent has arrived or not. And if we've done it on the same frame, there is a possibility that the destination has not been triggered yet on the next date, and it will trigger arrive in the same frame. So it will cause a bug or issues, and this is how we are going to prevent it to make sure that the destination has been set, and on the next state, it will wait until the agent arrived to the destination. Okay. So now if we review the mechanics here, we want to go to the wait to arrive after set destinations. And this is going to wait the player while it's moving And later, we are going to add another transition to set for two different scenarios here. If we click again to another destination, then we want to go back to defined destinations. And if we arrive, then we want to go back to the first state, which is wait for clay. So now let's just create this way to arrive state. So I'm going to hold the control button and then direct the transition, and we can create the state automatically. Let's just call this way to arrive. Basically here on the way to arrive, we want to add a transition, and the first one is the mouse down transition, and the second one will be the finished transition. Here, basically we need to add two actions for now, and the first one will be the mouse button down and send this event to the mouse transition, so it will go back to the defined destinations and we can create those connections, and then we want to use the get agent remaining distance action. And basically, we want to put this below the Get mouse button down. And here, we don't want to store results, but we want to trigger an event, and we can use the finish transition and check the every frame toggle here. So these actions will get executed every frame. And then on finish, we want to create a new state by holding control and drag the transition, and let's just call this arrived. And let's add a finished transition for now. And for now, this state is going to be empty, but we are going to expand the functionality in later videos. So now let's just connect the finish back to wait for a click. Okay, Let's review the FSM. So we have this wait for click. It waits for the left mouse button down and go to the mouse down transition. And here we have the mouse pick, which is going to store the valid click value as a bulion and a target position. And we have the filter using the layer mask and it sets to ground and make sure that we set the ground object layer to also ground. I'm going to rename this for clarity's sake. And then on here on the devine destinations, we are testing the valid click values. Then we are going to target position. And here we are triggering the set agent destination using the target position variable that we've created from the mouse peak here. And then we are waiting one frame and then go to the next frame here. And basically, this way to arrive will stays for a while until we either press the mouse left click or we arrive on the destination. So let's just save the scene here, and now let's give it a try. Okay. I think I'm going to stop this and I'm going to make the same angle for our camera to our scene view here. And the easy way to do it is by selecting the main camera and then hold control SF and F key on the keyboard. And this will snap the camera to the scene view position automatically. If we go to the game view now, we should have the same view as our scene view. And now we can save the scene again, and now let's test this. Now it's running and let's select the player so we can see the FSM. Right now, we are on the start state, which is the wait for click. If I press click, it will move to that position. Here, as you can see, it waits to arrive and then it go to arrive and then go back to the wait for click. But if we are moving and then we click somewhere else, it will deviate to that position because we have this mouse down event on our way to arrive and it will go back to the defined destination. And let's just give it a try. Let's click to this position. It moves to that obstacles, and it will go around it. So it can avoid any obstacles with this navigation mesh. Yeah, basically, we are done with the basic click to move mechanics, FSM, and of course, we are going to expand this in later videos. A. 5. 04 Base Interactable FSM: Hello. Now we are going to continue develop our point and click game. In this video, we are going to start to create an interactable component. Intactable component is a component that we can attach to an NPC or other game object, and the player will be able to interact with those objects, either an NPC or other, for example, like an item like a door or anything. And we want to make it as modulized as possible. So interactable, we will hold an actions. And then whenever we interact with an interactable object, we won't trigger all of the actions that are registered on the interactable. The interactable part of the video will be split to a multiple videos. And now let's create the base interactable component. So here, in the scene, I'm going to create a new three d game object, a capsule. And let's just rename this capsule to NPC one. And on the scene here, let's just reset the transform and set the position y21, and we can move to a certain location, for example here. And make sure that the transform or the coordinate is set to local, so we can see the local transform of an object here, and as you can see, the z is facing that way. And with this interactable, we want to create a default interact position, and this position will dictate the player position whenever we want to approach this interactable game object. So for example, let's just rotate this NPC by pressing E, we can switch to the rotate control here, and then hold control, and we can rotate it by five degrees incrementally. So for example, if we want to make this character facing that way, and with this orientations, we can set the interact position to run in front of this NPC game object. So now let's create the FSM. I'm going to add an FSM here, and let's just call this interactable. And here, we want to define the target position of this interactable. So let's just change the state name, define position. And basically, with divine position, we want to get the owner first. And with G owner, we can save the game object where this FSMs is attached to. So let's just create a new variable. And let's just call this owner. And next, we need to add a get position action. So let's just type get position, and we should be able to use the Gt position action here. And let's put the get position below the Get owner. And we can specify game object. Although we can use owner, but we can specify game object, and later we are going to use this owner variable for running the action. So we need this variable anyway. So I'm going to use that owner variable. And let's just store the vector position to a new variable. And let's just call this target position. And let's set the space to world. Let's minimize this. The next thing that we want to add is the transform direction. So let's just type transform, and we should be able to use a transform direction actions. Basically, this is for converting a local directions of the player or a certain game object, and it will change those direction into a world space vector. So basically, we just need to use the owner here, and we want to get the di, the forward directions, which is the z axis, so the local directions would be zero, zero, and one on the z axis. And this will be equal to the local directions of the blue axis of this player here. But we need the value in world space. In d space, the value is not going to be 001 because 001 on oral space will align with this arrow on the view gizmo here, and this is the 001 on the world axis. So we need this value to be converted in world space. Let's just save this to a new variable called forward. And we want to dictate the distance from the interactable to the target position. In order to do that, we need to multiply the forward with a float number and this will change the length of the vector. Here on the variable, I'm going to create a new variable called stopping distance. I'm going to expose this as an input variable here, so we can see it here, and let's set its value by default 201.5, for example. Now we have this value here. The next thing that we want to add is the vector three multiply. Let's just search for multiply and pick the vector 31 here. And we want to multiply the forward direction with the stopping distance that we have just created. And now we will have a longer or shorter forward depending on the stopping distance value. In this case, it's going to be longer because we set the value to 1.5. The next thing that we want to add is the Vector three ad operation, so let's just search for it, and this is the one that we want to use here. Vector three d. And basically, we need to put this vector three at below the multiply because the order is important in this case, because some actions realize on values that are generated by previous action. Here the Vector three variables. Let's set this to the target position, and we want to add this position, or we want to offset this position based on the forward. Because the forward doesn't contains position informations, I just contains direction information, so we need to add both the get position result and with the transform direction result. Now that we have added, this will change the target position value actually. We don't need to store these operations into a new variable. This will override the target position. Now we have finished set up the define position state. We need to create another state here. And let's just call this interaction. And we need to create a global transition here. I'm going to create a new event here and I'm going to call this interacted. Let's at this as a global event here by checking this wave icon form here. And now we can add the global transition here and pick interacted. And now we want to go back to defined position whenever we finish running the interaction. I'm going to add a finish transition and go back to defined interaction. For now, we are not going to do anything other than debugging. Let's just open the action browser again. I'm going to run the debug log here. And let's set this to info. We can set a text, for example, interacted, and we can send this to Unity Log so we can see it on the console here. Okay. Now we are just going to do debugging. Let's save the scene. Next, we need to modify the player FSM, which is the click to move FSM here. And basically, we need to check if we are clicking an interactable. And in order to do that, I'm going to add a new layer for this NPC here. So let's just create a new layer, and let's just call this interact. And go back to the NPC, and we can pick the interactable. And now let's go back to the player game object. Here in the defined destination state, we want to duplicate the mouse peck here by pressing control C and then control V, and we need to change the started peck object to a new variable, so let's just create a new one. And let's just call this valid interactable. And for the layer, let's change this to the interactable. We don't need the position here, so let's just set this to none. But we want to store the game object with this one here. So let's just create a new variable, and let's just call this interactable. And now that we have add this mouse pick, let's just minimize the mouse pick, and we need to create another bull test here. Let's just duplicate this. And then let's just pick the valid interactable. And in this case, we want to change the true event here. Let's just create a new event. I. And let's just call this go to interact. And let's add this transition, go to interactable. Let's move this transition up, so it's nicely ordered here. And let's pick the go to interactable event. I don't think we need this finish here. Yeah, correct. We don't need this finish because this finish, we want to set the bull test here to the first bull test. But if we are setting this finish transition here, Then if we are not clicking interactable or if the valid interactable bul in value is false, then it will go back to finish, and it won't evaluate this second bull task. So we need to do that. So let's just set this to none, and then we need to create a new state. And we can create it by holding Control and drag a new transition. This will create a new state. In this new state, we want to get interact position. So in order to do that, we can use the get FSM vector three action. So let's just type get FSM, and we should have a lot of get FSM with different types here. So I'm going to pick the vector 31. And now that we have saved the game object, we can use that game object by specifying the game object, and we can pick the interactable game object. The FSM name, it's going to be interactable. So we can just type this. Because we know that on the FSM, basically the FSM with the name of interactable is the one that have this target position defined here. So we need to access this variable. And here on the player, we can type the variable name, it's target position. And this has to be exactly the same case wise also. So always make sure to check on your source FSM here. And store its value to the target pause here. Once we have set up the target pause here, we can just add a finished transition and we can go to this set destination. Now we have set up the go to interactable. We need to trigger the interacted event whenever the player arrive. So in order to do that, here, we can check inside this way to arrive. In order to run the FSM, in the interacted event on this FSM interactable. We need to go to this arrived state. And here we want to check if a game object is null or not. So let's just use game object. I think it's with space game object is null. And let's check the interactable. If it's null, then we want to go to the finished state. And we can run this every frame. And if it's not null, then it will stay in this arrived, and we want to also send an ev. So let's just add a send action here and make sure that this is below the game object is null, so I'm going to drag this to the top. And we can use the game object FSM here and specify game object, and we can pick the interactable. And at this point, interact won't be null because if it's null, then it won't get to this action. It will go to the finished state here, as you can see, and it will go to the first state. So we don't need to worry for any null reference. And we know that the FSM is called interact. And we want to send a global event and we have created this interacted. So we can use that. And by default, the player might not be facing the interactable game object. So in order to do that, we can add a smooth looked at action. And for the target game object. We can use the interactable. And let's set the vector 21 on the y axis, so it will rotate on the y axis. Check the keep vertical and set the speed 210, so it rotates quite quickly. And once it's finished, we want to run the finish event also. Now let's save the scene, and let's give this a try. Now we can click on I'm going to open the console and we can click the interactable. And as you can see here, once it's arrived, we have this log output on the console says interacted. So it means that the states here, it's running, it gets fired. So it means that our interactable component is working. And now, for example, if we stop this and if we change the stopping distance on the interactable FSMs to a very far value, for example, four, then we will have a very far stopping distance. And this might come handy in your game design. So let's just give it a try. There you go. It stop at that position, and it says interacted. So yeah, that is the basic intractable component, and we are going to expand this further. We are going to add actions that we can pair or chain in the intractable FSM. 6. 05 Base Action FSM: Hi. In this video, we are going to implement the action FSM. And this action is going to be a template. Template is very powerful in playmaker because it can create or it can convert an FSM into an action. So those template can be run as an action. Here I already created some sort of a concept here, a flow chart, a graphics. And basically, any action FSM must have a global transition called run action. And this is where all of the actions happens. And with this agreement that any action FSM needs to have a global transition called run action, We can create different actions, and the interactable component can easily run those actions, even though each action has like a different ability or capability like showing messages or moving an am object, like moving an NPC. Also some sort of creating interactions with item like giving or receiving item and any other actions that we are going to implement in this scheme. So let's go back to unity. And here, the first thing that we need to do is we need to create a simple basic action, and right now, we are just going to show a message in the console. To make this work, and later, of course, we are going to implement the dialogue manager where we can show messages in the game. So let's select the NPC now, and let's create another FSM. Just to make things easier to organize, I will always create an action on the child object of the interactable game object or the game object that has interactable component or FSMs attached to it. So here, let's just create an mt game object, and let's just call this base dialogue. And here I'm going to create new FSM. And in this FSM, we are going to create a basic dialogue FSM. So here we are not going to do anything on the start, but let's create another state, which is the state to show the message. And let's just call this show dialogue. Right now, we only want to show the message in the console so we can use the debug log again. And for the text, we want to create a variable. And basically, we want to create an array of string because we want to have the capability to create some sort of multiple dialogues that are continue after each other consecutively. So here on the variable, let's just create a U variable called messages. And let's change this to an array. And for the type, let's set this string. K. And this is going to be an input variable. So let's just enable this. We are exposing this variable to make it easier to modify via the inspector without opening the FSM. Here, let's just create one element, and let's just call this test dialogue. And now we want to show this in our show dialog, the bug log. So we need to get the value array or get array. I and basically, we want to get the first one, which is index zero, and in order to get a ray member, we need to sort it into a variable, so let's just create a new variable. For now, I'm going to call this debug tax, and I'm going to show the value in our debug log here by selecting the variable. And if we go back to the concept here, we have this global transition called run action that we need to add into each of the action. So I'm going to create a new event, and let's just call this run action. And enable the global event here. And now we can add this Run actions global transition. Okay, so now we have this base dialog FSM setup. We need to create some sort of an action that can run multiple FSM. So we can hook those actions into this interactable component. And this run interaction state can run multiple FSM or multiple actions in it. So now we are going to create the run FSM action template. We can just create it here on the base dialogue for now, and later we can just delete the FSM, so I'm going to right click here, and I'm going to create a new FSM. We need to click it here, so let's just create new FSM. And let's call this FSM action un FSM. You can name it anything you want. But for clarity's sake, I'm going to add a prefix action for an FSM that are going to be saved into a template, but it will be used as an action as a custom actions, and I'm going to add this action prefix. And later, we are going to also have a template FSM that has a template prefix on it, and that will act as a different FSM. It's not going to be an action FSM. And here on the action run FSM here, we want to loop the array. First, we need to create an input variable. So I'm going to create an array variable called actions. And this is going to be type of input, and input output is very useful for creating template. Basically input variable, we can fit a value or a variable from the FSM that is running that template as an input variable. And for the output variable, this is a variable that are going to be a result or a return from that FSM action template. So for example, if this FSM actions shod return any values or any data or any object, then we can put it on the output and the other FSMs that are running this action FSM can get those value once the actions has finished running. Okay. So the next thing that we want to add is a object variable. And this will be the current FSM because we are going to loop the FSM. And for the type, we can change this to a playmaker FSM. Okay. Now for this array float, we want to also change the type to object, and then object type, we want to also pick the player FSM. So this is going to be an array that holds reference to the player FSM that we are going to assign later. So here on the start, let's just rename the state to Loop array. And I'm going to create a local event called Loop, and let's add that loop transition and as well the finish transition. And here for the loop, let's create a new state. And let's just call this run FSM. And for the finish, we want to also create a new state. And inside this finished state, whenever we are running an FSM as an action via a template, we need to run a finished FSM to let know that the action has finished running. So we need to add the finished FSM action here, and that's it. And whenever we are running the FSM, we want to add a finished transition, and then connect this finish back to the loop array here. Okay. So here on the loop array, we want to use the array, get next action, and this will look. Every member in our array, and for the array, we are going to grab the actions. For the start and n index, we can set this 20, then this will loop every member inside of our actions array or any array that you want to loop. But if you want to loop from a certain starting index or two a certain n index, you need to insert a certain value here. And we need to set the loop even to loop here and for finish to finish. For the result, we want to save or we want to grab the member when we are looping this array to the current FSM. So for example, if the array get next is starting from the first index, then the current FSM will be the first FSM on the actions array. Then we loop to the run FSM. When we are finished entering this state again, then it will go to the next member, and it will save those next member to the current FSM, and it will do the same again. It will run the FSM again here. So now we have set up the loop array. The next thing that we want to do, we want to run the FSM, and we want to send the run action global transitions event to this FSM. We can use a SN event action. But with this, if you want to send an event, you need to grab the game object by specifying the game object here, and you will need to know the FSM name. So you need to get those information from our current FSM here. It's a bit tedious, so there is a better way to do this. I'm going to delete the SN event here, and we can use the call method. And this is basically accessing a method from a script if we have a custom script that we want to run via Plemker, but we can also run a method in FSM. Because basically when we are transitioning from one state to another state via transition even here, we are actually sending a method with a string argument, so we can use that. Let me just show you here to make it clearer. I'm going to select the behavior and then pick the current FSM, and it will know that this is a type of playmaker FSM. So it can list the methods that are available, at least public methods that are available in this current FSM because Playmaker FSM is basically also a class script that behave the same like any other C shop script. So we can access the public methods that are available in it. And I'm going to use the SN event here. And SN event as for a event name. And event name is basically the event that we have created here. In this case, we want to run the run action, because as we can see here, every action FSM should have run action global transition. So that is the transition or the event that we want to run. So we can easily just type this with all capital, and this should run the global transition run actions on that certain FSM. Okay, so now we have set up this. We need to save this as a template. So in order to do that, just right click here, and we can save Tplate. And here we can go to our project folder here. Plate Maker folder already has a template folder, so we can just use that if we want. I'm going to rename this two action run FMS. This will indicate a plural FSM, so we can run multiple FSM, and let's just save this. And then we don't need to use the safe template here. We can just delete this second FSM. Okay, now we have created those template, and we are going to use the template that we have just created on the interacted state here. Here instead of running the debug lock here, let's just use the FSM. Run FSM will enable us to run an FSM template that we save in our project. So if I browse here, you see that we have no category here, and we have action run FSM. And if I click this here, you see that we will have an input actions, which is an array of play Macer FSM. So we can just use variable here, and we can just create a new variable that we want to use. So let's just create a new variable called actions. And we need to also hook the finish event back to finish. So when the finished FSMs gets executed in our FSM template here, the action, then this will get triggered and it will go back to the start state. Okay. So now we have created the actions. We want to make sure that this actions is an input variable, so it is visible here. And now we can hook our base dialogue FSM. So for example, if I add a member here, we can drag the base dialogue, and it will register our FSM. And now let's save this. If everything runs correctly, we can see that it should show our first member of the string here in our message, the Test dialogue exclamation mark. And probably we want to send the action back to the first state whenever we finish showing the dialogue here or showing the message. So let's just add a finished transition and go back to the first state. Okay, now let's give it a try. Here, let's take a look at our console, and I'm going to go to the interactable. Okay. There seems to be an issue. Let's take a look here. I'm going to click this again. Okay. It runs the interactions, but for some reason, it doesn't run this. Okay. We can debug this by selecting the base dialog and go to the interactable, and it gets triggered actually. Oh, yeah. I forget to enable the cent Unity log here. So let's just stop this here. And on the run action, let's enable the cent unity log, so we can see the console. So it was actually working before, but we don't see the message in console because we are not sending those message to the console. Okay, now let's try this again. There you go. We have this message shown in the console, and it has this test dialogue message. And the neat thing with the setup is that if we change the message, for example, to Hey, how are you? For example. Then if we run the game again, the message will be different this time. So now we have the basic actions running. Let's try to test for multiple FSM. So I'm going to duplicate the base dialogue, and let's just call this second dialogue. Although since we are using an array of messages or string here, we can create multiple dialogue in one FSM. So we don't need to do this. But just to illustrate the multiple FSM or the action run FSMs working with multiple FSM. Let's just give this a try. So let's just change the second dialogue here. Message. That's good to here. And if everything works correctly, then we should see two message here. Oh, sorry. I forgot to assign the second one, so I'm going to stop the game here and go back to this interactable FSM here and expand the actions. Let's increase the size. Then we want to drag the second dialogue. Okay. So now, I think we are done set up this. Let's just give another run. Okay, as you can see, it works great here. We are seeing the first message in the console, and we also see the second message in the console. So it means that our run FSM is working as it so, and in next lesson, we are going to expand these actions. We are going to create multiple different actions. 7. 06 Dialog Manager UI Setup: Now we are going to continue to create our actions more usable because currently we only outputting message to the Csole. So in order to make a dialog messages, first, we need to define the dialog manager. And first thing that I want to do is I want to change the game view from three aspect here to 16 by nine aspect so we can design our UI according to the screen ratio sizing. So here we want to create a new Canvas under the UI. Let's create a new Canvas game object. And with creating Canvas, it will automatically create event system, and this will be used to handle the event from mouse clicking so our UI component can responds to our mouse position or mouse status like clicking, hover and other stuff. Here, on the Canvas game object, we want to change the Canvas scaler from constant pixel size to a scale with screen size. And let's just make this a full HD resolution ten ADP. So this is the width and this is the hight, and let's just make the match to middle 0.5. So it will try to match the width and the height. If the resolutions on the target device or on the user device changes, and this will decide how do we want to match the UI layout to those new screen sizes. I'm going to save the scene here. And the next thing that we want to create is we want to create an empty game object here. And basically, this empty game object will hold all of the dialogue window component as a child here. So I'm going to change the view to the view here, and let's just center to our game object here. And this is our UI space. And I'm going to rename the game object to dialogue Manager. And I'm going to set the height to around 250. And I'm going to put its position to this one here, this stretch on the bottom area of our screen. So if you hold out, we can line or we can snap the settings and the anchor preset to this position here, and we will have a very wide panel below here. And now we can create another game object, and the next game object, it's going to be an image game object because this is going to be our panel, and we can hide and show this game object later to show any messages that we want to show. So I'm going to also stretch this, but I'm going to add a margin on the rec transform here. At least I'm going to add 25 pixel on the left side and 25 pixels on the right side. And for the bottom side, let's just add this like 40 pixels. So we should have something like this. Or if we want to make it even more larger in gap from the site, we can add like 150150, for example. Okay. Maybe this makes more sense for dialog UI. And the next thing that I want to do is, I want to make the color black, so I'm going to change the color here and set the transparency to around 50%. I should do the trick. And the next thing that we want to do is we want to rename this image to panel. And we need to add another child object which is the text object, and I'm going to use the text Mash pro here. Since this is a new project, we need to import the TMP essential, so Let's just click this button. Now it has finished importing. We can close this, and I'm going to also stretch the transform of this tax object. So it fits our panel. But let's add a margin. I'm going to set this 240 by 40, and then top also 40. I think it's two far, 40, let's make this 20 on the top. And for the bottom, we need to make this bigger than our top margin because we want to have a button for a DLO button for choosing an options. So I'm going to make this probably around 60. Yeah. Six this should be good. And we can save the scene here. And we want to create the button that that will be used for deciding if there are an options or if we want to add a yes or no options in our dialogue. So let's just create another empty game object here. And I'm going to make this stretch here below. But let's just set the height 260. And then snap it again, and we want to add a left margin. So let's just add like 500 or 600 and for the right, let's add this 20. So now we should have something looking like this here, and now we can add the child game object. So I'm going to rename this game object to button questions, for example, And then we want to add a child game object, which is a button, and we are going to use the text mesh pro button here. And for the button, we can change the source image. I think I'm going to remove this source image because sometimes it gets blurry, so I'm going to just to set this two none. And let's set this two color black color. This is going to be the yes button. So let's just rename that. And we can just set the text to it. And we want to duplicate this button, and let's set this to no button. And now that we have set this up, let's add a horizontal layout group, and this will distribute our button automatically. I want to stretch the child size of the button at least on the width, so it will fill up our empty game object or the parent game object here, the button questions. Let's add a spacing like 20 pixels. This should do, and let's set the alignment to middle center. We will have this center and we can increase the height of the button here. I'm going to set this 250 or 45, so we will have some sort of gap. And for the button, probably we can add a gap here on the parent game object. We can change the right margin to run 25 or perhaps 40, so it a lines with our text box here, and we should have something looking like this right now. So basically, we have set up the UI for our dialog manager. In the next video, we are going to create the logics or the FSMs for this. 8. 07 Dialog Manager FSM Setup: Okay. Now we have set up the dialogue manager UI. Let's create the functionality for our dialogue manager. Let's select the dialog manager here and let's create a new FSM. And for this FSM, I'm going to call this dialogue manager. And the first state, it's going to be an initialized state. So let's just initialize this. And we want to create a global variable. With global variable, we can easily access that variable from any FSM in our project. So the gist is that we want to create a global variable that will hold reference to this game object, the dialog manager, and any other object FSM can access the dialog manager via that global variable. So let's go to the playmaker menu here. Under the editor windows, we can just pick global variables. And here, let's add a game object. And let's just call this dial up manager. Okay. Now, we have created this global variable. We can just close the window. And for initializing, basically, we want to use the get owner action and store the owner to a global variable dialog manager. And this will save the dialog manager game object into this variable. So we have a easy reference for other object to know where this dialog manager is. Okay. And next thing that we want to do is we want to disable the panel on start, so it gets hidden. And basically, we want to create a variable game object here. And let's just call this panel. And to make it easier, we want to expose this as an input variable, and we can direct the panel game object to our inspector here. So we will have reference to our panel. And here on the start state, we want to use the activate game object action. And then we want to hide it. So we need to specify game object, pick the variable that we've just created, we just panel, and disable the recursive, and also disable activate. And this will hide the game object or it will uncheck the checkbox here us hiding the game object. So go back to the dialogue manager here, save the scene. And now we need to create an event first. And this need to be a global event because we want to access this event from other FSM. I'm going to create this show message and check this global broadcast or global event, and let's create a new state, and let's just call this in dialog window, and we want to add a global transition show message. Here, basically, we want to get the message length that we have, and then we want to deactivate the button questions panel game object here, so it doesn't show the button at first. And then we want to go to the next state after that. So first, we need to use the array length. And array length with basically we'll get the member amounts of any array that we have defined. And on the variable, we need to create a new string array. So I'm going to pick array, and let's just call this messages. And let's change the type to string. And the string messages, let's make it as an input variable. And here on the array length, we want to get the length of our message. And let's save this into a new variable, which is a type of integer, and this will automatically create the variable, and I'm going to call this messages length. Sorry. Messages length, like so, and y create this. And then the next thing that we want to do is we want to use the activate game object here. And basically, we want to deactivate the questions panel. So let's just create a new game object variable. And let's just call this questions panel. And for this questions panel, we want to set this also as an input variable, and we want to hide that game object. So let's uncheck this recursive and activate. And now we have this expose. We can drag the button questions to the slot here. And then we can just finish this state here, and we want to go to the next state. So I'm going to create a new state by holding control. And this is going to loop for looping the messages. So we want to create a loop messages state because we are using array, so we want to have the capability of showing multiple texts using this array of strings. Here in the loop messages, we want to use the ray get next action. And basically array get next actions will quickly look through all of the items of an array to perform actions on them. So we can add this here, and we can pick the messages, and we can decide the start index and n index. But if you want to look through all of the members of our array, then we can just leave this value to zero on the both start index and n index. But if you have a specific start index that you want to start from, or if there are specific n index that you want to at, then you will need to insert a certain value here. In this case, let's just lift this to 00. And for the Loop event, we want to create an event called Loop. We don't need this to be a global, so let's just uncheck those. For the Loop event, we want to pick the loop. And let's add the loop transition here. And whenever we are looping the messages array, we need to sore the result into a string variable. So let's just create a new variable, and let's just call this current message. We will have a string here, and we can use the string to show the message. We want to also save the current index because we are going to need it later when we are showing the buttons. So let's just save this into a new variable called current index. And we need to add a finished transition. And we want to finish the event by sending it to the finish transition here. So let's just pick finish. And now whenever we are loping the array, we want to go to a new state, and basically, we want to show the message. And here on the show message, we want to activate the panel. So let's just add activate game object action. And then we can pick the panel variable, and we want to activate this, but we don't need to enable the recursive options. So let's just check the activate options. We can minimize this. And then we can use the type writer. We don't have that. So we need to download it from ecosystem. So let's just open the ecosystem browser here, and we can type type writer. Now we have the actions that we need. We can just press the get button and it will download these actions into our project. Okay. Now it finish compiling, so let's just close this ecosystem browser. And now let's just search for the string type writer action. We can add this. And this will create a very nice typewriting effect on our dialog text. And basically, we need to get the covered message string as the base string, and we want to save this to a result string. And for the result string, we need to create a new variable. Let's just call this type message. And we can just leave the default setting here. And whenever we finish the typewriter, we want to go to the next state. So let's just add a new transition. I'm going to create the transition first. Here. Let's just call this next, and we can add the transition next. And here on the type writer action. Let's just pick the next transition in the finished event. And next, we need to show this type message string, which is going to be a animated string or string that change over time to this text mesh pro game object on our dialog panel. And in order to do that, we need to download a custom action for modifying or accessing the text Mash pro functionality in unity. And I'm going to put the link to the Gita page for this custom action. And here, basically, you can just download the repo to a ZIP. Once you've downloaded, you should have a ZIP file similar like this, and we can drag this folder. So I'm going to drag the Text Mh pro playmaker folder here into our project folder. So let's just open the project folder here by right clicking it and show Explorer, should open the project folder. Go to the access folder and inside the playmaker custom actions, I'm going to drag our folder here. And once it's finished extracting, let's just rename this to Text MSP. Okay. So let's just close this folder and let's head back to Unity, and it will compile the new actions that we've just imported. Okay. Now it's done. And let's go back to the playmaker editor. Let's select the dialogue Manager. And here, after we are updating the text or the string here, we can just minimize this now. And add a new action, and now we should have new group, which is going to be the tex Mash pro here. And as you can see, we have a lot of subcategory here, and the one that we want to use is the tex Mash pro GI basic, and we want to set the set tex mash pro I tax here. So let's just use this. And then we can specify game object. And for the game object, we need to create a variable. So let's just create a new variable game object here, and let's just call this dialogue tax, and let's enable the input variable, so we can access it here, and let's just direct the TMP game object here. And now we want to use that game object. And for the text, we are going to use the type message, and let's enable every frame. So the text will get updated every frame when we are in the state. And basically, here we want to add a on click event. So let's just use the UI on click on point or click event. And we can just set the game object to the panel. So let's just specify game object and then pick the panel game object. And for the event target, we want to set this two self, so it will trigger any transition that we have added here, and let's create another event called complete message. And we want to add that transition. And here on the point or click event, we want to go to that complete message, then we want to create a new state out of this transition. And in this complete message, we want to add a couple of actions. So let's just rename the state first, and let's just call this complete text. And here, we want to use the text Ms pro again. So let's just for I think it's the UI basic. Yeah. And we want to set the text Ms pro I text again. We need to pick the game object. From the variable, which is dial up text. And for the text, we want to set this to the current message. So we want to complete this upon clicking. So whenever user click the panel, it should skip the typing and then show the complete text here. Then we want to add a next transition, and add on click event again. We can pick the panel, then we want to go to the next. And here we want to go back to the loop message here. But if the text finish showing, we should fire the next event, so we need to create a new state here. And we can call this wait for click. And let's just add a finished transition. And we want to use the on point or click event again, set the same game object, which is panel, and let's just call the finish. And now we have this. But when we are finishing the showing the all of the message, then we want to hide the panel. So let's just create a new state here. And let's just call this end of message. And here, basically, we want to hide the panel. So let's just add and activate game object action, we can pick the panel. And disable it or the activate it by unchecking the activate, and we want to also uncheck the recursive. Okay. So this is the basic dialog manager, and now we are done with this. Next, we are going to implement the action to use this. And of course, once we are adding functionality for the questions, we are going to modify our dialogue manager. 9. 08 Send Dialog Action: Now let's modify the dialog actions or the one that we have created for this NPC here. And basically, we want to modify the run effem. Let me check here. We have this interactable base dialog. Okay. We want to modify this base dialog FSM, so it will run multiple messages. Right now here on the show dialogue, we are only debugging the first message, but we want to send this array text to our dialogue manager and show it using the dialogue manager. Let's just delete this ray get and debug log here and to show a dialogue. We want to create a FSM template to be used as an action. So let's just add another FSM here. And let's just call this action sen dialogue. And basically, on the first state here, we want to rename this two SN dialogue, and let's add a finished transition, and then we want to end the FSM here. For ending the FSM, we can just add finished FSM. Because this is going to be an action that we are going to use using the run FSM action, so we need to run this FSM to notify that action that this template has finished running. Let's go back to the Send dialogue, state here. And basically, we want to send the array string array of messages. So let's just create array. And let's just call this messages. And this should be a type of string, and we want to make this as an input variable. We also need to add a couple of string variable. So let's just add the first one. And this will be the question no. Although we haven't implemented this yet, but let's just add this now. And this will be the question yes. And this will be the copy for the button text for the yes button and the no button. And we also want to send the questions bulion. And this should be a type of bully, let's just change this. Okay. For now, this should do. Let's set up the state here. The first one that we want to send is the messages. Let's just use the set FSM array. And we want to send this to a specific game object, which is the dialog manager that we have defined on our global variable. And since it only has one FSM, we don't need to specify the SSM name for this dialog manager, but we need to specify the variable name, so I'm going to type messages. And let's double check this again. If we go to dialog manager, we should have the messages. Yeah, this message array of string, so we have this. Let's go back to this base dialogue here. And now we want to set the messages variable on the dialogue manager to use the values from our messages here that we have defined. And we want to check these copy values here. Let's minimize this. And we need to set a couple of FSM string and FSM b. So let's just specify this to the dialogue manager. We haven't set up the variable name, so let's just set the value for now here. This won't do anything because it won't find the variable name. But once we've implement this, this should work. So I'm going to copy this here, and let's set this to the string. Let's minimize this. And let's just set the ble also. And we need to specify the dialogue manager here and set the value to the questions here. And we also haven't defined this, so we cannot put any variable name. Onto it. And the next thing that we want to do is we want to send an event. So let's just use the send event here. For the event target, we need to set to the game object FSM and specify game object, which is going to be the dialogue manager again. And we can just leave the FSM name empty and we want to send the global event show message. Here. Okay. So now whenever it finished the state, it will go to the N FSM, and it will finish the template. We have this error. Icon. It doesn't look very good. So let's just quickly implement those variable. So here, let's add a string, and let's just call this questions Q yes, Q underscore yes, and this is going to be the input and create another string. This should be the Q no. And let's create a bullion, and let's just call this questions and set this to also as an input variable. And now we have defined this variable on the dialogue manager. We can go back to the base dialogue here, and now we can set those name as the variable name. This should be the same Q, yes, because we have defined the same name. This is or underscore, and this will be the questions. Okay. You can name the variable anything that you want or you can follow my convention. It's really up to you. And now we have set up this FM template. Let's save this as a template. I'm going to call this action San dialog. And let's save this. We don't want to use this in this FSM because we are going to delete this, so let's just remove the component here. And now in this show dialogue, we can use the run FSM action here, and then we can pick the action underscore sen dialog tplate here. And for the message, we can just send the messages that we have here. Okay. We need to also expose this variable, the no, the yes, and the question variable. But for now, we can just lift this. Once we are going to implement the interaction, then we are going to change this. So if we go back here, you see that we should be able to run the dialogue or to send the dialogue. And here on the event, we want to send the state back to the first state whenever we finish this event here. And this is why we need the finish FSM on our template because this will trigger this event here. So let's save the scene, and now let's delete the second dialogue. And under the NPC interactable, we want to set the action back to one, so it will only trigger this base dialogue FSM. And now we can have multiple message. Let's just change this to something else. Let's just type the weather is very nice today. Okay, so we should have two dialogue here, the first dialogue, and this is the second dialogue. Let's save the scene, and now let's give it a try. I'm going to select the dialogue manager so we can see what happens inside the FSM. And as you can see here, it shows the message. And if I click, it continues the second message, and we can close this by clicking it again. It will close the window. But as you can see, whenever we are interacting, then we are pressing this I. We also move the player. So we want to prevent that. And we need to also hide the button. So here, let's add a couple of modification. We should activate the game object here. Okay, I put the wrong variable here. This should be the questions panel. So let's just save this gain. And now with this clicking and it moved the character instead of keeping the character on that position, we need to create some sort of a bulion that are indicating that we are opening the dialog window. And with this bion whenever this bulion is true, we want to ignore any clicks on our player FSM. So basically, we want to set this bulion to true whenever we are activating the panel here. In order to do that, let's create a global variable. And let's just call this UI open. And this is going to be a type of bull. Let's just call this UI opened. L et's close this. And now we want to set a bullion value using the bull value set bull value here. Drag this to the top of our stack action, and then pick the UI open variable and set this to true. We can copy this actions by pressing controls while highlighting the action. And let's go to the end of message state here, and we want to paste this actions, and we want to uncheck this. Okay. So basically, whenever we are deactivating the panel, then we want to disable or set the UI open bulion value to falls. Okay, save this. And now we want to go to the player game object, and we want to modify this FSM here. So basically, we want to test a bulion value. If the bion value is true, then we want to go back to finish. So here, let's just duplicate the bull test. We should have two valid intractable. Okay. Let's keep the second one, and let's change the first one to use the globals UI open, and we want to set the second one to none. But we want to set the first one to finish. So if UI or the dialogue UI is opened, then we want to cancel this defined destination, and it will go back to the finish transition to the first state here. And if it's false, it means that the UI is closed, then we want to ignore this bull test, and it will check for the other two bull task, depending on the condition. Let's save the scene, and now let's give it a try again. Okay. It's showing the dialogue and we don't have the button anymore. If I click this, it show the second one. And if I click this again, it will close the window and we can move around. Let's just try it again while we are on the dialogue, we cannot go anywhere. But we need to add functionality where if we click outside of the UI here, then we should be able to cancel dialogue and move the player to that position. Okay, so now let's implement that. First, we need to create an empty button or a transparent button or run or a canvas here. Here on the Canvas, I'm going to create a new button from the UI, and let's just call this empty area. And I'm going to put this on top on the stack here, so it gets rendered first before the other UI dialog manager. And here on the button, we want to expand this transform to cover the screen area, and we want to also delete the text object. And for the image here, we want to set the source image to none, and let's set the color transparency or alpha value to zero. It is transparent. And here on the dialogue manager, let's create a new variable, and this is going to be a type of game object. And let's just call this empty area. And I'm going to enable the input variable here so we can access it easily on the inspector. And let's drag the empty area game object into this slot here. Next, we want to add a new event called cancel dialogue. And here, we want to add this cancel dialogue on the complete text state here. On the show message state, and also on the wait for click. So whenever we are given any chance to have input like mouse click on the dialogue UI, we want to have also the options to cancel dialogue. And here, basically, we need to copy these actions. I can press Control C and Control V. It will copy it and we want to pick the empty area, and if we click the empty area, then we want to send the cancel dialogue event. Let's just copy this action by pressing Control C again on the second one here, and we can paste it on the state here on the wait for click, and also on the show messages, so we can highlight this. And then press Control V, it will paste this below the highlighted action. So basically, we need to have two poin or click event, first panel, and the second one empty area. And for the cancel dialogue, we want to go to the end of messages. And this should cancel the dialog if we press or if we click the mouse outside of the dialog window because we are going to click those empty area button. There is one thing that we need to do here is basically, we need to add a bullion variable, and this is going to be the reset variable for resetting our array get nex because when we are canceling dialogue, there is a chance that these actions doesn't finish looping all of the member iterations. So whenever we are entering the array get next, it will keep the current index behind the actions or behind the scene, and it will continue that index when we are showing the next dialogue or a different dialogue. So we need to reset the we need to use these reset flag options. And basically, this asked for a bulion value. And whenever we are passing a bulion, if the bulion value is true, then whenever we are executing this array get next, the iterator or the index will reset from zero. And after we are resetting this array get next, this bleion will change to falls automatically. So in order to reset this, whenever we are initializing the dialog window, we want to set that bulion reset value to true. So the flow will be that whenever we are starting the dialog window, we are initializing here and we are setting the reset bulion to True. When we are entering the second state, the array get next will gets reset, and then the reset bulion will turns to falle. We can see it on the run time. I will show it in a bit. But another thing that I want to add is I want to add weight actions on the init dialog window. And I want to send the finish after a fraction of a second, so we don't have infinite look when we are already arrive on the NPC position, and we are trying to conversate again. And I'm going to set the value to 0.2, and now let's give this a try. And now let's go to this NPC, and now we can cancel this dialogue by clicking outside the window. And if we click this again, it will show the dialogue again. And let me just show you here. If I disable this weight action, And let's just click this again. There you go. If we arrive on the position here, and if I click on the NPC, there is a chance all of this transition happened in one frame. So it evaluates the clicks in one frame, and we are canceling the dialog because the NPC position is outside of the UI dialog window. So this is why I added the weight action. And this way we can try to conversate. Okay, there is a bug here. For some reason, I connect this finish to a wrong state, so this needs to be to the loop message. Okay, I'm going to stop this and let's just modify this on edit mode here and save the scene again. And now let's give it a try. So we can conversate here. Okay, nice, and let's try to conversate again. We can talk again, and we can cancel. We can talk, we can cancel, and we can talk again, and we'll reset the dialogue. Okay. So yeah, that is basically how we create the sen dialogue actions to interact with the dialogue manager. 10. 09 Dialog Options: In this video, we are going to continue our dialog manager, and we are going to add the dialog options functionality with this yes and no button. So in order to do that, let's go to the dialog manager, game object here, and now we are going to expand this FSM. Okay, so first, we need to create a couple of events. The first one would be the yes action. No action. Okay. So the next thing that we want to do is we want to show the questions whenever we are completing the text here. And basically, the thing that we need to add is the conditional expression. And this is basically a way to easily do a conditional expressions for a variables without having a multiple actions or a stack of actions to evaluate that condition. So here, basically, we want to check if the current index is already at the end or the last index of the string array inside the messages are a string here, and if the Boolean variable questions is true, then we want to show the questions. So here to evaluate a variable. If the variable name has a space like this, then we need to put it inside $1 sign inside this parentheses and put the variable name here, for example. And here, as you can see, the variable was not found, but if I type dialog text, then it found the variable here. But since most of the variable that we are going to compare, which is the current index, the message length doesn't have space in it, and also the questions, then we can type the name right away. So I'm going to check if the current index is equal to the message length. I think it's messages length. Yeah. But subtract with one because the array index always starts from zero, so the last index is going to be always the length substract or minus by one. And we want to check also if the questions is true. And since the questions is a bulion variable, we don't need to type equal true. This will evaluate you true, and if we want to e if the bleion is false, we can just add an exclamation mark in front of it. Okay, so this is the conditional expression that we want to add. And if it's true, then we want to send a new event here. So we need to also create show question. And here, I'm going to add that show questions transition, and we want to send it if this value is true. So we can send the show questions. And here we don't need to check every frame because this will be evaluated whenever we enter the state. So we should have all of this value already initialized whenever we're entering this complete text state. And whenever we show questions, we want to create a new state and go to that state here, and we can call this wait for answers. And basically, whenever we are waiting for answers, we want to set the button text for the yes button and the no button accordingly. So we can use the set text mesh P GI text and pick the button game object, and we haven't defined that yet, so let's just create a new variable. And this will be a type of game object. And this will be the questions yes button. And I'm going to set the input to be enabled. And another one is going to be the no button. And let's enable the input also. So now we can assign the yes and no button here. And you expand the button questions here, and yes buttons should be on the yes button, and no button should be on the no button here. And I think we can just hide this Q and Q yes because we don't need this to be exposed in the inspector. So let's just uncheck the input options for the Q and Q and make this inspector more simpler and easy to read. So let's just save this. And here, we want to modify the yes button. And let's duplicate this action and change this to the no button here. Okay, there was a mistake here, so let's just fix this quick. This is the yes and no button, but we need to create another game object for the Q yes or yes button tax. And enable the input. And another one should be a type also game object. But this is for the no button text and enable the input. And we need to expand the yes and no button and direct the text accordingly. So this should go to the yes button tax, and this one should go to the no button tax. And this is the game object that we need to use actually. So let's just change this s, yes button tax, and this is the no button text. And for the text, we want to set this to the Q, This one to the QS. We already set up the text appearance or the button text copy, and now we want to also activate the questions panel, so we can use the activate game object. Let's just direct this down here, specify game object, and we want to pick the questions panel, and we want to activate it. Here on initializing, we are always deactivating the questions panel. So if the dialogue doesn't have any questions at all, then the questions will not get activated. But if we go to the state and we are to show the questions panel, then this will get activated. And then we need to wait for a click. So we need to add the click sorry, not on pointer, but on UI button on click event. And let's just delete the pointer. Click. And here, we can just specify game object, and then we can just change the variable to the yes button, and this should trigger the yes action. And we are going to add the transition. Yes, as well. No action, and we want to add the cancel dialogue also. And cancel dialogue should go to the end of message here. And we can just duplicate this click event here, and change this to the button and send the no action. And lastly that we want to add is this on pointer click event to the empty area. So let's just copy this action here and paste it here, and this should trigger the cancel dialogue. And now we have this yes and no transition, we need to add a new state for each of the transition. This is going to be the yes response. Let's just type yes response. And this is going to be the no response. Another thing that we need to add is we need to add a object variable. And let's just call this sender FSM. And we are going to send the FSM the dialogue FSM or the NPC FSM to this dialogue manager. Whenever we are interacting with an MPC that has a dialog FSMs attached to it, we want to send that FSM also. And the object type, we need to change this to pla maker FSM. Right now it's going to be empty, but we are going to set up the state anyway. Basically on each of the state here, we just want to use the call method action, and basically, we want to send an event to the sender FSM. Let's just use the send event and just type the event name, and this is going to be yes action. This is going to be the yes action, and I'm going to duplicate this or copy this call method and paste this on then response, and this is going to be then action. And let's just add a finished transition and go to the end of message here. And also for the neuro response, we want to add the finished transition and connect this to the end of message. Okay. So now we have set up the options or the button interactions with the dialog manager. We can save the scene. Next, we need to modify the base dialog FSM here that we have on our NPC. So I'm going to move this down here. And here we are going to add a event called s action. But let's make this global. And the no action. Also enable the global tech here. And then we want to create a new state, and we can just call the state run yes actions. Here on the variable, we need to define another variable. This time is going to be a type of ray, and let's just call this yes actions. For the type, I'm going to change this two object and set the object type to playmaker FSM. And I'm going to create another variable called no actions. And this will be also the same changes to object and set this to playmaker FSM. And now we have this. Let's just expose both of the variable to this inspector. And we want to add another state. Or we can just set up the yes state and then change this by duplicating it. So let's just add a global transition and set the yes action as the transition and add a finish local transition and connect this to the first state. And when running the yes action, we can use the run FSM action, and we already define the template for running an action. So let's just pick here on the category and use the run FSM. And for the actions, we want to send the yes action. And whenever finish the event, we want to send the finished transition. Okay. So now we have this setup. We can just duplicate this by pressing control C and then control V and change the global transition to the no action, and we can just rename this to run no actions. And for the actions that we want to send is the no actions. And let's connect this to the first date. Okay, so now we have this setup. We need to add a couple of variable. Basically, we need to add a bleion variable. So let's just call this Q as question. And this would be a type of bleion. And let's enable the input so we can easily modify it here. And the next one that we want to add is a type of string. This will be the Q yes tax. Sorry, yes tax. Also check the input. And the last one would be the Q no tax or string. And let's just add this, enable the input here. So now we can customize the response button text via this dialog FSM here. And basically, whenever we are sending the dialog here, we want to send this additional information. So the first thing that we need to do is we need to edit the SN dialog template here. Let's go here. And as you can see, we already defined this Qs Q and the bleion, but we haven't exposed that yet. So now we can just easily expose it on the variable by checking the input. So we can input this variable from the run FSM template. Okay, save the scene here, let's go back to the base dialogue. FSM here. Now on the run FSM, we should see additional fields or variable that we can customize here. For the no, I'm going to set this to the QO. For the S questions, I'm going to set this to the QS questions. And for the yes, I'm going to set this to the Qs. Okay. Now let's save this. Later, we are going to convert this FSM into a template, so we can easily use this actions on another game object. But right now we can just keep this as a local FSM. And now let's just delete the second text here. I'm going to set this back 21, and we can set an answer. I'm feeling great, for example. Yes, or if no, then I'm a bit sick, for example. And we can enable the S questions. And also, we can trigger actions if we are responding different options by adding an FSM to this no and yes actions. So now we have set this up. I'm going to add one actions to then and also one actions to the yes actions here. And let's just duplicate this base dialogue. And let's just call this one yes response. And we can just disable the questions and delete all of this field here and set the actions to zero, and we want to show different message because this is the yes response. Let's just say that that's great. And we can duplicate this and we can call this or rename this to no response, and let's just type get well soon. So we can see different responses. And now on the base dialog, we can just drag this game object to the FSM slot, and it will read the FSM that are attached to this yes response, and for the no response, we can do the same. Put it on the no actions. Let's save the scene here. Another thing that we forgot is we need to send the sender FSM or this FSM because we already create this sender FSM variable here. And it tries to run this event, but the sender FSM is none or no. So yeah, let's go to the base dialogue here. And on the variable, we need to add a object variable with a type of FSM. So let's just call the sender FSM. And then we can change this to playmaker FSM and enable the input and to connect this, we can just direct the header of the playmaker FSM to the slot here, and it will register that one. Now we have set this up. We need to also send the sender via the send dialog here. So if we added this, we should add a new variable type of object, and let's just call the sender FSM. And for the type, let's change the supply maker FSM and enable the input so we can see it on the run FSM action. And on the state here, we want to set FSM object, not game object, but object here. And put this on top here. And we want to send to the dialogue manager, same as this other set FSM ray and string and Boulan. So let's just specify game object and pick the dialog manager from the global variable. And we know that the variable name is the same, which is Sender FSM, so we can just type it and send the sender FSM. Let's double check on the dialog manager. The name is yeah, Sender FSM with capital FSM. Okay. So yeah, let's go back to the base dialogue here. We already have the sender FSM, so we can just because we modify the send dialog, and we are exposing the sender FSM. So now if we go to the run FSM action that are running the action San dialog template, then we can see the sender FSM. So let's just enable the use variable button and pick the sender FSM. Let's save the scene, and now let's give this another try. Okay, so I'm going to skip Davi. And if we press the button, it should trigger the message. That's great. And if you talk to this person again, you see that ops, I think it doesn't reset. Okay. We need to check for this bug, but yeah, let's just check the no response, and it will respond to the second one. I'm going to check the dialogue manager here. Okay. It still waits for click. And if we finish this, Okay. It ends the messages. Okay, yeah, I found the issue here. Basically, whenever we are waiting for a click here, when it finished, the finish will always go to the end of message, and it will never evaluate our questions Bulen like we have here on the complete text. So in order to fix this, we need to create a new state from finish loop message because there is a chance that we are finishing our strings of messages on the loop state not on the complete text. If the text finish typewriting itself and goes to the wait for click, and it will go to the Look message. And it will skip the state. Basically, the state will only get executed whenever we are skipping the typewriting effect, and it will go to the complete text here. So in order to fix this, yeah, let's just change the finish transition and hold click. I'm going to create a new state. And let's just check questions. And I'm going to use the bul test here, and we want to check the questions bulion, if it's true or false, then we want to send different event. So here I'm going to use the show questions and a finish transition. Show questions should go to the wait for answer state here, and finish should go to the state here. And now here we want to send the Show questions event if it's true, and we want to send the finished event if it's false. And we don't need to check every frame because this will be evaluated as soon we enter the state, and we should have already the value initialized. So let's save this. And now let's give another try. Okay, I'm going to try to click this. Okay. That's great. And now, there you go. We can show the questions again, and we can response differently this time. And Yeah. It works. It works great, actually, and I can try to conversate repeatedly without any issues here. And the cancel dialogue still works. As you can see here, if we're showing the state, we can also cancel dialogue, and we can talk to the NPC again. So, yeah, that is basically how we can create the dialogue options and execute different actions. And with this base dialogue, it's quite powerful actually because we can use different FSM here to trigger some other stuff that we want to whenever we responds to a certain questions. Yes. Okay. 11. 10 Activate Deactivate Multiple FSM: Hi, in the last video, we have created the dialog options, and now we can trigger another FSM action using these options. And now we are going to create an activate FSM or the activating FSM actions, so we can keep the response that has been triggered. So for example, if we trigger the yes response, then we want to keep those dialogue intact. This is useful for an epic whenever it receives an item, or if an eps at certain stage or certain phase of the game needs to have different dialogue, then we can use this action. In order to create this action, let's create an empty game object, and let's call this yes activate. I'm going to put this below the yes response, and let's create a new FSM. Basically, inside this FSM, we want to create a new state, and in this new state, we want to run the activate the activate. FSM. And we need to add a global transition. And let's just choose custom event. Custom event is basically the event that we have created, and we take or we marked it as a global transition, and let's pick run action because we want to run this FSM using the Run FSM action. And now we can create a local event called Run FSM. And here on the variables. Let's add a bleion variable. And let's just call this Run FSM. And let's enable the input tech, so it's feasible on the inspector. And then we want to create another two different array. First one is the FSMs to activate. And we want to change the type to object and object type to playmaker FSM. And I'm going to also enable the input. And the second one would be the same array, but this is going to be the FSMs to deactivate. I'm going to change the type to playmaker FSM and enable the input. Now we should have those variable exposed in the inspector. Here, we want to add a local transition, which is the run FSM, and we want to create a new state here. And basically, in the run FSM state here or the state that are coming from this run FSM transition, we want to add the run FSM action. And use the template that we have just created, which is this one here, run FSMs. And for the action, we want to pass the FSMs to activate. So basically, we want to trigger the one that we are activating it. And this is actually optional because if we uncheck this, then we won't trigger this. So in order to create those option, let's add a bull test here. And let's check if the run FSMs bullion is true or not. And if it's true, then we want to run the FSM, but if it's fall, then we want to stay on the state here. And now the next thing that we need to do is we need to create another FSM to create the template to run de activate and deactivate FSM. So let's just save it in first, and here I'm going to add a new FSM. And for this FSM, let's just rename this to action, activate multiple SM. Here inside this second FSM, we are going to convert this into a template later. The first thing that we want to add is the variables. I'm going to add an object variable and I'm going to call this current FSM, and I'm going to change its type to play maker FSM. Then the other variable is going to be an array, and this is going to be the FSM activate, and we want to change the type and similar to the first FSM that we've created, and let's enable the input here. Another one it's for the activating. Let's just change the type. And enable the input. So now we have two inputs variable that we can send when using the run FSM later. And here, the first state is going to be the sorry, the activate FSM. And here we want to use the array get next action. So I'm going to type ray get next. And we need to create a local event called loop to loop the array get next action. And for the array, we want to set or get the FSM to the activate. And let's just set the loop event to loop transition, and we want to add that transition. And let's create a new state here, and let's just call this disabled FSM. And here, whenever we are looping, we want to save the result into the current FSM variable that we have created. So now on the disabled FSM, let's add a finished transition, and then connect the finished transition back to the activate FSM. Here, we want to use the set property. I think we have set property here. Yeah. And now for the target object, we want to pick the current FSM and we can pick the enable property here, and we want to uncheck this. And basically, this will uncheck this checkbox, the property enable if the actions gets executed. So if we set this value, and it will enable the component, but if we disable this, then it will disable the component. Let's just re enable this. Now we need to add a finished transition and then go to a new state here. And basically, to make it things easier, we can just copy these actions and put it here, and here we want to activate FSM. So let's just change this to FSM to activate, and then we want to add the loop transition. And here we need to set the finished event to finish. So once it's finished loop the array, we go to the next state here, and we want to add also the finished state here. And let's create a new state. And this one is going to be the opposite of the first one, which is the activate or enable to make it more synchronized with its naming with the first one here. And let's add a finish transition here. And we want to connect the finish transition to the activate FSM. And here, we can duplicate the set property here. Paste it here, and this time we want to check this because we want to enable the FSM. So now basically, this we look through the FSMs to activate and put each of the member into this current FSM variable. And while we are looping, we are going to enable each of the current FSMs. And now we need to add a finished transition because the finished event as for it. So let's just create a new state here, and let's just call this finish. And I'm going to add the finished FSM action. Okay. Now, so we have created this template. Let's just save this as a template. And I'm going to call this actions activate multiple sorry, multiple FSMs. I don't think we need to use the save template, so let's just press no, and let's just delete this FSM. And now on this s activate, I'm going to call this s activate. L et's add a run FSM action, and we want to put this on top of the bul test, and let's pick the action activate multiple FSM. For both of these array, we want to use variable, so we can just use the activate and deactivate array, and this will send any FSMs that we have set up here. And whenever it's finished, we want to keep this MT, but we want to send the run FSMs if the run FSM value or the Bulen variable value is true. So let's just save this. And now we can actually duplicate this, and let's just call this no activate. And basically, we want to change of the FS active status using this activate action. So for the yes activate, let's say we want to Activate the yes response, and then we want to disable then response and the base dialog. So this should disable the other two, and we want to run the FSM because whenever this gets triggered, we want to trigger the yes response. And for the activate, we want to do the same, one on the FSM to activate and two on the activate. And for the activate, we want to put the S response and the base dialogue. And for the activate, we want to add the nu response, and also run the FSM. Let's save this on the base dialogue for the yes actions and the no actions, we want to change this to the yes activate instead. So for the yes actions, we want to run the yes activate, and for the no response, we want to run the sorry, not no response, but the no activate. And basically, since we already had this run FSM, whenever this gets triggered, the no activate will also trigger then response. So it will also show the same order of dialogue as we have before, but it will change the active status of our FSM. And on start, we want to disable the yes response, and we want to also disable then response. Let's save this, and now let's give it a try. So here, I'm going to talk to this person here. And if we pick one of the options, it should trigger the response. That's great. And if we try to talk talk to this person again, Okay. Let's check. There seems to be an issue here. So on our Okay, y. Sorry, my mistake. I forgot to add the other actions here. So basically, to make this work, we need to increase the size of our interactable actions, and we want to add the remaining response also here. And basically, by default, or when we are starting the scene, the yes and no response won't be triggered because by default, it was disabled the FSM, as you can see here. But when the yes activate or the no activate kicks in, then the active status will change, and the other two will be disabled, and the one that are intended is going to be activated. Let's just rename this, so it's not confusing. It should be no activates the same with the game object name here. Save the scene again. And now let's give it a try. Okay. So let's just talk to this person. And we can cancel this. And if this is canceled, then the order or the active status of the FSMs are not going to be changed. So if we talk to the NPC again, it will show the same message. But if I responds, then it will show this message. And if I talk to him again, as you can see, we have the yes response because the FSMs gets disabled the other FSM. For example, this base dialogue and no, and if we restart the game and let's try to pick the no option, we should have a similar response. So if I talk, it will have the similar response. Later, we are going to create also a save system, and we want to also save this state. We for example, if we gave an item to an NPC, then we want to have different response kind of bake or set permanently to that NPC. So the next time we talk to that NPC, it will show the dialogue that should be shown whenever that NPC has received an item, for example. And we want to save those state. Yeah, this is basically how we create activate multiple FSMs. Another thing that I want to do is probably I want to make this as a template. For example, we can just save this as a template. Let's just rename this. And now we want to save this template, and this should be a template, not an action because we want to add this template to an FSM instead of running it. So I'm going to call this template, and let's just call this activate multiple FSMs. And if you want, you can use the safe template here. And now once we use the template here, as you can see, we can see it, but we have these options here. So we can change the options for the FSM to activate and activate on the inspector here. And for the no activate, we can just try to reset this FSM, so it's resets everything, and let's just use the template activate multiple FSM. Here, by default, it already picks this FSM, so let's just fix that. Here on the variable. I think, yeah, let's just clear this, set this 29 and set the size 20, and set this size also 20. And for the run FSM let's just uncheck this, we want to save this value by default. Now let's try to reset this and add template. There you go. Now once we have reset the FSM. We don't have those options anymore. Now we can add this on the inspector. And now let's just set up reset up this again, and we want to sorry, we want to disable the yes response, and we want to enable the no response instead. And let's save the scene, and I'm going to check our yes response or yes activate here. Okay, we still have it because when we change the template, we reset the template, it doesn't change this. So yeah, it works fine. And this makes it easier when we later want to create another activate, for example, and we can just add an FSM, and we can just pick the template. And then we can just set up the FSMs to activate and deactivate here without worrying how to set up the FSMs all over again. So let's just delete this and I'm going to save the scene. And now let's give it one more try because we have changed this to a template. Okay. As you can see, it still works just like before, so everything is good, I think. Yeah. In the next video, we are going to continue develop this game. 12. 11 Item Definition and Inventory: In this lesson, we are going to implement the inventory and item system. So first, in order to do that, we need to create a custom scriptable object, and this is to make easier to create item definition, and we can hold a couple of letter that we can use later in playmaker. And to create this scriptable object, we need to create a very simple script. So let's create a new folder, and let's just call this script. And inside this folder, let's create a new sheet sharp script. And I'm going to call this item class. Let's open the script. And this is going to be a very easy script. So don't worry. Don't be afraid. I'm going to guide you every step of the way. First, let's just delete all of this built in method from unity, and we want to change the base class type from mono behavior to scriptable objects. If you type script, it show this intelligence, and we can use this by pressing enter and it will autocomplete. I need to delete this backslash. And then the next thing that we want to do is we want to create a couple of variable, and it's going to be a type of public. When we set this to public, this makes it easier to dit on the inspector, and we can also retrieve the value from playmaker later using get property or set property. So the first variable type is going to be a string, and let's just call this good, and this is going to be the unique identifier for each item, so we can compare if a certain item is similar to the other item that we can use this value. It's just for creating a unique identifier. And then we want to create the second variable, also a type of string, and let's just call this name. But since scriptable object already has a name property, this hides inherited members. So we need to add a new keyword before the string keyword here, type public new string name and then semicolon at the end. And then we can add a new string, and this is going to be the description, and we can also create a sprite object here, and this is going to be the image. And then upon instantiating the script object or creating the item definition. We want to generate the guid if this grid is empty. So in order to do that, we can use the validate method, and this will get trigger every time we change a certain value on the inspector, this will be called. So in order to make sure that we only fill the grid one time, we need to check if the guid using the string data type, and then we can check isnull or empty, and then we can test the g or the grid variable. And here, if it's empty, then we want to fill it. We want to generate it automatically using the system namespace, and it has the GID class or struck, and we can use the new GID method and this will automatically generate a ID. But then we need to convert this two string. And then we can end it with semicolon and press save. And the other thing that we want to do is, we want to put this item class inside a name space. So it's nice and organized. So let's just put this on the point and click, for example. Game. And let's just cut all of this code here and paste it inside this name space. And this will make it easier to search it on the custom variable definitions on playmaker when we are generating a reference to this data type. So the next thing that we want to do is we want to add a create asset menu attribute. And basically, this will create a new asset menu that we can use whenever we want to create a new item class object or scriptable object. So first, we need to pass the file name that we want to use with equal sign or a sign operator here. We want to set the name of the file name, so I'm going to call this item definition or item de. And the second one will be the menu name, and for the menu name, I'm going to pick item definition. Like so. Okay. Now we can save this script, and we can just close the fisL studio because we are not going to use it anymore. Now when we are back in UT, after it finished compiles, we should be able to create item definition. In order to do that, I'm going to create a new folder in the assets, and I'm going to call this data inside this data, I'm going to create a subfolder and let's just call the items. And inside this items folder, we can create a new item definition now. As you can see, we have this menu because we have set up the menu inside the greet menu attributes in our scriptable object. So let's just press this menu, and it will automatically create a new object. And we can change this two lighter, for example. And now, whenever we try to enter the name, for example, let's add a name. It will automatically generate the grid as you can see here. So I'm going to type this name lighter, and I'm going to add a description, for example, a how fiel lighter. And for the image, we can pick the lighter image that we have prepared when we are setting this project. So I'm going to use that. And then I'm going to create a new item definitions, and let's just set this two key. Rename that two key, and for the name of the object is going to be key. And it also generates this grid unique grid, as you can see, it's different from the lighter one. And we can set the description a key to the bathroom, for example. And for the image, we can pix these items underscore three. And now we should have this item. And the next thing that we want to create is we want to create a variable type definition. So here in the data folder, let's just right click, go to the create menu, and under the playmaker menu here, we should be able to see this new custom variable type definition. So here, once this is created, we can create a variable type definition. So I'm going to create a new variable type, and we can just call this item. And for the type, we can type the namespace. Which is, let's just take a look one more time. To make sure it's point and click game, and we need the class name. So let's just copy this keyword, the namespace, and remember the class name and back in unity on the data folder. We can paste the name space and then the class name, which is item class. And this will create a variable types that we can pick on the playmaker editor or variable panel. For example, if we select like this NPC here and go to the variable, you see that we will have this item, and then we can create a variable and this variable can select the item definitions that we have created. Another thing that we want to do in this lesson, we want to prepare the inventory array. So in order to do that, let's just create a new global variables, so open the global variable window here, and let's create a new array, and let's just call this inventory. For the type, we can pick the item. And let's just press yes, and this we'll create an array with a type of item class. Now we can set the size here and we can add a item to our inventory, and in the next video, we are going to create actions to give item and to receive items from NPC when interacting. 13. 12 Give Item Template: In this video, we are going to continue working on the item and inventory. And this time, we are going to create an NPC where this NPC, it's going to give an item to the player. So in order to do that, let's just duplicate this NPC dialogue here that we have. I've renamed this NPC to NPC dialogue, so we know what this NPC does actually, and to duplicate this, let's just press control D or command D on MAC. And now we have a duplicate NPC here. I'm going to reorganize the hierarchy, Let's rename this NPC to give item, for example. And let's reposition this NPC so we can interact on different NPC in our scene here, and I'm going to rotate the NPC slightly here on the y axis. So it kind of facing this direction. And here, let's just delete all of the child object. And we want to reset the action, so I'm going to set this back to one for now, and we need to create the dialogue template because right now the dialogue that we have created, it's still not a template. It's an FSM, so let's just create it so we can reuse this easily on other NBC. I'm going to duplicate this base dialogue just to create this template here because I'm going to reset all of this variable. So let's just set this message 20, the no actions 20 in size, also with yes actions, set the 20, disable the ask questions, the no string variable and the s string variable, and let's just set the sender FSM 29. Okay. Now we have save this player, FSM, let's go to the playmaker window here, and here on the FSM. We can right click here and then press save template. And let's just call this template Underscore dialogue. FSM, and save this. It doesn't matter to use this or not because we are going to delete this now. Now we have the dialogue template. Let's go back to the gift item here. And now let's create a child object, and this is going to be the yes response. And let's duplicate this and let's call this no response. And for the yes response, let's create a new FSM, and this is going to be the gif item FSM. And this is going to be quite straightforward. First, let's define the variable that we need. We need to create an array, and this is going to be the call. And this is going to be called chain actions, where it's going to be an array of FSM that we can assign so this gift item can run a series of actions if we wanted. And for the array type, let's change this two object, and the object type, I'm going to pick playmaker FSM. And let's enable the input checkbox, so it's available on the Inspector. And the next one that we need to create is the item to give. And for the type, let's set this two item, and we also want to enable the input checkbox so we can change the object here. And here on the FSM, we want to create a new state, and let's just rename this give item. And add a global transition custom event. Let's pick Run action. And I'm going to add a finished transition. And with this finish, I'm going to create a new state here, and let's just call this Run actions and add a finished transition also, and we want to connect finish back to the first state. So here on this state here on the gift item. Let's add a array add action. And basically, we just want to give the in the item that we have set up here so we can access the global variable inventory here, and for the value, we want to pass the variable item to give. And this will be all for this give item state. And here on the run action state, we want to use the run FSM action. And basically, we want to run the custom action that we have created from a template. Here, let's just pick the action run FSM. For the actions, let's just pick the chain actions. On finish event, we want to set to finish, and this should be all for the give item FSM. Now we want to save this as a template. Let's just do that. For this one, I'm going to call this template underscore, give item FSM. And we can use this here. Now we have the setup. Let's set up the dialogue here, I'm going to add another FSM, and I'm going to pick the template dialog FSM here and this will get triggered by the interactable FSM. Let's just drag this into this action slot. So whenever the player click on this NPC, it will go to this NPC and it will trigger the second FSM. Here on the FSM, we can say the message or set the message like do you want this key, for example, because for example, if we open the global variable window, we see that our inventory, we already have lighter. I want to make it this NPC is giving us the key, and we want to add an actions and also the S actions. For the s actions, let's just direct this yes response. For the actions, we want to add the FSM first to this no response game object, and let's just pick a dial of FSM. And direct this no response to that no action slot here, and enable the ask questions. And let's just set then to N, for example. Yes, to sure. And for the sender action, we want to drag this own FSM itself to the slot here. And the same goes to other dialogue. So for example, in the response, we want to drag the FSM itself to the sender FSM. And here, the other thing that we want to set is, I think this will be all for the dial of FSM here. But here on the yes response, we want to add a dial up template also to say something when the NPC is giving the item to the player. So here we can expand the chain action and we can add the playmaker FSM here. And for example, here, we can just say that use it wisely. There is a tipo here. Let's just fix that and drag the FSM to the sender. I don't think we need to set the others because this is going to be a message, not a dialogue. And for the item to give, I'm going to pick the key that we've created on the other video when we are defining the item. Let's save the scene here, and I think it's all set up on the side here. And for this, yeah, we already set up this here and also the no action. Here, we need to like, input a message. For example, when we refuse the NPC, when he wants to give an item. Let's just say that. Suit yourself, for example. Okay, so I think we are all set up. Let's just save the scene here, and now let's give it a try. Okay. Here, let's take a closer look to the global window here, global variable windows, and let's try to talk to this NPC here. And let's try NFs, and it says, suit yourself. And if we talk to this NPC again, if we pick this S answer, it will say a different thing, which is use it wisely, and it works our dialogue. And as you can see here, in our inventory, we have the key item received. And the good thing with this is when we stop this, it will reset the array, so changes during run time won't be safe. And this is actually good because we don't have to reset the variable manually. Okay, yeah, that is basically how we create the gift item template, and later, we are going to create the opposite template where we are giving an item to a NPC and we will have different response depending if we have the item or not. 14. 13 Take Item Template: In this video, we are going to continue the item action, and this time, we are going to create the take item template for an NPC to take an item from our inventory. So I'm going to duplicate this NPC gift item. And for now, let's just disable the NPC give item original. And we want to rea the duplicated one to NPC take item. And here, let's expand the yes response. And this is basically a give item template. So let's just set this non here, and this will reset our FSM. And here for this FSM, let's just change this to take item for the FSM name. And here inside the take item FSM, we want to create another state. And this state is going to check if we have the item or not. So let's just call this check item. And we want to add a global transition custom event run action. So we can run this using the interactable or any other run action FSM custom action. And then we want to create a local event called Success and fail. And we need this option because when an NPC is going to take an item from the player, we want to have a two output depends on the availability of that item inside our inventory. If we don't have it, then we should trigger the failed event. And if we have it, then we should trigger the success event. So let's add those transition success and fail to this tech item state. And basically, inside the check item state, we want to use the array contains. And here we can go and pick our global inventory array. And for the item that we want to check, we want to create a variable for that. So let's just create a new item variable, and let's just call this item to take, and we want to expose this as an input. Back to our state tab here, we want to use variable for the value, and now we can use the item to take. And we can trigger the event. So if it's contained or if we does have the item, then we want you to trigger the success event. And if we don't have it, then we want to trigger the failed event. Now let's just create two new state from this transition. And here we can just call it gift for the success event. And for the failed event, let's just call don't have And basically on this gift state. We want to remove the item from our inventory. So we can use the array to remove. And then we need to pick the global inventory and here for the value, we can just pick the item to take, and this will return the item from the array. And after we remove this, we want to run an FSM actions. So we need to create two new array. And this is called Success action. There is a typo. And for the type, I'm going to change this to object and playmaker FSM and enable the input. And then I want to also create another array, and this is for failed actions. And for the failed actions is going to be the same. We should pick playmaker FSM and enable the input also. And now, as you can see, the inspector, it doesn't really organize right now, so we can organize it by adding category. Here, we can add actions category for the success actions and set the failed actions to that category. And now we see our inspector variable in an organized group. And for the item, we can just leave the category empty, so it sits on a separate sections of our inspector here. This make it easier to read the inspector or the variable that this FSM template have. Next, we want to run each of these actions depending on the state. Here on the give state. Here I made a mistake. The array removed should be on the gif state, so I'm going just to cut this action and paste it inside the gift state. And then we want to add the run FSM. And we can just pick the action and use the action run FSM. And for the action, we can just add the success actions here, and we want to trigger finish. So we need to add a finished transition, and now we can pick the finished transition. And whenever we finish the action, we want to go back to the first state. So let's just copy this action here and paste this here. And inside Don't have state, we only want to run the failed action, and we want to trigger the finished transition. Go back to the first state. So here we want to remove the item because we have successfully give our item to the NPC. And here, since we don't have any item, then we don't need to remove anything. We only need to run the failed action. And now the take item template it's done. We can save this as a template. So I'm going to rename this to template, take item FSM. And we can use this now here. And just to test this, let's pick the same item that we have on our inventory. So let's just pick the lighter. And for the failed action, we need to create a new empty game object to hold the action. And let's just create a new empty here, and let's just call this down or doesn't have. And here, let's add a playmaker FSM, and we can pick the dialogue template dialogue FSM here. Let's add the message and direct the playmaker FSM as the sender. And for the message, let's just say, you don't have a here on the yes response, we can just drag the doesn't have as the failed action. And for the success action, we can just drag this message here. Let's just say thanks, man. For example, and drag this to the slot here. So now we have set up the take item FSM here on the main NPC game object. We need to change a couple of strings on the dialog FSM. The first dialog FSM here. Let's just say that do you have a lighter? Can I have it? And here, I think this is already set up. Just to make sure, let's just direct this one more time to the slot here. And for the yes action, it should trigger this that one here. Yeah, it's correct. So let's just direct this one more time, just to make sure. And for the response, I think this is also correct. Yeah. And let's select the no response. Let's just say something else. Let's just say that that's a shame, for example. Okay. So now I'm going to save the scene here. And let's check the game object already using the template. Yes. We need to change all of this FSM into a template, to make it easier to design the gameplay, and later if we need to modify one of the FSM, we can only modify the template, and it will get applied across the game object that are using those template as an FSM. Make it easier to edit things and to fix things. Okay, so now let's give it a try here, and let's try to interact. And we don't need to worry with the NPC give item because we have disabled it. Here in the globals. Highlight the inventory. We can check our item. Let's just interact with this person here. And if I say Na, then it will trigger this dialogue, and we keep the item. But if we give this item to this NPC here, and as you can see, the lighter gets removed from our inventory, and it will respond a different dialogue here. In this case, it says, T thanks, man. And with this take item template, we can trigger some other things, for example, like opening a door or something else. So if we give an item, then we have access to new areas, for example, we can just do that using the success actions. Yeah, if we stop this and we should have the lighter return because changes on runtime doesn't get safe. With that, we can conclude our take item lessons. Next, we will need to create a UI for the item, but I think we are going to cover that a bit later. 15. 14 Tidying FSM: In this lessons, we are going to clean up some of the FSM here because I just noticed that like our interactable, we are still using a base FSM. It's not a template here, and other NPC have this interactable because we copied the NPC from the first one. So we need to make sure that it's using FSM template to make it easier to fix things when we need it later. So I'm going just to duplicate the take item NPC here. And open the pla Maker window here, under the interactable FSM. Let's go here and let's set the actions 20 in size. And for stopping distance, we can set this to default 1.5. It's okay. And here, since we already reset the variable, and this is the default value of the variables that we want it to be. We can just right click and then press save template. And let's call this template interactable. And it doesn't really matter if we use save or not because we are going to delete this here. And now let's apply this to our other NPC. So here we can just pick the template interactable, but we are going to lose the settings here. So let's just remember this. Basically, we want to access the base dialogue, yes, response and no response. So let's just pick the interactable. Now set this back to three, and let's expand this and we want to get the base dialogue, and then the yes response and the no response. Because this two other FSM or game object, yes, activate and no activate is going to be triggered by this base dial up game object here, as you can see. So we don't need to worry about that. And I think this is good here. Let's just select the other NPC here, like this one here. And since this only have one FSM reference, this is quite easy to fix, and this is basically this game object sorry, this FSM here. So let's just pick the temperate intractable again. Set this b21 and drag this one here. And this should work. And then on this one here, we can just pick the intractable template. Set this 21, and then we can just direct this here. And let's just give it a try to see if everything working correctly or not with this template here. Okay. If I press sure, it takes our item. Yeah. So now if we try to give it again, it will response. You don't have it because yeah, we don't have it. So it's working very well, actually. And we can also interact with this person here. If we say I'm a bit sick, get well soon, and it will keep those interactions because we have this activate multiple FSM in the base dialogue here. So, yeah, that's for setting up the template, and then we are going to continue working on the game in the next video. Oh. 16. 15 NPC Move Action: In this video, we are going to create an NPC move action. This action is going to move the NPC using the NMS agent component. And with this action, we can make it so the NPC can move to a certain position, and this would come handy in our point and click game development. Now let's just duplicate one of the NPC here, and let's rename this one to NPC move, and let's reposition this NPC to a certain position, for example, in this area here, I'm going to rotate it, so it's facing this direction. And now we want to delete this second FSM. And I think we can safely delete the child object for now. With this NPC move here, let's add a new FSM. Let's open the playmaker editor here, and I'm going to right click here. Oops, and I'm going to create a new FSM. Where is it? Let's just select the game object again, and here under the FSM name, we can add a new FSM. And let's call this FSM move. So there are a couple of variables that we need to create. Let's create the variable needed for this action. First, let's create a game object variable, and let's call this vector, and this is going to be the child object that have the animator components attached to it. And we need also a vector t, and this would be the target position. And we need another game object variable, and this will be the target game object. Let's just type this target. And we need to also create a string variable. And this would be the animator speed reference. Then we want to create an array variable. And let's just call this chained actions. For the type, as usual, set this two object, and then we need to pick the play maker FSM. We want to expose a couple of the variable. First, we want to expose the actor, so let's just enable the input. The imeter speed reference, we want to expose this. And then we also want to expose the target variable and the chain actions. And we want to keep the target positions private or hidden in the FSM. So for the animator speed reference, let's set the value by default two speed, but later we can change this in the inspector here. Okay. So now on start, we won't do anything, but we need to create another state, and let's call this move. And then we want to add a global transition to the state here and pick custom event, and we can pick run action. And we need to add a finished transition. So for the move, we want to set the agent destination to the target position. But as you know here, the variable target position is not exposed, so we need to set this value here. On start, we want to get the position from the target game object. So let's just pick the target game object by specifying game object and then pick the variable here and pick target. And for the factor, we want to save this to target position. This will get the position of the target game object and it will save this position as a vector, then we can use that. And here, basically, we want to go to the next tape when The agent destinations path pending is done. So when the path of the movement is generated, then we want to trigger finish, then it will go to the next state. And then on the second state, we want to remain this to wait until arrive. For the wait until arrive state, we want to add the get agent, sorry, agent remaining distance. And here we want to trigger the arrived event. So if it's arrived, then we want to trigger the finish, and we need to enable the every frame. Now we want to add the finished transition. Then we want to go to the next state, and when it's finished, then we want to run the chain action. So let's just rename this. And here we want to add the run FSM action, and we want to pick the action run FSM, and we need to pass the chain actions here. So this will trigger the chain action. And now we need to create another anti game object. It can be the child of the NPC move. So let's just create the target position, and let's set this position to here and the direction, for example, to this direction here. And now let's just rename this two target, and I'm going to enable the icon for it, so we can see it on the scene view here. And now on the NPC move, I'm going to drag this second FSM to this action slot on the interactable FSM. And then for the target, I'm going to pick this target game object as the target. Now if the player interacts with this NPC, it so trigger this move action. So let's give it a try. Okay. There is one error because we don't have mesh agent attached to the NPC move game object. So let's just add that. So I'm going to add an agent here. And now I'm going to put this agent on top here. By dragging it and save the scene again, and now we should clear out the error message that we were having before. So let's just save the scene again and now let's give it a try. If we click on this NPC here, it should move the NPC, as you can see, it moves and it triggers the chain actions. We have a working move actions right now, and next, we are going to add a character model, and we want to also sing the animations. When the character is moving, we want to play the walk animations, and if it stop, we want to play the idle animation. And then later we want to turn this into a template. 17. 16 Add Model and Animation to NPC: Now let's continue our NPC move action, and now we want to add the model, so the model we'll play the animation accordingly when moving and when standing still. So first, let's prepare a couple of things. I'm going to create a new animations folder. So let's go to create folder and then type animations. And here inside the animations, let's create a new animator controller. Let's call this people. And now let's open the animator controller. Let's create a new blend tree, and for this bland tree, let's call this idle dash walk. Here inside this blend tree, by default, it will have a parameter blend. So this will create a float parameter blend on the animator, but let's rename this parameter chose speed, and we are going to use this value to drive the motions that are playing. So if it's zero, then it should play the idle animation, and if it's one or if it's greater than zero, then we want to play the walking animation. So here on the side here, when the blender is selected, we can see its inspector. Under the motion section, we can add a motion field. So let's press this and press this twice. And the first one, we want to use the male idle A. This is the first animations for idling, and for the walking, we want to use the male walk, but the first one, not the second one, because the second one is with root motions, and we don't want to use the root motions actually. So let's just pick the first one, and we should have these animations when we are importing the two, tiny people a set pack. So now we have this set up. This should trigger our animations correctly. So now if we play these animations, you see it's idling, but if I direct the speed, it will change to walk. And vice versa. So we can use this value to dictate the animations of the character. So now we are done with the animator setup. Let's go to the scene here. Go to the two tiny people folder. Under the TT demo folder. We should have a lot of prefs. And let's pick the police character, and let's wreck this police to the child of the NPC move. And we need to reset it transform. Let's just reset this, right click and then reset. And for the y position, we want to move this by negative one. So it's aligned with our capsule game object. And here on the parent game object, we can just remove the mash render and also the mash filter component here. Let's remove this. Now we should have this. And here, under the NPC move, we want to set the actor to the child object that has the model and the animations in it. So let's just sect the TT model police. And under this TT demo police model, we want to pick the P Controller. So let's just pick the people Controller. Okay. Let's save the scene here. And here on the NPC move, we should have set the animator speed reference to speed by default, because we did the same on our animator controller. But if for some reason, the game object has a different reference float variable, then we need to change the name so it matches the one that has been set up in the animator. So once we have set up the actor, we need to modify the FSM. So let's go to the playmaker window here, and under the Move FSM, we want to add a couple of things. So here, When the NPC is waiting until it's arrived, it means that it's moving. We want to set the animator or the speed float animator to one. So let's just use the set animator float action. And for the game object, we want to specify game object, and then we want to pick the actor variable. And for the parameter name, let's use variable and then pick the animator speed reference, and we can safely set this value to one because we know that in this state, the NPC it's moving, and then let's copy this set animator float action, and whenever we arrive, we are going to the next state. So here in the next state, we can just move this to the top and then set the value to zero. So let's just save this. And now let's press play. And let's give it a try. So now it's playing the idle animations, as you can see, and if we go to this NPC here, it will move to that position. Yeah. So that is how we set up the character and the animations to synchronize with the move actions. Now let's turn this actions into a template. So in order to do that, I'm going to duplicate the game object here. And for the second game object, I'm going to set the actor to none. And for the target, we want to also set this to non because it's a scene reference K. And now that we have set this up, let's go to the move FSM, and here, let's just save this as a template, and this is going to be a template, not an action, so let's just type a template. Let's just call this move NPC. And save this. We don't need to use this in this object because we are going to delete this. But here on the NPC move, we want to use the template. Let's just pick the template here, and it will get reset, and now we can set the actor to this TT Do police game object and for the target, we can just pick this target game object. Let's save this. Now if we give this another try, it should also work. Okay. It's working fine. So yeah, now we have the move actions and the NPC animations also synchronize with these actions. 18. 17 Replace Player Model and Add Animation: Next, let's replace the player model with the player character. Now in order to do that, let's go to the project folder and inside the two T people folder, we have this T T demo folder, and inside this folder, we have prefe folder. And for the player, we are going to use the Do male A. S, not demo male A. It's going to be D M B pre let's just drag this pref and make it the of the player. And let's just reset its transform. And here, let's set the y position two negative one. So it's align with the capsule game object. And now we can go to the player game object. We can remove the mash filter, and we can also remove the mash render. Now we have this set up. And for the child object, we want to add the controller that we have just created in the previous lessons. We can use the P Controller because the controller actually can be shared between NPC and player. And now let's select the player game object, and let's open the playmaker Editor window. And here in the click to move FSM, we want to add a couple of actions. Basically, on the way to arrive state, here, we want to get the fellocity of the agent. So let's just type get felocpy, and we should be able to filter out the get agent felocity here. And here we put it on top. And then we can check every frame, and we can save the velocity magnitude or the square magnitude. I'm going to pick square magnitude because this is more performance because there are no root square calculation with this value. But for magnitude, there will be root square calculation since we are running this actions every frame, I believe that velocity square magnitude should be better. So let's just create a new variable, and let's just call this player velocity. Now we have this. Let's minimize the other two action. And then we want to use the set eimator float action. And for the action, we want to put this below the get agent velocity, and let's create a couple of variable. So first, I'm going to create a new game object variable, and let's just call this tor, and let's expose this. And then I want to also create a string variable called the animator speed reference, and expose this variable also. And I'm going to set this value to be string called speed by default. But since we expose this variable, we can easily change this on the inspector. Now let's go back to the state tab, and for the game object, let's specify a game object here, and then let's pick the actor game object. And for the parameter, we want to set this to the animator speed reference. And then for the value of the float, we want to pick the player velocity here. Let's check every frame, and we can lift this on update. And now let's save this, and let's give it a try. Okay, there seems to be an issue here. Yeah, I forgot you set the actor. So let's just drag the child game object into the actor slot here. Let's save this again, and now let's give it another try. As you can see, it walks and it stops. And the rotations is a bit slow, so we can increase the value to make it more perfect. Here on the player game object, on the NF mass agent component, we can increase the angular speed value. I'm going to make this 2720 and save this and this make the rotations si. And I believe this works better. Okay. Now we have replaced the player character. Let's continue to develop our game in next lesson. 19. 18 Inventory UI Panel Setup: In this video, we are going to create the UI for showing our inventory. Let's go to the view in the scene view here and let's focus on the Canvas, and let's expand the Canvas on our sample scene here. I'm going to create a new empty child game object here, and I'm going to make sure that this child game object stretch to the screen here, and let's rename this inventory. And we want to create a child object, which is an image, and this is going to be our panel. We're going to rename this panel. And we can make the transform to also stretch, but we want to add a margin on the left side by 400 and right side also 400 and top by 200 and bottom by 300. Now we have this panel here, and let's change the color to the black transparent that I've saved before here, which is 40% or 40 in the Alpha value here, and the color is black, and we want to add the background. So this is going to be also an image, and let's stretch this background here. Pick the same color, and now we can delete the image on the panel game object. So let's just delete the image component, and let's rename this two background. And for the background, let's add a margin on the top by 100, and we want to put a title here. So let's just create a new UI and Pi tax Mash pro. And let's put this on top, this one here, by pressing all and shift, you can select this, and it will adjust automatically here, and let's expand this. And now let's rename the text to inventory. And we can increase the font size, that's set this 260 or even 70, and then we can set the alignment center and middle. Now we want to add a scroll view on the background game object. Let's just select the background game object, go to the UI menu, and let's pick the scroll view, and this is going to be the items holder, and we want to also expand this stretch to our panel. But we want to add a margin on the left side by 25 pixels, right also 25 pixels, and the bottom 225 pixels also. And here we can just disable the image component on the scroll view, so we don't have this white background color, tinted white. And let's change the movement type to clamped and make sure that the movement type will clam depending on the content size window. So we can only scroll to the bottom part of the window size. We cannot scroll much further. And here on the child of the scroll view, we have this viewport and we have the content. So for the content, we want to add a grid layout group, and this will make sure that the child objects will be arranged in a grid manner, and let's create the item entry. And for now, let's create it as a child of the content, so we can see it. So go to the UI menu and pick the image. I'm going to duplicate this image so we can see it nicely aligned and select the content. Now we can adjust the spacing and stuff. First, we can add the padding. Let's add ten to each of the padding here, ten pixels. And for the spacing, let's make this around 20 pixels. W spacing, we will have space between item entry, and let's rename the first one to item I. And for the content game object, we want to also add a content size fitter component and make sure the vertical fit it sets to preferred size. So by using this content size fitter, it will change the height of this content game object depending on the child member. So if we have a lot of inventory, then the height will expand to accommodate the child game object or the item UI entry. And this will make the size of the height content change dynamically based on the child game object, and this will also trigger the scroll bar to react and adjust its scroller so we can scroll the view. Let's save this here. The other thing that we want to prepare is we want to create the info panel. This info panel will show whenever we hover to the item, and it will show the item name and item description. So let's just create a panel or an image as a child of the inventory. And this is going to be the info panel. So let's rename the game object. And for the info panel. Let's change its size its width to 400 and height to 200. And we want to also change the anchor to the top left here. So we can use the mouse position to reposition this info panel. And I'm going to change the pivot the x pivot to negative 0.1. So it's slightly offsetted from our left side of the panel, and for the y pivot, I'm going to make this 1.1, so it's slightly offsetted also on the y axis. So we will have a slightly distanced pivot to our panel, and this will align nicely whenever we trigger its position, then we will have space between the mouse position and the info panel. And for the info panel, let's change the color to this black transparent. And we want to also add a child tax object. So I'm going to add a tax here. And let's stretch this to the size of the info panel. But let's add a padding on each of the side of this panel here. And for the font size, let's set auto size, but not by much. So let's just set the minimum to like 22 and the maximum to 38. So the font sizing will adjust automatically depending on how many character we have, so it fits this window. Let's save the scene here. And yeah, we have set up the inventory Panel UI. And next, we are going to create functionality for this. 20. 19 Inventory Panel UI Functionality: Hi, in this video, we are going to continue our inventory UI system, and right now we are going to create the functionality for this inventory UI. So let's get started. Okay. First, we want to expand the Canvas game object here, and under the inventory game object, we want to create a new FSM. Let's just create one FSM here, and let's just call this inventory. Okay. So now that we have created the FSM here, let's create Git owner action here, and we want to save the owner, the owner game object here, the inventory game object into a global variable. So I'm going to go to the Globals, and I'm going to create a new global variable here. And I'm going to call this inventory Manager. Now we have this new game object. It dict owner will store the game object reference to this global variable, and we can get the inventory game object via this variable. This makes it easier for other FSM to access the inventory FSM from this inventory game object. And then the next thing that we want to do is we want to cache a new line character. And we need this to define the text of our item information here. We want to show the item name and then the item descriptions, and to break the line, we need this new line character. And in order to do that, we need to open our ecosystem roser, and then we want to get new line. Here we have this action called Get new line character. Let's just get this. Now is compiling and once it is done, let's add that action. Let's just type get new line character, and here, let's just store the new line to a string variable, and let's just call this new line. The next thing that we want to do is we want to deactivate the panel, and we also want to deactivate the info panel, a smaller one here. Let's just add a activate game object and put this below here, s Let's just put this activate game object below and disable the recursive options. For the specified game object, we want to create a new variable. Let's call this panel. And let's duplicate this action. So we have two activate game object. Let's just minimize this. This one here, Let's just create a new variable, and let's just call this info panel. And now we will have two new game object variable in our variable. Let's expose them. The first one, I'm going to expose as an input. And for the panel, let's also expose this variable as an input. And here, let's assign the game object. First, we want to drag the panel game object to the panel slot and the info panel to the info panel slot here. Let's save the scene. So now we are done here with the initialization, let's just rename the statue in it. And here, let's add a finished transition, and let's create a new state here. And this is actually for refreshing the inventory. So we want to refresh the inventory. I mean, we want to delete all of the inventory item entry, and then we want to generate a new one based on our inventory array changes. So if there are any changes, we want to refresh the UI. So in order to do that, let's just create a new event, and let's just call this refresh inventory. And let's make this a global event, and I'm going to add a global transition. Here, we want to remove all. In order to do that, we need to also download a custom action. Let's just open ecosystem again and I'm going to search for child here, and we so be having the destroy children action. It sounds bad, but, it's basically just destroying the child objects. Pun intended. Let's just press get here. Now, it's finish compiling. Let's add the destroyed children. I'm going to type destroy and we will have this destroyed children action. In order to do this, we need to create a new variable that will reference to the scroller view and the content game object here. Here under the inventor game object, let's create a new game object variable. Let's just call this item parent. We want to also expose this. Now we can wreck the content game object as the value for this item parent field. And then here we want to destroy all of the child of the content game object. So basically the item parent game object here. And now let's add a finished transition. So once we destroy all of the entry, I mean, the child game object of the content, so it's going to be this item UI here. We want to go to the next state here, and then we want to loop the inventor array from the global variable. So in order to do that, let's just use the array get next action, and this will loop the array, and let's pick the global inventory, and let's just set the start and index 20. And we want to loop the event. So in order to do that, I'm going to create a new local event called Loop, and here I'm going to add the loop transition and the finished transition. When we are looping, we want to go to the loop transition. And basically, we want to go to a new state when we are looping here. And let's rename the state to loop inventory, so we know when it's finished, we want to go to finish transition, and here on the loop inventory. We are done, basically, we want to save the value of our inventory on every loop, let's just create a new variable that we hold this. Let's type current item. We need to also have a reference to the item UI prefab but the game object that we are going to copy, for example, here. Let's just create a new game object. And let's just call this item prefeb. Although it's not a prefe actually, is a live game object on our scene, but we can copy that. So let's just expose on input here. And on the item prefe slot here, let's just direct the item UI. Now I'm going to delete the second object here. And for this item UI, I'm going to put this as a child of the viewport now. It's not going to be the child of the content anymore, and let's just disable this game object so we can see it. And let's go back to the inventory. Now we should have the item prefabs. Now we have the current item. Here, we want to add a finished transition, and when it's finished, we want to go to the loop inventory, and when it finished looping the inventory, we want to go to a new state that where we are going to stay idle for this inventory FSM. Let's just rename this idle. Here on this new state here, we want to rename this to set up item entry. And basically, there will be a lot of action. The first one, we want to use the create object action. Let's just type create object. And with this create object, basically, we want to copy the item pref. Let's just pick the item prefs. For the parent, we want to make sure it goes to the content, so it should be the item parent. And the spawn point, we can just leave this blank, and then we want to store the object into a new variable. Let's just create a new variable, and let's just call this item entry. Now we have this game object reference, the copy, the copy game object. Let's just minimize this action. And then the next thing that we want to do is we want to get the property from our c object here, the item class. So let's just get property here, and then we can use variable and then pick the current item. And here we should be able to pick the images, the name, and the description. So first, let's just grab the name. Let's save this to a new variable called item name. Let's just copy this property here. And I'm going to pick the description now here and get the string and save the description into a new variable called item description with a shorter item desk. Let's just minimize this and we can copy this here. And for the third one, we want to get the image and we want to get the sprite. And here we can save this new variable called item sprite. Okay. So now we have get all of the data that we need to instantiate to populate the item entry and to show the correct information on the inventory panel UI. Now we need to set up the FSM on the item UI. Let's just set up the item UI, and then let's create a new FSM here. And on the item UI here, let's create the variables that we need. First, we need a string variable called description. And this is going to be a type of string presenter. The next one is going to be the name. This is also string. And for the image, let's just create a new variable sprite and set the type to sprite. This one here. And then we want to create a new factor three variable, and this is going to be the N three position. Basically, the position of this UI, and you will see in the sac that why are we needing this variable? Now, here we have set this up. On the start state, here, we want to set up the display of the item, so here we can just use the UI image set sprite. And then for the prt, we can just pick the sprite variable. And right now, that would be all for the item UI. Let's go back to the inventory. Now we have set up the FSM and the variables on the item UI game object, we can use the set FSM string action to set the value on one of the variable on the item UI. So let's just pick the game object and for the game object, it's going to be the item entry because we want to modify the spawn UI here, which is the item entry, and we can leave the FSM name empty because the UI only have one FSM, so it will refer to the FSM. And for the variable name, It is called name, and we want to set this value to the item name that we've grabbed previously using this get property. So let's just duplicate this FSM string action, and then we want to send to the description variable. And we want to set the description value variable on the item UI to this set value using the item description that we just grab from this get property. So now we have set up the FSM string. The last one that we want to do is we want to set an FSM sprite, but we don't have that, so we can use set FSM object. Let's put this pillow here and do the same. We want to pick the game object, the item entry, and for the variable name, it's going to be sprite. And for the value, we want to pick the item sprite. This will send the sprite to the sprite variable. Now we have set up all of this action. The last thing that we want to set up is we want to set the scale because from my test, when we are spawning the UI, the scale is off, so I'm going to force the scale of the UI using the set scale. And we can just pick the game object, which is the item. And for the scale, we want to set all of them 21 on each axis. So we can use this float variable instead of creating a new variable, and let's just type one on all axis and minimize this. Then we want to activate the object because by default, the object is the activated. The copy will also be activated. So let's just use the activate game object, disable recursive, and then we want to activate the item entry game object. Okay. Now we have finish set up this here. Now let's just give it a try and see how does it work so far. Basically, when we start the game, when it's finished initializing, it will go to the finished state and it should refresh the inventory. And then when it's finished refreshing the inventory, it should go to this idol until we refresh the inventory again. Let's just press play, and we should be able to, right now, it's working, but For some reason, the panel doesn't get hidden, so we need to deactivate it. So this is where I'm wrong, I need to deactivate this, and I need to also deactivate the info panel on start. So let's just save this again. Let's give it a try. Okay. Now, basically, we don't have a way to show the inventory now, so we can just try to enable it from the inspector here, and as you can see, we have the lighter. So right now, the refresh inventory event and the states are all working good, actually. And now we want to create a behavior where when we hover the item, we should see some sort of a item info or description. So in order to do that, we need to create A couple of events. The first one would be the show item info, and make this global, and the second one would be the item info. And this also needs to be global. For showing and disabling the panel, I'm going to create another event called show inventory. And make this also global. Here on the idle state, we want to add the show item info and we want to also add the height item info. For this transition, we want to create a new state both on the height item info and the show item info. Let's rename the first state to show info, and here this one, let's name this to Hide info. Basically, when we are showing the info, We want to set the info panel position. We need to use the set position, and then we can just pick the game object info panel. For the position, we haven't created a variable yet, but we can just create let's just call this invo position. And we are going to set this value from the item UI FSM. So let's just leave this zero for now. And then we want to activate the game object info panel. Let's just use the activate game object, disable recursive, specify game object, and then select the info panel. Let's make the set positions on top here, and let's just minimize it and minimize this one also. And then we want to build a string. So let's just use a build string action. And for this build string, we want to use the item name. And then second, we want to use the new line character that we've cache or we save on it. So the next line will be below the item name string. So the next line is going to be the item description. And we are going to set the item name and item description from the item UI. Okay. So I think the built string, we need to store this to a result. So let's just create a new variable, and let's just call this info string, and let's just minimize this. And the next thing that we want to do is basically we want to change the text of the info panel. Let's just use the set text mesh. Let's just search for the text mesh pro UGI text. This one here. And we want to create a new variable to hold this info tex. Let's just create a new variable. Let's just call this info text. For the text, we want to use the build string result, which is the info string here. Once we have set this all up, we want to add a finished transition, and then we want to go back to the idle. Case. Now we have this here, Let's go to the variable and let's expose the info text variable here, and now we can expand the info panel and direct the game object to this infotex slot here. Let's save the scene here. Now upon hiding, we want just to deactivate the info panel. It's very easy. So we can just use the activate game object and disable both recursive and activate, and then we can just pick the info panel variable. And we need to add the finished transition to go back to the idle state here. And then we want to create the functionality to show and hide the panel. Let's just create a new Boulan variable that will hold this state. So let's just call this panel. Let's just call this panel opened, and by default, it's going to be false. So let's just add a transition, the show inventory transition from idle here, and let's create a new state. And let's just call this togal panel. And basically inside the state here, we want to flip the bulion. So we can use the bulion flip, and bulion flip we flip the bulion back and forth from false to true and true to false and so forth. So whenever we enter this state, this value always change to the opposite value, and we can use this value to activate or activate the panel. So let's just use the activate game object. And disable the recursive, and we can put this below here, and we need to pick the panel variable, which is the main panel here. And for the value, we want to set this to the panel open variable. So the activate game object. Activate value will be depend on our panel open that are being flipped all the time. Whenever we enter the state. Let's just add a transition finish and to go back to the idol. Now we should have something like this here. Since this is a global event, we can trigger this from another FSM, but we can also trigger this from the button callback. And now let's just create a button group here. For make it easier button group. And this is going to be let's go to the scene view here and I'm going to put this button group on the top right of the screen, make it bigger. I'm going to make sure to round this value here, maybe 2250 or 300 in width and make this also 300. The next thing that we want to do is probably we want to add a vertical layout group, and now we can add a button. Let's just add a button text Mach pro here. Let's set the size of the button to 250, the height 260, for example. Here on the button group, let's set the child alignment to upper center, and let's add a padding. We have space on the left, but on the top and the bottom. K. This is going to be the inventory button. Let's just type inventory button. And let's rename the text value to inventory. I'm going to make the out of size tech, so we will have a bigger value. I'm going to set the maximum to run 40, so it's smaller, but it's quite readable from our game view. I'm going to say the scene again. And now we can create an FSM to trigger the panel, but it will be easier if we just add an on click event here, and we can the inventory game object. And here under the function, we can access the playmaker FSM, and we can send an event, and we can type the event. So we know that the event name is show inventory all caps, so let's just type this. And this is the global inventory. Sorry, this is the global event that we've expose on the inventory FSM here. There you go, so we can use this name here, and this basically will trigger the event. Every time and it will toggle the panel. So we can easily show and hide the inventory panel by clicking this button. So now let's save this. We already set up this, but we need to set up the item UI FSM right now. So now let's just start working on this FSM. First, let's just add a finished transition because we finish initializing this, and let's just call this in it. Let's create a new state from this here. And I'm going to call this wait for Mouse Hover. And basically, we can just create a local event called for example, on Hover. And then on exit. So let's just add on hover here, go to the other state, and then for the other state, we can just add on exit and then go to the wait for hover. Basically, on the wait for hover, we want to send the item info to the inventory manager. So we can use the send event. And now we have cached the inventory game object into a global variable. We can just pick the game object FSM here and specify game object, and then we can pick the global inventory manager. For the vN, we don't need to set the FSM name because inventory only has one FSM, and we can pick the global evN, and we want to hide item info here. Because whenever we are hovering, we want to show it here, and when we are exiting, we go back to the state, we want to hide the, sorry, I add it to the wrong state, so let's just cut this action by pressing control X. And then here, I press control V two paste the action, and then we can copy this se event to the state here. But instead of hiding, we want to show the item information here. Okay. And the other thing that we want to add on this date here, we want to use the UI pointer enter event. So this will works when the mouse are entering the UI space or area, then this will get triggered and we can trigger the on hover event. And we can copy this sorry, we cannot copy this. We need to add a different action here, let's just add the pointer exit event this time, and when exit, we want to trigger the on exit transition. And basically for the wait for Hover, we are done, but for the update descriptions, there are a couple of things that we need to do here. So before we are sending the event, we need to send the data of our item I. First, we want to get its position. L et's use the get position here, put it on top, and we can use owner. But we want to store this two a vector entry position that we've created before, and this is where we are going to use this variable to send this position into the inventory manager. And then we want to use the set FSM vector three variable, so we can set a vector three variable on other FSM. And here we can just pick the global inventory manager, and then if I remember correctly, the name is item position. So let's just check for a moment here. In the inventory, when we are showing the info, we are getting the value from the invoke position. So the name is info position. Make sure we type that name correctly. Oh, sorry, not item but info position. So let's just type invoke position. We want to set the value to the entry position variable that we have just grabbed before. And then we can use the set FSM string to send the name and the description of this item that we have here, so let's just pick the global inventory manager again. And for the variable name, we are going to overwrite the item name. With the name of the game object, and we can duplicate this FSM here, and then we can overwrite the item description, and we want to pass the description. Now we have set up the position, the string and the name and the description string here. Let's save the scene. Now let's check one more time. When we are showing the info, what variable did we use on the built string here. We use the item name and item description. So it's all correct. Now let's test this and hopefully all works great. Okay. If I open the inventory panel here, as you can see, we can show and hide the inventory using that click event on the inventory button here, we can send an event. And here, for example, if we ho over the lighter, we should be able to see that, as you can see, but the position is wrong. So let's just check. I found the issue here. Basically, when we are setting the set position info panel, we need to make sure that we are using the world space because we are getting the info position in world space, for example, if we select the IMI game object here, we are getting the world space of the position. We need to make sure that the info panel set position, it's also ino space, and it was on local space here, let's just select this world, and let's give it an try. Okay. Now as you can see, if we hover, it shows the panel pop up on the correct position, and if we exit the UI or the item UI, it hides itself. And now, a small changes that we need to do is we need to trigger the refresh inventory whenever we receive or we remove an item. So here on the gift and take item, we want to addit that. So here on the NPC take item, whenever we are changing the inventory, either via take item FSM or give item FSM, we need to change this, so let's just addit this here, and for the take item, whenever we give The item when we remove the item, we want to call the refreshed inventory. In order to do that, let's just add a sign event here. And we can access the game object FSM via the global variable, which is the inventory manager here, and then we can call the global event refresh inventory. And here we can just copy this action here by pressing Control C, and then I can select the gift item NPC here, and I can edit the template. And here, basically, whenever we receive the item here, we can just run the same refreshed global event from the inventory manager. Case. Now let's give it a try. I'm going to disable the take item NPC and enable the gift item, so we should be receiving the item, and now let's test this. Let's talk with this NPC here and there seems to be an issue here where we don't see the dialogue. After looking into the problem, I found the issue that the inventory game object for some reasons, have a text mesh pro tax UI components attached to it. And this could happen for a couple of reasons. The first thing that I've noticed that when we add this text mesh pro UI text action, I might have clicked the warning button that adds this component automatically into the inventory game object. And this text mesh pro component is now covering the recast to this dialog panel. So we can just safely delete this component here, and we can also delete the CVAs render component. So now let's give this another try. And let's take the item. Let's not take it, but let's see our inventor. Okay. We only have lighter, and the NPC is offering offering us a key. Let's press sure. And let's check our inventory. There you go. We have inventory, the lighter, and the key. And we can see both information very nicely. Now let's give this another try, let's disable the gift item, and let's enable the NPC take item, and let's check the yes response. It as for the lighter, so we should see that our lighter gets removed when we are interacting with this NPC. Now we have the lighter. If we talk to this NPC, for example, if we gift our lighter here, sure, we should ok, there seems to be an issue here. We still have our lighter. Let's check this problem. So yeah, the problem is that here on our take it template FSM here, whenever we give our item to the NPC here, we are running this FSM success actions, and it will run the list of FSM array on our take item FSM here. It will trigger the success actions, and it will run the finished transition when it's finished. So it this sN event never really gets executed. So in order to do that, to fix this, we need to move this to the top here, and we need to make sure that this event gets executed before this run FSM is running. So let's just minimize all of this here. I'm going to save our project, so it will save the changes on the template FSM. And now let's give this another try. And, I have this Tgal Breck pron enabled on the inventory, so let's just disable this and save the scene again. And now let's try, sorry. Let's check our inventory first. We have lighter. Let's talk to this NPC here, and let's press sure. And then if we go to our inventory panel, you see that we don't have inventory anymore. And in our inventory global variable, we don't have item also anymore. So, this is quite a lengthy lessons, but yeah, because basically there are a lot of things that needs to be set up, yeah. But with this setup, basically we can create a very modular inventory system, and we are going to continue to add more features in the next lesson. H 21. 20 Save and Load Concept: Now we are going to create the safe system for our point and click game. And basically, there are two things that we need to save in this game. First is the transform of an object. Either is it a player or an NPC? We need to record its position and its rotations whenever we are saving or whenever the object has finished moving. And we also want to save the active state on each FSM. For example, this NPC dialogue here, if we check the inspector here on the intractable, you see that we have this list of actions, which is an FSMs actually, and this are the FSMs on the child object, and we want to record the active state of each of the FSM. So for example, if the base dialogue is activated, and if we check the inspector here, the intractable component, I mean, we know that the other FSMs that are being tracked by this interactable component is the yes response and the no response. So we want to record all of those FSM active states. In this case, currently, the base dialogue is activated, the yes response is de activated, and then response is also de activated. And if we talk to this NPC, for example, if we try to interact with this NPC here, and then we response from one of these two options. You see that the active state will change. Now the base dialogue is disabled. The yes response is activated, and that no response is still disabled. So we want to keep track of these changes, and we want to convert the value of this Bula into a string, either zero or one. So we can easily save this data into our safe file on under this, so we can continue the progress or the game progress, and we can load those save states from string back to bion Okay. And the thing that we need to only keep track is the actions on the interactable. Because this is the one that are going to get triggered whenever the player interact. So if there are changes of state, then we want to change the state only on these FSMs. And we don't need to think about the other FSM like this S activate and no activate, because these FSMs only change the active status on the FSM objects. So yeah, that is the basic for the states recording. And here, I've already created some sort of diagram here. So basically, for the transform is quite easy. We want just to record the position and rotations. And for the states, we want to record all of this FSM states. F Boulan converted to a string format. For example, if the start dialogue is disabled, and yes, response is enabled, and this one is disabled, then the string format will be 01 and zero from the top to bottom. And we want to save all of this here to our safe manager, and inside the safe manager, we are going to use a custom actions called JS Safe and JCN load that I've created, and it's available on ecosystem. And then once we've create the safe manager, whenever we are loading, we are going to load the data from the disc also from this load manager, and then we are going to apply the transform to the object that it's transformed was safe before. And then we are going to apply the position and rotations, and the same goes with the states. We are going to apply the state that are safe in string back to bul and then apply those values to enable or disable the states depending on the safe value. And you might wonder, how do we keep track which object gets which data? It's actually quite simple. Basically, we create a for example, I'm going to create a new node here. We are going to create a couple of array. So for the array, let's just call this entity name. And this one for states, for example, Then we want to save the game object name that holds this intractable component. This should be the game object name, and we need to make sure that the game object names is unique on each object. There are no different game objects with same name, for example. Then we want to save this to an entity states data, for example, and this will be a type of FSM array. But it's string, for example. And this will be also a string. FSM array. String. And whenever we save a new NPC, for example, we are going to store the game object name into this array of string, and we are going to save the state of the FSM to this states data. So whenever we add a new entry, both of this string game object name and the states data are going to be filled on the same index of this array. And this will be our identifier. Whenever we are loading later, we can search for the game object name on the entity name states array. And once if it's found, then we want to copy the index value, then we can use that index value to get the entity states data. So that is the basic disk of the safe system. And the same goes with the applied transform, for example, for the applied transform, we are going to need to create a separate identifier here. For example, I'm going to create an array string called entity named TR S for transform, and this is also FSM array string. And this would be also the game object name. Then we can add another array, for example, the position, and this would be a type of FSM array vector t. Then we want to save also the rotation, and this needs to be on a different array. This is going to be the FSM array vector t also. Whenever we want to get the transform that we are going to apply to a specific game object, then we can look through this entity name transform. Based on the game object name, and once we found the entry, we can get the index and we can use the index to retrieve the entity position and entity rotation, then we can apply those values to the game object. This way, we can create a complex safe system with different objects that can store its position rotations and the FSM states, and then later, it can be reloaded to the game objects when the player continue the progress of the game. So that is the basic concept of the safe system, and if there are more questions, feel free to ask in the questions and answers section. 22. 21 Setup Save Manager: So now we are going to working on the safe and load system mechanics. And the first thing that we need to create is we need to create the save manager. So I'm going to create a new empty game object, and we can just reset its transform. And let's rename this to save Manager. And I'm going to put this game object on top of our scene here. Let's take the scene. And now we want to create a new FSM. I'm going to make the FSM window bigger and press at FSM to create a new one. And here, first, we want to create a state to save the data. Here let's create a new state, and let's just call this loop all it FSM. Basically, we want to look all of the record transform and the record state FSM from the entity and we want to run each of the FSM run actions transition. In order to do that, we need to create a global variable. Let's just go to the editor Windows global variable. And here, I already have mine opened. Let's just create a new array. And let's just call this NTT saver FSM. For the type, we want to change this two object, and we want to pick the playmaker FSM as the object. Now we have this. We can loop this saver FSM by using the array, get next action. And then we want to pick the global array that we've just created. We can leave the start and N index 20. It will loop all of the member here, and we want to create a loop event. Then we want to add that loop event here. Then we want to also pick the loop event, and for the finish, we can pick a finish transition. I think we need to add that first so let's just add the transition finish, and now we should be able to pick finish transition. We need to also create a global event called save, and let's mark this as a global so we can easily trigger this transition from other FSM. Let's add a global transition save here. And now we want to save the result into a single variable or a single playmaker FSM variable that we can manipulate with. Let's just create a new variable here, and let's just call this current FSM. And this will create a new variable that are compatible with the array object type here, the play Mer FSM. And then basically when we are looping, sorry, when we are looping, so we need to create a new state from the loop transition. We want to invoke each saver FSM. So let's just rename this to invoke each FSM. And then here on the invoke each FSM, we want to use the call method. Action here, and we can pick the current FSM as the behavior. And for the method here, we want to run the SN event string, and we want to run the run action given. So the entity saver FSM for either the transform or the states, we also have a global transition run actions just like any other actions or template that we are using for the NPC. This is to make it easier to run the state that we want to run whenever we are loading or saving a data. Let's save the scene here. And now, if it's finished, then we want to go to a new state, then we want to save the data. So let's just call this save all data. And basically, we need to import a custom actions that I have just created, and it's available on ecosystem. Right now, let's just go to the add ons menu here under ecosystem. Let's open the brocer, and let's just type JSN. And we should be receiving the result here, and the action is called JS and save and s and load. Let's just press get for the JC and save, and let's also get the Ks and load. Right now, the script is compiling, and now it's done. So let's just close the ecosystem here. And if I type save here, we should have the JCN save actions, and this action can save a lot of variable, including vector types and also an array variable type. Here on the JCN save, we need to save a couple of array that we need to create. Under variable, let's just create a new array, and this will be the entity name transform. And this is for transform, and we want to change the type from flow to a string. It's going to be an array of string, and I'm going to create another array, and this is going to be the entity position. For the entity position, the type should be vector three, and I'm going to also create the entity rotation, and this should also be vector three. Now we have all of the variable that we need to save the transform of an object. Here on save all data, we want to adjust the array variable. Member here, 23, and the first one would be the entity transform. The second one would be the position, and the third one would be the rotation. Now this save whatever values that we have here. And basically, we need to prepare this value in a new state. So here, I'm going to create a new state, and basically, we are going to check the entity name, and we need to create a global event to be used as a global transition. So let's just type record position, for example, and make this global. And then I'm going to add a global transition record position here. Basically, we want to check if the entity name transform array does contain the entity name that we are checking currently. Here, we want to use the array contains action, and then we want to check the entity name transform. For the value, we want to create a new variable type of string. Let's just call this current entity. And we are going to set this value whenever we are saving the FSM objects, and we are going to grab the name of each FSM that is currently invoking, and we can compare this value here. And basically, we need to create two new local events. First one is add, and second one is replace. And let's add both of those transition at and replace. Basically, if the array does contain the name of the object, then we want to use the replace transition here on the event. We want to use the replace because we already have the data save previously, so we want to override it. And if the entity name transform does not have the name safe in its array, then we want to send the ad event here. Let's just create the ad state and the replaced state. Okay. So for the add state, I'm going to rename this two ad transform, and we want to use the array ad. For the array ad, we want to pick the name transform, and then we want to pass the current entity value as the new value that we are going to add to this array. And then we are going to also create another array ad here. And for this one, we want to add the position. We need to create also a new variable. And let's just call this current position. Later we are going to set this value. Then the last one, we want to add a rotation. Let's just pick the entity rotations array, and then for the value, we want to add the new variable called current rotation. Then we can just add finished transition whenever we are finished, adding those values to the arrays. Let's disconnect finish back to this loop all entity FSM. Then here we want to replace the transform. So once we found the name inside the array, we can save its index. So we need to save this to a new variable. Let's just call this current index. Then here, we can set the array based on its index, so we can use this ray set action. And here we only want to set the position and using the current index, and we want to set this to the current position variable. And for the other one that we want to set is the rotation. Let's just adjust this order, put the rotation below. Here for the array, let's just pick entity rotation, and then the index should be current index also, and for the value, we can use the current rotation. Now this replace the value if the entity that contains the object name that are currently recording its position. So let's just minimize this at a finish transition and connect this to the loop all it FSM state. So basically here, what is going to happen here. Whenever we trigger the state here, it will loop the entity saver FSM, and then when it's looping, it will invoke each FSM, and each FSM event will be invoked. The run action event will be invoked on that specific FSM, and on that FSM, the run actions will actually invoke this record position. After we are setting the current entity name, the position, and the rotation from that FSM from each of this FSM here. And now let's save this. And I'm going to add a finish transition from save all data to the start state here. And basically on start state, we need to initialize a couple of things. So let's just call this initialized and here, basically, we want to get the owner of this game object and save this to a new global variable. Let's just create a new global variable type of game object. Let's call this safe manager. And let's save this to the safe manager global variable. And this will make it easy to access the safe manager from other game object. And we want to create a button to test this functionality. So here on the Canvas under the button group, the inventory button here, I'm going to duplicate this inventory button twice. And the first one, I'm going to rename this to safe button. And the third one is going to be the load button, and we can remove the on click event on each of the button. And then let's expand the text game object here, and let's change its caption to save and this one to load, for example, let's save the scene again. And here on the save manager inside the initialized state, we want to add the UI button array action. And this makes it easier for us to pair a couple of buttons to trigger certain event here. So where is that? Okay, I put it on the wrong state, so let's just cut these actions. Go to initialize and then paste it here. And basically, we want to only access two button here. For the button, let's just expose the game object. So let's just type the safe button here, and the type be game object. And we can expose this. And I'm going to add a new category UI. And then let's just create a load button. And for the variable type, change this to game object. And let's also enable the input check box and add the UI category. So it's categorized nicely here in the Inspector. And now we can pick those variable for the safe button and the load button. But Load button, we haven't implemented that yet, so we are going to set up this later. But for safe, we can pick the safe event. Whenever this button gets pressed, it will trigger this safe event. And now we can put the load button and the safe button accordingly to the slot in the inspector here. Let's save the scene here. And now let's set up the safe and the FSM template for the object that are going to change in position during the gameplay. Now we need to create that custom action, so I'm going to create a temporary empty game object just to create these actions. So let's just add an FSM here. And for this FSM, I'm going to call this Action record Tit transform. Basically on the first state here, we can just We can just rename this two initialize. Inside this initialize, we want to get the name of the owner. Let's just use the get name here. And basically, we need to create a new variable called owner here and start the name to a new variable called tit name. And for the owner, we want to expose this as an input because this is going to be a custom action, so we can assign this variable from the run FSM action later. Here on the state here, whenever we finish initializing, we want to go to another state here, and basically we want to grab the transform. So let's just call this grab transform. And basically, we want to get the position, and then we also want to get the rotation. And here we want to get the position of its owner, so we can just specify game object because we are going to receive this value in this owner variable. And for the position, we want to save Sorry. For the position, let's just change the order here and set this also to the oder variable. For the position, we want to save this to a new variable called position, and make sure the space is rolled. And for the get rotation, we want to get its uler angles, and let's save this as rotation, and we can just minimize this. And now whenever we are finished, grabbing the transform, we want to go to another state. And we want to save this value into the safe manager. So here, first, we need to use the Set FSM string. And basically, we want to save or we want to send the name of this game object so we can set the value to the variable entity name. And for the variable name, it's called current entity on safe manager that we are checking against. And then we can leave the FSM name. Empty because safe manager only consists of one FSM. And here on the game object, we can specify game object, then we can pick the global safe manager. And this is why we are preparing the global variable to hold the safe manager to make it easier to access this from any actions that are going to communicate with the safe manager. Next thing that we want to add is that we want to add the set FSM factor three. So let's just use the set FSM factor three action. And then here, put it below. We can just pick the safe manager again. And for the name, it's going to be the current position and current rotation. So the first one, we can just type current position and sets its value to position. And then we can duplicate this action, and this is going to be the current rotation. And we can set its value to the rotation that we grabbed before. And now we have set all of the variable needed to be sa in the safe manager. We can send an event. To the Safe manager. Let's just pick game object FSM here, specify a game object, and then we can search for the safe manager in the global variable, and we want to send the record position global event. If we go to global event, we should be able to see this record position. And this will record the position of the owner of this action. Let's just save this as a template, and let's just call this action record entity transform. Now we have set this up. We can just delete this game object here. And now we can try this on our NPC move game object, and we want to create another FSM to record this. Here, let's just add let's add a new FSM here. Let's call this FSM record TT transform, for example. Here, on start, we want to get the owner. Let's just use the get owner action. And then we want to store into a new variable called owner, and we want to get the FSM component. Let's just get FSM component. I think this is custom action. Let's just open the ecosystem here. And I'm going to I'm going to type FSM component and we should be able to download the get component. This one here. Get FSM component. Let's just press, get. And now we have import the action. Let's just search for get FSM component. Now I have it. But this requires FSM name, so we want to create a new variable. And let's just call this this FSM name. And for the result, we need to save this to a Plam FSM variable. So let's just create a new object variable, and let's just call this this FSM. And for the type, let's change it to Playmaker FSM. And now we can save this to this FSM variable. And basically, we want to send this FSM to the entity FSM saver, global variable that we've created here when we are creating the safe manager. So now let's add an array ad action. And then here, we want to take the global entity saver FSM, and we want to add this FSM here. Let's just minimize all of this here. Now we want to create another state, and then we want to add a global transition run action, so we can use that the one that we have created before. Inside this run action, basically, we want to only use the FSM action. And then here we can pick the action record entity transform that we've just created. And for the owner, we can pick the variable owner that we've grab here on start. And let's edit this action, and I'm going to make sure that here on the SN event. I'm going to add a finish FSM action. And this is needed to stop the FSM from running whenever it's being used. So for example, here on the record entity transform, this will trigger the finish event. Okay. Let's just save this scene here. And now we need to create the load transform action. So let's just create the action. Now I'm going to create another anti game object. And I'm going to add an FSM here, and let's just call this action load entity transform. Basically here, on the first state, we want to get the FSM array from the safe manager. So let's get an FSM array here. Let's specify game object, pick the safe manager. And here we need to grab the let's take a look for a moment. The variable name. I'm going to rename this to entities, so we know it's an array to make it more clearer entities, and this so be also its and this is going to be also entities. Now we have saved this. Go back to the new game object, and on the first state here, let's pick the entities position and we can save this to a new variable with the same type, so we need to create those variable. Let's just call this entity position and create another one called entities rotation. And the last one is going to be the entity's name. For the name, let's set the type to string. For the position, it's going to be a vector t and the same goes with the rotation. It should be also a vector t. Now we have set up this array. Let's just store the values that we are getting from the safe manager to the safe position here. Let's duplicate this action, and let's grab the rotation this time and save it to the entities rotations. Let's minimize this. I'm going to copy this again, minimize the second one, and this one will be the name transform. Let's take a quick look here. Yeah, this entity's name transform. So this should be correct. And let's save this to the I think we need to reset this, so I'm going to reset this actions because it won't read the entity's name, because it was previously used for storing Vector three array variable. Let's just pick the entity's name and I'm going to retype the variable name here, and we want to specify the safe manager as the source FSM. Now we have set this all up. Let's just rename this go entities transform data. And here, let's add a finished transition, and we want to go to the next state here. And basically, we want to check states data. And here we can use the array contains again, and we want to check the entity's name variable, and we want to check against a new string that we are going to create, which is called entity name. If we do have the name inside these entity names, then we want to send a event here, and otherwise, we want to send the not found event here. And here, we can add load, and then we can add not found as the not contained event. Let's add both of those transition. And here, if it's loading, then we want to go to the state here below and we want to extract the transform data. Basically, when we are checking the name, we want to save the index here. So let's just create a new variable called index. And now we want to use the array gap. Action. And this will get a specific value from an array based on its index, so we can get its position, for example. And then we can get using its index to get the position and we can store the value to a new variable. Let's just call this position data. And we can duplicate this. For the second one, we want to iterate through to the entity's rotations, and we want to save this to a new variable called rotation data. Now we can just at a finished transition and go to the other state here, and we want to apply the data. Let's just call this apply data. And when we are applying the data, we need to create a new variable. Let's just add a set position action, and we want to create a new variable called entity, and then we want to set its position to the position data and make sure that the space is led, because we are saving in real space, and for the other action that we want to use is the set rotation. Here, we want to use the same game object, which is the entity, and we can paste the rotation data into the uler angles value here field and make sure the space is also rolled. And now we can minimize this action here. We can add a finish transition. And whenever it's finished, then we want to run the finish FSM action. Let's just rename this to finish action. If it's not found, then we want to go to a new state just for the bugging. The bug here. And we can add a D bug log and probably say warning, and we can send this to Unity log so we can see it on the console here. And we can type like entity Name is not found in transform record, for example. We know there is an error here and we can just add another finished transition and then connect to the finish action. Here, let's just call this get data and then apply data. And then we need to make sure that a couple of variable here are exposed as an input. First, the entity, we want to make sure this is an input variable and the entity name is also an input variable. So we need to send this value whenever we are using this action. Now we can just save the template here by pressing right click and then pick save template, and then we can just save this as action load entity transform. We can just use it because we are going to delete this anyway. Now on the NPC move here, we can add a new FSM. Let's just call this load entity transform. Here on start, we want to do the same as we did on the safe. So first, we want to get the owner and save this to any variable owner. And then we want to get the name. Let's just pick the owner variable and store this as the name variable. And then we want to minimize this, and we want to get FSM component again here. And for the FSM name, we need to create a new variable called this FSM name. Then for the result, we need to create a new object variable. S object variable here. Let's just call this this FSM. And for the result, we can pick this FSM. And then we want to add this FSM that we've grabbed using the Get FSM component to an array using ray ad, and here we need to create a new global array variable called entity loader FSM, and this would be a type of object, and then pick playmaker as the object type, and we want to add the FSM to this array here. Let's just pick the global entity loader FSM array, and then we can pass the di. Okay, this is an FSM object. I need to change the type. I forgot to change this. Let's change this FSM to the playmaker FSM. Yes, and then here, we should be able to pick this FSM, and we should be able to store this FSM to the entity loader FM. So now we need to add another state here for loading and add a global run action transition. And here inside this run action, we want to run an FSM. And for this FSM, we want to pick the action load entity transform. And this will ask for the entity game object, which is the owner, and for the name, we can just pass the name, and let's save this. And now we have set up the transform loader template on this NPC move here. This one here, we want to create a load mechanics in the safe manager. In order to do that, we need to add a new event. Let's call it load and make sure this is a global event. And let's create a new state for loading here. And basically, we want to load the data from this. So here I'm going to rename the state to load from disc. And I'm going to add a global transition peak load here. And here inside the initialize the button array, for this load button, we can send the event to load whenever we are clicking here. So let's just set this two load here. And now inside the load from this state, we want to use the Jasen load action. And basically, we want to do the same with the safe all data here. So for example, right now, we have three array variable, and this is the order, the name transform, the position, and the rotations. We want to make sure that we have the same order in our load action. So let's just set the same amount here. And for the first one, it should be the entity's name transform. The second one should be the position, and the third one would be the rotation. So basically, this will load the data from our JC that we saved in the disc before in this safe all data state. And this will load all of the data that are saved before, and then we can use this for the NPC or the objects that requires its recorded position and rotation. So now I'm going to add a finished transition, and we want to go to another state here. And basically, we want to loop the loader FSM. So in order to do that, we need to use the array gat next. Probably, I'm going to rename this loop all loader FSM. And here for the array, we can pick the globals and then pick the entity loader FSM. And then we want to store the current iterations to the results slot here. So let's just pick the current FSM. We can use this because it has the same data type playmaker FSM, and these are being used in the loop entity FSM here. So now when we have the result, we want to look through it and then invoke the run actions on each of these loader FSM. So here, let's just rename the state to invoke each FSM. Since the name has been used, then we can pick another one like invoke each loader FSM. And then inside this state here, we want to use the call method action. And then here, we want to use the variable, and we want to use the current FSM. And for the method, we can use the send event. And since we are using the run action to invoke the saver and the loader FSM. We can just type run action. L et's add a finished transition here. And let's connect this to the looping here. And basically, when it's looping, we want to go to the loop transition, and when it's finished, we want to add a finished transition and then set the finished event to the finished transition. And whenever we finish looping all of the loader FSM, then we want to go back to the start state here. So let's just save this. And now let's give this a try. So basically, the NPC move here, the record entity transform and the load titor transform, both are registering itself to the entity safer FSM and entity loader FSM. L et's check the settings here. We should have the FSM name expose. We haven't exposed that, so I'm going to expose the one on the load and the transform here. Set this as input, and then here we want to copy the name of the FSM. The same goes with the record entity transform. Let's just expose this FSM name variable, and we can just copy the record transform name into this field here and let's save this. Now let's give this a try. By default, when we are running the game, We should be able to see that this entity loader FSM will have a member now. So as you can see here, the entity saver has a FSM registered to the first element, and the same goes with the entity loader. It has this FSM. And this is referred to each one of these. Record will go to the entity saver and load it transform will go to the entity loader FSM. Right now, we have this registered. Let's try to interact with this police officer. And once he is moved, let's save the gain. There seems to be an issue here where it says that access path to. Let me check of this issue here. Okay. So I found the issue, and it was basically a silly mistake that I did. I haven't set the file name, so we need to set that. So I'm going to give this file name, Jason, Save Jason. And let's just duplicate this string here, copy and paste this on the load from this. So it has the same name as the safe action. H, sorry. I think it was cut before, so let's just paste this again, and I'm going to save the scene. And now we can test this But before that, let's make the record entity transform to a template and also the lot entity transform FSM. I'm going to delete the FSM name here, this variable here, and I'm going to save this as a template, and I'm going to call this template record transform. And we want to use the save template to this NPC move here. Now we can copy the name and paste this into this FSM name. And the same goes with the load entity transform. We want to save the template, and we want to rename this two template load transform. And basically, we want to copy the name to this variable slot here. And make sure that this FSM name is exposed so. In order to do that, we can just addit the template here and go to the variables and select this FSM name and make sure the input was checked because this was unchecked before, and I had to check this. And the same goes with the record entity transform. So if we dit this, make sure that this FSM name input option is checked, so we can set up the value in the inspector. So now we have saved the record entity transform and load entity transform into a template. We can use that also to the player. So let's add new FSM twice on the player. So we have two new FSM, and let's just call this record transform. And the second one will be the load transform. And we can use the template that we've just saved here, let's pick the template record transform, and this one will be the template load transform. Now we need to copy the name and paste this to the input field here, and the saving goes with the load transform and paste it here. Now let's save the scene, and now let's give this a try. So let's interact with this police officer and once it's finished moving, let's save the data. Now it's gets safe. And if we stop the game and we try this again, Let's try to load this. And as you can see, there, it loads the data of the police officer, as well, the player, and it loads both its position and its rotation. And now we can check the GSN data that we've saved on this here. So for example, I've already opened the folder. Basically, it's on my user name, app data, Local. And since I haven't changed the default company name in the player setting, so it's in the default company and the project name playmaker point and click. And this is the save data. If I open this, As you can see here, we have a JCN but it's not formated correctly, so we can just copy this. If we want to see in a formatted manner, and we can go to this website. It's called jcnlin.com. We can paste the data and validate the JCN as you can see, it will format the JCN correctly, and the entities name transform array has two string values, the player name and the NTC move name. And both the position and also the rotation also have two vector values for its position and its rotation. And as you can see here, this entries corresponds to each entity transform. So for example, the first one would be the player position, and the second one will be the NPC position, and the same goes with the rotation. The first one is the player rotation, and the second one is the NPC rotation. And as you can see here, using this approach, we can get the index from the name transform and using that index, we can access the position and the rotation. So that is basically how we set up the safe system for the transform, and we'll also work on the safe system to save the states on each NPC because there will be different states on the NPC depending on the face or on the moment of the game. For example, if we give an item or if we take an item from an NPC. 23. 22 Record Entity State: Now, let's continue to work on our safe system, and this time, we want to create the record state action. So here we want to save the dialogue state here. So, for example, here on the NPC dialogue, we have the three actions that are assigned in the interactable component. And right now, the one that it's enabled, it's the based dialogue. And yes, response is disabled actually here, as you can see, and the same goes with no response. It is disabled. And we want to save this value for all of the FSM that are assigned in the interactable FSM here. So we want to save the state. And in order to do that, let's create a new action. So I'm going to create an anti game object. This way, I can create an FSM, and we can save this as a template right away. And basically on the first state, we want to initialize. And we want to use the set string value because we are going to save those FSM states value in a string. That's why we need to create a new string here. And let's just call this FSM states. And let's clear it. So we want to set an empty value on the string value. This will clear it. And then we want to get the name of the owner. So let's just use the get name action. And here we can create a new variable. Let's just call this owner and put this below the set string, and we want to store the name, and let's just call this entity name. And basically the owner variable, we want to expose this. So let's just expose this under the input option here. And then we can finish the state here, and then we want to go to the next state. And basically, we want to look through the FSM. Look through the FSMs that are assigned here on the interactable FSM. So in order to do that, we need to create an array variable type of playmaker FSM. So let's just create an array. And let's just call this FSM list. And for the type, let's change this two object and set the object type to playmaker FSM, and we want to expose this. Okay, now that we have created this array, let's just look through that array, and we can use the array get next. And basically, we want to pick the FSM list here and we want to loop the event. We don't need to change the start and end index. This will loop through all of the members of this FSM list. Let's add a loop event, and I'm going to add the loop transition as well the finished transition here. And when it's looping, we want to go to the Loop event, and if it's finished, we want to go to the finished event. So loop here, we want to go to the other state to a new state here, and we can call this get FSM active state, for example. Now that we are looking through the FSM list, we need to save this two A variable, so let's just create a new variable, and let's just call this current FSM. And then here in the GT FSM active state here, we want to use the GT property. Get property and set property is actually using reflection, and this is a bit slow, but if we use it only once, every couple of times, for example, we don't use it in an update or every frame state, then we should be okay. Another note that we want to avoid using Get and Set property when building for mobile platform because not all mobile platform supports this reflection. Okay, so now we want to pick the current FSM here. And basically, we want just to get the enabled properties here, and we want to store the value to the new variable, new Bullion variable. And let's just call this FSM enable state. And now we have a bul in value. We need to convert this two A string. So in order to do that, we can use the convert bull to string action. Here, we can just pick the bullion that we've just created, and we need to store the value into a new temporary string variable. Let's just create the variable, and we can just call this state in string. And for the false string, we want to set this 20, and for the true string, we want to set this 21, and we want to put this below the gut property and then we want to use the built string action to build the state string that we are going to save in our save system. So basically, we want to set the string part to, and then we can get the FSM states, the one that we've cleared in the initialized state here. And then we want to set the second element to state in string. So this will save this value to the FSM state, and we want to store the result back to the FSM state string. This way, when we are looping this FSM here, on the next iteration, the state in string will be added after the previous value that been saved in the previous iteration. So now we can just disable this at two N, for example, because we are not using separators, so we can just uncheck this. And now that we are done here, let's add a finished transition. And let's go back to the loop state. And basically, when we are finished, we want to go to another state here, and then we want to send the states to save manager. Or we can just call it two manager. Okay, so now here in the state here, we want to set an FSM string. And basically, we want to specify the safe manager game object, so we can go to the Globals, pick Safe manager. And here we want to save the value, but this is something that we haven't specified yet. So let's just save the scene here, and let's go to the Safe manager. And basically here on the Safe Manager, we want to add the mechanics to record states. So first, we want to create a new state to record the states. I'm going to create new one here, and let's just call this Cech entity name for states because we already used this here and let's just rename this two for transform because this is the one for recording the position. So we want to check the name from the transform list. And here, we want to create a new global event, and let's call this record state. And let's set this as a global event. Let's add a global transition here and pick the record state that we've just created. And basically, we want to add two transition, add and replace, similar to what we've done with this record position. And here, basically, we want to check if an array contains the name that we are sending from the action that we've created before. So let's just use the array contains here. And basically, we want to create a new variable in this case. So let's just create a new entity's name states, for example, and let's set this to an array, and this should be a type of string. So let's just sorry. We can pick it right away here. We don't need to pick object, so let's just set this to string. And then we want to check this array if it's contain the current entity that we are recording. So we need to create this variable also and this will be set from the action that we are currently creating here. So going back to the Safe manager. Let's just call the Oh, we already have the variable current entity. So we are going to use the same one that we are using here on the record position. Okay. Now let's just pick current entity here, and then we want to grab the index, so we can pick the current index, and we can use the same variable because recording states and re position almost never happens at the same time. So we can reuse the variable. And then we can just go to a different states here. For adding, we want to add a new entry, so we can just use the array add action. The first one, we want to add the current entity name into the name state. So let's just pick the current entity variable as the value and the array entity's name state, and this will add the value if the current entity exists or doesn't contained in the entity name state. And then we want to add the data here. Let's just now we need to create another array of strings that are going to save the active stats FSM that we are saving. In order to do that, let's just go to the variable tab here and pick array type, and we want to call this NTT states, for example. This should be also a type of string. Since we are passing the states into a string to a value of zero and one, and then we can just pick the entity states data, and then we want to create a new variable in this case, let's just call this current states data. And now we have this. We want to add a finished transition, whenever it's finished, go back to the safe state here. And for the other state, we want to replace the value. Here on the second state, we can use the array Set action, and here in the ray set action, we can just grab the entity states data. And since we are checking if it's contains and if it's contained, then we are saving the index, then we can use the index, which is in the current index variable, and we want to set the value to the current state data. Now let's just save this and then go back to the first state. We going to rename the state here at states data, and for the other one, we are going to rename this to replace states data. Now we are done with the record states. We can continue defining the action here, and now we can send the variable name, which is going to be the I think it's let's check. It's the current state data that we want to send here. So let's just sec here and copy the name, and let's go back to game object. And here we want to set the variable name to this here, and we want to set the value that we've built here, the FSM states, the one that we are building in the build string here. And then we want to also set the name of the current entity that are currently recording, for example. So let's just use the set FSM string. The same goes with the game object. We want to pick the save manager. For the variable, it's called current entity because we want to send the entity name here, and here we can pick the entity name that we are saving in the initialized state here. Now we have set up the data, the states data and the entity name. Now we want to send an event here. Let's just use the send event action. And we need to specify game object FSM, specify a game object, and then pick the safe manager again here, and we can use the global event record states. And then we want to add the finished FSM states. Okay. So to make sure that when we are sending, we already finished saving or setting the FSM string, let's make this an action sequence state, and this will make sure the order of the execution of each actions are going to be in this actions order. So let's save the scene. Now let's convert this 28 template. And let's just call this action. Record entity states, and we can use it. It doesn't really matter, actually. And we can just delete this, and now we can use it. But before that, let's create the it stats action. 24. 23 Load Entity State: And now let's create the load action for the entity state here. I'm going to create another anti game object, and let's create a new FSM on this anti game object. And now let's set up the action that we are going to create. So the first state, let's just call this GT entities states. And basically here, we want to get an FSM array. And we want to pick the safe manager. And we want to get the entities states array. And for the value variable, we need to create one here. Let's create an array of string. Let's just call this the same name, so we are not confused. States data, and we will also need to create another string of array that will hold the entity's name. So let's just change this to a string, and this will be the states name. For a type, let's set this to string. And basically, we want to save this entity states data to the entity states data. And let's check the safe manager. Okay. Here, we have the entity's name states. So we want to use this array. Let's just copy the name. And then go back to this game object here, and we want to get FSM array again. Pick the safe manager again. And then for the variable name, let's just paste the variable name that I've copied earlier, and under the store value, we want to save it to the state's name here. I don't think we need to use copy values, so let's just uncheck this and minimize this. And let's add a finish transition. Go to a new state here, and we want to check the state's data. And basically here on the check states data, we want to check if the array or the entities array that contains the name of the entities that are sending this action. Let's just use the array contains And here we want to check the entity states name, and we want to check against the variable that we are going to create. Let's just call this entity name. And for this entity name, we need to expose this. Let's just select the variable and then expose via input checkbox. And we will also need to create another array type of FSM. Let's just call this FSM list. And change the type to object so we can select the playmaker FSM type, and we want to also expose this one here. And go back here. We want to save the index if the entity name is found inside this entity state name. Let's create a new variable called index, and we want to create two new event here. The first one will be load. The second one will be not found, for example. Here, let's add the load transition and the not found transition. A And basically, if it's contained, then we want to go to the load event, and if it's not contained, then we want to go to the not found, so we can debug this. And for the load, let's just create a new state, and we want to extract state data. And here inside the extract states data, we want to use the array get action, and we want to pick the entity states data, and we want to get the member from the index that we've grabbed when we are checking this states data here. And then we want to save this to a new variable, let's just call this loaded states data. And then we want to reset the index value here because we are going to reuse this variable. So let's just use a set integer value action, and let's pick the index variable and set this 20. And now let's add a finished transition, and then we need to go to a new states. And here, basically, we want to process State data. Inside the state here, we want to get the length of the string that we've extract here, the loaded states data because this is going to be a string. Now we can use the get string length, and let's grab the loaded states data and we want to save the result into a new variable called data length. And when we are finish getting the string length, we want to add a finished transition, and then now we want to look through this string. So here, we can just call this loop state data. And here, basically, we want to use the loop action, and we look through an integer that we are passing here, so we can use the data length, and this will look through how many character we have on the loaded states data. And basically, we want to store the current loop into an integer, which is index that we've reset here. It starts from zero, and then we want to add a custom event loop. Sorry, not load, but it should be transition event, custom event loop. And at a finished transition. And for loop, we want to go down here to a new state, and we want to set the FSM state. So here, basically, we want to get the substring of our data. We can use the get substring action, and then we want to get the loaded states data. And then for the start index, we want to use the index that we are currently looping and the length one would be enough, so we want to only get one character on the index, and now we can save this result into a new variable called current value, for example, and now we need to parse the string into A B. So in order to do that, we need to use the string compare. And here we need to put this below the gat substring, and now we want to compare the current value. And for the current value. We want to check if the value is one, and we don't need the equal and not equal event, so let's just leave this empty. And for the store result, we want to save this to a new bleion variable. So let's just call this ble state. And basically, if the current value is one, then this will be true. Other than that, it will be false, and we can use this bleion state to enable or disable the FSM from the FSM list. So here, we want to use the array gt and basically, we want to get from the FSM list. And for the index, we can use the same index that we are currently looping because basically the index will represent the states the FSM states that were previously saved. So the index should be the same. And now when we are getting the FSM list, we can save this into a new variable called current FSM, for example, and this will be the type of play makeer FSMS you can see here. And now after we are getting the array, we want to use the set property action. And let's just pick this one here. And then we want to set the property from the current FSM here and pick the enabled state, and for the value, we want to use variable and then pick the bull state. And this will enable or disable depending on the Boulan state when we are comparing here. So now that we are finish setting the FSM, we can add a finished transition, and then we can go back to the loop states here and on the finish state, we can go to next state. Basically in this state here, we only want to finish this FSM, so it will finish running. And now that we have set up the no found, we want to debug this. Let's just create a new state, and let's just call this the bug. Inside this the bug here, we want to use the debug log. And for the log level, we can change this two warning and we can send a text like entry or entity is not found in the saved states that, for example. And then we can enable the sent to Unit log so we can see on the console here. At a finished transition, and then let's go to the finished state here. Now let's save the scene and we have this action set up. Let's check the variable, and we basically need to make sure that this entity name and FSM list is exposed. So we have done that. And now let's save this as template, and I'm going to call this action load, entity states We can just use it doesn't really matter and we can bled this. Now we need to set up the NPC dialogue here. Basically, we need to create a new FSM. Let's just add a plan maker FSM. Let's just call this record states, and let's add this here. In the record FSM, we need to create a new string variable. And let's call this FSM name. And let's expose this string variable. And go back to the state here on this first state. We want to get the owner. So let's just use the get owner action. And here we can save this to a new variable. Let's just call this owner. And basically, we want to get FSM array. And we can just use the owner because basically we want to get this array of actions here on the interactable, and we don't need to set up the name. We can just search for the variable name, and this will search through all of the FSM in the owner in the same level of this NPC dialogue, so it will check the neighboring FSM. And then we want to store this to a new array variable that we need to create. So let's just create an array variable, and let's just call this FSM list. For the type, we want to change this to object and then select playmaker FSM. Here, we want to save this to FSM list. And we don't need to copy the value. So let's just uncheck that. And then we want to use the get FSM component. And this is basically an actions from ecosystem we have downloaded in the previous video. If you can found this get FSM component, you can just search in the ecosystem. And basically, we want to use owner. We want to pick we want to select use owner in the game object sections here field. And for the FSM name, we want to use this FSM name, and for the result, we need to create a new object variable, and let's just call this this FSM. And for the type, this needs to be playmaker FSM. And we want to save the FSM to this FSM variable here. And basically, we want to add this FSM that we've grabbed using the Get FSM component to a global array variable, which is the entity saver FSM, and Basically, every template FSM, either for recording states or recording transform on initialized. On start, we need to save the FSM reference to this entity saver array, and this is the arrays that are being looped by the safe manager whenever it wants to save something and the loader counterpart is being used when it's going to load the data. So yeah, we need to save reference of the FSMs that are going to be recorded. And now we can add a new states here, and we can just call the save here. And we can add a global transition custom events, and we are going to use the run action here. And basically here we only want to run an FSM. So we can just do that easily here. And for the template, we are going to select the actions record entity states. And for the FSM list, we can just use variable and then pass the FSM list that we've grab here. And for the owner, we can just send the owner, and we can save the scene here and let's save this as a template, and let's just call this template record states. We can use template here, and now basically on this FSM name, the variable that we've exposed, we need to copy the name of the FSM. And now we need to create the load states template. Let's just add another playmaker FSM, and let's just call this load states, and similar to record states template. We want to initialize this first. We can just use the get owner r to make things faster, we can just paste template here. Use the template record states, and now it is paste. Let's just delete these actions. And the start should move to the state two here, and let's just call this in it. Now we have all of the actions that we need, but instead of saving, we want to load here, and for loading, basically, we want to use the actions entity states, and we need the entity name here. So we can just convert from the owner, and owner will be a game object, but we can convert this value and it will be saved into the entity name. And here for the FSM list, we can just pick the FSM list here, and this should work. And now that we have set this up, let's save this as a template also. And let's just call this template load states, and let's save this use the safe template, and then we can copy this FSM name into this FSM name slots. Now we have set this up. Now let's take a look and let's test this out. Here on the safe manager, let's zoom this a bit. Yeah, there's a couple of things that I forgot to set up here. And basically here on the tech entity name for states here, we haven't set up the contained and not contain event. So we need to do that. And if it's contained, we want to go to replace, and if it's not contained, then we want to go to add, and this will make sure that the data are being saved correctly in the array. And here on the save all data. Basically, we haven't saved the additional array that we need to save load. So we need to change this amount to five because we have two new additional array, and this would be the name states and the fourth or the fifth one should be the entity states data. And this way we are going to save all of the array that are being processed in the record states. And the same goes with the load from this here. We need to also change this array variable amount, and we need to add the entity name states and the entity states data. And this needs to be in the same order with the safe actions. So if it's name transform, position, rotation, name states and states data, then this should be also the same name transform position rotation, name state, states data. So, we have fixed those and now We need to also fix one other thing that I did by mistake here on the load state template because we are pasting from the safe states. In the initialized states here, I forgot to change the array. Variable here. We should be adding this FSM to the loader instead FSM because this is basically a template two load state. So we need to put this FSM in the loader FSM array list. So now we have fixed those things and save this. And there is also one thing that we forgot to set up here on the action load entity states here. If we edit this, on the loop state data here, we haven't set up the event. So we need to set this two loop here, and if it's finished, we need to go to the finish event. Now let's save the scene, and now let's save the project, and let's give this a try. So let's talk to this MPC here, It should give that's great response. So let's just save. And now let's stop the game, and then let's run this again, and now let's try to load it. It's loaded, and let's talk to this MPC here. Okay. There you go. It says that's great. Now if we try to create a new safe here, And then let's talk to this NPC and it will go and then talk to this person here, and let's just respond to the other. Okay let's just save this, and if we stop, and then if we run this again, we should be able to sorry, let's just stop and then load. We need to fix this bug because it will always go to the last destination, but now we can just top the game first and we are going to address this. Now let's press load here, and if we talk, it will mention get well soon. So it will record the states of the conversation that we have on an NPCs. Now we have implemented the record transform and record states. The last thing that we need to implement is the record inventory. 25. 24 Record Inventory: Hi. In this video, we are going to implement the safe system for the inventory, so we can keep track the changes in the inventory and we can save it to this, and we can load all of those inventory in the next session of the gameplay. So in order to do that, first, we will need to create a global array variables that will hold all of the items available in the game. So now let's just create sory Here under the new variable window, let's create new inventory database variable. And this will be a type of array. And the type will be the item. This is the custom variable that we have defined, which is an item class. And we want to populate this array with every item available in this games. So I'm going to set this 23, for example, under the projects that and items, we should have these items. And we only have two so far, so I'm going to put two of them here and then set this size to two for now. So basically, this is the item reference that we can look whenever we are loading later because basically we can only save the grid data of the items. For example, if I highlight an item here, we can only save this grid string data. So we will keep track what item that we have by saving this grid into a new array of string in the safe manager. Okay, now we have created this new variable. Let's select the save manager. And then under the playmaker editor, we want to create a new states to handle this. So basically, when we are finished looping all of the entity FSM instead going to the save all data state, we want to go to another state first. And here, basically we will save the inventory. So the next thing that we want to do is we want to create a new variable. And let's just call this inventory grids. Since we are going to save this grids into this array, and let's pick an array, and for the type, this can be a string. And now basically here on the state here, we want to remove or clear the array. So we want to use the array remove all. And we are not using clear because clear basically just clear the value on every entry, but it will keep the size and remove all, basically, we'll delete all of the entry, and we'll make the array size back to zero. So we want to do that. Let's pick inventory guilt and we want to clear inventory goods, for example, here we want to add a finished transition. And then on the next stage. We want to loop our in array item for any item that currently the player have, so we can use the array get next here. And then we can pick the global variable inventory, and we need to add a loop transition and a finished transition. And let's rename the state here to loop inventory. And for the loop event, we want to go to the loop transition and the same with finished event, we want to go to the finished event. And we want to save the resulting or the member the entry that we are getting to a single variable of item. So let's just create a new variable. And let's just call this current item. And next, we want to go to the loop state here. And when we are looping, we want to get its grid and save it. So let's just call this safe item grid and here, basically, we want to use the get property action. And we can pick the current item FSM, and then we can get the grid and get the string. And let's just save this to a new variable, and let's call this current item grid. And then we want to add this value to the inventory grid that we are clearing here. So let's just use the array ad. And for the array, we can pick the inventory grids, and for the value, we can use the current item gods. Basically, this will save the grid that we've retrieved from the current item and save this to the array of string here. And when this finish, we want to go back to loop inventory, and then once the loop is finished, then we want to save all of the data here. We want to go to the save all data. And basically, we need to add an entry here. And we want to save the inventory grids to the safe file that we are saving using this G and safe action. Now we have created the safe mechanics. Next, we need to create the load mechanics. And basically, we are going to do the same as save mechanics. But instead of getting all of the items, we are going to parse all of the guids that we load from the disc. So here in the load from this state, we need to increase the array variable amount to six, and then we want to load the sixth member 115 to the inventory g ray variable here. And this will load the string of guids to this array, and then we can loop this on a new state when we are finished looping all of the loader FSM here. So instead of going to the initialize, we want to go to a new state first here, and we want to clear previous inventory. And here, basically, we want to use the array remove all, and we want to remove the inventory in the global variable. So we want to clear the inventory right now because we are going to look through all of the goods, and we're going to re add those items from the safe data into the inventory. So if we don't remove it, then we might have double items as a bug as a resulting bug because we are not clearing the inventory first. So now when we finish or removing all of the inventory, we can go to a new state here. And then we want to look through the grids that we've saved. So we can call this loop grids, and here, as usual, we can use the array get next, and then we can pick the inventory goods variable, and as usual, we need to add the loop and finish transition for looping and array. And let's set the event accordingly. And here we want to save the resulting to the current item good. And when looking, we want to go to another state here. And basically, we want to look the item database here, and this is where we will need the inventory database on the global variable here. So basically, we want to add a ray get next again, and we want to look through the global inventory database, and we need to add the loop and finish transition. So basically, this is a nested loop. First, we are looping the gits and while we are looping the gits, we are also looping the item database here and set the event accordingly. And then save the result to current item because this is going to be a type of item class. And then when we look both of this value, the g and the grids and the item database, we want to compare the grids. Here, basically, we want to rename this to compare GIDs, and then we want to use the GT property action. Then we want to get the current item and we want to get its grid and store the grid to a new variable, and we cannot reuse the current item grid because we want to compare this value with the variable current item grid. Let's just call this compare grid. Let's minimize this and let's add the string com action. Here we can compare the current item grid that we are evaluating here. With the grid that we are grabbing from the current item from the item database. Let's use variable here, and then let's use the compared guid and basically, we can reuse the event that we have here. If it's equal, then we want to add the item, so let's just use ad and if it's not equal, then we want to use the finish event here. Let's add both the add event and finished transition. Now we have both transitions added. When adding the item, we want to go to a new state here, and then we want to add item to inventory. Here, basically, we want to only use the array add action. And then we want to pick the inventory array from the Goble variables, and we want to add the current item. Because when we are getting the current item, here we are comparing the grid of the current item that we are evaluating from the grid and with the compared grid, which we retrieve from the current item here. So if it's equal, then that is the item that we are looking for. Hence, we can add the item to our inventory here. Now let's just add a finished transition. And when we finish here, we want to Go back to the loop item database here. Here in the compared grids, if it's finished, then it means it's not equal, then we want to go back to the loop item database also. So we will check for another entry. And then if the loop item database is finished, we want to go back to the loop goods. Basically, this will look through the next goods and it will do the same again. I will look through the item database to find a match. And when we are finished looping the goods, then we want to go to the new state where we are going to refresh the inventory. Here, let's just call this refresh inventory. Inside this refreshed inventory state, we want to use the send event action. And for the target, this is going to be game object FSM, and we can specify the game object here. We can select the variable, and under the globals, we can access the inventory manager because we want to send the refresh event. Here under the send global event, we should have the refreshed inventory events exposed, and then this should be all here. And here after its finished refreshing the inventory, then we want to go back to the initialized state. And let's save this. And now let's test this out. So I'm going to press play. Okay, now it's running. Let's check our inventory. We don't we have a lighter. And now let's talk to this person here. Okay, I don't want to give my lighter. I want to instead of, I want to get the key from this NPC here. Okay. Now we have this key here. Let's check our inventory. Okay. Yes, we have the key. Now let's save this. And then let's stop the game, and let's play it again. And let's load the game and check our inventory. And there you go. We have the lighter and our key loaded because basically when we're starting a new game, for example, here, we should have only the lighter. And if we check the safe, the JC safe data, let me just open the file first here. We can see here, but we need to parse this, so I'm going to copy all of this here and we'll open my browser, and let's open the Json Lind website here and validate this. Now we should have a inventory quids variable here, and we should have the goods saved. And we can check this because this is start with one F A 22 here, let's just take a look. Basically on our key or the lighter, yes, the lighter has that grid, that correct grid. And sorry, not this one here, but this one. The second one start with 30 38f7. So if we check this, we should be able to see it on our key. Yeah. K. Yeah, that is basically how we save a inventory by utilizing the database here and saving its gid. And that's why we are having this grid value to make it easier to keep track of things because this grid value is going to be unique, and it has very small chances that are generating the same exact grid on two occasions. We can easily use this to make a unique identifier. 26. 25 Audio and Animation Action: In this video, we are going to create another interactable action such as playing audio and playing animations on NPC. But before we start to do that, let's pause this video, and I'll give you a challenge. Try to create the actions yourself and let me know how it goes in the QN A section. Okay, so now I'm going to show you how to create these actions. I hope you succeeded in your challenge on how to create since we have been creating a lot of custom template and actions in the previous lessons. So this one should be very straightforward. Okay, so now, the first thing that we want to try is we want to try to create an audio whenever we are interacting with an NPC. So, for example, if we talk to this NPC dialogue person here, we want to play an audio. So first, let's go to the scene here, and then let's add a new FSM. I'm going to create a empty child game object. And this will be the talking audio. And I'm going to add a new FSM here. Opening the playmaker editor, let's create the Play audio template FSM here. I'm going to rename this to play Audio template. And I'm going to add a audio clip variable, and this will be the Audio, and we can expose this. It's available in the Inspector. And here, let's create a new state and let's rename this state to play Audio. And we can just add a global transition from the custom event. Let's pick the run actions. And with this setup, we should be able to execute this FSM via the interactable FSM. So here in the play audio state, let's add play sound action, and we have play audio play and play sound. Basically, the difference is that audio play requires an audio source in the object, but play sound does not require audio source, and it will create a temporary instance when playing an audio, and then it will gets destroyed after the audio is being played. So I'm going to use the play sound instead to make things simpler, but this sound is going to be a treat sound, so it will be relative to the game object position, which is what we wanted. And Another thing that I want to do is I want to remove the audio listener from the main camera, and instead, I'm going to put the audio listener on the player game object. So all of the sound will be relative to the player position. Here. Okay. So now let's go back to the talking audio, game object here, and here, let's just select to use Variable and pick the Audio variable. And now we have created the FSM. Next, I want to convert this to a template. So let's just pick safe template, and I'm going to call this template play Audio. And we can use the safe template in this FSM here. And now we can just pick any audio. So for this example, I'm going to use the mail A dialogue here. And next, let's create the template that plays custom animations on an MPC. So in order to do that, let's just create another empty game object here. And let's just call this trigger animation. And here, let's add a new FSM on the trigger animation scape object. And here we can add a new states. And for the second state, let's just call this play custom animation. And let's add a global transition, custom event, and pi run action. And here we can use the set animator trigger. But set animator trigger requires a game object that have an animator component attached to it. So in order to work with this warning, we need to create a new variable, a type of game object, and let's just call this animator. And we want to expose this so we can select the animator game object easily via the inspector. And the other thing that we need is a string variable, and this is going to be the animator trigger. And we want to also expose this. So now we can set to specify game object here under the game object, and then we can pick the variable that we've implemented here, animator. And for the trigger, we want to also use a variable, and this time we want to pick animator trigger. So this should work, but we need to assign this correctly. So first, we need to prepare an NPC model for this NPC dialogue here. So the first thing that I want to do is I want to remove the capsule component here and also the mess render, And then let's just grab one of the character from this TTD move folder, and under the prefep, I'm going to grab the male A here. And let's put this as a child game object of the NPC dialogue. And now let's set this 20 on the y axis, it's rotations. And for the position, I'm going to set this two negative one. So it aligns with the dialog capsule collider there. And now we have this game object or this model attached to it. We can use this animator as a trigger animation. So let's just drag the game object to the animator slot here. And now we need to use a controller. So I'm going to pick P Controller here, and we can add a new animations inside of it. So here inside the animator, when we are selecting this, we should be able to see the P Controller animator, but right now we are inside the idle walk plan tree. So let's go to the base layer here, and we can create a new state. And for example, let's call this state talking. And we can create transition from the bland t or the default animation to the talking state. So let's make a transition, and we want to also create a transition to go back from the talking to the idle walk state here. So first, when we are entering the talking, we want to trigger the state when certain parameters is triggered. So in this case, we want to add a trigger parameter, and let's just call this talk. And we can use this trigger to trigger the talking animation. So with the transition from the idle to walk to talking is selected. Here under the inspector, we should be able to add a condition, and now we can select a couple of parameters that we have created. In this case, we have speed, which is a type of float, and we have t which is a type of trigger. In this case, I'm going to use the trigger one, which is talk so we can just select talk trigger. And we can disable the has exit animations. So the transition will occurs instantly, whenever we are whatever state we are playing before. It will go to the talking animation directly. And for the state or the transition from talking to the idle walk state, we just want to use the has exit time, and we don't need to put any conditions. And in this case, this will let the talking animations play until the end, and then it will go back to the idle walk state here. So now we have this trigger defined. We can go back to the game view here, and under the trigger animations, we can use the top trigger. So let's just type this, and this is case sensitive. So for example, if we type it this way, then I need to make sure that I also type it the same way down to the capitalization. So let's just rename this because I type it incorrectly before. And let's save this. Okay. So the next thing that we want to do is we want to trigger this animation. So here on the interactable FSM, we can increase the size of the actions, and then we can drag the trigger animation. And this will always be triggered because we don't change this FSM enable status since we are not adding this on the yes activate and the activate FSM. So we don't change the FSM activate status. And this worked well with our intention because we want to make sure that every time we talk with this NPC, the NPC plays the animations. And we also need to trigger the talking audio, and we haven't done that. So let's go back to the NPC dialogue here and add more actions here, and we can drag the talking audio game object to one of the slot here. Okay, let's save this. And now let's give this a try. Okay. Let's talk to this NPC here. Could you be go home. Okay. So Could you be. I go jump. Shu k m f. Okay, there seems to be an issue with the animations. Let's just inspect this whenever we try to talk. Could you be jump Shook Op. So we need to fix this issue. Let's check this out. Here, if we select the game object that has the people controller animator, we can open the animation window under the animation and pick the animations, not the animator. And now if we duck this below here, if we pick the other animations. We don't see it. Okay. This is my mistake. I forgot to assign an animation. So here, let's just select the game object with the animator controller and open the animator window. And I haven't set anyimations in this. So by selecting the talking state, we can we can assign a motion in the inspector. Let's just press this button, and I'm going to pick the male handshake animations. And if you have imported the every day motion pack free from the asset store, you should be able to find these animations in your project. Okay, so now let's go back to the game view here and let's give this another try. Could you be. Jump Shook feet. It plays the animations quite well, and it's synchronize also with the audio playing. Could you be? I go jump. Shoot K O feet. Okay. So yeah, I hope you managed to do this template actions by yourself. And if you manage to do it, then you should be able to create any custom FSM that can be triggered when a player is interacting to a certain NPC or to a certain object even to another object other than NPC, such as like a door or cabinet, for example, we can trigger some animations. 27. 26 Camera Manager: Hi, in this video, we are going to create a camera manager and a camera switcher. So this camera manager will handle all of the camera in our scene. It will receive registrations from each of the camera, and then we can create some sort of a trigger area to change camera when player enters a certain area. So in order to do that, let's create a new empty game object for the camera manager. Here on the scene, I'm going to create a new empty, and let's call this camera Manager. And we want to group all of this manager into one game object under one game object. So let's create another anti game object. Let's reset it, and let's just call this managers, and I'm going to put this game object on the top of this hierarchy. And I'm going to direct the safe manager to become the child of this manager game object. And the same goes with the camera manager. I'm going to direct this game object also to be the child of this manager's game object. In this way, we will have a nicer or a much organized scene here, and we know where to search for our manager. So let's save the scene here and I'm going to reset the transform of this camera manager. You don't need to do that. It's just I'm a bit obsessive compulsive with these values. And now let's create the FSM for this camera manager. So in order to do that, let's right click here and add the new FSM, and we can just call this camera manager as the name here. And then the first thing that we want to do is we want to create a global game object variable to store reference to this camera manager. So other game object can easily reference to the game object of the camera manager. So let's just select a variable type here, and then select game object, and let's just call this camera manager. And now we have a couple of manager. It's better to create a category for it. So let's just create a new category called Manager. Now as you can see, the camera manager Variable is under the manager category, and we can select the other manager like Safe manager here, and now we can pick a category here, and it will group the variable in the same category. This makes things easier to see or to navigate. And then I want to do the same with the inventory manager. And now let's also do the same with the dialogue manager. Okay. So now we have organized the Manager Variable game object. Let's save the scene again, and let's save the project this time because we want to save this global settings here. And now back to the camera manager FSM. On the first state, let's rename the state to initialize. And basically, this is for initializing the camera manager here. And inside this initialized state, basically, we just want to get the owner. So this is too big. Let's minimize this. Okay. And now we want to use the get owner action. So let's type get owner. And then for the get owner, we don't need the send event. I'm going to remove this. And for the get owner, we want to store the game object to the camera manager under the global variable here. So let's just do that here. And now we need to create a new state, and this is for registering the camera. And we want to create a new global event called ad and a local event called register camera. And basically, we want to make sure that we check this check mark for the add event. Here, under the registering camera, let's create a global transition, and let's pick the ad event. Let's add a local transition or a normal transition, and let's pick the registered camera. And on the variables, we need to create a couple of variables. So let's go to the variable step here, and I'm going to create an array variable. And this is going to be called cameras, and this would be a type of game object. Then we need to also create two new game object variable, a single variable, so as a pick game object, and this is going to be the active camera. For the second one, we want to create a variable called current camera. Okay. Now here back to the registering camera state. We want to use the array contains actions, basically, whenever we are Registering a camera, we are going to set the camera that are registering as a cur camera game object. And then we want to check if the cameras variable or the cameras array, already have the current camera as a member in it. So we need to use the array contents here. So before adding a new cameras, we want to check if that camera is already inside the cameras array. So here, let's just pick the current camera, and if it's contained, we want to stay in the state, but if it's not contained, then we want to go to the register camera, and we will need to create a new state here. And basically on this state here, we want to add the camera to the array. Let's just rename it to add camera. And we can use the array add action. And for the array, let's just pick the cameras, and for the value, we can just pass the current camera game object variable. Basically here in the state, if the camera already have the current camera that is registering, then we are going to prevent the camera to be added to the cameras array, resulting duplicates entry in the array. So this is to prevent duplicate entries and The next thing that we want to do is we want to create a new state, and the state is for switching the camera. So let's just call this loop state. And how this switching camera works is basically, we want to disable all of the camera inside the cameras array. And when we are finished looping all of those camera and disabling those camera, we want to go to the finished state and then to a new state, and we want to activate the active camera. The only one camera that should be active when switching the camera. So here we need to create a new global event. Let's create one, and let's just call this switch camera. And make this a global event. And then here on the loop state here, we want to add a global transition switch camera. Then we need to add a loop transition, so let's create local transitions, and we can use custom event, and we can search for loop. Because we have created this event on other FSM, so we can access it via the custom event menu. And we want to also add a finish transition here. And basically, for looping, we are going to use the array get next as usual. And we can just pick the cameras here. And for the looping, let's just pick loop here for the finish event, we can select finished. And then we can just create a new state from loop here and back to the loop state, we want to save the Caron camera into a game object variable, so we can use the current camera again. And here, basically, we want to deactivate the current camera. Here, let's just create a check first if the game object isle, so we can use the game object is null, and we want to check if the cin camera is null or not. And we want to add a finished transition here. And basically, we want to intercept if the current camera is, then we want to fire the finish event right away without going to the neck action here. And then the next thing that we want to do is we want to use the activate game object action. And here, we want to specify game object, then we want to pick the cin camera, and we want to deactivate it, and we want to disable the recursive, because we don't need this. And basically, this will automatically disable the current cameras or the camera selected in this loop iterations in the current loop iteration. And then we want to make sure that this activate game object is below the game object is no action. So let's just put this here, and let's minimize both of this action. And now let's fire the finish back to the loop state. So let's just rename this the activate camera. And then upon finishing the loop, then we want to go to a new state, and then we want to activate selected camera. Here, basically, we just want to use the game object action again. But this time we want to pick the active camera. And then we want to activate it. So let's just disable recursive and keep the activate checked. Now we have created the camera manager. Let's create the FSM for each of the camera in our scene. So basically on each of the camera in our scene, we want to create an FSM that will register itself to the camera manager. So Here under the main camera, let's create a new FSM, and inside this FSM here, we basically just want to get the owner. Let's just use get Owner, and then we want to store to a new variable. Let's just call this camera. And then we want to set an FSM game object. In this case, we want to set the camera FSM game object variable called current camera. So let's just use the set FSM game object. And then we want to pick the camera manager game object from the global variable. And for the variable name, we know that it is cur camera. And we need to make sure that the writing is correct down to the capitalization. And then we want to set this value to the variable that we've grabbed before. And once we send the value here to this current camera variable, we want to send an event. We're just going to be the Ad event. Let's just use this SN event. And let's make sure that this sN event is below the set FSM game object action and pick game object FSM as the target and specify game object, and now we can select the camera manager. And here we want to send the global event called Ad. Now basically we are done with the camera FSM for the camera to register itself to the camera manager. Now we can save this as a template, so let's just save template here. Let's just call this template register camera, and we can use it here. Now to set up this, let's create another camera from this position, for example. I'm going to create a new camera here, create a new camera, and I'm going to set the future this position here by selecting this camera and then hold Control Shift F. This will move this camera to this position, as you can see. And now we have two camera in our scene. The first one is this one, and the second one is this one. Okay Let's just adjust the position slightly, much more closer to where our characters are, and let's rotate this a bit. Basically, this is the main camera, and let's set the tag to main camera also. Now we want to put the camera near each other or better, yet we can just group them later. Now for the second camera, we want to create a new FSM, but we want to use the FSM template that we have just created which the template register camera. Now this should work with the camera manager, and the next thing that we want to create is we want to create the trigger area. Let's just move the player out of this area here and put it here as the starting position. Then we want to create a new empty game object as the trigger area. Let's just create an empty here and I'm going to add a box collideer. For this box collider, let's make the size to three on the x and three on the z and three on the y, for example. I think this is still too small, so let's make it even bigger five by five on the x and the z xs, and I'm going to keep the y23, and I'm going to reset its position. And here, let's move this and put it around this area here near this police officer, for example, and let's enable the trigger option. Basically to make the collider works with the player, one of them needs to have a rigid body. So in order to do that, instead of adding rigid body to each of the trigger area, I'm going to add a rigid body to the player. But I'm going to make sure that the rigid body is set to is kinematic. Let's just check this is kinematic here. And we can just disable the use gravity, and this will make sure that this rigid body is not going to be included in the physics or dynamic object calculations in the scene here. So it will act like just a static or an animated or pre animated object instead of getting the motions or the animations from the dynamic simulation. Now we can just minimize this here. Let's save the scene again, and now go back to the trigger area, and let's just call this camera trigger zone, for example. And for this camera trigger zone, we want to create a new FSM. Let's just right click here and add a new FSM here. And for this FSM, basically, we want to create two states. But let's just focus on creating the first state here. And basically, we want to use the trigger event action, and let's just search for the trigger event actions. And here, basically, when we want to use the trigger enter as the trigger mode here, and for the collider tag, we can just pick the player, and we want to send an event, a custom event that we need to create first, so let's just go to the event, and let's just create enter event. And then we want to create the exit event here. And basically, we want to add enter transition, and we want to use that. And basically, on this first state here, we want to set FSM game object to the camera manager. So let's just use set FSM game object. And we want to send a enter camera. So for the camera when the player is entering and to do this, let's go to the variable, and I'm going to create two new game object variable and let's just call the first one camera on enter, and let's enable the input so we can access this easily via the inspector. And then let's create another game object, and let's call this one camera on Exit. And we want to also enable the input checked here. And going back to the state here. Let's use the variable. Let's use the variable as a set value here. And this is for the camera on exit because basically when we enter the state, we are going to enter the state from a state where we are exiting the trigger. So here for the variable name, we should type active camera, and this is the variable that we have defined in the camera manager. And now we want to specify game object here and then pick the global camera manager. And then we want to send an event. And for the send event, we want to specify game object FSM has the event target, specify game object and then pick the globals camera manager, and we want to send the switch event switch camera event and make sure that the send event is executed after the set FSM. Now we have set this up. Let's just duplicate this state here, and then we change the transition target to the transition event to exit here. And then for the trigger event, we want to change the trigger to trigger exit and send the event to the exit state here. And basically on the set FSM game object here, we want to set the value for on camera enter, and why we are choosing the camera enter. Because whenever we are triggering the trigger method here, whenever the player enters the trigger, we are sending the enter event, and when we are going to the next state, we want to activate the camera on game object or the camera that we have set up as the camera when entering the triggers. We have set this camera on enter. Let's check the send event here. Yeah. We don't need to change anything here. And basically, now we need to connect this state here. Let's just connect the enter to the second state and exit to the first state. Now we have set up this trigger zone here. I'm going to save this as a template, so we can easily use this template for other game object, and let's just call this camera switcher, and let's just use the save template. And basically here, let's save the scene. On this camera trigger zone. On the variable, we want to set the camera on to be the second camera here. Let's just direct the second camera. And when we are exiting the trigger, we want to go back to the first main camera here. And now let's save this, and let's give this a try. So sorry, there is one thing that we need to do here. Basically, we need to disable the second camera on the scene, so let's just disable this. And this we'll make sure that the scene will start with the default the first camera. So after disableling the second camera, there is also one thing that we need to change here. Basically, this is for delaying the registrations by one frame here in the template register camera. So if we open the template register camera, we can add a next frame event. And basically, this will make sure that this initialization of registering the camera will happens on the next frame once the camera manager is ready or has been initialized by the camera manager here. Otherwise, there might be a race conditions where the registered camera tries to run when the camera manager is not yet ready or is not available yet. But this is just a temporary solution. And later, once we implement the additive scene loading and stuff to load the levels, we won't be needing this next frame event. So yeah, let's just add this for now to the template register camera, put it on top, and then make sure on the state settings here, on the gearbox button here enable the action sequence. So this will make sure that the stack will run in sequence. Okay. So the other thing that we need to do is that we need to select the player, and we need to make sure that the player has the tag of player because right now the camera trigger zone relies on the player tag. So let's make sure that the player is tagged correctly, and now let's save the scene. And let's select the camera manager, just to the buck here. I'm going to open the variables window and select the camera array game object variable, and let's play this. And here, on start, as you can see, the main camera gets registered and it become one of the entry of the camera's array on the camera manager. And the other camera is not yet registered because it's still deactivated as of now. So let's just give this try. And let's go to this area here. And now as you can see the camera switch to the second one. And once the second camera gets activated, it gets registered to the camera manager right now. Now the camera has two camera member in it, and if we exit the area, we'll go back to the main camera, and this will make it easier to set up a different camera view on a different area. 28. 27 Switch Scene FSM: In this video, we are going to create a custom template to switch a scene, and we are going to use an additive mode of loading a scene so we can load a scene on top of a previous scene. So for example, sample scene is going to be the main scene where we have the player, the lighting, the managers, and other stuff that needs to stay all the time in the game. It's going to be inside this sample scene, and probably we are going to rename this two main scene later. And then the scene, the places are going to be on a separate scene, like the CD, the club Holloway, the office, the park and everything. Before we start, let's create those new scene or sub scene. I'm going to go to the scenes folder and I'm going to create a subfolder here. And let's just call this sub scenes. Inside this folder, let's create two new scenes. First one will be the CD scene, and let's create another scene, which is going to be the club hallway scene. Here, let's open the City scene here. And I'm going to check to open the Club Hallway because I was having issues when I saved a scene with Club Hallway as a name for unknown reasons, so I'm going to check. It seems just to work fine because I can see the main camera in directional light here. So I'm going to go back to open the CD scene here. And if we have already imported all of the assets in the setup lessons or the introductions video, we should have this point and click folder, and then we should have the prefex folder. And inside the prefex, we should have all of the scene needed in this game here. So for the CD scene, I'm going to drag the CD game object here. And basically, I'm going to remove the directional light here. And I'm going to reposition the camera to be around this position here. Okay. And then I'm going to add a knife mesh in this scene here because if we open the navigation window here, as you can see here, we don't have the navigation mash baked yet here. So let's just bake before that. Let's check our CD game object. And basically, the prefabs when I've set up this, it sh already have the static checkmark checked. And the same goes with the child object here. And here we already have the box collider for the clicking part. Let's make sure that this layer is set up to ground, so we can click on it and the player can move around when we are clicking the ground collider. Okay, now let's go back to the navigation tab here, and under the Bak tab, let's press the bake button, and this will pick a new navigation mesh here. Okay, now we have set up the CDC. Let's save this, and now let's open the other scene, which is the club hallway scene. So I'm going to open the cub hallway here and go back to the Point click folder, prefab folder. Let's drag the club hallway, and let's delete the directional light game object. And now let's adjust the camera position. So I'm going to get the view that I want in the scene view here. And once we have the angle, the position and the angle of the camera that we want, the view that we want, we can select the main camera game object and then hold control shift F, and this will automatically snap the camera to the same position as our view, as you can see in our game view here. And now in this prefabs, I haven't set up the ground collider, so let's just create a new empty game object, and let's just rename this two ground collider. And let's add a box collider that we can click later and here from the top view and then autographic view by pressing the middle cube here. I'm going to adjust the collide size by pressing this edit collider button, and then let's just direct the points here so we can adjust the collider to fit the size of the ground. Okay. So I think this is enough, and let's make the y size 20.05. So it's very small. And if we go to the side view here, let's align the collider, so it aligns nicely with the ground here. Okay. So we have set up the ground collider. Let's change its layer to ground. And now the same goes with the city. The club hallway pre static options have been checked so we can go to the navigation tab directly, and then under the big tab, we can press the big button. This will bake a navigation mesh for this scene here. And let's save the club hallway. Okay. Now we have set up club away and CD just to test this scene switching template. Let's open the CD scene. But before that, if you are wondering where we can open this navigation tab, if you don't have it on your editor, you can go to the window AI and then pick this navigation. This will open this navigation tab. If it's floating, you can direct the name and you can dock it into a panel of your choosing. Okay. Now let's go back to the main sample scene here. Here in the sample scene, we want to hide a couple of things. Basically, we want to hide the environment, the dialogue, the NPC, all of the NPC here, and let's just hide the camera here, and then let's hide the camera trigger zone also. We don't want this trigger to trigger camera changes for now because we want to test this switch scene action. Let's just hide all of this here. We can save the scene. Now let's set up the CD scene here, but we can just load the CD additively on top of the sample scene. If we go to the subcene here, we can just drag our scene and put it here, and this will load the scene on top of our previous scene, and we can still modify all of the object on the sub scene or the additive loaded scene and the base scene here, and we can save each of the scene separately. Here, for example, I can create a new empty game object by clicking on the scene name and then right click and then go to the game object menu here and I can create an empty and this will create a game object inside the scene here. And I'm going to rename these two interactables. This is going to be the group of interactables, in this city scene here, and now I'm going to create another anti game object, and this will be the side door interaction. Now let's reposition this side door interactions, and I'm going to make sure that this object is on this door here. And another thing that I want to make sure that the Pipot sets to local or the transform set to local and rotate this on the green axis or the y axis so that the z axis is pointing outwards that way. And this will be the stopping direction and distance when the player interact with the door. The next thing that we want to add is we want to add a box collider. And let's set the layer to interactable, and let's adjust its size. So I'm going to use the edit collider button again and probably make it thinner and increase the size, so it covers the size of the box, and I'm going to make it a bit wider. Okay. I'm going to move this slightly forward here and push the back side two forward, so we have a thinner door there. And yeah, I think they should do. The next thing that we want to do is we want to add an FSM. So let's just type FSM, and we want to add the playmaker FSM here. And here we can pick the template, which is the interactable template here, and let's increase the size 21 because we want to assign the neck FSM that we are going to add. So here let's add another FSM, and this is going to be our sin switching FSM here. So with this selected, let's go to the playmaker editor here and By default, it's showing the top FSM. In order to edit this, we can just press this edit button here and it will open the second FSM here. Here in the first state, we don't want to do anything, and we want to add a state here. This second state, we want to add a global transition and we can pick custom event run action. This way, this FSM can be run by the interactable FSM here. Let's just call this switch scene for state here, and we want to create a string variable called target scene. This is the target scene that are going to be load whenever the player interacts with this interactable object, and we want to also expose this variable. So let's check the input options so we can type it here. And then we want to create another string variable, and this is going to be the current scene. That is loaded, then we can unload the scene here. And here inside the switch scene state, we can add a action called get scene name. And then we can save the name to the current scene variable that we've just created. But for the scene reference, we want to get not the active scene, but we want to get the scene by the game object. So basically, this will get the scene where the game objects reside. Instead of getting the sample scene, it will get the CD scene, and it will save the reference of the CT scene to this current scene string. So it will get the name of the scene. And let's save the scene now and go back to the side door interaction here. If we select active scene, then this will pick the basin loaded in our scene, which is the sample scene, and we don't want to do that. Make sure we change this to scene by game object, use owner, and then store it to a current scene. Then we want to use the load scene asynchronous here, a sin. And then we want to use scene by name and then for the scene by name here, we can use variable and then we can pick the target scene. Here, let's set the load scene mode to additive, so it will load the scene on top of the basin or the main scene, and let's allow scene activation. This will automatically load the scene when the progress of the scene loading is done. Otherwise, we can help the scene activations and probably add an input, press space bar to start, then we activate the scene that can be also achieved using these options. These options is there to Change or to make those behavior. Okay. Now we have set this up here. There are no other things that we need to set up, so let's just minimize this. Next, let's use the unload sync asynchronous. And this time, let's put this unload sin below the load scene. And here we want to use the same name also scene by name, and then we want to pick the current scene. And that will be all for the unload scene asynchronous. And here, let's enable action sequence here on the gear cog settings and enable action sequence. So this will make sure that the actions run in sequence. After this one is finished, go to the next one, and then when this is finished, we go to the next one. Now we have set this up. Let's save this as a template. And let's just call this template, switch scene. And we can use the safe template here. Now we need to modify the camera manager. And basically, whenever we are switching the scene, we want to clear all of the cameras that are registered in the camera manager. So in order to do that, let's go to the managers here and under the camera manager. Let's create a new state to delete the camera. So I'm going to create a new state here, and let's just call this delete all cameras. And let's create a new event to do this. So let's just call this delete cameras. And let's make sure that this event is a global event. So I'm going to check this here, and let's add a global transition, and then we can use the delete cameras event here. Basically, we want to delete or we want to clear the array values of the cameras array here. Here inside the delete all cameras state, we can search for array, remove all. And then here we can just select the cameras array here. And now we have this setup. Let's go back to the side door interactions here. Let's edit the template here. And basically, when we are switching the scene, let's clear the camera also. In order to do that, we're going to use the send evan action. And let's put the send event on top of the stack here in the state, and let's pick the game object FSM. We can specify game object here. And let's use variable here. Then we can go to the global variable and pick camera manager. And then we want to send the global event called delete Cameras. And this will automatically trigger the event on the camera manager. Okay. So now we are done with the switch scene template set up here. The next thing that we want to do is we want to also set up a interact, a scene switch intractable on the club hallway. So in order to do that, let's drag our club hallway into this sample scene here. Now we should be able to see our club hallway, but it is positioned incorrectly here. So in order to fix this, we need to move all of the object inside the club hallway scene, so it's aligned with this blue building here. In order to do that, I'm going to go to the top view here, and then I'm going to create a new empty game object. And I'm going to put the main camera and the club Hallway game object as a child of this ti game object. And now I can move around the ti game object to move the main camera and the club hallway object. And basically, what I want to do is that I want to rotate this by 60 degrees, so I'm holding control now while rotating. And then I want to make sure that this part here where we have the door for the club hallway, aligned with the door of this building. We want to add an offset, of course, so let me just reposition this. And probably we want to make it around this position because we want to make sure that whenever the player interact with the outdoor or this side door interactions, when the player stops in this position, then we load the club hallway, we want to set that the player is already inside the building. And vice versa, when the player exit the club hallway and then interact with this door, for example, we want to make sure that the player is top in this position, so it's already outside of the building, when the player is going to enter the CT scene. So I think this is a good position. And now we can just drag the main Cameron club hallway back outside from the game object that we have just created. And now we can reuse this game object as a interactable for the door interactables of the club hallway. So with this one here, I'm going to reset its rotations. I'm going to leave its position. And let's just rename these two interactables. And basically, this will be a group that will hold all of the objects that are interactable inside the club hallway. And here I'm going to add another empty game object, and I'm going to move this empty game object. So it aligns with the door from the club hallway. And let's rotate this on the y axis. By 90 degrees. So we make sure that the z direction is facing inward. And then we want to make sure that this lies on the middle of the door here. And now let's add a box collider. And we want to also make this object layer as an interactable. So let's just select that layer. And now let's adjust the size of this interactable here. I'm going to Make it wider. Let's just re edit this, and let's make the collider slightly wider. So it fits the sides of the door here and also make the height higher, so it fits with the door here. Basically, we can just move this so it aligns with the front side of this door here. And I think the should be okay. And basically, with this interactable, we can just call this exit interaction, for example. And here we can add a playmaker FSM, and this is for the interactable FSM. So let's just pick a template here and then pick the template interactable. We can increase the action size, and we want to create another playmaker FSM. And this one, we can just pick the newly created template, which is the template switch scene here. And then we can wreck this FSM as the actions of the interactable. And for the target scene, we can just type this CD because we want to make sure that when player is interacting with this door, we should go to the CT scene. Okay. So now let's save this scene here. There is also one thing that we want to change here inside the player FSM. If we go to the playmaker editor here, we want to make sure that whenever we are sending the event, we can just remove the name here, so it will send to the FSM that has interacted event. We don't have to type the name correctly. Because, for example, here, in the CD scene here. If we don't rename this two interactable, then this won't work when we still have the FSM name. So I'm going just to clear this out, so it won't detect the FSM name, but it will search for an FSM that has an interacted event. Okay. So let's save the scene here. And now we've done set up the club hallway. Another thing that we want to set up is that here on the side door interactions of the City, we want to direct the playmaker FSM, so it become the actions on the interactable component here. And we want to also type the name of the target scene here, which is club hallway. Let's just type clap hallway and make sure that the capitalization is also correct based on our scene that we have saved, and here let's just save the scene here. I'm going to remove the clap hallway scene, but I'm going to keep the CD scene here just for testing right now. Before we test this, we need to add our scene in the scene list of our build settings. In order to do that, we can just open the file here, go to the build settings, and let's add the scene from our project. First, we want to add the sample scene here, and then inside the sub scene, we want to add the CD scene and also the Clap hallway scene. And when we are adding the scene, we want to save our project, so these settings get safe. Let's just go to the file, and then pick safe project. Okay. Now we can test this. So I'm going to run the game here. Okay. So now let's just try to interact with the door here. We should be able to go there you go. Now we are inside the club hallway, and if we interact with this door, we should be able to go back to the city. And as you can see here, the objects are facing or aligning nicely in the interaction position. So for example, if I go back to the club hallway, we will enter the club, and that is why we need to align those scene objects in the sample scene, so everything aligns better. So pe conclude with the scene switch lessons, and we are going to continue in the next video. 29. 28 Door Swing and Transparent Wall: Hi, in this video, we are going to continue working on the club hallway, and we want to create a swinging door so the player can go inside and outside of the room in the club hallway, and we want to also make sure that when the player is inside the room, we want to render the wall and door transparent. So we want to switch material when the player enters, and we want to revert the material when the player goes outside of the room. Before that, let's just here on our sample scene. I'm going to disable the CD scene. And here we can just pick unload scene in the menu here, and this will hide the CD scene. And basically, I want to delete this navigation mass. So here on my naviigation panel, I'm going to go to the baked tab here, and I'm going to press clear. This will clear, and we can reopen or we can reload the CD scene here. And I want to also save the sample scene here. So now let's go to the subscene folder, and let's open the club hallway scene. Here in our clap hallway scene, we also need to fix our nafigation mesh. So let's just clear this and then rebake it, and this will create a new naviigation mesh on our scene here. And I'm going to change the agent radius to 0.35. So we have like a smaller radius for our agent. Thus, this will make the navigation mesh larger than what we have right now. So let's just press bake again, and this will change the navigation mess. And the next thing that we want to do is we want to create a swinging door. So in order to do that, We can select the door here. And basically, once the door is selected, we can see that the objects are expanded in the hierarchy. We want to pick the pivot here, and then we can change the view to the top view, and I have disabled the perspective view here with the pivot selected under the inspector, let's add a rigid body. And for the rigid body, we want to disable use gravity so the object will stay in its place. It doesn't falls down. And we want to also add a hinge joint. For the hin joint, we want to change the axis to 01 and zero. So basically, we want to only affect the y angle as the axis for the hinge joint. So the door can swing with the rotations in y axis. And we want to also use the spring. For the spring, I've tested the value. You can change this to your liking, but this value 20 for the spring, Damper five works well on my case. And then we want to also set the limits here. For setting the limits, we can enable this added angular limits button, and you can see that we have this red gizmo, and this dictates the rotation range of our door. Right now, the door cannot rotate at all because it sets 20 on the minimum and the maximum. I'm going to change this to negative 90 for the minimum, and for the maximum, I'm going to set this 290. We will also need to enable the use limit, so I'm going to press this. Now, you can see that the door will be able to swing up to this line here and also to this line here. It will be able to swing both ways when the player enters or going outside from the room. So that will be all for setting at the rigid body and the hinge joint. Now let's just create a box collider for the door game object, so the player can collide with it. The default fitting of this box collider is actually quite spot on because we are creating the box collider on top of the mesh render. So the collider can detect the mesh object, and it will create a collider that fits the three D model. And we don't need to add rigid body component anymore on this game object because the rigid body is being handled on the pivot, and the parent game object will detect the collider of the child object, and it will consider that collider as one object with the pivot. So it will consider that collider as its own collider for this pivot game object. So now we have set up the door. I'm going just to copy the hinge joint component here. And then I'm going to paste this to the same pivot game object on the security door. So here let's just add a rigid body. Let's disable use gravity, and then we want to right click here on the rigid body, and we want to paste component as new, and this will paste a new hinge join with the same settings that we have on our door here. Okay, so now we have this setup. Another thing that we want to do is we want to add a box collider to the security door here. So let's just add that component. Box collider. And then pick that one. So now, basically, we are done with the swinging door setup. Next, let's create the FSMs to switch the wall and the door to a transparent material when the player enters the room. So I'm going to save the club llway scene first. Here from the top view, I'm going to select the toilet wall here, and I want to create a new box collider. And this box collider, I want to increase the size because this is very thin. It fits to the wall. So let's just change some value here in the inspector, like the Z value or the x value, for example. Oh, sorry. I'm going to change the size, the size or the X size. Yeah. And now let's make this box coll fits the room. So let's just drag this by enable the added collier here, and we can drag this nodes. And let's make this box coll the size of the room. So I think this should do, and let's enable the e trigger option. We want to also do this to the other security room wall here. So let's just do the same. At a box collider. I'm going to change the excise so we can see the box collider. And let's press this added collider button, and let's drag one of this point here, so it fits the room. And let's just the front facing here. And let's also enable the trigger option. So now we have this setup here. We can apply this setting to the prefabs. So by selecting the root game object under the override tabs here, we can press apply all. And then let's save the club hallway scene again, and let's select the toilet wall again. Here, we want to create a new FSM. So let's just add a new FSM under the playmaker tab here. And then we want to initialize the material first. So in order to do that, we need to create a couple of variable. First, I'm going to create a variable array, and this is going to be the renderers. And for the type, let's change this two game object. And let's enable the input options here. And then we want to also create a material variable. And this is going to be the transparent material that we are going to use whenever we are changing the material of the wall and the door. And we want to also enable the input checked here, so it's visible on the inspector. And the other thing that we want to create is a array of material. So let's just create an array variable, and this is going to be the original materials. And for the type, I'm going to change this to material. And we don't need to expose this material. So now we can start creating our FSM. Here on the first state, I'm going to rename this state to safe original materials. And here inside this loop here, Use the array, get next action. And we want to loop through all of the renderers array. So let's just sick the renders variable. And then we want to add a custom event called loop here. And we want to set that loop event to the transition, and another transition is going to be finished. And for the finish, we want to send this to the finish event. And we want to catch the result or the member that we are looping to a new variable. Let's just create a new variable here, and let's call this current render. This will save the game object into this variable here. And then when looping here, we want to get the material and save it to the original material array. Let's just call this get material. And for this action, we want to use the get material action. And we want to pick the cur render game object. So let's just use variable here and pick corn render. And for the material, we want to save this to a new variable, and we can call this corn material. And then we want to save that current material to an array. So use ray add action. And basically, we want to add the material to the original materials. I We need to add the car material to the original materials. And this will make sure that the original materials will have a list of material that is the same order as our renderers array order. Now let's add a finished transition here, and let's connect this back to the safe original materials. Once it's finished, we want to go to a new state here, and we can just call this player outside because by default, the player will be outside of the room, and let's add a new transition, but we need to create the event first. I'm going to create a new event called player in. Y And then I'm going to add another event called player out. And here I want to add the player in transition. And basically, when we are in, we want to change the material to the transparent material. So here we need to loop through the renderers array again. So let's just use the array get next, and we want to loop through the renderer add a loop transition, and then a finished transition and set this event accordingly. And we can call this loop renderer. For loop, we want to assign the transparent material to the game object. Here we need to save the result and we can use the current render variable here, and here we want to set a material to the render game object. Let's just use set material. Pick specified game object, and then we can select the cron render, and for the material, we can pick the transparent material. And let's just add a finished transition here and look back to the loop render. And when it's finished, we want to go to the new state here, and we can call this player inside. And basically, when it's inside, we want to add a player out transition, and then we want to go to a new state. But instead of going to a new state, we can just duplicate the state here. By pressing control C and then Control V. Then we want to connect this player out to this loop render state here. And basically, this is all already been set up. But here, we want to get the material from the original material array for so let's just use the array get action. And for the array get action, we want to pick the original materials, but we need to pass an index here. Here in the loop render state, let's save the current index instead. So I'm going to add a new variable, and let's just call this current index. And here, we can use that current index as the index for this array get actions, and we can start the value to the current material. And now we want to set the current render game object material back to the current material or the material that we get from the original materials here. So let's just pick current material here, and when it's finished here, we want to go back to the state here. And now basically here on this player outside state, we want to use a trigger event. And for the trigger event, we want to check for a player tag here. And then we want to send the event player in. So whenever the player enters this collider, we want to send the player in event, and it will change all of the game object material to a transparent material. And here, we want to also use trigger event. But instead of using the trigger enter, we want to change this to trigger exit and pick the player tag and then send the player out. So this shot works. And right now, I want to save this as a template, so I'm going to right click here and then save template. And we can call this template switch, transparent material. And we can use the safe template in this FSM. So let's just press yes here. And now, basically, on this game object here, we can set the render size and set the transparent material to a material that we have in our project, and this is the material the transparent material here. So let's just pick this one here. And for the render game object, basically, we want to hide the wall itself and the door game object here. And this toilet door doesn't have any measure render. It is just an anti game object that halts the pivot here. So basically, we only need to assign the toilet wall and the door. And the same goes to the security room wall here. So let's just add a FSM. And here, let's just pick the newly created template switched transparent material and set the renderer size to chew, and we can drag the security wall here and game object here and set the same for the transparent material. So here, let's just apply the prefabs again. On the overwrite tabs here. I'm going to press apply all and save the club hallway scene. To test this, let's open the sample scene. And let's load the CD scene as the additive scene here just for testing. And now we can run the game. I'm going to make this slightly bigger. Okay. So let's go to this door here, and this will load the club hallway scene here, as you can see. And now let's enter the room. And now when we enter the room, you can see that the wall and the door change to a transparent material. And if we go outside, it will switch back to the solid material there. So, yeah, we have this working very nicely this action where we can switch the material of a wall when it occludes the player. So this is basically how we want to set up the club hallway, and we are going to continue the lessons on the next video. 30. 29 Cursor Manager: Hey, in this video, we are going to create a cursor manager, so we can see whenever we can interact with a person NPC or an object like a door or anything else. First, in order to do that, let's just enable a couple of our MPC here. As you can see here we have the two NPC here, and first, we want to create a new manager to handle the cursor. Here under the managers, let's create a new empty game object, and let's call this cursor Manager. For this cursor manager, we want to create a new FSM. Here while the cursor manager is stft, let's right click here and then add an FSM. Basically, in the first state, we want to make sure that we are moving the cursor on the Canvas. In order to do that, I'm going to create a new image on the Canvas here under the UI image, and this is going to be our cursor. For this cursor, by default, we want to set this two disabled. We want to disable the game object, and for the cursor manager, let's go to the variable tab here, and let's first add an array variable, and this is going to be the cursor type. For the type, we want to set this two. Then the next one, we want to add a game object variable, and this will be the cursor game object. And we want to expose both of the variable here. Let's just enable the input here, and for the cursor, we want to do the same. The next thing that we want to do is we want to make sure that the cursor type is populated with correct cursor. Here I'm going to set the size 23. For the first sprite, I'm going to select the hand cursor, and for the second spr is going to be the bubble dialog cursor, and the third one is going to be the i cursor. And for the cursor game object, we want to drag this disabled cursor game object under the Canvas as the game object. Let's say the seat here. Next, we need to create a new enum, so define the cursor that we want to show whenever the mouse is hovering the interractables. Here under the projects and the scripts folder, and here inside the scripts folder, let's create a new C sharp script. Let's call this interact type. Let's open the script. For the script here, I'm going to delete this mono behavior and delete all of the content here and change the type from class to um. Let's first type hand with all capital. For the second um, I'm going to set this to and the third one is going to be the i. Here we can select which type of the cursor that we want to show whenever the mouse is hovering the interactable. And for organizing the am, I'm going to right click here and then select the quick actions refractory, and I'm going to move to namespace here. Here I'm going to pick the point and click game. We can search for this am easier under the point and click namespace here, just like what we did with the item class. Now this is done. Let's just close isle studio here, and now we can use that am in playmaker. The next thing that we want to do is we want to go to the cursor manager here under the playmaker tab. Now we want to move the cursor every frame inside the state here. First, we need to get the mouse position and by default, playmaker provide us with the get mouse x and y, but there is a compact version of it in the ecosystem. I'm going to go to the ads here under ecosystem ser open it, and then I'm going to search for mouse position. And should return the custom actions that we need, and I you change the capital. Here. As you can see, the first result is the GT Must position, so we can just get this action. With this action, we can get the vector of the most position directly without having to build the new position from a float. Here, let's go back to the actions browser and use the get most position here. Let's just store this most position to a new variable called Moz we don't want to set this to normalize, Disable the normalize and we want to enable this every frame. Then we want to set the position of the cursor using the set position action. For the game object, let's specify game object and then select the cursor variable here. For the vector, we can select the most position, and for the space, world should be good here, and let's just select every frame here. Now to test this, we can just enable the cursor and Under game view, we should be able to see this wide square. If we press plea, you see that the image is following the mouse cursor, as you can see. Now we have this cursor working. We need to implement more to show different cursor whenever it hovers different intracts. The next thing that we want to do, we want to disable the cursor back. Under the cursor manager, we want to add a new state to switch cursor. Here, let's just change this two switch cursor, and we need to create a global event. I'm going to create a global event called switch cursor. I'm going to enable this broadcast event here. I'm going to create another event called Hight cursor. And I'm going to also enable this broadcast event. Next, I want to add a global transition stitch cursor to this state here. I'm going to create another state and add a global transition height cursor on this one. Let's rename the state to Hight cursor. Now we have created the switch cursor and the height cursor state. On the switch cursor, we want to get the cursor using the array gap from the cursor types array here. For the index, we want to create a new variable called index, and this will be set by each of the interactable later. Then we want to store the value to a new variable called cent cursor. And we want to add a finish transition. If the index is out of range, we want to go to finish. I will skip this next action below. Then here, we want to use the UI set image sprite. For the game object, we can just pick the cursor game object. For the sprite, we can pick the current cursor here. This should do here and another thing that we want to add is we want to add and activate game object. Action here. Basically, we want to activate the game object. Whenever we have finish getting the cursor and sting the cursor, then we want to enable the cursor game object. Let's just specify game object here. Pick the cursor variable and activate it. And we can copy this action here. Basically on hide cursor, we just want to hide the cursor. We can just activate this wel hide it, and we want to add a finished transition and connect the finished transition back to the first state. I'm going to reorganize this here. Here this is basically what we want to do with the cursor manager. The next thing that we want to do is we want to modify the interactable FS. Let's just pick one of the NPC here, and under the playmaker FSM, let's just click to add the template here. Here, basically, we want to add two new state to switch cursor, and then to hide the cursor. Let's just rename this two switch cursor. And this one to cursor. We can use a custom event that lemker has provided us here. I'm going to add a transition system event and here we have the mouse over. I'm going to use that and go to the Switch cursor. Under the Switch cursor, I'm going to add a transition system event, and then this is going to be the most exit. I'm going to connect this Ms exit to height cursor here. For the cursor, I'm going to add the most over transition back so we can go back and switch the cursor again. Basically, this will look through the two states whenever we are entering or exiting the interactable when the most position is entering the interactable or exiting the interactable. Here on the first stage here, we want to add a mouse pick event. Let's just search for it and let's pick this mouse pick action event. Whenever we are hovering, we want to send the mouse over, and let's add a layer mask and for the layer mask, let's just pick interactable. And we want to make sure that this every frame is checked, so it will check for the mouse every frame. Now we can copy the stft action here, minimize it. Inside the high cursor, we want to paste this back. For the switch cursor, we want to paste this and we want to set the most over back to none, and we want to set the most off to most exit. Now, we need to create a new global variables to hold the cursor manager. Let's just create a new game object variable. Let's call this cursor Manager, and I'm going to set this category to manager. For the value, we need to set this up from the cursor manager. Here inside the cursor Manager, I'm going to add a new state here and let's just call this in it. Basically what we want to do is we want to get the owner of this FSM. And safe this to a new variable called owner, then we want to set game object variable, which is going to be the cursor manager. For the game object, we can pick the owner variable. Let's move this down so we get the owner first, then we set the cursor global variable to be the owner. Let's just minimize this and set this as the start state at a finished transition, and connect this to the first state. I'm going to save the sample seam here and back to the NPC dialogue, the interactable template here. Now we want to send an evN to the cursor manager whenever we are switching the cursor here. Here, let's just first set an FSM in. And we want to set the index based on the type of the icon that we want to set as the interactable icon or cursor. In order to do that, here in the variable, I'm going to create a new variable called type. For the type here, I'm going to change this to um. For the um type, I'm going to go to the point and click game, which is the name space that we've created and tick interact type. By default, it will set this value to hand. We want to expose this variable as well, Let's just press the input here, check the input, and now we have this am in our inspector. Back to the state here, we want to set the FSM integer specify game object, and then we want to pick the cursor game object. Here for the variable name, if we go to the cursor manager here, you see whenever we are switching the cursor, we are getting the cursor types based on the index integer here. We want to set this value. So Let's go to the interactable template here. Here, the variable name is index that we want to change and we want to set the value to the Nam that we have here. So here, we can select the use variable and basically we can convert enum to a integer automatically by using this convert menu and then pick the type um, and this will set the integer based on the index of the enum. Basically this by default, is going to be in order starting from zero, an is going to be zero, Tk is going to be one, and I is going to be two, and we need to make sure that this order is the same as the order of our cursor here. As you can see here, The first cursor type index zero is the han, and then the second one is the talk, and the third one is the i. We need to make sure that the order of our am and the order of this array is the same. Go back to the NPC dialogue here, add the interactable template again. Now we have set up the index variable on the cursor manager. We can just minimize this and then we can just send in the event. And we want to target game object FSM for the game object specify it and get the cursor manager here, and for the event, we want to search for the global event called switch cursor. And we can copy this action here, and whenever we are going to Hight the cursor, we want to basically, we want to send the ight cursor event here. Let's change this order here. We want to boot the most event to be the bottom action here. Same with the switch cursor, we want to change this to them of the send event. Now let's save the scene here and let's save the project. It updates the template here. Now let's give this try. Here, if I hover the police officer, as you can see, we can see the hand icon, and I can see also the hand icon. This is because that the hand icon is the default icon or the cursor. In order to change that, you can just easily go to the NPC here and then change the type to and the same with the other NPC here. Under the intractable, we can change the type to tok. Now if we test this again here, you will be able to see that if we hover the NPC, we have the bubble dial up on or cursor here, and we can interact with that PC. We can talk this NPC here. Yeah, that is basically how we create a cursor and this is going to be useful. So the user will be able to know which object that we can interact in our seat If we want to make this door interactable then we can set those cursor type here in the interactable FSM. 31. 30 City Scene Story: Hi, in this video. Let's start creating the story gameplay, and here I've already created a base story for our game here, and we are going to start working on the scene one, which is the front club or the City scene here. So first, let's just disable this NPC here from our example here and this one here. And let's open the se tab here. And first, we want to create the bouncer here to guard this door here. So basically, we want to make sure that we want to create a story where whenever the players try to interact with this door here, we want the bouncer to forbid the player to enter this door here. So in order to do that, I'm going to create a new anti game object under the interactables on the CD s here. And create a new T here, and I'm going to rename this NPC underscore bouncer. And for this bouncer here, I'm going to add a capsule collider. And I'm going to set the height to two and the center 21, so it aligns with our ground here. And for the layer, let's set this two intractable, and we can add a playmaker FSM here. Okay. And we want to add the three model that is going to be the bouncer here. So let's just go to the project tab here under the two tiny people here. Go to the prefix folder, and I'm going to pick this male A and drag this as the child of the NPC bouncer. And let's set the rotations to zero on the y axis here. So it's facing forward. And now we want to select the parent game object, which is the NPC bouncer and rag this, so it stands on the side of the door here. For this NPC bouncer, we want to add the interactable FSM. So let's just pick here from the template and select the interactable. And for the type, we can set this two talk. And here, we can add an anti game object. Let's just call this Talk response. And I'm going to create another anti game object. And this is going to be the door response. And for the talk response, I'm going to add a new FSM, and I'm going to select the template dialogue FSM here. And for the message, I'm going to set this to. What are you looking at And we don't want to set the other stuff here because we only want you to show the message. And let's add the name of the bouncer here. And I'm going to press enter. L et's also enter this message here. Let's check this if this is on a different line. So I'm going to open a node path here and paste let's just enter this here and copy all of the message here and paste it here. Now we should have a new line between the name and the message. Here on the NPC bouncer, we want to set the actions 21 on the intractable FSM and direct the top response. And then we want to create another empty game object, which is going to be the front door. And for the front door, we want to add a box collider, and we can set the size of the x to 1.7. This should be enough. For the Y, I'm going to set this to 2.5. And for the z, I'm going to set this to a very low value, 0.3, for example. And for the center, I'm going to set this to be the half value of our y size here. So it's going to be 1.2 or 25 here. And now let's align this game object to the front door here. So around that position. Let's perfect this position here. Okay, this should do here. And let's change the layer to intractable. And then we want to add a new FSM, and let's pick the template, which is going to be the intractable here. And for the type, we want to keep this to hand, and we want to set the size to one for the actions. And now we can expand the NPC bos bouncer. And for the door response, we need to create a new FSM and select the dialog template here. And for the message, we can just say, like, let's just type it here on the notepad. So we have this new line. And let's just say that you're not allowed to enter. For example, and let's just copy all of this text here, and then paste this here to the message. Okay. Another thing that we want to do is we want to play an animation whenever this bouncer is talking. So let's just add a new anti game object. And this is going to be the animation, for example, and let's add a new playmaker FSM. Let's pick the template play animation. And we want to drag the animator game object, which is this prefabs game object here, the child game object that has the treaty model on it, it should have an animator. And for the controller here, we want to select the people here because the controller, we already have the animator set up. Basically, we have this idle animations in the bland tree, and we have this talking, and we're talking, we can trigger this talking using the top trigger. So if we go back to the scene here and under the animation game object, we can type the trigger, which is talk. And basically, whenever we are interacting with this NPC, we want to trigger the top response, and then we want to trigger also the animation. And the same goes with the front door here. First, we want to trigger the door response FSM here, and we want to add another FSM, and then trigger the animation. Now, let's save the scene here. If we press play, we can talk with this bouncer. Oh, we need to check those new line, but right now, let's just keep it like this here. And if we talk or if we interact with this door here, it will also says that you're not allowed to enter. So basically, this bouncer will guard the door here. The next thing that we want to do is we want to create two different cameras in the scene here. So basically, first, we want to have the main camera pointing to this angle here. So right now we can just select the main camera here, and then hold Control Shift F to change the position of the camera to be aligned with our view here. So now, in our game view, you see that we have the same view as our scene view here. And for the main camera, we want to remove the audio listener. And we want to add a plan maker FSM. And here we want to select the register camera template, and we don't need to set anything else in this FSM. And I'm going to create another camera, and I'm going to call this side door camera. And for this side door camera, I'm going to change our scene view to point in this area, for example. Yeah, I think they should do. And now with the side door camera selected, we can just hold control shift F, and this will change the position of the second camera here. And we want to also disable the second camera here. But now we need to create an area to trigger the camera zone. We already created a similar game object here on our sample scene here, the one that has been set up, so we can just duplicate this game object and then drag this game object to the CD scene here. And this will be the CD game object right now. And let's just enable this trig camera zone. And let's rename this two side trigger. And now we want to go to the top view here and drag this glider. And basically, we want to put this around this position here. And I'm going to extend this scider by pressing the edit glider and then extend this scaliter, so it will cover this area here. Maybe this area as well. Okay, now that we have the trigger zone setup, Here, we want to change the camera on enter, and then on exit value here. Let's just track the main camera as the camera on exit, and on enter, we want to change this to the side door camera. Let's save the scene here. And now if we test this, if we go to this area here, we should be able to see that the camera is switching. But if we go back to this area here, then it will go back to the main camera. So the next thing that we want to do is we want to create this side door interaction. Here we already have the side door interactions, and basically the side door interactions will switch the swing right now. But we want to change this. So here I'm going to add a new anti game object. And I'm going to call this failed response. And then I'm going to duplicate this game object, and I'm going to call this success response. For the success response, we want to copy this FSM here, the switch scene template here. Let's just copy this component. And then here I'm going to paste component a new. So we have this. And on the side door interaction, we can just delete this. And then we want to create another couple of anti game objects. And we are going to call this password unknown, for example. Put it on top here. And here, basically, we want to show a dialog and a response here. So basically, we want to add a playmaker FSM here, add a dialog template, not the action, but the template FSM here. And let's just set the message to do. And then ask the player, what is the password? And then we want to enable to ask questions here for the yes. We want to set this to chicken, for example, with question mark, and for no, we can just type this no idea. For the sender FSM, we can just drag this FSM to the slot here. And we can add a no action and yes action. And both of these no and yes actions, we want to direct the failed response. Oh, we need to add FSM first, so let's just add a new FSM here, and this is going to be another dialogue template here, but without any question. And for the message, I'm going to type. Nice try. For example. And now if we go back to the password known game object, we can drag this failed response to the slot here and failed response to the other slot here. And basically, we want to trigger this password ag node whenever we are interacting with the door, but we want to increase the size here, and then we want to add the password known game object here. So this is when we are already interacted with the password non or with the password intractable that we are going to create after this. So for the password known FSM here, we want to set the success action or the yes actions to the success response here. And for the yes answer label here, we want to set the two help with capital eight. A capital letter with ds in between. This can be anything. It's just that this is the one that I've decided for this game here. And basically, we want to disable this FSM. And here on the side door interactions, we want to direct the password known. Basically, this will triggers if the password known FSM is enabled, and right now it's disabled by default, so this won't get triggered by this interaction. And now we have set up the side door interactions. We need to create another thing here, another anti game object, and this is going to be the password, for example. So let's just add a box collider, not the two d one. It should be the three D one here and set the layer to interactable. And here we want to add a FSM. And then for the template, we can pick the interactable template here. And we can create another anti game object. And let's just call this activate known password, for example. And here we want to add FSM. Then we want to add the template activate multiple FSM. So here we want to disable the password unknown and activate the password FSM. Let's expand the side door interaction and direct the unknown to the activate one here, and then direct the password known to the activate FSM here. Okay. So this should do here. And on the password here, we can add another FSM, and we can add a dialogue FSM here. So basically, we want just says that there is a writing in the wall, and let's just type the password is E P, like so. So now we can trigger whenever we are interacting with this password here. Let's just drag this FSM as the first FSM on the interactable here. And then for the size, increase the size, and we want to d the activate known password game FSM here. For the type, we can just change this two I, and let's save the CD s here. And now this is the password game object. So I'm going to make this a bit smaller. And I'm going to align this to the texture here. So here on the side door, you see that we have the texture, scribble texture here. So I'm going to align this game object to that position. Okay, yeah. Let's save this, and now let's give this a try. So if we interact with this NPC, we won't be able to enter. Let's go to this area here. If we talk to this door here, for example, we don't have the answer. So if we answer anything, we won't be able actually to enter the door. But if we interact with this password here, T. See that now the password unknown is disabled, and the password known is enabled. So we now will be able to see the changes in the behavior of the door here. Now we have the correct answer. And if we respond with no idea, we cannot enter anyway. So we need to answer the correct password. Now if we press help, as you can see, now we are entering the club hallway. So that is basically what we want to set up with the gameplay story of the CD scene here, and we are going to continue this on the next video. A. 32. 31 Club Hallway Story: Hi. In this video, we are going to continue to create our gameplay story for another scene. Last time we already create the story for the city here. The next thing that we want to create is the club hallway. Here I have the base story. We already implement the first scene, which is the front club here, and now we want to implement the club rear hallway. Basically in the hallway, there will be a toilet room, a security room. And then the story is that well, the protagonist the player, need to ask the security regarding a regular visitor of the club. And show the pictures. And the security will tell him that he haven't seen the person. But there is another person in the toilet, which overheard the conversations, and then we can talk to that person and that person will give us a hint on where we can find that person. If we haven't talked to the security at that moment, trying to talk to the guy in the toilet will give us just a vague response. So we need to talk to the security first and then talk to the guy in the toilet. And this is part of the puzzle. Let's just do that. Here, first, I'm going to basically remove the CT scene here, and I'm going to direct the club hallway so we can edit this. And here in the club hallway, we already have the interactable game object. This is basically an ant game object that holds all of the interactable objects. And right now, we only have this exit interactions so the player can go outside and back to the CD scene here. First, we need to create two NPC here. I'm going to create an mt game object here, and this is going to be the security guy. So I'm going to call this security guy. And for this security guy, let's add a capsule collider and set the height to two, and I'm going to set the center to one. So it aligns with the ground there. And perhaps I'm going to add a y position. So it aligns very well to the ground. Here, I'm going to set this value to 0.2 K. Yeah, that should do. The other thing that I want to do is I want to change the layer to intractable and add a FSM. And this is going to be an intractable FSM. Let's just pick the intractable template here. Now we can add the model by going to the Toni tiny P, TT here, and then under the prefabs folder, I'm going to direct the pols and make this pols as the child of this security guy. I'm going to reset the position to zero and set the rotations to zero as well. And I'm going to change the controller to use the default people that we have created. So it will play the idle animation. Okay. Now on the top view, I'm going to direct this security guy. It stands inside this room here and I'm going to rotate. And I'm going to probably hide the gun here because it doesn't make sense that he is holding his gun in the room there, so let's just set the handgun and then we can hide it. And basically for this police officer here or the security guy here, we want to create a response here. So first, I'm going to create another anti game object. And this is going to be the normal response. Or we can just call it this response because this person will only have one response. Okay. Now we want to add a FSM here. And basically, for this FSM, we want to use the dialog template, and we want to create a couple of message. So first, let's just type will, and we want to say that E me. Have you seen this guy around showing picture to the security. Okay. There. And for the second message. I'm going to type security guy here. And probably let's just say I'm sorry, but I haven't seen him for a while. Okay. So this is the response, and we don't want to set questions here. It's just going to be a normal response. And then we want to also create another FSM here, another anti game object. And let's just call this modified toilet guy. And here we want to add an FSM, and for the template, we want to pick the activate multiple FSM. And this will modify the toilet guy FSM here. Since we haven't created it yet, so we need to create one. Here I'm going just to wait a second. We we move the model of the security guy, so I'm going to copy the transform here. And then I'm going to paste the component values here. And then let's just reset this transform of the security guy here. So it sits back on exactly on the parent game object. So now this so be correct. Previously, it was wrong. And for the type of the interaction here, we want to set. And for the actions, we can just add one for now and then direct the response here. L et's save the scene here. And now let's create another anti give object. And this time, this is going to be the NPC toilet guy, for example. Let's set the y value 20.2, and let's add a capsule glider and this should have the same value as the security guy. I'm going just to set this. And we want to add also an FSM here, and this is going to be the same. It should be the interactable. We want to also change the layer to interactable. Let's set the type as well to top on the interactable. And now we have this folder open, the model open. We want to drag the male A as the child of this toilet guy. But we want to hide the baseball bet here. Let's just select this and check the active, so it's hidden. And now we can just also reset the rotation choose zero, and we can reposition the parent game object, which is the NPC toilet guide. And I'm going to put him in the toilet around this position, for example. I'm going to rotate him a bit. Okay. So now we need to set up a couple of FSM on this toilet guide here. Here, first, I'm going to add a normal response. And this is going to have an FSM with a dialogue template here. And I'm going to say going to type here that I'm out of stock now. Like he's selling something, for example, He's selling something, but he is out of stock. And then we can add another Anti object. Let's just call this Eaverop response. This is the response when he eave drops our conversation. And let's add a dialog template FSM here. And then we can just say that. I've overheard your conversation. And for the second message. And I believe you will find the person on this address. We did more string here. Then he gives you a name card with an address on it, for example. So this is like an explanation that he is giving us a name card. And this is also not a dialogue, but we want to check this playmaker FSM here. We need to create another anti game object. This should be give name card. And let's add an FSM here, and then we want to use the give item FSM. Basically, this NPC will give us an item and we will have this item given to us to our inventory here. But before that, we need to create the definition of the item. So I'm going to create a new item inside the data folder items. R, create and then item definitions, and I'm going to just call this name card, for example. For the git here, I can just right click on the script here and we can copy the git And then paste it here. We have a good number, and let's just call this name card a name card with an address on it, for example. Then for the image, we can pick one of the item image that we have prepared. I'm going to pick this item six. So now we have name card. And the next thing that we want to do is we want to add this name card definition into our inventory database. So let's just increase the size of our array inventory database here and direct the name card as the third item here. So now we can save the scene here, and now on the NPC toilet guide, we can add the name card item as the item to give here, then we want to add a chain actions. For these actions, basically, we want to create another FSM. We can call this revert FSM, for example, and here, we can add a FSM, then we want to add the template activate multiple FSM. Basically, this should be disabled. Give name card should also be disabled, and we want to put all of this three FSM onto the intractable here. Let's just set this 23 and then direct the normal response. IFS drops response, and then the gif Name card, sorry, the gift name card response. We should have this three FSM, but it will only execute the one that is active. The disabled one won't be executed. And this revert FSM. Basically, we want to revert the FSM back to the normal response. Once the NPC gave us the item that we want to revert the dialogue back to the normal response. So we want to disable two FSM and activate one FSM here. Basically, we want to activate the normal response. At the same time, we want to disable the eaves drop and the gf name card. Response. But whenever we successfully receive the name card, we want to also disable one of the FSM on the security guy. So we can add this the activate here, and we can disable the modified toilet guy here. So basically, once we talk with this security guy, it will modify the toilet guy, and then it will change the order or the FSM that is activate and deactivated. Here we can just do that now. Basically, we want to activate two FSM and deactivate one FSM here. And here we want you to activate the normal response. And then we want to enable the Ifrops as well the give name card FSM. So once we talk with the security guy, we should be able to get the name card from the toilet guy. But then when we revert the FSM, we want to revert back to the normal response and disabled all of these three FSM. So the next time we try or the player try to talk to the security guy again. It will only run the response, but it will skip this second FSM, which is activating because this can reactivate the gift name card FSM, which will allow the player to talk to this person again and then receive another name card. So it will cause a bug that where the player can receive multiple name card item. Here on the security guy, we want to increase the action. Do, and then we want to direct the modified toilet guy FSM here. And then let's save this and now give this a try. As you can see here, the player is outside of the area, but if I run this, it will snap the player inside the Nai mesh. Okay. Now let's give it a try. Basically, I think we need to change the camera angle here, but y, we can talk to the security guy here. Oh, let's top this. Let's try the whole thing first. Let's try to talk with the toilet guy first. Okay. We only get that response. Now let's try to talk with the security guy. Okay. Now if we go out and then we talk with the toilet guy again, it should have different response. There you go. I've overheard your conversation, and now in our inventory, we have name card. Previously, we don't have it. And I believe you will find a person on this address. Then he gives your name card with an address. Now if we open our inventory here, we have the name card. There you go. And I can confirm this that because if we stop this and then if we press play again, you see that on our global variable inventory, we only have the lighter, and if we open the inventory here, we only have the lighter. So with this system, it works, actually, and we can try it again here. Let's just try to talk with him again and then try to talk to the person in the toilet here. We should receive the name card. And now let's talk with this police officer again. And if we talk with this guy here, it will, yeah, we need to fix this. So it's still giving us another name card here. So basically, we need to disable this FSM. Here, let's check give name card. Oh. Yeah. This is where I forgot. Basically, we have this revert FSM, but this is not being called anywhere. Basically, after we give the name card, we have the chained actions where we can run another FSM whenever this action is executed, so we need to direct the revert FSM here. This is basically will prevent the modified toilet g FSMs to be ever executed again here. Now we can try this one more time and hopefully this works. Let's just talk to the officers right away. And then talk to the toilet guy here. And now we should have the name card. Yeah, we have the name card, and let's talk with the officer again. Now if we talk with the there you go. It keeps saying the normal response here because talking to the police officer again, won't change the FSM active status on the toilet guy. Now we have implement the story for this club hallway scene, and we are going to continue this on the next video. 33. 32 Keep States Between Scenes: Hi. Now, in this video, we are going to continue to work on our point and click playmaker project. Last time we've created the Club Hallway story implementation where we can interact with the Security guy as well with the toilet guy. But there is one issue here that we have now. So I'm going to show you here. Let me just remove the scene here. And let's track the City scene, so it starts from the City scene. Right now, we have no way to keep track the changes or stated changes on a certain object or NPC whenever we switch scene. So for example here, with our password here, basically, if I interact with this password, and then I interact with the door, I can enter the club hallway And if I go back outside to the CD scene here and then try to interact with the door again, you see that it resets itself. We don't see the password anymore, so we need to interact with the password again. And this is not ideal. We want to make sure that object states are safe between scenes. Right now, the states are only safe if we press safe and then if we load. Now we want to make sure that every object that has different state or a possibility of different states get safe whenever those states are changed. So in order to do that, we need to create a couple of things first. First, we need to modify the password. Basically here, this is where the cyt interactions change. For the door here, it's being modified by the password. So we need to insert some FSM that trigger the safe whenever we change the order of the active FSMs on the cital interaction. Here I'm going to create another anti game object. And this is going to be called the Safe state, for example, and let's add a Plamcer FSM. Here, I want to add the template record states as well the load states. So I'm going to add another FSM. And the load states. By default, this record states and load states will work automatically or register itself automatically to the entity safer FSM array on the global variable, as well the entity loader FSM for the load states. This is fine and all, but we need to create some modifications on this template here. First, I'm going to edit the record states here. And I'm going to add a new variable, a type of game object, and I'm going to call this interactable FSM. And basically, we need to expose this variable. And now we need to define the intractable FSMs in order to get all of the action array list. And now since we are putting the safe state or the record state and load sits on a different game object, this won't find the correct variable. So we need to target this to the correct game object. And this is why we need the intractable FSM. Now we can just direct the side door Itraction parent game object here, and this should have the intractable FSM. This is to make the template more modular where we can put this template on different game object and still target the correct intractable FSM. The same goes with the loader state here or a load state template. We want to also create another game object. Let's just call this intractable FSM as well, and then enable the input. And on the first state, whenever we are getting the actions, we want to target the intractable. But in the load states here, we want to add a finish transition, and then we want to connect the finish to the load. So we want to load the data, if there are any data on the scene start. So whenever the scene is loaded, then we want to try to load the states if there are any states that are safe or loaded in the safe manager. And if there are no states with the correct identifier, then this won't trigger anything at all. So it shod behave as we want to. So now we have this, and we need to drag the side door interactions. So let's just call this password safe and copy the name and paste it here. And then we want to also save this to be password load, for example, and then save it here. And now here, we want to trigger the record FSM or the record states here whenever the password is called here. So here we can just add an FSM to the actions of the intractable and then drag the safe state. And this will get the first state in the component here. So this will get the password safe FSM. It will not get the password load. So whenever we are interacting with the password, we want to save the state changes on our side door here. But there is one thing that we want to do as well with the safe manager. Right now, the record state is basically trying to run the template using the run FSM. This will run the safe manager, and it will run the record position or the record states. But right now whenever we are finished recording the states or the position, it will go to the loop all entity, and we don't want to do this if we only want to save a certain state of an object. We only want to loop whenever we run the safe event, then we want to look through all of the entity FSM. We need to create a bulion here to prevent those from happening. Basically, we want to create a bullion variable in the safe manager, and let's just call this loop. Then whenever we are saving, we want to set that b to true. Let's just set bull value here, select the loop and then check the bull value, and this will set the Bulen value to true, and we want to copy this action, and whenever we are going back to the first state, then we want to set this back to falls. The logic is that whenever we are running the safe event here, and we want to do all of this FSM here. We want to enable the loop. So whenever we are iterating through all of the FSM or the saver FSM, this will direct or the flow of the states will go to the correct state here for looping. But we need to create a new state to decide whenever we want to either to loop the FSM or go back to the initialized here. So let's just select all of this here, and let's just move this, and I'm going to create a new state here. And I'm going to call this check for loop, for example. Then we want to add a loop transition as well a finish transition. For the finish, we want to connect this back to this initialize. And for the loop, we want to connect this to the loop all entity FSM. Basically, we just want to do a bull test here. And we want to check if the loop value is true, then we want to lo, but if it's false, then we want to go to the finished transition. And now we want to redirect all of the finished transition on all of the state here to this check for loop. Let's just change this, direct this, this one as well, this one, and this one. Basically, this is what we want to do or what we want to change with the safe manager, and there is nothing we need to change on the load side of it. Let's save the scene here. And now we have this setup, and we also trigger the safe state. Whenever we are interacting with the password. Now we can give this a try and see if this works. Okay. Now I'm going to go to this area here, and let's talk or interact with this door, and we don't have the correct answer now. Let's interact with this password. So now we have the correct answer. We should be able to enter the club hallway, and now let's try to go outside again. And once we are outside, let's interact with this door again. And as you can see here, now we have the correct answer without having to re interact with the password again. So now all of this state are preserved whenever we are changing those states. But we need to always remember to run the record states, whenever the states change here. So here on the password, we trigger this record state action whenever player interact with this password. Because we know that before we are triggering this record states, the order of the active FSM is changed by the second FSM, the activate known password here. Okay. We are done with the states, but right now we need to also create changes or make changes with the NPC move. So for example here, we have this disabled MPC here, and this NPC have a move action. Whenever we interact with this NPC, it will move. We want to also save the transform whenever the NPC or the object is finished moving. So let's drag this to our city scene and put this under the intractable, and let's enable the NPC move here. I'm going to move its position, so it doesn't collide with the bouncer there, and I'm going to also change the target position to be around in this position here. Okay. So now let's save the city scene, and I'm going to show the problem that we are having right now with the NPC move here. So if we interact with this police officer, and then let's say we go to the other scene to the club hallway here. And then we go back outside. If we walk here, you see that the police officer goes back to its initial position. And if we want to preserve the state, then we need to trigger the record transform whenever it's finished moving. So it's quite easy to do this. We just need to make sure that whenever the move is finished, then we trigger the record entity transform and the entity transform so handle the transform whenever we are switching scene. Here I'm going to add an action and then direct this record entity transform FSM to the state here. Let's check the load entity transform here. For the load transform and the record transform, we don't need to add the intractable FSM because we don't want to save the action state or the FSM state, but we only want to save the transform, so we don't need to do that. And here, we need to do the same with the load state template, which is we need to add the finish transition on the first state and then connect the finish to the run action. And basically, we want to try to load if there are any data for this specific entity, and if there are any data are safe and then it's loaded, then we want to try to get those data and then apply those data to this transform or to this object. Okay. So remember, we need to put the record transform to the chain action of the move FSM, and we need to modify the load entity transform. So it try to run the actions on start. So let's save the City scene here. Okay. So now let's test this again. Okay. So I'm going to talk to the police officer here, and he moved. And let's go to another scene by checking the password here and then interact with the door. Okay. And now if we go back to this area here, you see that the police officer is in the correct position. We can always make sure that the NPC reset its previous position. And if we want to do that, we can just make sure that the entity transform FSM doesn't get called here. So you have options to keep the position persist between scene or reset it position between scene for any objects or NPC or intractables that we want to keep track of. And here we can also save here, but we will have an issue here because as you can see, when I leave the scene here, we created an empty member on the entity safer here. So here the element one and element two has no object in it. And this will cause issue in the safe manager. If we go to the safe manager here, and then you see that here under the L all entity FSM here, when we invoke this, this will stop, and it will stop the iterations of loading the data, and we cannot finish loading, and it will cause a buck here. So we need to fix this. So let's just stop here. And to fix this, basically, we need to check if the current FSM is null or not. And in order to do that, we don't have an action to do this, but we have a conditional expression. So here, if we go to the action browser, and then under the logic here, we have this conditional expression. And we can use this to evaluate a certain variable with a certain value in this expression. So I'm going to show you here. Basically, to check for a certain variable. First, we need to add $1 sign, and then we need to type the variable name. And the variable name is current FSM with a space on it. If there are no space, you can just type it right away like so. But since we have a space between the current and the FSM word, we need to add a parent C to close the text here and then add space here. As you can see here, it says that this variable was not found here. But if I add space, then it says that it's false because this is null here. But if we add if this is null, then it says it's true here. So we want to check if the current FSM is null or not. And basically, we want to add a new event here. So let's just add skip, for example, and then add that transition skip. And basically, whenever this is true, if the current FSM is null, then we won't to send to skip here. And basically, this will skip this call method, and it will go to the next entity saver that is available. But if it's false, then we can just leave this empty, then it will execute the call method here. And now we can connect the skip to this loophole entity FSM. And the same with the loader here because we will have empty entries here, for example, let's just save the scene here, and let's give this another try to check if we don't need to interact with the police officer here. We just need to make sure that we see the password here, check the password, and then go to the other room. And as you can see, we have empty member there. And if we go back to the CD scene here, we will have new member, and this will gets added, and we will keep the empty member here. So we need to also fix the load part of it. So we already fix the safe part, and for the load here, Basically, here, we want to check if the carbon FSM is null or not, and we want to skip the call method here. So I think we can just copy this conditional expression here, and then paste it in this state here and put it above. And we can just make sure that if the carron FSM is null, then we want to execute the finish right away, and this will skip the call method. So this is for a safeguard, if for some reason, the entity loader or the entity safer has an empty or a object that is none in its member. So now let's save this, and let's give this another try. Now we should be able to save the game. So the police officer is moving there and let's interact here. Here and then we can go back to the CDC in here, and now let's save this. I'm going to highlight the safe manager and let's see if this gets safe. It's get safe there. Now if we stop here, we can try to play it again. And if we load this, it should load the game. And if we talk to this door here, you see that we have the state saved. And if we go to this area here, we can see that the police officer is in the correct position. So yeah, that is basically how we persist on NPC or interactables between scene. And we will also want to keep track the scene whenever we are saving the game. So we need to add that to keep track which scene when we are saving last time. And we are going to do that in the next video. 34. 33 Park Scene Story Part 1: Now, in this video, we are going to work on the park scene, the last scene of our game. In order to do that, let's create a new scene here inside the subs scenes folder. I'm going to create a new scene here from the menu, and let's just call this part. And let's open the scene here. Now we want to set up the environment first. First thing that we want to do is we want to go to the point click folder here and under the prefabs, we should have the Par prefe. We can use this directly to the scene, and now we have this there. I think we can just delete the directional light, the default directional light. Now we want to prepare a couple of things here. I'm going to create an anti gable check and then reset the transform. Let's just rename this two environment. And I'm going to drag the park prefs to be the child of this environment here. For the main camera, I'm going to select the main camera here, and I'm going to reposition to be around this position here. For example, maybe something like this. In order to reposition the camera, to follow the view that we have on our scene here, we can just select the main camera and then hold control, shift, and then at, and this will align the camera with our view here. Now if we go to our game view, you see that we have the view or the same angle with what we have in our scene here. T. Okay. Now we can save the scene and the next thing that we want to do is we want to create another anti game object. So I'm going to create an anti game object, and I'm going to call this one interactable. And this is for grouping the different types of object that we have in our scene here. And this will holds everything that we can interact with. So here, I'm going to add a new anti game object as a child of this interactable, and I'm going to call this NPC police officer. And here, let's just go to the two tiny people folder here. C mo, and under the prefs. Let's just direct the police prefabs here to be the child of this NPC police officer. Now let's reset all of this position here and also the rotation. And now we can select the parent game object, and we can move this and I'm going to position this police officer around this position here, and I'm going to rotate this so it's facing to this side here. Now if we go to our game view, we can see the police officer. Maybe we can move this a bit back on the Z axis. Maybe around this position and see in our game view. As long we can see it in our game view and be sure that the player can interact with this police officer. This is a good position. For the police officer, there will be a couple of states that we need to create as a child here, an empty game object that will hold different states of interactions. The next thing that we want to create here, I want to create another empty game object to be the child of interactable. I'm going to call this game object blocker. And then I'm going to add a box collider. And then let's move this blocker so it blocks the area here, the park area. I'm going to put around in this position in front of this barrel. And I'm going to disable the perspective mode. Here, for the sizing, I'm going to set the z size to a very small one like 0.2. I's thin and I'm going to create a wall. I'm going to increase the size to 0.4. For the x value, I'm going to set this to 20. It covers most of the view here. I'm going to make this even bigger, for example, and move this to the site a bit. For the y size, I'm going to set this to two, it's around two units or 2 meters. And move this slightly up. One on the y position here. That should be good. Now we have this blocker, and I'm going to this slightly down on the y axis, so it conforms to the surface to the ground surface. Let's increase the y size here to three, for example, and adjust the base position. It sits on top of the ground surface of the park. Now we have this blocker here, The blocker should cover everything. The purpose of this blocker that we don't want to allow the player to interact with the dead bodies that we are going to put next here. Here, let's create another anti game object under the interactable game object, and let's just call this NPC dead body. For this NPC dead body, I'm going to add the male A again as the child. I'm going to move the NPC here. I'm going to rotate this 90 degrees on the y axis and also 90 degrees on the x axis. So I facing down to the ground here, and we can adjust the position of the bones. We can post this. Here, let's just unpack this prefabs, and I'm going to delete the animator component here. Now I'm going to open the child object, expand the BiP object here, and this is basically the bones. If I hold out and then click on this expand button, you can see that we have a lot of child game objects. First, I'm going to select the baseball bat that we have here and I'm going to hide it. Then for the head, I'm going to rotate the head bone, so it's facing this way, or maybe we can just rotate it to so it's facing the other way. Then we can adjust the hand clavicle here to make it more spread like this, and the same goes with the other clavicle. And we can rotate this a bit here like this. For the leg, I think, we can adjust the i if we want, make it something like this. Then once we set up the pose here, I'm going to readjust the position of the parent game object, which is the NPC that body, and I'm going to push this on the or local of this game object here. I s move b slightly below, so it conforms to the ground. And here we want to add a capsule collider, so we can interact with this NPC later, and I'm going to set the y value the height two, maybe around two units or 1.7 units and move the center to be around maybe 0.85. And now we have this here, we should be able to interact once we've disabled the blocker later, and I'm going to enable the s trigger options. For the layer, I'm going to make sure that this is going to be the interactable layer, and I don't want to change the child object, so we can just change only this object here. For the blocker, we want to do the same. We want to change this to an interactable layer. The same goes with the police officer here, we want to set this to interactable layer. And make sure that we don't change the children as well. Now we have set up that body here. Let's add a capsule glider for this police officer as well, and I'm going to set the same value, 1.7 on the height, and for the center, shift the Y axis to 0.85. And here I'm going to add a playmaker FSM, and I'm going to use a template, which is the intractable K. Then for the actions, we are going to set this up here. Basically, there will be a couple of states that we want to set up for the police officer. We want to have the base dialogue, so I'm going to create an empty and this is going to be the base dialogue. Let's add a playmaker FSM and form the template. We can pick the template dialog FSM here. Then here we want to trigger the base dialogue whenever we are interacting with this police officer. Let's just drat the base dialogue here. And we want to create another anti game object, and this is going to be called after bribing. We are going to bribe this police officer to remove the blocker. For this after bribing, we can just add a Plamer FSM, and this is going to be also a dialog FSM, and we are going to set up this later. But for now here on the intractable, we want to expand the action, and we want to trigger also the after bribing here. But we are going to disable the FSM. By default, this bribing FSM won't be called whenever we are interacting with the police officer. I will only be executed once we have activated this FSM. For the base dialog, let's just create a couple message here. And then for the message, can we can just say that police officer, you are not you are not allowed to enter, for example, and then for the second line, we can just say that unless and then with a grin, for example. So we want to give a hint to the player that we can interact with this police officer and we can offer some money to it. Here, we can just enable the ask questions, and just for the, we can just ignore him, and for the yes string, we can just say this give money. For the center FSM, we can just drag this FSM itself to the slot here, and the s actions, and for the yes actions, we want to create another child object that will trigger a couple of actions. Let's create an empty game object here. Let's just call this yes action. For the s actions, we want to add a clacer FSM, and then we want to use the template take item item FSM here, and we want to create a new item. I'm just going to be the money here. Here on the Neta folder and items folder here, let's create a new item definition here. Let's just call this money. I'm going just to copy here from the lighter, for example, I'm going to change a couple of character here. Change the number here. Yeah, we should have a unique get here. For the name, I'm going to call this money for the description. Let's just type this a couple of bugs. For the image, we want to use the money icon here, this one here. The next thing that we want to do here, here under the inventory database. We want to add the money here. Let's just increase the size and for the fourth member, we want to add the money here. And we want to put this money as the default item in our inventory here. Here in the inventory, I'm going to increase the size and then drag the money as the second element of our inventory here. Let's save the seat here and I'm going to save the project, so it will save all of the changes that we have created here in the items folder as well the global variable. Let's go back to the yes actions of the police officer. For the items you take here, we want to drag the money. For failed actions, we want to say or we want to show a dialogue that saying that we don't have this item. For the success item, we want to trigger a couple of things. I'm going to set the sides to two here. For the failed actions, I'm going to create another child game object here, and let's just call this failed action. And add a playmaker FSM, and here we want to run the dialog template, and this is not going to be an option or a question, so it's going to be a message. Let's just type don't have any money. For the s action here, let's just direct the failed actions to the failed actions, and we want to create another anti give object for the succeeded action. Let's just create another anti gm object, and I'm going to call the succeed one Add the playmaker FSM here, and we want to deactivate a game object, which is the blocker game object here. For this FSM, we need to create a new template here. Here, under the playmaker, let's create a new FSM here. I'm going to add a new state here, and I'm going to add the global transition run action. Basically, we want to enable or disable certain game object here. Here I'm going to create two new array variable, and let's just call this two disable. For the type, I'm going to change the two game object, and let's expose this in the input, and let's create another array variable. Let's call this two enable and change the array type also to game object and then enable the input checkbox, so we can set up this value here in the inspector. Basically, we just want to look through all of those. Object here. Here, let's just use the array get next, and then let's just pick the two disable game object. For the result, we want to cache the array that we are iterating to a U variable. Let's call this current game object. We don't need an index for this, let's just add a transition a loop transition and a finished transition. For loop here, basically, we want to create a U state, and then we want to disable or deactivate. Let's just use the activate game object action, and then we want to specify game object, and we want to pick the current game object that we are iterating, and then we want to disable this game object. We want to uncheck the activate options here, and then we can just add a finished transition, and let's just go back to the state here. Let's just rename the loop all two disable, for example, let's just call this disable current O. When we are finished, we want to go to a new state and this one is going to be loop two enable. And here we want to use the array get next again. This time we want to look through the two enable go the array, and then add a transition loop, and then we can just create a new state here. And we can use the activate game object action, and then specify game object, pick the current game object that we are iterating and we want to activate this. Upon finish, this transition or the state, we want to go back to this loop state here, and for the loop event, set this two loop so we can just look through the game object, and we need to store the result to the current game object variable. When finish from the state here, let's just go back to the first state here. Here on the second loop, we want to set the loop event to loop and the finished event to finish transition. The same goes with this first state here, we want to send the loop to loop event and the finish to finish event. Now, basically, whenever we are running these actions, we are going to look through all of the disable array or the game object that we want to disable in this array inspector, and then it will disable it. Then once we finish this is going to look through all of the two enable array, and in this one, we are going to enable we want to activate the game object instead of disableling it. Let's just rename the state to enable current game object. Now we have this state setup. I'm going to save this as a template and here, I'm going to call this template activate multiple game object instead of FSM here, we can just use the safe template in this FSM here. Now we have used this template now. Basically, we just want to disable the blocker here. Here I'm going to add a disable game object here and then drag this blocker game object. In this yes actions, for the first one, we want to drag the succeed action. Whenever we are giving the money to the police officer, we want to disable the blocker game object. Here, we want to add another anti game object, and this is going to be the succeed two, for example, here. Let's just in sued the second succeed child game object. We want to use the template activate multiple FSM. And then we want to enable and deactivate one of our previous FSM that we have set up here. Basically, we want to disable the base dialogue. We want to deactivate this, and we want to activate the after bribing FSM. This is going to make sure that whenever we bribe this police officer, the next response is going to be different than the base dialogue, which is the after bribing. I'm going to add another child game object, which is going to be the succeed third action. Here is going to be just a simple dialogue and it's going to be a message only without a questions. Let's just say thanks for the police officer here. Here in the yes actions, we want to make sure that we are running all of the succeed actions whenever we are successfully giving the money to the police officer. Let's just add the success action again and then drag the third one here. Now, make sure that first the after bribing FSM is disabled, and here I'm going to add a dialogue here, like singing. Something like that. This is the last thing that we want to create is we want to create another dialogue whenever we are interacting with the blocker game object here. I'm going to add an empty child object, and I'm going to call this blocker dialogue, and here I'm going to add another FSM, and then use the template dialogue here. For the message, I'm going to say this let's just say what something like this. This should prevent us and giving the player hint that the player cannot go to the dead bodies. It needs to do something before we can interact with the dead bodies. Another thing that we want to create is the animator. We want to trigger an animation whenever we are interacting with the police officer here. Let's just add FSM here, and we shod have the template. I think we have this one here. The play animation. For the animator game object, we can just direct this mash game object that has an animator. Then here, we can just use the default people, I think. Let's take a look in the animator here. Yeah. We have this talk trigger and we have this talking animation state. We can use this actually. Here in the trigger animations, I'm going just to trigger this talk parameter. Here in the trigger animations, we can just type talk here as the trigger. Then the other thing that we want to add is we want to create a trigger audio. Here let's add another playmaker FSM. Let's just pick the play audio here and let's just pick one of the dialogue here, like Mel C Dog for example. Now we need to always play this trigger animation and trigger audio in our base interaction. Here I'm going to increase the size of our actions in the template in FSM here and drag this trigger animations and audio here. The next thing that we want to do here is in the blocker. We want to add a playmaker FSM, and then we want to pick the template intractable. For the actions, we want to set this 23, and we can just drag the blocker dialogue here, the trigger animation, and the trigger audio here. Now let's give this try. Oh, we cannot try it this way, so we need to open our base scene. Let's just go to the scenes folder here under the sample scene here. Let's just go to the subscene, and then direct the park scene to the scene here. Let's test this out, and I think we need to move the player. Let's just move the player a bit here around this position here. The other thing that I think we need to do is we need to bake the navigation mesh because we haven't done that yet. Here under the park, I think I've already marked this prefab static s. I'm going just to open the park scene. Remove the park scene here under the subse. Let's open the park. We can just save the sample scene here, and then here inside the park scene, then we want to do the bake. Now we have bake the scene here, that save the park scene. And once we successfully bake the navigation mesh, we should be seeing a folder called park inside the sub scene. Now we can go back to the main scene here and then drag the park scene from the sub scene. Now let's run this and give this a try. Another thing that I forgot is that we need to create a glider. I'm going to create an mt game object here, and for this anti game object. I'm going to add a box coli. I'm going to set the y size to 0.2, and I'm going to increase the x size to let's say 30 by 30, for example. We have something that is covering our scene, from the side view, I'm going to move this ground colier. I lies on the tre surface, let's change the layer to ground here and I'm going to enable a trigger here, let's just call this ground glider. Now we can save the park seal here and test this again. Here we should be able to walk around and I'm going to mute the audio here, and basically if we interact with this blocker. Na sgment. The police officer is basically saying, what are you doing? Na named the sage mail. We cannot interact and let's try to interact with this police officer. Let's just ignore him for now. When we are ignoring him, we want to make the police officer say. We are going to do that. Next thing here. Let's just stop this. Here under the interactable I think on the base dialogue here, we should have the no action. Let's just increase no actions, and let's create another anti gave object. Let's just call this no action. Then here we want to add a claim maker FSM and pick the di time plate here, and let's just type police officer suit yourself. And here, I'm going to put this below the yes action here. For the base dialogue, I'm going to direct the newly created no actions as then actions in our FSM here. And we can save the park scene again. Now let's try this again. Okay. And we can try this here if we remove the money from our inventory here and then try to interact with this police officer. And we want let's say we try to bribe him. We we should not be able to You should get a response here. Let's just check because there are no response failed actions. Here, the issue was very simple, actually. I forgot to put the s actions in the base dialogue here. Basically here as you can see the yes action is till set two none, so I need to drag this yes action to the slot here, and that sho fix this. Here, let's try this again. Let's try to interact with the police officer here and then I'm going to remove the money from our inventory here. Let's just try to give him money and it says that you don't have money because it failed to give the money here and it triggers the failed action. It triggers this dialogue here. Now I'm going to stop this again and then try this again and this time we want to give the money from our inventory here. Let's just give him this money here and it says, thanks. Now when we are interacting with this police officer, again, it will just sing and it will not show the base dialogue anymore. Here, if we see that we can see that our blocker is now disabled, we should be able to walk around and we should be able to try to interact with this dead body here. We are going to continue this in the next video. 35. 34 Park Scene Story Part 2: In this VO, we are going to continue working on the park scene, and we are going to create the ending cut scenes for this scene here. So let's jump into it. First, we need to create a new anti game object that will hold the cut scenes data. So I'm going to create a new game object here, and it will create by default in the sample scene. So I'm going just to click and then direct this game object to the park. And we can discard the changes on the sample scene here. And here in the park scene, I'm going to rename this game object en cut scene. Let's just reset the transform here. Then we want to add a couple of child object in this cut game object. The first one, we want to add the female model. I'm going to go to this folder here, Titmo, and under the prefet I'm going to direct the demo female. Now we have the female game object here. The next thing that we want to do is we want to add a new camera as the child object here, and then we want to create another anti game object that will hold the dialog signal that we want to trigger. Basically, this will hold all of the game object that we'll have like a dial of FSM, and we can trigger each of those dialogues via the cut sins or the timeline. I will show you this later. Here I'm going just to call this dialog group, or we can just call this dial receiver. And I'm going to create one empty game object, and let's call this dial one. And for this game object, let's just add a Pla Maker FSM, and then we can add a template dial of FSM here. Let's just leave the settings as it is right now. Here for the dial up receiver, we want to add the signal receiver. We are going to setting this in a bit later. Now, first, we need to add a new timeline to this cut scene game object here. Here I can just open a timeline window and if you then have this opened, you can go to the window menu and then sequencing and then pick timeline. And then we'll show you this window here. Okay. So now we can just create a new timeline, and we can save this. So I'm going to go to the SS folder animations, and I'm going to create a new folder called sequence inside the animations folder. And then here, we can just save this timeline playable format. Now once we save this, we should have this interface where we can add tracks, we can direct the timeline here. So first, we want to animate this female game object. So let's create a track group, and I'm going to call this female gao, for example. And the neat thing with the group is that we can create a couple of tracks inside this group, so we can order or organize our timeline nicely and less cluttered than without any track group. Here I'm going to create two animation t, two different animation track. Then the last one, I want to add the activation track. Yeah. Here we can just drag the demo female model here to this animator slot and then the second one. For the third one, we want to also direct this game object and we want to activate for the length of the cut scene here. The next thing that we want to do is we want to adjust the camera view first. I'm going to select the camera game object here, and I'm going to change, for example, I'm going to change the view to be around this. Or maybe make it like this, for example. And the reason is that we want to make sure that we will able to put the female outside the camera frame and then start running going inside the camera frame. So here with this camera set that, we can just hold control shift F and this will align the camera there. And the next thing that we want to do is we want to pick the sens again, and now we want to animate the female model here. Here, for the second animator track here, I'm going to press this recording button here, and then we can just select the female model here and I'm going to direct position. And this will create keys there, as you can see here. In the first frame, we have a new key. If we go to the camera view, we want to make sure that this female is from this position here. Let's just put this way out of camera here. And I'm going to change the y axis as well, the position. It sits above the road or the three D mesh. And here maybe we want to I think we want to create a key frames around frame 90, so we want to make sure that the female starts running from this frame or around frame 100. I'm going to add a key all animated here. It will create key frames there, and then I want to go to frame 150, for example, or 160. I'm going just to type it here. With the female module selected, I'm going to move this female, so it stops around this position here. In front of his husband, for example, and rotates a bit. Here we be able to see the animations there. And here I'm going to create rotation animations. It's running straight first, and then it rotates. We can addit these animations later. I mean, the timing, we can change the key frames. But for now, I think they should be enough. The next thing that we want to do is we want to disable the animations button here, so it doesn't animate anymore. And for the first animation track, we can add a clip. So here I want to add a running clip, starting from Frame 100. So let's just right click here, add from animation clip, and then we can pick the female run and make sure that we pick the run only without the RM suffix because this is the root motions where the animation has the translations information. So we want to use the animation that is running in place. Now, as you can see if I run this, we can see the run animations there. We need to make this keyframe longer so we can just drop a click on this track here and it will open the clip in the animations window. And basically, we want to make sure that this part here, we want to scale the animation. In order to scale this, we can just drag this blue lines here near the key frames, and this will stretch the keys. I'm going to make sure that maybe it stops around this point here. Now if we go back to the timeline, we should be able to see that our animations now ends in the different frames. Here, if I scrub this again, you can see the animations. I think this runs much better. And we can loop the run animations by dragging this clip here, and this will loop. And around this position, I want to stop the animations. There, it stops. And then we can add new clip female idol, for example here. Let's just make this very short idol, and we can drag this idol and make sure that this idol is overlap with the run animation, so it will create transition. We can just drag this and make it overlap like this, and this will be the transition value here. Here if I scrub this, you see that at the end of the point, it transition to the idol there. Here I'm going to add a new animation clip and this one is going to be the female death. This is not for the death animations actually. I just want to make a fainting animation, so we can just use this animation. Just move this. We don't need to change the timing and make sure that this death animations overlaps a bit with the idol. There you go. Now we should be able to see that it will stop the animation and here it will faint. And here we need to make sure that the active track here, we want to extend this, so it doesn't make the female game object disappear like so. So here let's just set the end time around this position, for example. I'm going to just to type it to make it round, 260 and then direct this. So we should be able to see the female game object all the way through the p. Okay. So the next thing that we want to do is we want to also add a new active ation track, and this is going to be outside of the female game object because this is going to be the active track for the camera. So we want to enable the camera during the cut scenes here and make sure that the length is the same as the previous timeline or here a frame 316. We want to make sure that the track is the same length as the one that we have above here. Okay. The next thing that we want to do is we want to add a track or senal track here, and this needs a senal receiver. For this, we can just drag this dialog receiver here and we can trigger different signals, and I'm going to show you this inhibit. Okay. Next thing that we want to do is we can just save the scene, make sure that we have saved all of the changes that we've created. Here, for the female game object here, I'm going to disable the preview. And for the female game object here, I'm going to select the knife model here and I'm going to make sure that the knife model is selected and hide this because we don't need this to be shown. Then we want to also disable the female model by default. It's not feasible during the gameplay, and we want to also disable the camera here. It's not activated during the gameplay. Let's save the park scene again. The next thing that we want to do is we want to create a new signals for the animations dialogue here. Here in take the animation sequence. We'll create a new signal, and then let's just call this dialogue one, and we can uplicate the signal. And this is going to be the end dialog to. Here inside the dialog receiver, we can add reactions. I'm going to add two reactions. For the first reactions, I can just pick the first end dialog signal here. For the second, we can just pick the second dialog. Here we can trigger the dialogue here. Here on the first dialog, I'm going to add a new message, and I'm going to type wheel and he will mention something like, this is not good, for example. And out of the worry of the wife that's going to be said when she sees the scene. We'll mention about this. And then we can just duplicate the dialogue here. I'm going to change the name the game object name here and for the second dialogue, I'm going to type this wife. And then that's just like screaming like so. Then here in the dialog receiver, we can add a new reaction event, and we can direct the first dialog to the first slot here, and then we can go to the playmaker FSM, and this, basically, we want to force the run a global transition. In order to do that, we can use the send event method here and then type the global transitions name. It's going to be run action with all CAPs the same goes with the second reaction here. I'm going to direct the second dialog. Here, we can just pick the playmaker component FSM, and then we can just use the set event methods as well. Then we can just type run action here. Now we have set up the receiver. In the timeline here when we select the can s, we can trigger those receiver. Here, maybe around frame 20, I'm going to add a new senior emitter, and we can pick the first dialog here. And when the wife came running and arrived. Maybe around this frame here, we can just start emitting the second dialog signal, like so. Here, this should play the animations. And now we need to trigger this cut sins from playing when the player interacts with this dead body PC here. Here in the end cut scenes game object, first, we want to disable the play on awake. We want to make sure that this cut sins doesn't get played automatically when the scenes start. And then here, we can just expand the interactable group here and then select the NPC dead body and make sure that it has a capsule glider. We already done that. In the last video, we also set the layer to interactable. And now we can just add a playmaker FSM, and we can pick the interactable template. Then here, we can add a new child object, and this is going to be the trigger cut sin FSM. In order to do this, we need to create a new FSM, and we need to create a new template FSM here. Here I'm going to add With this selected here, let's just press edit here. We should be able to edit the FSM now, and I'm going to add a new state here and I'm going to add a global transition custom event, and then pick run actions. And here, basically, we want to trigger the timeline. In order to do that, we need to know the type of the timeline component or this playable director. So in order to do that, we can just select the FSM here and then drag the cuts in game object that has the playable director component attached to it. And then here we can just use like score method here, and now we have a method that can trigger a method from this component here. Now in order to make this easier, we know that the Unit engine playable playable director. So here we can create a new object variable. And let's call this timeline. For the type of the object, we can change this to Unity engine and then go down here under the letter P. We should have a sub menu called playables, and here we can pick the playable director. We can also expose this as an input in the inspector And the next thing that we want to do is we want to make sure that this is on the second state. I'm going to copy the selected actions and then paste this on the second state and delete the one from the first state. And for the second state, we can just pick a variable timeline, and for the method, we can just trigger the play method here. Now we have a FSM that can trigger the cut ins to play. Here I'm going to save this as a template. And I'm going to call this template trigger timeline. Can just use the safe template here. Now we can trigger the playable director, so we can just drag this cut scenes here. Then in the main NPC that body game object, we can trigger this cut sins by increasing the action size and then drag the trigger cut sins game object into the slot here. The next thing that we want to do is we want to make sure that the z directions of this game object is facing this way here. We need to change that. I'm going to recept the rotations of this game object, and I'm going to rotate the male model instead. I'm going to rotate 90 degrees on the y axis and also 90 degrees on the x axis here. Now we need to change the orientations of the capsule collider here. Here we can just change it to the x axis. Now we have the orientations correct, but we need to make sure that we reset this value here, and then we can add 0.85 on the x axis. It fits to the mesh here, as you can see. Now if we select this and select the Move tool, the Move gizmo, as you can see here, we have this z axis correct. I'm going to move this collide a bit to the center, for example, set it 20 here, and then change the mesh instead to be like maybe negative 0.85 on the sorry. Not this here. I think she. This should be negative 0.85 there, and now it should be on the middle. The z axis here, and now we can just move this body back to its position. Now this will date the stopping position of the player when interacting. Now let's save the scene here and let's give this a try. So here we need to interact with. Okay. One thing that we need to fix is the police officer position here. So let's just do that before we continue further. I'm going to reposition the y axis, so it stays above the ground. Maybe like so. Yeah. Let's save the scene again and test this now. Let's just interact with the police officer here, and then let's just give him money, and now we should be able to walk around and we can interact with this dead body. Now as you can see here, when we are interacting, we can see the timeline here playing, and we need to fix the timing of dialogue, but that is an easy fix. Now, let's wrap up this cuts ins here. One thing that we need to fix is the timing of the dialogue here. So in order to fix that, I've already adjusted the First dialog signal here, I put it on the very start of the cut scenes. And the second one, I put it around frame 190. So you should have enough space between dialogues to finish, but user can also click it to finish up the text from writing. The last thing that I want to do is I want to transition the scene here to a menu scene that we haven't created. So for now, we can just create a more scene here. I'm going to create a new scene here inside the scenes here. I'm going to create a new scene and let's just call this menu, and I'm going to open the scene here. Basically, I just want to put a text object in the Canvas space. Let's just zoom out here and I'm going to set up this very quickly, change the UI scale mode and then set the match 0.5, so it match the width and height. And now we can center the text here by selecting the text object and under the direct transform, we can use the anchor presets here and then hold all and then press the middle one. This will center the object, and I'm going to center the alignment as well and change the text menu. And then for the main camera, I'm going to change the background or clear flags to solid color and then change this to color of black. So here we have this menu on top of a black background. Let's just save the scene here. And the next thing that we want to do is we want to put this menu in the build setting. So here, let's put the menu to the Bild settings, and we also need to put the park scenes to the build menu here. I'm going to reorder this so it's organized nicely and put the menu as the first scene. So now I have set up the scene in the build settings. I'm going to save the project. And now we need to go back to the main scene or the sample scene here, and I'm going to drag the park scene to the scene here again. Okay. Now let's create the transition. First, I'm going to create a new Canvas to be the child of this cut scene, so I'm going to go to the menufolder, and then pick Canvas. And for the Canvas, we can just set this to anything. I'm going to set this to scale with screen size. We can set this 0.5. For the match value. And then we can add a image hot on the Canvas here, and I'm going to stretch this to full screen. So I'm going to click this on the anchor preset and then hold out, and then I'm going to pick the most bottom right presets. And this will stretch the image to cover all of the screen here. So here for the image, I'm going to change this name to failer, and we can just set the color to black and set the transparent or the Alpha Vu 20, and we can just disable the recast target, so it doesn't interfere with the cast, the clicking, the UI and the scene casting. Here, under the Canvas, since we don't need any interactions with the Canvas, I will just delete this graphic recster here. Okay. Now we have this fader and let's go back to the cuts in here. And basically, we want to animate the fader, so it start fading from this frame here, for example. So here, I'm going to create a new animation track, and I'm going to drag the fader game object. And this will ask to create an animator, so we can just create animator on fader. And basically here, we can just enable the recording button and we can set up the fader. I'm going to change the value. Alpha value, and then put back to zero, so it gets recorded and basically, I just want to create a new key frame with an alpha value of zero in this frame here, and nearing the end, maybe ten frames before the end in frame 350, I'm going to change the color to full black or opaque set transparency to 100. Now we have this here. I'm going to disable this recording mode and here back in the project in the data folder, sorry in the sequence animation sequence folder, I'm going to duplicate the signal emitter here. And then I'm going to rename this to go to menu. I'm going to add a new reactions in the signal receiver here. I'm going to add new reactions and I'm going to pick the go to menu. And then we can add a reactions in it. I'm going to create a new empty game object. And I'm going to call this go to menu. Let's add a playmaker FSM. Here, basically, we just want to create a state where we are transitioning to the menu scene. Let's just add a global transition. We can just use the run actions and we can trigger this transition from the set event later in the signal receiver. Here on the state. Let's just we can use the load scene asynchronous. And we can just use the by name and we can use a new variable. Let's just create a new variable. Let's just call this target scene, and we want to activate the allow sine activation. Basically, this will open the scene once it's fully loaded because we can delay the scene loading by pressing a button, and if we want to do that, we can just disable the all sine activation. Okay. Now we have this target scene. I'm going to expose this, and I'm going to type menu. And this is the mockup scene that we've created previously here in the scene. And now that we have this FSM. We have this state load scene asynchronous in the second state with the run actions global transition. We can go to the signal receiver and then directly go to menu here. And then we can pick the playmaker FSM, and then we can just send an event, and we can just use the run action. Here. Okay. So now that we have created this signal and the reactions back to the timeline, the end cuts in here. We can go to this frame, frame 350. And then on on the signal track, we can just right click here, and then add signal emitter, and then we can pick the G two menu here. And this will trigger this sent event to the good two menu FSM here. Okay. So let's save the park scene and now let's give this a try. Okay. So let's talk to the police officer. Okay. So let's give him money, and then let's interact with the dead body here. Now we have this. Once it's finished, it's fade out and then it opens the menu sine, and later we can continue working in the menu sine to create interactions. 36. 35 Connecting City to Park Scene: Hi, in this video, we are going to tie up our gameplay, and basically, we need to create a way to transition from the CT scene to the park scene, and we haven't set up that yet. So here, I have the sample scene and the CT scene opened. I'm going to add a new game object as the interactable, so expand the interactable game object. And then we can add an empty game object, and I'm going to call this taxi. For this taxi here, we can go to the project folder. Under the point and click folder here, we have the models folder inside the models folder, we should have the taxi three model. Let's strike this taxi and make this object as a child of this taxi game object here. And now we can move the taxi game object here and I'm going to move it to be around this position here. I'm going to move the child game object, so it's centered, for example here. Then we can just move the taxi game object here. Move it to this position, for example. For the taxi game object, I'm going to change the layer to intractable, and we can just select know this object only, so it doesn't change the child object. And I'm going to add a box coller. For the box cooler, I'm going to set the size 24 on the x axis, and then I'm going to set the y axis to two for the z axis, I'm going to set this also to two. For the center, I'm going to change the y value 21. It's offset and it aligns correctly with our taxi model, so we can click on it. Here I'm going to add a new playmaker FSM. And for this pimter FSM, we are going to use the template intractable. And for the type, I'm going to change this to the top icon, and I'm going to increase the action size to one here, and I'm going to change the z direction of the parent game object. As you can see now, the z is pointing that way, so I need to make sure that the z is pointing to the opposite direction here. So here we can just rotate the parent game object, 180 degrees on the y axis, and then select the child game object and then rotate this back to 180 180 degrees in the Y axis here. And we can just remove the negative sign on the position here. So it's inverted, and now we have the car or the taxi model back to its position, and it fits with the collider as well. So now we have this setup. I'm going to set the stopping list maybe to around 1.7. And the next thing that we want to do is we want to add a couple of anti game object as a child of this taxi game object. So the first one, we want to check for name card. So we can just call this check for name card. And for checking the name card, we want to add a playmaker FSM, and we can use the template take item FSM. And here, basically, we want to add a functionality where this FSM can also only check the item instead of taking the item from the player. So here, let's just press the edit button here, and here we want to add a new, a bleen variable. And I'm going to call this check only, and I'm going to expose this bulion so we can change it here. And here, basically, whenever we are successfully checking the item, we want to go to a new state, and we can call this state check gole option, for example. Basically, we want to add a finish transition, as well a skip transition that we have defined before, and it should be available in the custom event here. So here I'm going to use the skip one here. Basically inside the state, we only want to check for a bullion, so we can use the bull test action. Let's check for the check only variable, and if it's true, then we want to skip and if it's false, then we want to go to finish. Here basically for the finish, we want to go to the gift state, and here for the skip transition, we want to go to the first state. So now we have this here. And basically, we need to make sure that we run the success or yeah, the success actions every time we have the item. So instead of doing it here, we can just cut this action here and we want to do it now in this check bull option state, and put this above the bull test here. And one thing that we need to make sure here, we need to make sure we disable the finish event. Otherwise, the bull test will get skip. So I'm going to set this to none, and I'm going to let the bull test to handle the transition of the states. We want to only trigger the success action here. So now we are done with the modifications of the template take item FSM. If we go back to the check for name card here, we should have this option here. And for this check for name card, I want to enable this option, so we don't lose the name card that we are going to show to the taxi driver. So here for the item to take, we can just select the name card. And we need to add the fail actions sides 21, and for the success action same 21 here. Okay. So I'm going to add another a couple of another child game object here. And this one, I'm going to call this no name card. And for the no name card, I'm going to use a simple template dialog FSM here. And for the message, I'm going to set this to taxi driver, and I'm going to say going somewhere, Mr.. And this is going to be a simple dialogue. And for the other hid gate object, I'm going to call this H name card. And for this H Name card, I'm going to also use the template dialog FSM here. And for the message, I'm going to type taxi driver. Do you want to go do you want to go to the address on the name card, for example, we can set this as a questions for yes. We can just set this to yes. For no, we can just set this to no, and then we want to set the sender FSM. So as directly has a And for the yes actions, we want to enable one FSM here and we need to create another anti game object, and I'm going to call this switch scene. And here we want to add the playmaker FSM. We want to use the template switch scene. And for the target set, it's going to be the park seat, so we can just t park here. And now inside the H Name card FSM, we want to direct the switch Scene game object to this yes action here. Okay. So now we have set this up here. Let's check one more time. Okay? Now we need to add this failed actions and the success actions to the check for name card game object. So for the no name card, we want to go to the failed action. And for the H Name card, we want to set this to the success actions. So we can save the scene here. And then on the root taxi game object, we want to check for name card game object to be the element or the FSM that we want to trigger. We can save the scene here, and now we can test this. So Right now, if I talk to this taxi driver, we can't do anything with the taxi driver here. So we need to get the name card first. Let's go to the club hallway. And here let's talk to the police officer. And now we can talk to the guy in the toilet, and we should get the name card. So here now, in our inventory, we should have the name card in it. So let's go to the City scene again. And now let's try to interact with the taxi driver. And first, I want to try to say no and see if we still have the name card. There you go. I select no, and we still have the name card, and in inventory, we can still see the name card in it. But if we interact again and then we pick yes, we should be going to we arrive in the park scene here. And there is an issue here because, for example, if we transition to the park scene, we started inside part of the crime scene here, so we want to prevent that. So we need to modify the park scene. In order to do that, I'm going to drag the park scene to our scene here. So let's go to the scenes folder, sub scene, and I'm going to drag the park scene, and now we should be able to see the park scene. So for the park se, let's just adjust all of the park scene game object here. Basically, we want to select all of the park game object here. And then we want to move them all together, and let's move the park scene so we set it like around this position here. So the starting position, we will be around in this position here, the player near the taxi, and then when we transition to the park scene. We should be in the area where we cannot enter the crime scene yet. So we want to make sure that position. So let's just save the park scene, and let's remove the park scene here. Okay. Now let's test this again for testing this. Let's just increase the size of the inventory and then add the name card. And let's interact with the taxi here. And press yes. And now, as you can see here, we are starting in this position, and we won't be able to go to the crime scene unless we talk to the police officer. And I want to check for one thing here. I want to make sure that our cut scenes is working as expected. So here, let's just give money to the police officer, and then let's interact with the dead body here. Yeah. We still have the cut scenes working correctly. Okay. So yeah, that is how we want to tie our city scene to the park scene. And in the next video, we are going to implement how to save the current loaded scene into our safe file because right now we don't have that implemented yet. 37. 36 Saving Loaded Scene: Hi, in this video, we are going to continue to work on our playmaker point and click game. And in this lessons, we are going to implement to save the current loaded scene into the safe file. In order to do that, first, we need to expand our sample scenes, expand the managers, and then we need to create a new object here. And then I'm going to call this SN I. And for the scene in it, I'm going to add a new FSM here. Basically, I just want to load the scene the default scene that we want to load or the child scene that we want to load by default here. Here I'm going to add a new variables. I'm going to set the type to string, and I'm going to call this start scene. And I'm going to expose this as an input here. Here on start, I'm going to add a new load sin asynchronous action. And then for the scene reference, I'm going to use the scene by name, and I'm going to pick the start scene variable here, and we want to set this to additive, and we want to enable the all scene activation. And this will load the start scene by default. So now we can just remove the City scene from the sample scene here, but I'm going to do this later. The next thing that we want to do is we want to access the safe manager here. But we need to create a new variable in the Safe manager. So we want to keep track the current loaded scene in the Safe manager. So here in the Safe manager, I'm going to create a new variables, a type of string. And I'm going to call this current loaded scene. For this variable, I'm going to save the value whenever we are saving the data here. Here inside the save all data state, we can just add a new string a entry, set this 21 here, and we can set the first element to the current loaded scene. So this will save the loaded scene. But the next thing that we need to do is we need to set this loaded scene to a scene that we are currently loading. So for example here, in the scene in it, because we are loading the start scene on start, then we need to save the scene that we are loading into that string variable. In order to do that, we can just use the set FSM string. And then we have the global access to the save manager. So we are going to change the game object to specify game object. And then we can use variable here, and for the variable, we can use the global variable and then pick the save manager. And here we don't need to specify the FSA name, but we need to specify the variable name. So for the variable name, we can just type current loaded scene. And this is the variable name that we've defined previously in the safe manager. And now for the value, we want to select the start scene value, and we want to put this above the load asynchronous action. And we want to make sure that this is an action sequence, so it will get executed in sequence. It will execute this one first, and then the next it will execute this one. And then I'm going to add a next frame event. Because by default, the safe manager might not be initialized yet. Because we are assigning the safe manager on start here. Here, as you can see here on start, we are setting we are getting the owner of this safe manager FSM, and we are saving this to the global variable safe manager. So this might create race condition if we don't use the next frame event on the scene in game object here. So I'm going to move this next frame event to be the top actions in the stack here. And this will make sure that we are delaying the execution of these two other actions after the next frame. So by the time we are setting the FSM string here, the safe managers should be already initialized. Okay, so we can just ignore this error because we are not sending. We are using this action sequence. So I'm going to minimize this, and I'm going to save the sample scene. And the next thing that we want to fix is we want to modify the template switch scene FSM here. Here in the interactable cyto interactions in the success response. We have this template switch scene, so we want to edit this here. And basically, whenever we are loading the sine asynchronously, we want to set the current loaded sin string variable in the safe manager to the target scene that we are loading here. So here, I'm going to use the set FSM string again. And put this before the load scene asynchronous here. And for the game object, I'm going to specify game object. And then we can pick the safe manager. And for the variable name, we can just type carbon loaded scene, and we want to set this value to the target scene. Okay, so this should do the trick. The logic is that whenever we are loading scene, we want to set the current loaded scene in the safe manager to the target scene that we are loading. Because in a moment when we are executing this load scene asynchronous, then we should be transported into the new scene. So we want to set the current loaded scenes always to the new scenes that we are loading. That way, whenever we are pressing the safe button in the safe manager, then the current loaded scene will get saved into the JSON file to our safe system. Okay, so now, I think we can just remove the CT scene here. And then here in the scene in it, we can just input C in the start scene here, so it will load the C scene by default. We can save this. There's one thing that I forgot here. In the safe manager in the FSM here. We are saving the current loaded scene here, but we need to load that as well. So here whenever we are loading from the disc here, we want to enable the string variable, and we want to save this to a new variable. I don't want to overwrite the current loaded scene, so I'm going to use a new variable, and I'm going to call this saved scene. And here, whenever we are refreshing inventory, we want to go to the new state first. And here we want to rename this to load saved sen. Here, basically, we want to use the load sen asynchronous. And we want to use the scene by name, and we want to use the save scene variable here. Let's set this to additive, and we want to allow scene activation. At the same time, we want to unload sine asynchronous here below, and then we want to use the scene by name here, and we want to use the cirro loaded scene. This way, whenever we are loading the scene, it will try to load the safe scene, and then it will remove the current loaded scene. So if we start a new game, we start in the City scene, but our safe state have the information that we are in the club hallway when we are saving last time, that it will try to load the club hallway in the load scene asynchronous, and then it will try to unload the city scene here. And once we are loading the safe scene and we unloaded the previous curn loaded scene here, we want to set string value or yeah, we can just type string here, and we can use the set string value here. And basically, we want to set the current loaded scene into our safe scene. So because we are loading the safe scene here, as you can see, we want to set this current loaded scene to the safe scene. And now we want to add a finished transition, and then we want to connect this to initialize. Okay. So now we are going to test this. So first, I'm going to run the game, and let's try to go to the club hallway. Here and let's interact with the writing and then go to the door. Press help. So I'm going to save the scene. I'm going to save the game now here in this game saved. So now let's stop and then let's press play, and let's try to load the game. And here, as you can see, the saved scene is working. We managed to load the clap hallway, and we managed to remove the city scene. So it removed the current loaded scene, and then it tries to load the saved scene. And we can go back to the CT scene here. For example, we can try to save again. And if we try to load this scene again, It loads. So yeah, I'm going to create a new safe where we are in the club hallway, and I'm going to show you one bug that we are having currently, so we need to fix the bug here. So I'm going to save this in the scene again here. And now let's try to run this. And while we are going to load the scene, I'm going to walk very far and then try to load this. And as you can see, it starts it loads the scenes, but it tries to move the player to that position. And if the player cannot arrive, it will keep playing the walking animation. So we need to fix this. First, to fix this, we need to add a new global event in the player game object and the click to move FSM here. I'm going to add a new global event called arrived, and I'm going to broadcast this event, so it's accessible from another FSM. And I'm going to add that global transition to the RV that we just created. Here. And basically in this arrive here, I'm going to set the speed of our animator using the set animator float here. I'm going to copy this action, and then paste this arrive in the RF state and then put this to the top stack here. For the value, I'm going to select the variable and set this value to zero, so it will stop the walking animations whenever we are arriving. Then the other thing that we want to modify is we want to modify the load transform template here. I'm going to press dit here. Basically, I want to create a function that where we can chain another FSM when we are finished loading. Here I'm going to add a new array variable, and I'm going to call this chained FSM. I'm going to expose this as an input so we can assign another FSM here. For the type, I'm going to change this to a object, and then I'm going to pick the playmaker FSM here. O Go back to the state here. I'm going to use the run FSM action. And for this run FSM actions, I'm going to pick the action run FSMs. And for the actions, I'm going to pass this chain FSM that we've just created. So I'm going to set this to chain FSM here. And then we don't want to do anything here. Okay. Now we have this implemented. I'm going to create a new playmaker FSM on the player game object. So let's just add the playmaker FSM here. Put this above the audio listener. A And here, I'm going to add this Oh, I minimize this by mistake. So I'm going to addit this FSM here. And then I'm going to call this warp agent. And basically, I'm going to add a new state here. And for the second state, I'm going to add a global transition run action. So we can invoke this FSM using this chain FSM because the run FSM action will trigger this run actions on all of the FSM that we are going to list in the chain FSM variable here. So here, basically, I want just to get the position. Of the owner. When we are loading, we should get the position, and we want to save this to a new vector called current position. Then I'm going to set this space to world, and I'm going to enable the action sequence here. I'm going to add agent warp action. This basically will warp the object to that position, and then it will clear the set destination. The agent will be in the correct position. Using this current position that we are getting here. So it will override the destinations and it will position the agent in that position correctly. So for the new position, we can just use variable, and then we can just use the current position here. And we don't need to set anything here. And basically, below here, we want to use the sand event. Action. And for the target the event target, we want to use the game object FSM here. Use order because we want to target the arrived transition or event on this click to FSM. So here we can just pick the click to move FSM here, and we should be able to pick the arrive. Transition here, and this do the trick. So I'm going to save the scene here. Now that we have created this warp Agent FSM, I'm going to increase the size of this chain FSM and then drag this FSM. So basically, whenever we are finished loading the transform, whenever we are loading the game state here. This will trigger this warp agent, FSM, and then it will try to get the current position because this is going to be the loaded position. If we execute this in the same frame when we are finished loading it. And then it will warp the agent to this position here. That we clearing the previous set destinations. So here, let's just save the sample scene here, and let's test this again. Now we know that we have the safe in our club scene. We can just try to move this far away and then try to load the scene. And as you can see here, we see that the player was moving to a certain distance. And then when we are loading the scene, it loads the character correctly and the character doesn't move anymore. D try to move to that position that we see in the previous bugs. So yeah, that is basically how we set up the safe scene. So we can save the scene whenever we are in a certain scene, and we can continue playing in that scene. 38. Bug Fixing: NPC Move Template Fix: In this video, we are going to improve the NPC move. Template, and this bug is reported by Niko Tansen. So thanks Nicole for informing the bug. Here, basically, I'm going to show you the issue. So I'm going to run the game. And now we have loaded the game In the C here, in the interactables, we have this NPC move, the police officers, basically. And I I select the NPC move here and we highlight the playmaker FSM here. You can see that we have defined the interactable position on the start. And when we run or we interact it, it runs to the interactions, and it doesn't define the new interaction or interactable position. And I need to do two clicks until it gets defined a new position. So we want to fix this. And in order to fix this here, basically, we need to open the template, the intractable templates, and here we need to change a couple of things here. Here on the start, we want to define the position, and then we want to go to a new state, which is going to wait for a mouse peak event. So here I'm going to move this slightly above, and then I'm going to create a new state here. And basically, I'm going to copy the mouse peak event here. And I'm going to move the mouse over event to the second state here. I'm going to add a new over transition. And I'm going to connect this mouse over to the switch cursor, similar to the divine position here. And in the divine position here, I'm going to remove the mouse peak event, and I'm going to change the transition event to finish. And I'm going to connect this transition event to the second state here. And here, let's just call this wait for clicks. And now we need to create a new state to redefine the position here. First, we need to create a new global event, and let's just call this redefined position, and we need to make sure that this global event is checked. Then I'm going to add a new state here. Let's just call this redefined position. And I'm going to add that global transition redefined position, and I'm going to add a finished transition that goes back to the weight for click state here. And basically here, we want to do the same as we do in defined position. We want to set the transform directions, and then based on the forward of the NPC or the owner. And then we want to multiply with the stopping distance, and we want to add this direction vector to the new position, which is the target position. Here I'm going to copy all of this three action here. And then I'm going to paste it here. And basically, for the target position, we are going to send a new vector from another FSM. Remember, we have this target position vector with capital T and capital P, and we don't want to use the get owner and position in this redefined position state. So now we have modified the template intractable. We need to modify the templates move PC here. Let's just open this here. And basically whenever we are interacting, we trigger this run actions, and then we set the destinations to the agent. We want to update the interactable position on that template interactable FSM. So here, basically, if we open the CD scene here, I'm going just to direct the CD scene. And we see the NPC move here. The intractable should have the name intractable. So we want to target this FSM. Here, we need to re open or we can select the move FSM and then we can addit the template here. So in the move state here, basically, we want to set a vector te FSM, and then we want to send the FSM name here. It would be better if we expose the FSM name in the variable on the template move NPC, so I'm going to add that interactable FSM variable. And for the type, I'm going to change this as string, and I'm going to expose this as an input variable. So instead of using FSM name, I'm going to pick the interactable FSM. For the variable name, we know it's target position with capital T and capital P. And then we want to set the value of this target position here. So let's just set this target position after we are setting this. Then we want to send the redefined event. Redefined position event. So let's just send event. And for the event target, we want to select the game object FSM. For the game object, we want to use the owner and the FSM name, we want to do the same. We want to select the interract FSM variable. And then we want to send the global event redefined position. Okay, now let's save the project, so this changes in our templates get saved. And if we select the NPC move here, the move should have the interactable FSM exposed here. So let's just copy the name. And now we have set this up. I'm going to save the City scene, and I'm going to remove the City scene from our scene here. Now, let's test this out. And to test this, we can select the NPC move. Game object here, and we can check the FSM here. So now the defined position is setting the interactable position in the front here. So let's just click here. And then when I run this, you see that it goes to the state briefly. And if I click this, one more time, it will go to the new position. So we don't need to click multiple times to get the defined position refresh. And yeah, this is an improvement that Nico report to me. So thanks again for the Help Nico. 39. Bug Fixing: Player Movement Fix: Hi, in this video, we are going to fix a bug that we have in the player movement, and basically, we have a bug where whenever we are moving the player, and while the player is moving, if we click on a invalid area, an empty area, for example, then the animations will never stop. We will see that the player will move to the point, and it will stop, but the run animation will not stop. And I can show you the issue here. If we press play, and I need to go to the club hallway to demo this bug here. I'm going to interract here. And let's go to the club hallway. Oops. So here, basically, whenever let's say I try to move to this position here, and then I click here. You see, we have this issue here on the player. And this is basically because whenever we are waiting to arrive here, when we finish arriving, it will go to the state here and then it will set the animator float to zero, so it will stop the animation. But there is a possibility where whenever we are moving while we are in the state, we click and then we go to this mouse down event, and transition to the defined destinations. And when there are no clicks at all, it goes back to finish to the first state, and then the animation never gets reset. So we need to fix this. And in order to fix this here, first, we need to add a new Bleion to the player. Click to move FSM. So here I'm going to go to the arable step. I'm going to create a new variable. I'm going to call this is moving. And I'm going to set the type to bleion and create this variable here. And basically, whenever we are setting the destination, I'm going to set the Boolean value to true. I'm going to put this above the next frame event, and I'm going to set the Boulan variable is moving to true in the state here. And then basically, I'm going to copy this action, the set Bolan, and whenever we are arriving to the destination point, here, I'm going to set is moving bulion to false, so I'm going to uncheck this value here. So now we have this bulion. We can detect whenever we are moving whenever we are clicking on empty area here. So basically, here in the defined destination. The last one, we are checking for valid clicks. This bulion variable will be true whenever we are clicking on an object that has collider. And now basically we want to set the false to empty on the state here, and we want to add a new bulion test, so I'm going to just to copy this action and paste it here. And instead of checking for the valid click, I'm going to check for the is moving here. So basically, when there is a valid click and there is a new position, we want to go to the target position. But if we click on an empty area, we don't want to go to finish yet here. We want to check is the player game object currently moving, and if it's moving, then we want to go back to the wait to arrive, and if it's not moving, then we want to go to to the wait for click here. So here, if it's not moving, I'm going to set this to finish, but we need to create a new event. So I'm going to call this is moving. And then we can add the moving transition to this defined destination state. And then let's connect the is moving back to the way to arrive here. And here for the Es true event, we want to set this to the is moving transition. So basically, we just need to do this in order to fix this. So let's save the scene here, and let's test this again. So I'm going to go to the club hallway. And let's go talk to the bouncer here. Okay. So I'm going to move to this point here and I'm going to click somewhere else. And as you can see here, whenever I go and then I click, it goes back to wait to arrive. Yeah, that is basically how we fix the Tuck on running animation issue. Whenever we click on an empty area, and this buck is also reported by Nico. So thanks for that, Nico.