-
Notifications
You must be signed in to change notification settings - Fork 0
Project Reference Guide v2.0
Note: The project now runs on Unity 2022.3.52f1 (up from 2019.4.28f1); the interface is nearly identical, so all the original instructions still apply.
Let's start by familiarizing ourselves with Unity’s interface. Fig 1.1 below is a screenshot of a Scene in Unity named ‘TEST‘, along with various labeled elements.
Fig 1.1 - Interface Navigation
These are the most basic and important elements of navigating the Unity interface. Almost everything involved in making a game in Unity takes places in one of these windows/tabs. Click on the links below to navigate to/learn more about the corresponding sections:
Scene view is where we can move and manipulate GameObject(s) in the physical space of the ‘game world’. Almost everything in Unity is considered a GameObject. If it’s in the game, chances are it is derived from a GameObject. They are essentially the building blocks of making games in Unity. A Prefab(s) is very similar to a GameObject, except that it has been predefined by the user to always behave in a specific way or perform a specific function. GameObject(s)(though usually Prefab(s)) can be dragged and dropped from the Project tab directly into the Scene view/game world.
A list of all the GameObject(s) in the current Scene is displayed here in a list format. This is almost the same as the Scene view in the sense that GameObject(s) can be placed here directly from the Project tab, yet it can be easier to find and select specific GameObject(s) here due to the list format, particularly if you know the name of the GameObject in a Scene where there may be hundreds or even thousands of GameObject(s).
This is where we navigate to the location of the files used in the project and add new art and other assets to the project. Notice that this is displayed in both in List format, on the left portion of the tab (for folder navigation only, not for selecting or adding new files), and Icon format in the right portion of the tab (for dragging and dropping assets, examining details of selected assets, etc.,).
Assets such as art and music or sound effect files can be added to the project by dragging/dropping from a file navigation application such as Windows Explorer or Finder (if using Mac OS) into the Project tab. Add new assets (GameObject(s), Prefab(s), etc.,) to the current Scene by dragging from this right area and moving them to either the Hierarchy tab, or to the Scene view tab directly. Note that Music/Sound Effect assets can NOT be dragged/dropped into the Scene directly like this, and we won't usually drag sprites in their raw form into the Scene directly either unless we are working on creating a new Prefab. See more on this in the Adding New GameObject(s) section.
This is where we can see a preview of the game, approximately as the player should see it. Some things (such as UI elements, because they are based on screen position and may be too large to fit within this window) may look strange here, and resolution can be a bit distorted based on how big the window and the application itself are scaled in your OS. In other words, this view likely won’t be pixel perfect, and may even play worse in terms of performance and quality than if you were to create an actual build, (which we will go over later) but it is sufficient for most general testing purposes. Game view can also be set to ‘Maximize on Play‘ with the click of a button just under the Game tab to the right indicated in Fig 1.2 below, though even when maximized resolution will still be distorted based on window size.
Fig 1.2 - Maximize on Play
Here we can inspect information of specific GameObject(s) and other assets by selecting them in the current Scene or Hierarchy tab, or also by selecting them within the Project tab. This is also where we attach new Component(s) to GameObject(s), and by doing so, add new functionality to them. All of the Component(s) (and by extension, any public or ‘serialized’ variables) attached to a given GameObject can be viewed and altered here.
Looking back at Fig 1.1, we can see the ‘Player’ Prefab(s) is selected in the Hierarchy tab, and in the Inspector, we can see the Transform, SpriteRenderer, Animator and RigidBody Components that are attached to the ‘Player’. Each of these Components has different variables, which can be altered to change the behavior of the GameObject they are attached to in some way.
For example, the Transform Component has X/Y/Z variables for each Position, Rotation and Scale, which as you may already be aware or have guessed, are used to define the position, rotation and scale of the selected GameObject in the game world. The Transform Component is automatically attached to all GameObjects by default and cannot be deleted or removed, but other Components can be added or removed as needed for functionality. Any scripts that are custom written for the project are also attached just like Components.
Not a Unity specific term, but one we will use to describe the structure of folder/file organization for the project. Project file structure may evolve over time and if it can be improved upon for the sake of organization, ease of use or practicality, should be, but for now the overall structure should be fairly adequate for keeping track of where things should go. It may be a good idea to familiarize yourself with where particular assets (art, music, sounds, Prefab(s), etc.,) are kept, as well as the overall file structure in general.
Adding and keeping art, music, sound effects, map files, etc., organized should be fairly straightforward. As stated previously, Assets can be added directly to the project by dragging/dropping from a file navigation application such as Windows Explorer or Finder (if using Mac OS) into the Project tab. Each type of Asset has a specific folder that it should be kept in. All of the Art assets, such as character sprite sheets or Tilesets are stored under the ‘...Assets/Resources/Art’ folder, as highlighted in the Fig 1.3 below, each with their own appropriate folders.
Fig 1.3 - Adding Art Assets to Project
The arrow to the left of the folder icon can be used to expand or collapse each set of folders/subfolder(s). You will notice there are many subfolders in the Art resources folder such as Animations, Animation Controllers, Debug, Effects, Items, NPCs, etc.,. Each of these folders are pretty self-explanatory except for a few. You would put art for the Player character in the ‘Assets/Resources/Art/Player’ folder, art for the NPCs and enemies in their respective ‘Enemies’, and ‘NPCs’ folders, etc., It is also important to note that the ‘Assets/Resources/Art‘ folder structure and the ‘Assets/Resources/Prefabs‘ folder structure are very similar, though serve different purposes. It is important to make sure we are placing art into the ‘Resources/Art‘ folder, and not the ‘Resources/Prefabs’ folder.
Tilesets as of right now have three subfolders into which they are divided, ‘Overworld‘, ‘Dungeons’ and ‘Towns’, but we could further subdivide those into different categories later if desired, this just seemed like a basic way to organize different types of locations the player may encounter.
Most of the time, when we are creating new GameObject(s) (or Prefab(s)) it is generally because we are adding a sprite into the game to create some sort of visual element that may or may not interact with the game world in some way. This process is pretty simple, as we can directly drag and drop any given sprite directly from the Art folder it is contained in, into the Hierarchy or Scene view, which will automatically attach that sprite to a new GameObject with a Sprite Renderer (and Transform) Component and place in it the game world via the Scene view or Hierarchy tab. If we are using art which contains multiple sprites in a single file, such as sprite sheets for characters, or Tilesets for tiles, we must first let Unity know that the artwork contains multiple sprites and we must then slice the art into different ‘cells’ using the Sprite Editor.
To do this we must access the Sprite Editor window, and first select the art file (the actual .png file, not the GameObject/Prefab) in the Project tab, and then view the Import Settings of the art asset in the Inspector tab. Within the Inspector tab will be a ‘Sprite Editor‘ button which will open the Sprite Editor. Alternatively, you can use the Unity toolbar at the top of the Unity application and navigate to Window/2D/Sprite Editor, though you must still first select the artwork you want to edit via the Project tab in order to open that art in the Sprite Editor.
Using the Sprite Editor, we can split a single .png sprite sheet file into a multi-cell or multi-framed art asset, allowing us to then make tiles or animations from that art. There are different ways in which we can split or slice artwork, which way we do so depends on what kind of art we are working with and what we intend to do with it. We will go over this process in further detail later on.
We have learned how we can create GameObject(s) from art files and how to work with them a bit, and we have talked about Prefab(s) but what exactly is a Prefab? Simply stated it is a predefined GameObject. We will mostly use them for things that the player interacts with, including doors, Items, NPCs, Enemies, etc.,. but we will also create Prefab(s) for Objects, which in this sense means any non-tile artwork that is used for making Tiled maps but isn't strictly limited to being placed on specific tile nodes.
For example, if we were to create an Item such as an Apple and we want to add some code to heal the player whenever they pick one up in the world, it is useful to make a Prefab(s) which always has the predefined behavior of an Apple. Basically it serves as the template or blueprint from which we will use to generate all Apples into the game world.
To make that example a bit more concrete, let’s imagine how we would create that Apple “template” or Prefab. First, we would need the art for the Apple obviously. Then, we would add that art into the project via the appropriate Art folder. In this case, perhaps the ‘...Assets/Resources/Art/Items/Power Ups’ folder would be a good location to place to drop this type of art. After that, we can grab it from the folder we just placed in, drag and drop it into the Hierarchy tab, and we can see that we now have a visual representation of our Apple in the game world, and have created a GameObject of an Apple by doing this. Which is great, but what about the behavior of an Apple? Well, if we want our character or other objects in the world to “collide“ with the Apple, then we will also want to add a Component called a BoxCollider2D.
We can add this Component by selecting the Apple in the Hierarchy tab, viewing the Components attached to the Apple in the Inspector tab, and then at the bottom of the Inspector tab, there is a button labeled ‘Add Component’ which we can click to bring up a pop up menu. In this pop up menu, we can actually do a search for the component we are looking for if we know the name of the Component (BoxCollider2D, in this case) or we can browse through different categories of Components, most of which come with Unity. This is also where any Scripts or code that are custom written for our game can be attached to different GameObject(s) as well.
Speaking of code that is written specifically for the project, there would also likely be another script called ‘Apple’ that would be attached to this ‘Apple’ GameObject in order to make it behave like we want the apple to behave for our purposes. For example, if we want it to heal the hero’s HP or perhaps we want the apple to be able to fall from a tree and disappear if the player doesn’t grab the apple within 30 seconds, or something to that effect. We would first have to write the code in order to actually make the apple disappear or to heal the player or whatever we want the apple to do, and then add or attach that code to the ‘Apple’ GameObject the same way we would add a Component.
So, now we have our 'Apple' set exactly the way that we want all the apples in the game to behave. We can now make a Prefab(s) from it, so that when we generate our apples from the code that loads the game maps, and by extension the items and characters that inhabit the world, all the apples generated from that code will load an exact copy of this apple template or Prefab. All we have to do to create a Prefab, is to drag this ‘Apple’ GameObject we have edited over from the Hierarchy tab into the Project tab in the appropriate ‘...Assets/Resources/Prefabs’ folder. This is why the ‘...Assets/Resources/Art’ folder and the ‘...Assets/Resources/Prefabs’ folder are structured almost identically, because in Tiled we refer to the location of the actual art file to generate the Tiled map, but in Unity we load any ‘Objects’ as Prefab(s), so it is fairly simple to tell Unity where the Prefab(s) is located based on Tiled map data and the location of the art that Tiled is referring to.
Creating Animations that can be used in-game is a bit of a tedious process but it is important to understand, though we will rarely ever actually animate a GameObject from scratch. Most of the elements in the game that require Animation are characters; NPCs, Enemies, etc.,. As such, once we have our Player character fully animated, we will use them as the base template for all other humanoid character too, though some might require additional animation work on a case by case basis as well.
Before we can begin to actually animate anything though, first the GameObject we want to animate must have an an ‘Animator' Component attached to that GameObject. To do this, ensure the GameObject we want to animate is selected, then in the Inspector tab, click on the 'Add Component' button and start typing 'Animator' into the search bar and then select it by clicking on it.
The ‘Animator’ Component must also have a corresponding ‘Animation Controller’ to reference. In order to do this, we must first create an Animation Controller for the GameObject. Navigate to the ‘Assets/Resources/Art/Animation Controllers’ folder in the Project tab. To create an Animation Controller for an NPC character, let's navigate to the ‘Assets/Resources/Art/Animation Controllers/NPC’ subfolder as well. We can go ahead and right click anywhere in the empty space of the right area of the Project tab and select ‘Create>Animation Controller’ as seen in Fig below, and go ahead and name the Animation Controller we just created ‘NPC001’. Note that each character or thing we wish to animate will require its own Animation Controller in order to have unique animations.
//Add Fig here showing Creation of Animation Controller
Now that we have an Animation Controller created for our NPC character, we can go ahead and attach it to a GameObject by selecting the GameObject in the Hierarchy tab or Scene view, then dragging the ‘NPC001’ Animation Controller we just created into the Inspector tab where the Components of the GameObject can be viewed, to the ‘Controller’ field of the Animator Component. Now, when we select that GameObject and navigate to the Animator tab (located just to the right of the Scene tab) we can view the Animation(s) that are attached to that GameObject/Animation Controller, and any Animation Parameters that the Animation Controller has as well.
//Add Fig here showing where to attach Animation Controller
You may or may not notice that we don’t have any Animation(s) attached to this new Animation Controller yet, but before we can add an Animation(s), we will need to add an animation Layer. For our purposes, most things in the game will only have one animation Layer, which we will always title the ‘Base Layer‘. To add this ‘Base Layer’, in the Animator tab select ‘Layers’ tab as shown in the figure below and click on the plus sign on the right hand side and name the layer ‘Base Layer‘. That’s all we have to do in this area, but we also have to add animation Parameters.
//Add a Fig showing 'Layers' tab within the 'Animator' tab...
Next we will add a Parameter to our Animation Controller which will serve as the ‘trigger’ to play our Animation(s). While Animation(s) and animation Parameters are different, we will basically use them in conjunctions. In other words, for every animation Parameter we have for an Animation Controller, we will also have a corresponding Animations for that Parameter. That way we can change the state of a Parameter, (True/False, in our case) and turn Animation(s) off and on accordingly.
The code we have in the projects works by switching the Animation(s) based on the current animation Parameter state. For example, if a character has a “WalkRight” Parameter, when the Animation is triggered by pressing the button that makes the character move right, all other animation Parameters are set to “False” and the “WalkRight” parameter is set to “True”, which in turn changes the Animation state itself to “WalkRight“ and disables all other animation states.
To add a new Parameter, all you have to do is navigate to the Animator tab, then below that you will see ‘Layer’ and ‘Parameter’. Select ‘Parameter’, and then click the + symbol to the lower right of the Parameter tab, and then select “Bool” (True/False) and name the Parameter. Keep in mind the Parameter itself should have the exact same name as whatever the name of the Animation itself is or will be. So now that we have a ‘Base Layer‘ animation layer, and a Parameter for our animation, we can actually create an animation, and then attach some sprites to that animation.
Now finally, let’s actually create an Animation. An Animation is an asset that we create from Unity, meaning that there is an actual file that references that specific Animation. All of our animations should be created/placed in the ‘Assets/Resources/Art/Animations‘ folder. In this case, we are creating an Animation for our 'NPC001' character so we should also navigate to the ‘Assets/Resources/Art/Animations/NPCs‘ subfolder. Once we have done so, right click in the right area of the Project tab and select ‘Create>Animation‘ and go ahead and name our Animation ‘WalkRight’, as seen in Fig 1.4a and Fig 1.4b below.
Fig 1.4a - Creating Animations
Fig 1.4b - Naming Animations
Now we have an Animation that we can to add to our Animator and start adding sprites to. To do this, navigate to the Animator tab, and drag the ‘WalkRight‘ Animation we just created into the right portion of the Animator tab, where the ‘Entry’, ‘Any State‘ and ‘Exit’ states can be seen. It will automatically be attached to the ‘Entry’ state, so that the ‘WalkRight’ Animation becomes the default Animation applied to this GameObject whenever it is first loaded into the game world. Now normally, we would probably want the ‘IdleRight‘ or ‘IdleLeft’ Animation(s) to be the default Animation(s) applied to a character but for example purposes, let’s continue using the ‘WalkRight’ Animation and follow through with that just for illustrative purposes.
//Add Fig here show how to add animations to the Animator...
So, now that we have added this Animation to this GameObject’s Animator, we can now navigate to the Animation tab to the right of the Animator tab as seen below, and now we have the option to select the ‘WalkRight‘ Animation we just added to the Animator in a drop down menu. In order to actually add sprites to this ‘WalkRight‘ Animation we must drag them from the Project tab into the right portion of the Animation tab shown in the image below. Once moved, they are assigned to the ‘WalkRight‘ Animation, and can be reordered as needed to produce the correct appearance and can also be spread out to lengthen a particular frame of Animation.
Fig 1.5 - Animation Tab
We can also preview the Animation here in the Animation tab just by pressing the play button. But in order to make our ‘WalkRight’ Animation loop so that it plays over and over as long as the ‘WalkRight’ parameter is true, we have to navigate to where we first created the ‘WalkRight’ Animation in the ‘Resources/Art/Animations/NPC‘ folder in the Project tab and select it. Now view in the Inspector and check the ‘Loop Time’ option as seen in Fig below.
//Add Fig here showing the Loop Time option
Note that we can also alter the speed of the Animation by changing the ‘Samples’ in the Animation tab as well, which is essentially the FPS (frames per second) of the Animation. Typically we want a lower number for most Animations such as walking, jumping, etc., typically around 8-12, but attack Animations and some other Animations might look better at a higher Sample rate.
To make transitions to new Animations, just right click on the initial state we want the transition to come from (typically ‘Any State’ for our purposes, though we may later require more complex animation transitions), click ‘Make Transition’ and just click on the Animation you want to transition to.
For most of our Animation(s), transitions will be pretty simple. Essentially what we want for most of our humanoid characters will look something like Fig 1.6 below:
Fig 1.6 - Animation Transitions
This is so every Animation can be reached from any other state, or ‘Any State’, and we want the default Animation to be the ‘IdleRight’ (or sometimes ‘IdleLeft’). Because this process is a bit tedious and complex, this is why we will use the Player character as a template for all other character Animations once he is fully animated the way he should be in order to save time and work.
Before adding a Tileset to Tiled to build a map, it is best practice to add the Tileset into Unity first and then using that same art file, load the art Tileset into Tiled so that when the Map is saved from Tiled as a ‘.json’ file, the art references the file location and is read properly into Unity when the Map is loaded in-game.
In order for the art to refer to the file location of the Tileset, it also has to be embedded into the map. What that essentially means is that when the ‘.json’ file created from Tiled is opened, the path where the art is located is embedded as text referring to the file location as seen in Fig 1.7 below:
Fig 1.7 - Tiled .json file with Embedded Tileset
In Fig 1.7 on line 696, a reference to the ‘adventuregame.png’ file can be seen, which is the value of the “image” attribute in the .json file. In a file where the Tileset is not embedded, there is no actual reference to the location of the file, but rather a reference to the file location of the ‘.tsx’ or the unembedded Tileset file, which makes it impractical for telling Unity where the actual art is since Unity doesn't know or care what a .tsx file is, and a .tsx file can contain references to multiple art assets. This is why it is best practice to first import the art into the appropriate folder in Unity before creating and loading the Tileset art into Tiled and creating your map, and to ensure all the tiles and objects are embedded into the Tiled map as well.
To add a new Tileset in Unity, first locate the most appropriate folder in the project to place the artwork. As mentioned earlier in the section on Project Structure, for now, Tilesets are divided into three categories: Dungeons, Towns and Overworld, and we can create new categories later or change how they are divided if for some reason it becomes too complex to navigate or a better system of categorization is later developed. When adding new Tilesets, before actually importing the art for the Tileset into the project, first create a folder for the Tileset and give the folder the same name as the filename of the Tileset art itself without the file extension. For example, if .png file for the Tileset is named “adventuregame.png“, name the folder which will contain the .png file, “adventuregame“, and place the .png file art for that Tileset in that folder. Best practice is to copy/paste the name from the file directly when creating the new folder in order to avoid any spelling differences/mistakes.
We will also need to split the art into sprites or cells in order to create the tiles in Unity. The easiest way to split a Tileset up is by navigating to and selecting the Tileset art file in the Project tab. Before we do that though, in the Inspector tab, let's set the 'Resize Algorithm' property to 'Bilinear', set the 'Format' property to 'RGBA 32 bit'. Now we can actually split the art into cells, first make sure the art is set to ‘Multiple‘ and open up Tileset art in the Sprite Editor. Then from the Sprite Editor, in the top left of the window select the ‘Slice’ option, then for Type, select ‘Grid by Cell Size’. In this case, our cell size will be 16x16, because that is the size of the tiles we are working with. So, then in the Pixel Size X and Y, enter 16. Also for Tilesets, we always want to select ‘Keep Empty Rects’, we will also always set our Pivot Point to Center, and our method to Delete Existing. Then we just click ‘Slice’ and our art has been sliced!
//Add a Fig here showing the Sprite information in the Inspector and the Sprite Editor
We will also need to actually create Tiles in Unity, so that they can be read by Unity in its native tile system. In order to do this, we need to open the Tile Palette by navigating to the Application window menu and selecting 'Window/2D/Tile Palette', which will open up another window. From here, we will need to create a new palette by navigating to the dropdown menu and selecting 'Create new Palette' as seen in the Fig below. Name the Tile Palette the same as the name of the .png art file, set the cell size to 'Manual' and then set the X and Y to 16. After doing this, it will ask you to save the Tile Palette somewhere, which we will save into the same folder as the artwork for the Tiles.
//Add Fig here showing Creating New Tile Palette, dragging artwork to palette grid area
Then we will need to drag the artwork for the Tiles into the grid area of the Tile Palette window for the palette we just created as seen in the Fig above. Once we do this, Unity will open a window prompting us where we would like to generate the Tiles. Create a new folder in the same folder we have our Tile art, and just name it 'Tiles'. This is where the actual Tiles themselves that Unity renders will reside. Lastly, we need to go back to the .png file itself in the Project tab, right click on it, and select 'Create>Sprite Atlas' and then check the checkbox for 'Read/Write' enabled, set the 'Filter Mode' to 'Point', set the 'Max Texture Size' to 512 (or 1024 if needed, though it's doubtful we will need Tilesets of this size), and set the 'Format' to 'RGBA 32 bit'. Then lastly, we need to add the .png file to the Sprite Atlas by clicking on the + symbol under the 'Objects for Packing' / 'List is Empty' area. Unity will open a new window asking for a reference to an art file, start typing the name of your .png file here and select it. Now our Tiles are ready for rendering in Unity and for loading into Tiled!
//Add Fig here showing the Sprite Atlas settings
To add a new Tileset to Tiled, first find where the artwork is located in Unity that we want to make a Tileset from. In Tiled, we have several options for adding a new Tileset. We can navigate to the Application window, and select 'File/New/New Tileset...'. There is also a 'New' icon in the Toolbar at the top of the Tiled menu which you can click and create a 'New Tileset' (or a 'New Map'). There is also a 'New Tileset' icon in the Tilsets Toolbar.
Ensure the ‘Stamp Brush’ tool is the active selected tool, indicated by the stamp icon on the upper portion of the Tiled Toolbar as circled in the Fig below. Also make sure you have the correct Layer you wish to place the Tiles onto selected in the Layers Window, and that you have selected the correct Tile you wish to place in the Tilesets window.
//Add Fig here showing the Stamp Brush circled
Flip a Tile on the x-axis: press the ‘x’ key while using the Stamp Brush tool.
Flip a Tile on the y-axis: press the ‘y’ key while using the Stamp Brush tool.
Rotate a Tile clockwise: press the ‘z’ key while using the Stamp Brush tool.
Rotate a Tile counter-clockwise: press ‘z’ + Shift keys while using the Stamp Brush tool.
Adding Tile Animations in Tiled is fairly easy. Select the Tileset in Tiled you want to create the Animation from in the Tilesets window, and at the bottom of the Tilesets window there is an 'Edit Tileset' icon which when clicked will open the Tileset in a new tab in Tiled. From that window, there is a 'Tile Animation Editor' icon which resembles a film camera. Click on that icon which will open up the Tiled Editor Animation window in which you can see the Tiles in the Tileset in the right side of the window and an empty box on the left wise of the window. When you double click on a Tile in the right side of the window, it will appear in the left side of the window and be added to the Tile Animation. You can also adjust the duration of the frame of animation by either clicking to the right of the tile animation frame where the number is and inputting a number, or by tweaking the number in the area above the box with the tile animation frames are. Then to place the tile animation on the map,
‘Objects’ in this sense are used to place things on the map that do not have the limitation of being bound to the map by tile size or even placement on the tile grid. This can range from things like simple art elements for example, perhaps an ‘object set’ of trees that vary in size and should not be bound to the map by placing them on specific tiles or tile coordinates. Also, anything which the Player interacts with that might require specific code in order to function as intended (Prefab) will likely also be considered an ‘Object’. For example, Items (both ‘Power Ups’ and ‘Inventory’ type items), or interactive elements in the environment such as doors, switches, etc.,. So, the 'Apple' example we looked at earlier is a good example of an Object in this sense.
Just like Tiles, we should first import the artwork into Unity before creating an Object set in Tiled and placing the Object into the map. However, unlike Tiles, we should save each Object individually rather than saving all of them together into one .png file, they should each have their own .png file essentially.
In order to create the Object in Unity, we essentially just need to create a Prefab(s) for the Object. So first need to import the art for the Object and place it in the appropriate folder, which will be one of the subfolders of the ‘...Assets/Resources/Art/...’ folder, then drag and drop it from the Project tab into the Hierarchy or Scene tab, as described in the Creating Prefabs section. Once the GameObject exists in the current Scene, we can then drag it back from the Hierarchy or Scene tab back into the Project tab but instead of putting it into the ‘...Assets/Resources/Art/...’ subfolder where we placed the art, we are going to place it into the corresponding ‘...Assets/Resources/Prefabs/...’ subfolder. Eventually, we will likely add a Sprite Atlas for Items, a Sprite Atlas for aesthetic Objects (such as environmental objects that the Player cannot interact with, etc., but for now this is unnecessary. We can work on this after the project has come together more.
To create an Object set in Tiled, we need to create a new Tileset but in the 'Type' field instead of 'Based on Tileset Image' we need to select 'Collection of Images', and be sure to select 'Embed in Map' also. Object sets should be logically based on types of Objects to some extent where possible. For example, in our 'AdventureWaterfall1' map, we have an Object set for 'Items' which consists of any Items the Player can interact with. We also have another Object set for '#Tools' which consists of things which serve a purpose for development but shouldn't be apparent or visible to the player themselves, such as entry points, portals, etc.,.
In order to place an Object onto a map, first we need to create an Object Layer by going to the Layer window and selecting the 'New Layer' icon towards the bottom of that area. After we create the Object Layer that we want to place our Objects on, make sure it is selected and then make sure the Object Tileset is selected in the Tilesets window. However, instead of using the 'Stamp Brush' tool, we want to make sure we have the 'Place Tile' tool selected in the Toolbar at the top which is indicated in Fig below. We also want to ensure that we have 'View/Snapping/Snap to Pixels' checked in the Application menu at the Top as indicated in Fig below. Even though we have 'Snap to Pixels' selected, it will base that off fof the center point of the object so if our height or width of the object is an odd number, the snapping will be off by a half pixel, which we can compensate for by padding the art a bit on the sides if desired to have placement exact but doesn't really matter all that much in the big picture.
//Add Fig here showing the 'Place Tile' tool //Add Fig showing Snap to pixels
Flip an Object on the x-axis: press the ‘x’ key while using the Insert Tile tool.
Flip an Object on the y-axis: press the ‘y’ key while using the Insert Tile tool.
Rotate an Object clockwise: press the ‘z’ key while using the Insert Tile tool.
Rotate an Object counter-clockwise: press ‘z’ + Shift keys while using the Insert Tile tool.
In addition to all of the ways we can edit tiles and objects individually, we can also apply certain properties to Layers as well, including Layer Opacity and Color Tint, which is fairly easy to do. Just select the layer in the Layer window, and in the Properties window, we can see several attributes such as 'Name', 'Class' 'Visible', etc.,. If a layer has an 'Opacity' of 1.0, that is full opacity. To adjust it, simply click in the field where the '1.0' is and set it to whatever you like. You can also adjust the Color Tint of the layer similarly, except there it will say 'Not Set' (unless it has been already set to a certain tint, in which case an array of RGBA values will appear here, such as (255, 0, 0) [255] which is a full red tint). To the left of the Tint Color field is a small arrow which when clicked will open the 'Red', 'Green' and 'Blue' fields which can be adjusted as desired. At some point in the future, we are going to also add a method for changing the overlay layer that creates the "dark" effect which can be illuminated by equipping a lantern, though at this point is not yet functional.
Just like we can adjust the Layer Opacity and Color Tint in the Layer Properties, we can also set the Parallax X and Parallax Y variables to add a parallax effect to the layer. A higher value than 1.0 will move faster than the camera moves (use this for setting the layer in the foreground) and a lower value than 1.0 will move slower than the camera (use this for setting the layer in the background). At some point, we will also create a standardized method of creating a repeating layer effect for weather effects such as fog, rain, etc., which will repeat over and over from left to right or top to bottom or whatever needed, though at this point is not yet functional.
We can also set other various properties in the Layer Properties such as 'Name', 'Class', 'Visibility', 'Locked' or 'Horizontal Offset' or 'Vertical Offset', all of which are fairly straight forward and self explanatory. We may devise a way to utilize the 'Class' property to apply certain effects later, though at this point the 'Class' property is essentially pointless.
In addition to Tile Properties and Layer Properties, we can also set certain properties to the Map itself, though we don't really have a need to do so in most cases. You might find some use of altering the 'Parallax Origin' at some point. We also want to make sure that our 'Tile Layer Format' property is set to 'CSV', our 'Tile Render Order' is set to 'Right Down' and our 'Compression Level' is set to -1. You shouldn't use the 'Background Color' property to actually set the background color though because the code that renders the map into Unity doesn't read this value in at this point. Rather you should use the 'SKY' layer and paint the entire layer with the blank white tile from the Blank tileset and alter the 'Color Tint' of the Layer accordingly.
The Dialogue Tree Editor is a custom window built right into Unity for writing conversations. Instead of editing text in a script or a spreadsheet, you lay out a conversation visually as a flowchart — boxes of dialogue connected by lines, with branching player choices. This is probably the tool you'll spend the most time in when writing the story, so it's worth getting comfortable with.
Open the editor from the Application menu at the top of Unity. There will be a menu entry for the Dialogue Tree Editor (look under the custom tools menu). Clicking it opens the editor in its own window, which you can dock anywhere in the Unity layout just like the Scene or Inspector tabs.
//Add Fig here showing the menu entry to open the Dialogue Tree Editor
The window is split into two areas. The large area on the left is the graph — this is your canvas where the conversation is laid out. The panel on the right (about a third of the window) is where all the buttons, settings, and properties live.
//Add Fig here showing the full editor window with the graph on the left and panel on the right
Fig 3.1 - The Dialogue Tree Editor
In the graph you'll see two kinds of boxes, which we call Nodes:
- Dialogue Nodes (red header) — a single thing a character says.
- Dialogue Options (teal header) — a choice the player can pick in response.
The very first Dialogue Node in a conversation is the Root (orange header) — it's where the conversation begins.
Moving around the graph works like you'd expect from Tiled or any map tool:
- Pan: hold the middle mouse button (or Alt + drag) and move the mouse.
- Zoom: scroll the mouse wheel, or use the ⊖ / ⊕ buttons.
- Select a node: click it. The right panel then shows that node's properties.
The right panel is organized into labelled sections — History (undo/redo), Tree Operations (new/load/save), Nodes & Connections (adding and linking boxes), Tree Settings, Layout Spacing, and the Node Properties for whatever you've selected.
To start a fresh conversation, click New Tree in the Tree Operations section. You'll get a single Root node to begin from.
To add more to the conversation, use the two buttons in the Nodes & Connections section:
- Add Dialogue Node — adds a new line of speech.
- Add Dialogue Option — adds a new player choice.
When you select a Dialogue Node, the Node Properties section on the right lets you type the Dialogue Text (what the character actually says). When you select a Dialogue Option, you type the Option Text (what the player chooses).
If the layout gets messy as you add boxes, click the Layout button and the editor will automatically arrange everything into a tidy top-to-bottom flow. The Layout Spacing section has two sliders — Horizontal Gap and Vertical Gap — that control how much breathing room there is between boxes when you auto-arrange.
A conversation is just boxes connected by lines. The lines show the flow: which line of dialogue leads to which, and which choices branch off where. There are a few simple rules the editor enforces so you can't make an invalid conversation:
- A Dialogue Node can lead either straight to another Dialogue Node (a continuing line of speech) or to a set of Dialogue Options (giving the player a choice) — but not both at once.
- A Dialogue Option always leads to another Dialogue Node (the response to that choice).
To connect two boxes, select the box you want to connect from, then click the Connect Node button (there's one in the right panel and one in the toolbar at the top of the graph — they do the same thing). A line will appear following your cursor. Then click the box you want to connect to, and the connection is made. To remove a connection, select a box and use Disconnect Node.
There's a limit on how many Options a single Node can offer, set by the Max Options Per Node slider in Tree Settings (default is a handful — raise it if a moment in the story needs more choices).
//Add Fig here showing a connection line being drawn between two nodes
Every conversation can show a character's name and a portrait image next to the dialogue. There are a few layers to how this is decided, which sounds more complicated than it is. Think of it as "most specific wins":
- Per-node: an individual Dialogue Node can override the portrait (the Icon Override field in Node Properties). This is handy if a character's expression changes mid-conversation — a happy portrait on one line, an angry one on the next.
- Per-tree: in Tree Settings, the Default Character Name and Default Portrait Icon apply to the whole conversation. Setting a Default Character Name here is a nice way to give a character a temporary nickname just for one conversation.
- From the NPC: if you leave the above blank, the name and portrait fall back to whatever is set on the NPC itself (more on that in Putting a Conversation on an NPC).
So in the common case you don't set any of this in the editor at all — you just let it pull from the NPC. You only fill in names and portraits here when you want to override the default for a specific conversation or a specific line.
This is how the story actually does things. Any Dialogue Node or Dialogue Option can carry Quest Events — instructions that fire when the player reaches that node or picks that option. Right now the two main events are Start Quest and Complete Quest.
When you select a node or option, scroll the Node Properties to the Quest Events section and click + Add Quest Event. You'll get a dropdown to pick the event type (start or complete) and a field to pick which quest it affects.
If a Quest Database exists in the project, the quest field becomes a convenient dropdown list of all defined quests. If there isn't one yet, you'll get a plain text field to type a quest ID into, plus a Create Quest Database… button that makes one for you.
A practical example: on the Dialogue Option where the player says "Yes, I'll help you," you'd add a Start Quest event pointing at the relevant quest. On the Node where the quest-giver says "You did it, thank you!", you'd add a Complete Quest event. That's the entire loop — no code.
//Add Fig here showing the Quest Events section with the dropdown
Conversations are saved as .json files, the same format Tiled uses for maps, so they're easy to keep track of. Use Save (or Save As…) in the Tree Operations section. Save your dialogue files into the Assets/Resources/Dialogue Trees folder so the game can find and load them.
The editor warns you with a small "● Unsaved changes" note when you have work that hasn't been saved yet, and it'll prompt you if you try to close with unsaved changes. Standard shortcuts work too — Ctrl+S to save, Ctrl+Z / Ctrl+Y to undo and redo.
Once a conversation is saved, you attach it to a character in the world. An NPC GameObject has two relevant Components:
- NPC — holds the character's canonical Character Name and Character Icon (portrait). These are the fallback values the Dialogue Editor uses when a conversation doesn't override them.
-
NPCDialogue — has a Dialogue Tree Json field. Drag your saved
.jsonconversation file from the Project tab into this field.
That's it — the NPC now has that conversation. Because the name and portrait live on the NPC, you can reuse the same dialogue file logic across characters and let each one supply its own identity.
A nice detail worth knowing: the NPC component also has an Is Hostile checkbox. An NPC can be peaceful (gives dialogue) or hostile (behaves like an enemy and can be hit), and this can even be flipped during the game — for instance, a friendly character who turns against the player partway through a quest.
Terrain effects change how the player moves through different parts of the world — sliding on ice, slogging through sand, swimming in water, sinking in quicksand. The whole system is data-driven, which means you create a little settings asset for each kind of terrain and then apply it wherever you want, without writing code.
There are two flavors of terrain, and the difference matters:
- Surface terrain is something the player walks on top of — like an icy floor or a sandy path. The effect happens because the player is standing on that surface.
- Volume terrain is a space the player moves through — like a body of water or a pit of quicksand. The effect happens because the player is inside that area.
Water is the clearest example of why we need both: a lake isn't a floor you stand on, it's a volume you're submerged in. Walking on ice is the opposite — it's purely about the surface under your feet. Pick the flavor that matches how the terrain works in reality.
Both flavors share the same settings asset, called a Terrain Modifier. To make one, right-click in the Project tab and choose Create ▸ Game ▸ Terrain Modifiers. Give it a clear name like "Ice", "Sand", or "Water".
Select the new asset and the Inspector shows all its settings. The main ones, in plain terms:
-
Speed Multiplier — how fast the player moves.
1is normal, below1is slower (mud, water), above1is faster. -
Friction Multiplier — how quickly the player stops. Very low (like
0.04) gives slippery ice; higher than1makes them stop on a dime (sticky sand). -
Jump Multiplier — how high the player can jump here.
1is normal, lower means stunted jumps (sand, water), higher means a boost (a springy surface). -
Fall Gravity Multiplier — how floaty falling feels. Below
1makes the player drift down gently (good for water).
For volume terrain specifically, there are a few extra settings:
- Volume Gravity Scale — makes the entire jump/fall arc floaty, not just the falling part. Great for the underwater feel.
- Continuous Downforce — a constant downward pull. Use this for quicksand that slowly sucks the player down.
- Infinite Jump — lets the player "swim" by jumping endlessly while inside the volume (see Swimming).
- Is Lethal / Lethal Delay — if the player stays in this volume too long, it kills them. The delay is how many seconds they have. Leave the death clock generous for water (so it acts like a future oxygen meter) or short for something nasty like lava.
You don't have to understand every slider — start from one of the common setups below and nudge values until it feels right.
| Terrain | Speed | Friction | Jump | Notes |
|---|---|---|---|---|
| Ice | 1 | 0.04 | 1 | very slippery |
| Sand | 0.65 | 1.8 | 0.8 | slow, short jumps |
| Shallow water | 0.55 | 1 | 0.75 | floaty, set Volume Gravity Scale ~0.4 |
| Quicksand | 0.3 | 1 | 0.45 | set Continuous Downforce ~250, Is Lethal on |
For a surface like ice or sand, add a TerrainType Component to the ground object the player walks on, and drag your Terrain Modifier asset into its Modifiers field. That's all — when the player stands on it, the effect applies, and when they step off, it stops.
For a volume like water, the setup is a little different because we're describing an area, not a floor. The simplest reliable approach:
- Create an empty GameObject over the water area.
- Add a BoxCollider2D Component and size it to cover the water. Check its Is Trigger box.
- Add a TerrainVolume Component and drag your water Terrain Modifier into its Modifiers field.
Make sure the GameObject is on the Trigger layer (the project uses this layer for these "you're inside an area" checks). That's the whole setup — when the player enters the box, the water effect kicks in; when they leave, it stops.
A note on water tiles and collision: water tiles are often very transparent, and Unity sometimes can't build collision for very transparent art. The map-loading code already handles this automatically by filling in a full-tile collision shape when needed, so you don't have to do anything special — but if you ever notice a water area that the player passes through with no effect at all, that's the kind of thing to flag.
//Add Fig here showing a BoxCollider2D trigger sized over a water area with the TerrainVolume component
To make water swimmable rather than just slow, turn on Infinite Jump in the water's Terrain Modifier. This lets the player press jump repeatedly to "stroke" upward through the water instead of being limited to a fixed number of jumps. Pair it with a low Jump Multiplier (around 0.5) so each stroke is a small push, and a low Volume Gravity Scale (around 0.3) so they gently sink between strokes. The result reads like swimming. Swim animations will be added later; for now it's about the movement feel.
Abilities are special actions the player gains by finding items in the world — a whip, a bow, and more to come. The system is built so abilities can be handed to the player the moment they pick up the matching item, and taken away just as easily.
Each ability is its own Component. The player has an PlayerAbilityManager component that keeps track of which abilities are active and connects them to the two ability buttons (call them Ability 1 and Ability 2). When the player obtains the whip, the whip ability gets added and slotted to a button; lose the whip and it's removed. For testing, you can also just add an ability component directly to the Player in the Inspector — the manager finds it automatically.
This modular setup is the same idea as the enemy behaviors below: small, single-purpose components you add and remove rather than one giant script. It keeps things flexible — new abilities slot in without disturbing the old ones.
The whip is a short-reach weapon that doubles as a grappling tool. It reaches about two to three tiles in front of the player. Its real trick is latching onto special Hook Points in the world and letting the player swing across gaps too wide to jump.
The WhipAbility component has settings worth knowing:
- Max Whip Length — how far it reaches (in pixels; one tile is 16).
- Min Hook Length — the whip won't grab a hook closer than this, which stops awkward tiny swings.
- Origin Height — how high up the whip emits from (so it comes from the hand, not the feet).
- Pump Force / Max Swing Angle — how much the player can build a swing by tapping left/right while hanging, and how far the swing can go.
The player aims the whip with the movement direction — straight ahead, diagonally up, or straight up — so they can reach hooks above and to the sides. Once latched, holding the button and pressing left/right pumps the swing higher, and releasing launches the player off in the direction they're swinging.
The visible "rope" is currently drawn as a simple line for testing. It'll be replaced with proper whip animations later, so don't worry about how the line itself looks.
The bow fires arrows and requires the player to have both a bow and arrows. The BowAbility component fires an Arrow Prefab when the button is pressed.
The player can shoot straight ahead (left or right) or diagonally upward. Straight shots fly level and fast; diagonal shots arc through the air like a real arrow. Useful settings:
- Arrow Speed — how fast arrows travel.
- Arc Intensity — how far diagonal shots carry before gravity pulls them down. Higher gives a flatter, longer arc.
- Spawn Offset — where on the player the arrow appears (set the Y to roughly bow height so arrows don't come out of the player's feet).
- Fire Cooldown — minimum time between shots.
To make an arrow, you create an Arrow Prefab: a GameObject with an arrow Sprite, a small trigger collider, a Rigidbody2D, and the Arrow component. Then drag that prefab into the BowAbility's Arrow Prefab field. Anyone comfortable making a simple prefab (covered in the original guide) can build new projectile types this way.
A Hook Point is a spot in the world the whip can grab. To make one, create a small GameObject (a 2×2 or 3×3 pixel sprite works) with a small circular trigger collider and the HookPoint Component, placed on the Trigger layer. You'll typically place these as Objects in Tiled, the same way you place other interactive Objects (see the Objects section of the main guide).
Hook Points gently pulse on their own to catch the player's eye, and brighten when the player aims the whip at them, so it's clear where the player can swing from. Place them thoughtfully across gaps — a hook that's higher up gives a wider, more natural-looking swing than one placed low.
//Add Fig here showing a hook point placed over a gap with a swing arc illustrated
Enemies are built out of small, mix-and-match Component(s) called behaviors. Rather than one big "enemy brain" script, each behavior does one thing — patrol, jump, see the player, chase, shoot, and so on. You build an enemy's personality by adding the behaviors you want to its Prefab. A timid creature might get Patrol + Sight + Flee; an aggressive one might get Patrol + Sight + Chase + ContactDamage.
This is the same modular philosophy as the player abilities — small pieces you combine, so we can create lots of enemy variety without writing new code each time.
To give an enemy a behavior, select its Prefab, and in the Inspector use Add Component to add the behavior you want, then set its fields. Add as many as make sense together. Most behaviors need the enemy to already have the basics (a Rigidbody2D and the Enemy component), which our enemy prefabs already have.
The behaviors fall into a few natural groups, covered below.
- Patrol — walks back and forth, pausing at each end. Set how long it walks and holds, and which direction it starts. (This one's been around a while; it's the backbone of most wandering enemies.)
- EnemyJump — makes the enemy hop on a timer. Good for frog- or spring-like creatures. The hop interval has a little built-in randomness so it doesn't look robotic. Needs a ground-check point at the enemy's feet, like the player has.
- EnemyLedgeStop — keeps a patrolling enemy from walking off the edge of a platform (and optionally from walking into walls). It looks just ahead of the enemy for solid ground; if there's none, it turns the enemy around. Add this to any patroller you don't want wandering off a cliff.
- EnemySight — gives the enemy a field of vision, drawn as a cone in the Scene view so you can see exactly what it can see. Settings control how far it sees (View Distance) and how wide the cone is (View Angle). It only "sees" the player if they're within the cone and not hidden behind a wall. Crucially, it has three events — On Player Spotted, On Player In Sight, and On Player Lost — that you can hook other behaviors to (see Wiring Behaviors Together).
- EnemyChase — moves the enemy toward the player. It's meant to be switched on when sight spots the player. It keeps chasing for a moment after losing sight (so the enemy looks like it's searching, not instantly giving up) and can pause a Patrol while it chases.
- EnemyFlee — the opposite of chase: the enemy runs away from the player. Perfect for timid creatures that scatter when seen. Like chase, it's meant to be triggered by sight.
The Sight + Chase (or Sight + Flee) combination is how you make an enemy that "notices" the player and reacts. Not every enemy needs sight, though — a feral creature that just wanders and attacks anything it bumps into can skip it entirely, which reads as an animal that doesn't really care what the player is doing.
//Add Fig here showing the EnemySight vision cone drawn in the Scene view
- EnemyProjectile — fires a projectile prefab on a timer, aiming at the player if they're within range (otherwise shooting straight ahead). It's the enemy version of the player's bow, and it can even use the same Arrow prefab. Assign a projectile prefab and set the fire rate and range.
- EnemySwing — makes the enemy hang from a fixed point and swing back and forth like a pendulum (a spiked ball on a chain, a hanging hazard). Place the enemy at the pivot point; it swings on a rope below. Set the rope length and starting angle.
- EnemyContactDamage — hurts the player on contact and can knock them back. Add this to anything that should be dangerous to touch. It has a short cooldown so it doesn't drain the player instantly, and optional knockback to shove the player away.
- EnemyHealthState — watches the enemy's health and fires an event when it drops below a threshold (and another if it heals back up). Use the On Enraged event to make a wounded enemy faster or more aggressive — for example, speeding up its chase or shortening its attack cooldown.
- SpawnEnemy — when this enemy dies, it spawns smaller enemies that burst outward in an arc from where it died (think of a big creature splitting into little ones). It checks for solid ground at each spawn point and nudges the spawn upward if needed, so the little ones never end up stuck inside a wall where the player can't reach them.
The real power of this system is connecting behaviors using events, and you do it entirely in the Inspector — no code. Several behaviors (like EnemySight and EnemyHealthState) have event fields that show up as little boxes in the Inspector with a + button.
Here's the typical setup for an enemy that patrols until it sees the player, then chases:
- Add Patrol, EnemySight, and EnemyChase to the enemy.
- On the EnemyChase component, point its Patrol To Pause field at the Patrol component.
- On the EnemySight component, find the On Player Spotted event, click +, drag the enemy itself into the object slot, and choose EnemyChase ▸ BeginChase from the dropdown.
- Do the same for On Player Lost, choosing EnemyChase ▸ EndChase.
Now sight drives the chase automatically. The same pattern works for sight → flee, or for health-state → enrage (point On Enraged at whatever you want to change). Once you've wired one of these, the rest follow the same rhythm: pick the event, drag in the target object, choose the action.
//Add Fig here showing a UnityEvent being wired in the Inspector (On Player Spotted → BeginChase)
If we want to create an actual build of the game that runs as an app built for various platforms (Windows, Mac, Linux, etc.,), all we have to do is select the 'File/Build Settings...' option in the Application window of Unity, ensure that we have added the Scene(s) we want to include in the build by checking them in the 'Scenes in Build' section, and ensure the correct platform is selected in the 'Target Platform' field. Then we can select 'Build and Run' at the bottom of the 'Build Settings' window, and then choose where we'd like the exported build to be saved and voila, build created!
An animation in this sense does not refer to just the sprites themselves which compose the animation, but rather a Unity construct to which sprites can be attached. An animation can be created by right-clicking in the empty space of the right area in the Project tab and selecting ‘Create>Animation’ (towards the bottom of that menu). Essentially an animation represents a collection of sprites, along with some other metadata which determines the 'Samples' (frames per second/speed) of the animation and other various information relevant to rendering or processing the animation.
A single-purpose Component that gives an enemy one piece of its personality — patrolling, jumping, seeing, chasing, fleeing, shooting, and so on. Enemies are built by combining several behaviors on one Prefab rather than writing one large script.
A Component is a script which gives functionality to a GameObject. Unity comes installed with many standard Components. The most basic of which is the ‘Transform’ component. Every GameObject automatically has a Transform component when they are created, which indicates its physical location in the game world (an X/Y/Z coordinate used to position the GameObject in the game world). There are many other standard Components such as the SpriteRenderer, which renders a 2D image which most of our art assets will probably have. Any custom written scripts are also considered Components. You can learn more about individual Components and what they do in the Unity 2022.3 LTS Manual here https://docs.unity3d.com/2022.3/Documentation/Manual/
A connection point in the Inspector that lets one component trigger an action on another without any code. Behaviors like EnemySight expose events (e.g. "On Player Spotted") that you can wire to actions (e.g. "BeginChase") by dragging in a target object and picking the action from a dropdown.
Unity defines a GameObject as a “Base class for all entities in Unity Scenes.” Essentially, everything that can be placed into the Game World is a GameObject. Including sprites, tile maps, the camera, and UI elements.
In the Dialogue Tree Editor, a Node is a single box in the conversation flowchart. A Dialogue Node is one line a character speaks; a Dialogue Option is one choice the player can make. Nodes are connected by lines to form the branching flow of a conversation.
Short for "non-player character" — any character in the world the player doesn't control, such as a villager, shopkeeper, or quest-giver. In our project an NPC is a GameObject with an NPC Component (holding its name and portrait) and usually an NPCDialogue component (holding its conversation). An NPC can also be flagged hostile, making it behave like an enemy.
A Prefab is an extension of a GameObject that has been saved as a predefined, specific instance of that GameObject. In our project, almost everything will have a Prefab, besides tiles. Essentially anything that interacts with the player or the world. The Player, NPCs, Enemies, Items, etc., will all have a corresponding Prefab that has all the of the appropriate functionality for the GameObject saved so that it can be loaded into the world in a specific way.
A single asset that holds the list of all quests in the game — their IDs, names, and descriptions. When it exists, the Dialogue Tree Editor can show quest choices as a convenient dropdown instead of asking you to type quest IDs by hand. Created via Create ▸ Dialogue Editor ▸ Quest Database (or the shortcut button in the editor's Quest Events section).
A Scene is essentially the equivalent of a level. Each Scene is loaded from the project separately. Scenes should be named the same name as the Tiled map upon which they are based. For example if the name of the Tiled map is “Dungeon1.json“, the Scene should be named “Dungeon1“. The reason being that the MapManager script uses the Scene name to load the appropriate map from the ‘...Assets/Resources/Maps’ folder.
A small settings asset that describes how a piece of terrain affects the player — speed, friction, jump height, gravity, and hazards. The same kind of asset is used for both surface terrain (ice, sand) applied via a TerrainType component, and volume terrain (water, quicksand) applied via a TerrainVolume component. Created via Create ▸ Game ▸ Terrain Modifiers.
A collection of tiles contained in a single ‘.png’ file. Tilesets are split when importing into Tiled / Unity respectively. Standard tile size for our project is 16 x 16 pixels. No spacing between tiles in the art file. “Blank” or “empty” tiles (a completely transparent area devoid of any pixels in a single tile area) in the Tileset are also considered tiles and will be assigned a number ID/index of their own upon splitting the Tileset.
