- Create a Unity account at Unity 3D in order to access Unity
- Unity can be used for free for educational purposes and also commerically, as long as you are not making $100,000 or more using Unity - after that point you need to pay for a license
- Choose and submit your account information
- Use your school email
- Write your password down on paper or in your phone or etc.
- Choose a school appropriate and unique username
- Feel free to use a pseudonym for the name
- Confirm your email address (if the Unity confirmation email doesn't show up in your inbox within a couple minutes, check the spam folder)
- In the "Individual" tab, select "Get Started" under "Personal"
- Agree to the terms and conditions to download "Unity Hub"
- Check to see if Unity Hub is already installed on your computer (press F4 and type Unity), if so skip ahead to step III
- If Unity Hub is missing, download "Unity Hub" from the shared class server:
- In Finder's Go menu, choose "Connect to Server..."
- If needed, change the address to smb://abarchive
- Choose "Connect"
- Choose the 3D Graphics class and click on "OK"
- Drag and drop the Unity Hub DMG file to the Desktop
- Double-click on the Unity DMG file to open it
- Drag the Unity Icon and drop it over the "Applications" folder
- Going forwards, ask for assistance at any point the installer asks for an admin password
- In Applications, click on Unity Hub to open it with Finder
- If at any time, there's a pop-up asking to install "Helper Tools" or something similar, ask for assistance - these need to be installed
- Sign in with your user account information
- If the sign in doesn't come up automatically, click on the profile icon and then select "Sign In"
- If you haven't already made an account, create one now and then sign in to Unity Hub
- There are a couple computers that can't sign in successfully for some unknown reason - I'm working on a fix but for now, just use Unity on a different computer
- If the sign in doesn't come up automatically, click on the profile icon and then select "Sign In"
- After signing in, if Unity Hub shows a notification about a new version at the top of the window, click on the notification and let it "Restart Now and Install"
- Make sure the personal license is activated:
- Click on the gear icon and go to "License Management"
-
- Select "Manual Activation"
-
Select "Save License Request" and choose a location to save the request file
- Follow the link to the "Unity Activation" page (sign in if needed)
-
Click on "Browse" to select the license request file (.alf format)
-
Select "I don't use Unity in a professional capacity"
-
Download the license file
-
Back in Unity Hub, click on the "Load" icon (...) to select the license from the downloads folder
- Select "Manual Activation"
- Exit Preferences by clicking on the X
- Click on the gear icon and go to "License Management"
- Install the modules:
-
With the left "Installs" tab selected, click on the the more options button (3 dots) on the top right corner of the installed Unity version
- Select "Add Modules"
-
Check "Visual Studio" and "Mac Build Support" (if your computer is not a mac, also select the platform you are using - ie. Linux or Windows)
Additional platforms/modules can be easily be installed later on if needed in the same way.
- Select "Done" and let the installation finish
-
- click on the "Add" button
- Select the version of Unity to Install and then press "Next"
-
Check "Visual Studio" and "Mac Build Support" (if your computer is not a mac, also select the platform you are using - ie. Linux or Windows)
Additional platforms can be easily be installed later on if needed.
- Select "Done" and let the installation finish
- click on the "Add" button
-
With the left "Installs" tab selected, click on the the more options button (3 dots) on the top right corner of the installed Unity version
-
Select the "Projects" tab from the sidebar annd press "New"
- Select "3D"
- Choose a project name and location
- Select "Create"
- Create 3 scenes: a game scene (ie. Level1), a lose scene, and a win scene:
- In the "Project" window, inside of "Assets" and then "Scenes", select the "SampleScene" and right-click to either delete or rename the scene descriptively
- Add additional scenes with "File → New Scene" or "Cmd+N"
- Save each scene "File → Save Scene" or "Cmd+S" in the Scene Assets folder for the project after it is created
- Use descriptive names without spaces or symbols (ie. Level1, Lose, Win or etc.)
- Add the scenes to the Build Settings (so they can be accessed in the game):
- Open the Build Settings under "File → Build Settings"
- Select all of your scenes from the Project window (click in the Assets folder and then use CMD+A)
- Drag and drop the selected scenes into the box below "Scenes in Build"
- Open the Build Settings under "File → Build Settings"
- In the Project window, double-click on the game scene (ie. Level1) to load it
- In the "Hierarchy window" go to "Create → Canvas" - any UI (user interface) elements must be created on the canvas
- With the canvas selected, find "Canvas Scaler" in the Inspector
- Change the "UI Scale Mode" to "Scale With Screen Size" to make sure the UI size works on a variety of screen sizes
- Right-click on the Canvas in the Hierarchy and under "UI" select "Text - TextMeshPro"
- At the top of the Inspector, rename the text object from "Text" to "Timer" and press enter (always use descriptive names - it is helpful if you are working collaboratively and when you reuse your assets)
- Lower down in the Inspector, in the type box, type "Timer" (or other placeholder text) into the text box
- If the text is not visible, navigate/adjust the view of the "Scene" window as needed:
- Zoom to cursor position - Alt+scrollwheel
- Rotate view - Right-click+drag
- Flythrough mode - Right-click+hold with:
- W - left
- A - right
- S - forward
- D - backwards
- Q - up
- E - down
- With the text object active, set your text size and alignment as necessary in the Inspector Window:
- To increase the text box, click and drag on the values for width and height under "Rect Transform" in the Inspector or turn on the "Scale Tool" and drag the handles
or
- To change the position to the upper left corner, click and drag the X and Y values in the Inspector or use the handles with the "Move Tool" active
or
- Standard font, alignment and color options can be edited in the Inspector under "Text"
- To increase the text box, click and drag on the values for width and height under "Rect Transform" in the Inspector or turn on the "Scale Tool" and drag the handles
- Save the Scene with "CMD+S"
- In the Project window, double-click on the "Lose Scene" to load it
- Add and customize your "Lose Message":
- Right-click in the Hierarchy to create an "UI → Text" object (the canvas will be created automatically)
- If an importer dialog comes up, click on the button to "Import TMP Essentials"
- In the Inspector, rename your text object to "Lose Message" and press enter
- Change the text in the text box to a lose message (ie. Sorry - You Ran Out Of Time)
- Under "Rect Transform", increase the width and height of the text box to around 525 (width) x 70 (height) as a starting point
- Increase the font size to 50
- If your text is not visible, either:
- Divide your message into multiple lines (use enter in the text box) and then increase the width/height of the text box as needed (height should be at least double)
- Or in "Text(Script) next to "Vertical Overflow", select "Overflow"
- Or if there's no font assigned/available:
- import the necessary font(s) to Unity using Finder:
- In Finder, in the top "Go" menu, click on "Computer"
- Go to "Macintosh HD" → "System" → "Library" → "Fonts"
- Copy the fonts you want (CMD+C)
- Navigate to your game's "Assets" folder (ie. Desktop/My Game/Assets)
- Create a folder for the fonts (click on the menu button - the circle with 3 dots)
- Paste the copied font(s) into the font directory for your game
- In Unity, attach the font to the button:
- With the button's text object selected, go to the "Font Asset" and click on the target button to the right
- import the necessary font(s) to Unity using Finder:
- Use the Scene Window's move/scale tools or the Inspector window to resize and position your lose message in the camera as needed
- Adjust other text alignment/display options in the Inspector as needed
- With the canvas selected, find "Canvas Scaler" in the Inspector
- Change the "UI Scale Mode" to "Scale With Screen Size" to make sure the UI size works on a variety of screen sizes
- Add a background
- Select the "Main Camera" in the Hierarchy
- In the Inspector, change "Clear Flags" from "Skybox" to "Solid Color"
- Click on the color in the "Background" field to access the color picker and select your background color
- Add a button to restart the game
- Right-click on the "Canvas" in the Hierarchy and select "UI → Button TextMeshPro"
- If an importer dialog comes up, click on the button to "Import TMP Essentials"
- Use the move tool to move the button below the lose message
- In the Hierarchy window, expand the button by clicking on the triangle to the left of button
- Select the button's text object
- In the Inspector, change the text in the text box from "Button" to "Restart"
- Adjust other text settings as needed
- Right-click on the "Canvas" in the Hierarchy and select "UI → Button TextMeshPro"
- Press the play button to preview the scene - notice there is no functionality yet as there are no scripts
- Exit the game by pressing the play button again and save the scene with "Cmd+S"
About Scripts:
Scripting in C# is made up of 3 major components: variables, functions and classes. For a script to work, it must be attached to a game object - or be called by a script attached to a game object
- About Variables:
- Variables can contain values and refer to objects
- First letter is lowercase
- Variable Structure:
- visibility keyword → type → name
- ie. public Light myLight;
- Most Common Variable Visibility Keywords:
- Public
- Allows different objects to interact with each other
- Accessible to other people
- Accessible to other scripts
- Accessible to other classes
- Private
- Easier to maintain/track
- Only accessible in the specific script
- Only accessible in the specific class
- Public
- Variable Types:
- Numbers
- Text
- Reference to Unity Components
- Variable Names:
- Rules
- Can't start with a number
- No spaces
- Conventions:
- Start with a lowercase word
- Add additional words with the first letter capitalized
- ie. myLight
- Rules
- About Functions:
- Collections of reusable code that compare and control variables
- First letter is uppercase
- Can be used multiple times
- Default functions (run automatically):
- Awake()
- Initializes variables that need an assigned value
- Called when an new instance of the class/object is created/instantiated - usually the first frame of the game, or when something becomes active
- Only works on an active object
- Works on an active object even if the component is disabled
- Start()
- Called when an object is active
- Only works if the component is enabled
- Update()
- For any logic that runs continuously
- Called once per frame
- FixedUpdate()
- For working with physics
- LateUpdate()
- Like Update but called at the end of the frame
- Called after Update
- Good for triggering a secondary action that should directly folow something else (second loop)
- Awake()
- Function Syntax:
- returned function type→ function name → (function parameters) → {function body}
- ie. void MyFunction () {
myLight.enabled = !myLight.enabled } - Function names start with a capital letter
- A Few Common Function Types:
- void - nothing is returned (ie. we're not trying to calculate values or etc. and get data back)
- int - number without a decimal
- float - "floating" point value that can represent a range of values with decimals
- string - text
- bool - true or false
- Color
- Rigidbody
- Multiple types can be set with commas between
- Custom functions:
- Custom functions are not called automatically like the default functions
- They can be called from another script, or from inside a default function (ie. awake, update or etc.)
- About Classes:
- Classes organize the collections of code
- They combine variables and functions together to determine the properties of an object
- Can be public or private
- Class guidelines:
- Class name must match the name of the C# file
- To add to a GameObject - Monobehavior class is needed (should be added by default)
- Serialize by adding [System.Serializable] directly above the custom class
- ie. [System.Serializable]
public class DataClass {
public int myInt;
public float myFloat;
}
- Custom classes:
- Custom classes must be serialized (or converted into simple data for Unity to read)
- Comments are added in C# with //
- Anything written after // in the same line, will not impact the game
- Anything written between /* and */ will not impact the game
- Comments are used for:
- Keeping code organized
- Leaving reminders for yourself
- Leaving notes for other developers
- Comments always display greyed out
Script to Change Scenes & Restart:
- Create a Script folder in the Project window (Create → Folder)
- Name the folder "Scripts" and then press enter
- With the Scripts folder selected, create a script (Create → C# Script)
- Name the script - ie. ChangeScene
The script is a text file that can be opened in Visual Studio and most text editors - In Preferences (Unity → Preferences → External Tools), change the "External Script Editor" to "Visual Studio"
- Open the Script in Visual Studio by right-clicking on the name in the Project Window and then select "Open"
- Default scripts made in Unity are Windows based - we should convert the formatting to work for Mac without errors:
- Go to "Visual Studio → Preferences → Text Editor → General"
- Change the "Line ending conversion" to "Always ask for conversion"
- Close out of preferences and if there is a warning notification at the bottom of the script, say "Ok" to convert the line ending for Mac (Unix)
- Understanding and changing the script:
- The beginning of the script should always specify the game engine and the system so that Unity knows what resources to use
- Delete lines 1 & 2 (often you will keep these lines, but in this case, we are using Unity's scene management capablities ‐ not collections)
→
- Click in the end of line one (after "using UnityEngine;") and press enter to begin a new line
- In the empty line 2, add "using UnityEngine.SceneManagement;" (this allows us to utilize some of Unity's scene handling functions)
- Line 4 should display the MonoBehavior class ‐ it is important to leave line 4 as is (without the MonoBehavior class, the script cannot be attached to an object and will not function)
- Notice that the name of MonoBehavior's class is the same as the name of the script file (required)
- Inside of MonoBehavior's curly brackets → {}, delete the default functions
→
- Inbetween these brackets (starting with line 6) we will add our own functions to change between scenes:
- Function to return to the start of the game after winning or losing:
- On line 6 (which should be an empty line between the curly brackets {}), write "public void GotoLevel1()"
- The function is public so that it can be accessed in the game
- The function type is void as we don't need to return a value
- The name of the function can be customized but must have the first letter in uppercase & not use any spaces (additional words can start with an uppercase letter)
- The parentheses () are empty as we don't need to set any parameters
- After the right parenthesis ), type a space and then a left curly bracket { (the right bracket should automatically be added)
- Press enter (the brackets should automatically move down and leave an empty line inbetween)
- On line 8, add "SceneManager.LoadScene("Level1");"
- We are utilizing Scene Management's SceneManager class
- We are telling the SceneManager class to use its static method called LoadScene so that we can load a scene based on it's name or index
- The parameters need to specify the name or index of whichever scene we want to load (if you are using a different scene name, use that instead of Level1)
- On line 6 (which should be an empty line between the curly brackets {}), write "public void GotoLevel1()"
- Function to load the lose scene:
- At the end of the first function (this should be line 9), click to the right of the curly bracket and press enter to begin a new line
- Copy (Cmd+C) your first function and paste it (Cmd+V) into your empty line 10
- Change the function name to "GotoLose"
- Change the variable in the data block to the name of your lose scene (ie. Lose)
- At the end of the first function (this should be line 9), click to the right of the curly bracket and press enter to begin a new line
- Function to load the win scene:
- At the end of the second function (this should be line 13), click to the right of the curly bracket and press enter to begin a new line
- Copy (comd+C) one of the functions and paste it (comd+V) into your empty line 14
- Change the function name to "GotoWin"
- Change the variable in the data block to the name of your win scene (ie. Win)
- Lets add comments as reminders of what the code does (this is always a good practice):
- Click in front of "public" at the start of your first function (line 6) and press enter to move the function down a line
- Back in line 6, type // and add a descriptive comment
- Click in front of "public" at the start of your second function (line 11) and press enter to move the function down a line
- Back in line 11, type // and add a descriptive comment
- Click in front of "public" at the start of your third function (line 16) and press enter to move the function down a line
- Back in line 16, type // and add a descriptive comment
- Save the script in Visual Studio (cmd+S)
- At this point the script is finished - at least for now. You can come back and make changes/additions as necessary at any time. Let's make sure the code is functioning back in Unity!
- Function to return to the start of the game after winning or losing:
- Back in Unity, in the "Lose" scene, create a "Game controller" to connect the script to:
- In the Hierarchy window, "Create → Empty" (like in Blender, empty's are not visible in the game)
- Drag the empty "GameObject" into the "Canvas"
→
- Rename the empty from "GameObject" to "GameController"
- Drag the script from the Project window over the Game Controller in the Hierarchy then release, to add the script to the controller
The script should now show at the bottom of the GameObject in the Inspector - Connect the Game Controller to the button in your lose scene:
- With the lose button object selected, in the Inspector, towards the bottom of "Button", click on the right + icon to add an on-click interaction
- Change "Runtime only" to "Editor and Runtime"
→
- Below, click on the circle next to "None" and in the Scene tab, select the Game Control empty
- Change "No Function" to select the "Level1" function (ChangeScene → GoToLevel1)
- With the lose button object selected, in the Inspector, towards the bottom of "Button", click on the right + icon to add an on-click interaction
- In the Hierarchy window, "Create → Empty" (like in Blender, empty's are not visible in the game)
- Enter play mode and test the functionality - if there is a problem with the script there should be a notification at the bottom of the Unity Window
- Press the play button
- Once the game is loaded, try to trigger the effect you are testing - ie. press the "Play Again" button
- When ready, exit the game by pressing the play button again
- If the script did not function as expected, use the warning notification as a guide or use the troubleshooting steps in the sidebar to correct the script as necessary back in Visual Studio
Placeholder Prefabs
Making and using Prefabs allows us to reuse groups of assets ‐ which we can then tweak as needed. This is a great way to save time.
- Make a Restart prefab to use in our Win Scene:
- Still in the Lose scene, in the Hierarchy, select the GameController and drag it over the canvas before releasing (this will group the controller with the button so that they can both be part of the Prefab)
- In the Projects window, make a Prefabs folder in the Assets folder
- Drag the entire Canvas from the Hierarchy into the Prefabs folder (now our restart Prefab is created)
- Rename the Prefab from "Canvas" to something like "Restart"
- Also drag the "GameController" from the Hierarchy to the Prefabs folder
- Save the Lose scene with Cmd+S
- Load the "Win" scene (Projects window → Assets → Scenes → double-click on Win)
- In the Hierarchy window, add an "EventSystem" if one is missing (+ → UI → EventSystem), so that the button will function
- Drag the "Restart" prefab from the prefab folder in the Projects window and drop it in the Hierarchy window
- Customize for the Win Scene:
- Select the "Lose" text object and change the name and message in the Inspector
- Change the background for the Main Camera from skybox to a custom color
- Select the "Lose" text object and change the name and message in the Inspector
- Press the play button & test the game functionality
- Press Play again to exit and save the scene (Cmd+S)
We will add some objects created directly by Unity to get our game play functionality working. If we make any placeholder objects into prefabs, we can easily replace the mesh components with original objects exported from Blender at a later time.
For the game, our player obect will navigate a ground plane with obstacles to reach a goal. Falling off the ground plane will hit a second plane which will act as a sensor & trigger the lose scene.
- Select the "Main Camera" in the Hierarchy and in the Inspector, set the position values to:
- X: 0
- Y: 1
- Z: -52
- Back in the Hierarchy window, click on the "+" icon to add each new object for the game
- Add a plane for the ground:
- In the Inspector, rename the plane as "Ground"
- Set the scale to X: 10, Y: 1, Z: 10
- Set the position to X: 0, Y: 0, Z: 0
- If this is just a placeholder and will be replaced, drag the object from the Hierarchy window into the Prefabs folder in the Project window
- Add a second plane for a "fall sensor":
- In the Inspector, rename the plane as "FallSensor"
- Set the scale to X: 15, Y: 1, Z: 15
- Set the position to X: 0, Y: -5, Z: 0
- Add a cube for the player:
- In the Inspector, rename the cube as "Player"
- Set the scale to X: 2, Y: 2, Z: 2
- Set the position to X: 0, Y: 1, Z: -48
- Drag the object from the Hierarchy window into the Prefabs folder in the Project window so that the mesh object can be easily replaced later
- Add a capsule for the "win sensor":
- In the Inspector, rename the plane as "WinSensor"
- Set the scale to X: 1, Y: 1, Z: 1
- Set the position to X: 0, Y: 1.1, Z: 48
- Drag the object from the Hierarchy window into the Prefabs folder in the Project window so that the mesh object can be easily replaced later
- Add additional cubes (or etc.) as obstacles:
- Create the first obstacle, name it descriptively
- Customize the size/position (setting the starting position to X:0, Y:1, Z:0 will place the cube in the center of the plane - adjust from there as needed)
- Drag the first obstacle from the Hierarchy window into the Prefabs folder in the Project window so that it can be reused and the mesh object can be easily replaced later
- Duplicate the prefab multiple times in the Hierarchy window to save time (Right-click → Duplicate)
- Scale & position as needed
- Add an empty as a parent for the obstacles:
- In the Inspector, rename the empty as "Obstacles"
- In the Hierarchy window, drag each obstacle slightly to the right of the empty object to place
- Make the camera a child of the player (so that the camera will follow the player):
- In the Hierarchy window, drag the Main Camera slightly to the right of the Player
- Adjust the camera's position if needed (click on the main camera to see a preview of the camera view - from a side view, it is easy to move the handles to adjust the exact camera position)
- In the Hierarchy window, drag the Main Camera slightly to the right of the Player
Materials
- In the Assets folder, create a "Materials" folder
- Open the Materials folder in the project window and right-click in the background to choose "Create" → "Material"
- Give the material a descriptive name and press enter
- With the new material selected, in the Inspector, use the color picker to choose a color
- Adjust other settings as needed - ie. Rendering Mode, Metallic, Smootness &etc;...
- Add the material to an object by dragging the material from the Assets folder and releasing it over the object in the Inspector
Physics
Like Blender, different types of physics can be utilized in Unity. We'll be focusing on the 3D physics options
- Rigidbody - similar to Blender, Rigidbody is dynamic & allows gravity to impact an object
- Colliders - colliders form a mesh outline of various shapes around an object (just like Blender's rigid body collision shapes) so that the rigidbody objects can interact/collide with the colliders; without rigidbody, colliders are considered static
- Joints - can connect rigid bodies to each other or to a fixed point; forces can be applied & movement restricted to specific ranges
- Character Controller - used to control characters so that they can interact with rigidbodies but won't fall through walls/floors; this uses a capsule collider & keeps the character upright (this controller is not limited by realistic behavior)
- Add "Rigidbody" to the Player object:
- Select the player object in the Hierarchy window
- In the Inspector, select "Add Component" at the bottom
- Under "Physics", select "Rigidbody"
→
- Since gravity is checked, the rigidbody can now fall when playing the level:
- Press play
- In the Hierarchy, select the player object
- In the Inspector, set the Y position to 10
- After the player falls, press play to exit (notice the Y value returns to the original value since changes made in Play mode are temporary)
- Press play
- For now, leave the default collider types for the various objects
- Obstacles & player = box collider
- Ground plane & Fall Sensor = mesh collider, set to plane
- Win sensor = capsule collider
Player Movement Script
This player movement script allows the up/down arrows and W/S keys to move the player forwards and backwards. Left/right arrows and A/D keys adjust the horizontal rotation of the player.
- In the Project window, select the Scripts folder
- Right-click in the Scripts window to create a new C# script
- Name the Script "PlayerMovement"
- Leave the first 6 lines as is
- Delete lines 7-11 and replace them with variables for movement speed and rotation speed (exact speeds can be increased/decreased later for more or less challenging gameplay)
- Inside of the Update function, change the rotation with the following:
- This multiplies the the horizontal axis with the time since the last frame and the rotation speed to change rotation
- Still inside of the Update function, change the position with the following:
- This multiplies the the vertical axis with the time since the last frame and the movement speed to change position
- The final script will look like this:
- Save the changes
- Back in Unity, drag the script from the Project Window over the Player object in the Hierarchy Window and release (the script should display in the Inspector when the player is selected)
- Play the game to test the script using WASD or arrow keys to move the player
- Exit the game and adjust the script variables if needed in Visual Studio
If the player speed is higher than 10, it might pass through obstacles instead of colliding - even if the physics are setup perfectly. We can change the depentration velocity in the Project Settings to prevent this.
- In the File menu, choose "Build Settings"
- In the bottom left of the window, choose "Player Settings"
- Switch to the "Physics" tab in the sidebar
- Increase the "Default Max Depenetration Velocity" to above your highest speed:
Win/Lose Script Adjustments
The player can win the game by reaching the goal in time. The player can lose the game by running out of time or by falling off of the ground plane.
The ChangeScene script already has the basic setup to trigger the win scene when the player object reaches the capsule (the goal). It needs to be adjusted to use a trigger. A trigger function can only be used once in each script.
- Open the ChangeScene script in Visual Studio:
- Edit Line 16 for the win script function:
- Delete "public"
- Replace "GotoWin()" with "OnTriggerEnter(Collider WinSensor)"
- When the collider for WinSensor is triggered by a rigidbody object, then the win scene loads
- In the function parameters, WinSensor could be replaced by "other" or "Capsule" & the code would function the same
- Save the changes
- Back in Unity, drag the "ChangeScene script from the Project window over the Player object and release (the script shoild display in the Inspector when the player object is selected)
- Add a trigger to the Capsule:
- Select the capsule in the Hierarchy
- In the Inspector, check "Is Trigger" under "Capsule Collider"
- Temporarily hide the obstacles by unchecking the the Obstacles empty in the Inspector when the empty is selected (this will make testing the win functionality go faster)
- Press the play button to play the game and make sure your player can trigger the win scene by touching the WinSensor capsule
- Press play again to exit the game
- Save any changes
- Edit Line 16 for the win script function:
Collisions between a rigidbody object and various colliders can also be used to trigger a script. The script does need to be attached to one of the collision objects. Usually the script should specify what is colliding or the function could be triggered unintentionally.
- Open the ChangeScene Script in Visual Studio
- On line 12, delete "public"
- Change "GotoLose()" to use "OnCollisionEnter"
- Add an "If statement" so that the only collision that loads the lose scene happens when the player collides with the FallSensor - otherwise other collisions could load the lose scene too
- The current ChangeScene.cs script should look like this:
- Save the changes and return to Unity
- Since the ChangeScene script is already attached to the player, it doesn't need to be placed anywhere else
- Play the game and make the player fall off the ground to make sure the lose scene is loaded
- If you want a more dramatic fall before the lose scene is loaded, lower the Y value for the FallSensor plane
- In the Project window, select the Scripts folder
- Right-click in the Scripts window to create a new C# script
- Name the Script "TimerScript"
- Double-click on the script to open it in Visual Studio
- Follow the directions at this tutorial by John at gamedevbegninner.com to modify this script to make a Timer
- If using an UI/Text-TextMeshPro object rather than the standard text object for the timer, make the following changes to your script:
- Enable TMPro on line 5:
- Change the variable type around line 13 from Text to TextMeshProUGUI
- Enable TMPro on line 5:
- Save the script
- In the Level1 scene, connect the script to your timer text:
- In the Hierarchy window, expand the Canvas to show the Timer text object
- Drag the TimerScript from the scripts folder of the Project window and drop it over the timer object in the Hierarchy window
- In the Hierarchy window, select the timer object
- In the Inspector window, scroll down to find the Timer Script component
- Next to "Timer Text", click on the circle and select the "Timer" text object
- Play the game to make sure the timer works
- The amount of time can be adjusted in the "Time Remaining" field in the Inspector
- In the Hierarchy window, expand the Canvas to show the Timer text object
- Save the scene
We can access data from one script within another script using GetComponent. If the scripts are attached to a different object, there are additional references that need to be set.
- Open the "ChangeScene" script
- Add references to the timerscript before the function to load "Level 1":
- For the script, type: private, the name of the script, and the new name to reference the script, with a semi-colon at the end
- For the script input, type: [SerializeField], GameObject, then a name for the field, with a semi-colon at the end
- After the new references, add an awake function to get the script:
- After the awake function, add an update function to load the lose scene when time runs out:
- Save the changes to the script
- In Unity, select the player object and in the Inspector find the ChangeScene Script component
- In the "Timer" field (or your equivalent), choose the Timer text object
- Play the game and make sure the lose scene loads when time runs out - it might be helpful to temporarily lower the "Time Remaining" value in the Inspector
Before trying to use Blender assets in a Unity game:
- Meshes should be formed with quads or triangles
- Make sure in the front view (numpad 1), the object is facing front
- Apply all modifiers
- Remove/reform any intersecting faces
- Remove overlapping vertices (M → Merge by Distance)
- Apply all transformations (Ctrl+A)
- Mesh & origin are centered in the grid:
- Select the mesh in "Object" mode
- Shift+S → "Cursor to World Origin"
- Shift+S → "Selection to Cursor"
- If needed, in the "Object" menu, choose "Set Origin" → "Geometry to Origin"
- In some cases, it might be best to slide up the mesh (in Edit mode) so that the origin is at the base of the mesh
- Unwrap the mesh to create a UV map - if you will be using Blender materials/textures:
- In Edit mode, select the entire mesh (A)
- Press "U" to unwrap and choose "Smart Project"
There are 2 ways to use Blender assets in Unity. Blender objects can be exported as .fbx files - this is usually recommended especially when working with a team as it doesn't rely on having Blender installed. Alternatively, Blender files can be used directly - which allows for easy updates if the asset changes but may slow down Unity.
FBX files are a standard 3d asset file format. They can be exported from Blender for use in a variety of programs, including Unity.
- In the "File" menu, go to "Export" → "FBX (.fbx)"
- Choose what will be exported as an FBX:
- Everything in the file, including cameras and lights (default behavior)
- The selected objects (check "Selected Objects")
- The active collection (check "Active Collection")
- Or control the type of data to export by enabling or disabling the different "Object Types"
- Give the file a name
- Choose the Unity project's asset folder as the export location
- Check "Apply Transform" under "Transform" (you may need to scroll down for this option to be visible)
- Setup the orientation for the Unity end:
- For facing towards the camera:
- Set the "Up" value to "Y UP"
- Set the "Forward" value to "-X Forward"
- For facing away from the camera:
- Set the "Up" value to "Y UP"
- Set the "Forward" value to "X Forward"
- For facing towards the camera:
- Press "Export FBX"
- In Unity's Project window, create a "Models" folder
- Using Finder, drag and drop the Blender .fbx file into the Unity project's new Assets/Models folder (or export the fbx file to that location to start with)
- In Unity, find and open the prefab with a placeholder object that is being replaced
- Select the object being replaced in the Hierarchy
- In the Inspector, under "Mesh Filter" → "Mesh", choose the FBX file from the assets folder
- As needed, adjust the various size/position/rotation settings to make the your model better fit the scene
- Move your .blend file into the Assets/Models folder of your project (using Finder, File Explorer or etc.)
- In Unity, Find the FBX file in the Project window's Asset folder
- Find and open the prefab with a placeholder object that is being replaced
- Select the object being replaced in the Hierarchy
- In the Inspector, under "Mesh Filter" → "Mesh", choose the FBX file from the assets folder
After adding your Blend file or FBX file in Unity, you may need to make adjustments to the scale, physics, and materials.
Blender Physics do not currently transfer to Unity - no matter what way you import your assets to Unity. For certain behaviors, you can bake/apply the physics (possibly converting to mesh) as a partial workaround. Otherwise, create the physics in Unity instead.
There are some adjustments that should be made in Unity to the Physics after replacing your placeholder objects.
- Select the replaced object in the Hierarchy
- In the Inspector, find the collider component and click on the "Edit" button
- Edit the collider to fit the object, checking the fit from multiple views:
- Click+drag the green squares to adjust the size/position of the collider
- Drag on the collider's labels to resize or position the collider differently
- Experiment with different collider types if needed
- Click+drag the green squares to adjust the size/position of the collider
- Adjust the player's rigidbody settings:
- Stop the player from passing through parts of the obstacles by changing the "Collision Detection" to "Continuous Dynamic"
- Stop the player from falling over when hitting obstacles by adding constraints to the rotation on the "X" and "Y" axi
The "Principled BSDF" material does automatically transfer into Unity but so far, other materials may not. For more complex materials, you can bake them in Blender. Alternatively, make the materials in Unity instead. Directions can be found on the More tab.
Cycles Materials can be imported into Unity from Blender - but only if they've been baked onto an image.
- Create a U/V map of the mesh (if one hasn't been created already)
- In Edit mode, select the entire mesh with "A"
- Press "U" and choose one of the unwrap optons (Smart UV Project is recommended)
- In the "UV Editing" workspace, adjust the map
- Create an image to bake the material onto:
- In the "UV Editing" workspace, click on "+ New" at the top of the "UV Editor" panel
- Give the image a name and choose "OK"
- Save the image using the "Image" menu → "Save" at the top of the UV Editor (save the image directly into the Assets/Materials folder for the game project)
- "Connect" the image to each material:
- In the "Shading" workspace, add an image texture node to the active material (Shift+A → Texture → Image Texture)
- Place the node to the side (not directly connected to the material nodes)
- Open the blank, saved image
- In the "Materials" tab of the properties panel, switch to the next material & repeat the previous steps so that the empty saved image is to the side of each material's nodes
- Repeat for any additional materials
- Bake the materials onto the image:
- In the properties panel, switch to the "Render" tab of the properties panel, set the render engine to "Cycles"
- Optionally, under "Light Paths", check "Fast GI Approximation" (this used to be Ambient Occlusion in the World Settings) to avoid overly strong shadows
- The AO distance can be increased as needed
- Still in the "Render" tab, expand the "Bake" subsection and click on "Bake"
- Save the changes to the baked material in the "UV Editor" panel (Image → Save)
- If necessary, move the baked material image into the Assets/Materials folder of the Unity project with Finder or File Explorer
- In Unity, create a new material for each Blender material in the Project panel (Create → Material)
- For each material, drag the image texture from the Project panel and drop it over the material's "Albedo" box in the Inspector
(the material should display the baked image in the material preview icon below)
- To connect the materials to the object, in the Inspector, find "Mesh Renderer"
- Click on the "+" icon to add additional material slots (elements) as needed
- Click on the right circle to each default material with the correct material
U/V maps automatically export as part of a mesh object in an FBX file. As long as the mesh object was exported from Blender with a U/V map already made, the material texture should apply perfectly in Unity. If the U/V map was created after, an FBX file should be exported again.
The process of creating/exporting a game app is called building. There are some settings that should be set before building the playable game app.
- In The File menu, go to "Build Settings":
- Select the operating system that you are building the game for:
- macOS for this class's game submission
- Optionally build the game for other OS, if needed for home use/sharing with friends
- Open the "Player Settings..."
- Under "Player" → "Resolution and Presentation", change from "Fullscreen Window" to "Maximized Window" (this allows the game to be minimized and closed without additional scripting)
- Select the operating system that you are building the game for:
- Build the game directly from the project settings window, or from the File menu
Before building the game, consider if there are missing features you would like to incporporate - some possible additions might include:
- Custom images for an app icon and/or splash screen (these can also be set in the Player settings)
- A menu or etc. upon opening
- A "Quit" action (start with the following code - the quit function could be accessed by a button...)
- Additional levels
Have fun customizing the game & making it your own! When you do build the final game, make sure to test out the app in the macLab to make sure it functions properly.