Introduction to GDD 210

In Game Lab 1 you will be learning about new ways to use Unity to make games in a series of Labs. Each Lab is comprised of:
  • Interactive Lecture: We will explore example Unity projects together and learn how the features of each scene are created so that you can begin developing an understanding of how to implement similar features in your own work. I showcase a new concept, feature, or tool, and then dive deep into how it works. I encourage you to ask questions, make suggestions, and cite examples of games where you've seen the relevant topic used.
  • Student Game: To support your learning of new material, you will use the relevant subject in a small Student Game. You should aim to build an interesting, compelling, experience into a "minigame" sized Unity project, due at the end of each Lab. The topic, style, and scope, of your game is largely up to you. The important element of these games is the effort you put into utilizing the relevant material and your dedication to enhancing your own understanding of the topic. Check the Grading page for information on what exactly is required.
  • Quiz: At the conclusion of each Lab, a quiz on the material covered will help you understand where your understanding of the topic should be before moving on, and introduce a chance to seek additional help if needed.


Projects

After completing the Lab work in the course, you will tackle a series of Projects. These are larger scoped than the Lab games, and will require more planning and work to deliver complete, polished, relatively-bug-free, experiences. Check the Project links in the Course Materials drop-down for information about each Project. You can also look at Projects from previous students in the Student Work page. You can also check the Grading page for information on what exactly is required for Projects.


Introduce Yourself

  • Let us know who you are, why you're here, your experience in game development, and the area of game development that you're most interested in. This will help me introduce material to the course that might help with your specific interest if there isn't otherwise a lesson on that subject.
  • Show off or discuss anything you've made in the past
  • Tell us your favorite game/genre

Getting Started

! When doing work for this course it is recommended that you avoid saving/installing Unity projects to OneDrive folders. Also avoid special characters in your file path names. The safest bet is a simple path on your machine, ex: C:/GDD/210/i>. You will want to make sure you back up your work on an external hard drive or use a version control system like GitHub.
  • Download and install Cyberduck to connect to  MyWebspace FTP . Instructions on how to connect
  • Cyberduck will allow you to copy files from your computer onto a server so that they can be viewed from the internet. This is how you will share your work.
  • When connecting: User name "mywebspace.quinnipiac.edu|QUUsername" (there is a vertical pipe before you enter your QU Network Username, the shift+backslash key)
  • Use the Bookmark > New Bookmark button in Cyberduck to save the connection for easier log in.
! The files that you add to Cyberduck become copies that no longer live on your machine anymore. This means that whenever you update a file on your machine you will need to upload that file again to update the Cyberduck version of the file.
  • Create a portfolio for this course. Here are a few options.
    • Create your own (HTML/CSS/JavaScript)
      • Copy this example portfolio to your computer and change the HTML to display your name.
      • This website will host links to all of your work. When you build an exercise or project it will generate a webpage. The links on this portfolio will point us to your builds.
      • To save the page: Open the page > right-click on the background > select Save Page As. Create a folder on your computer for your course work, ex: c:/GDD/GDD210/Portfolio and save the webpage in there as index.html.
      • Open your portfolio in a text editor so you can change the HTML to work for your account. Use VSCode if you need a text editor.
      • Change the name at the top to your page and change the username cblake inside all of the links to your username. Ex:
        <header>
        <h2>Lab 1</h2>
        </header>
        <section>
          <nav>
            <ul class="lab_links">
              <li><a href="yourTrelloURL"target="blank">Lab 1 Project Management (Trello Example)</a></li>
              <li><a href="https://mywebspace.quinnipiac.edu/yourUserName/buildFolder">Lab 1 WebGL Build</a></li>
              <li><a href="yourGitHubURL">Lab 1 GitHub Repo</a></li>
            </ul>
          </nav>
          <article>
            <h1>Example Lab 1 Project</h1>
          <img src="http://mywebspace.quinnipiac.edu/yourUserName/imageName.gif"style="width:200px;height;200px;">
          <img src="http://mywebspace.quinnipiac.edu/yourUserName/image2Name.gif"style="width:200px;height:200px;">
            <p>Description of your game!</p>    
          </article>
        </section>
        
      • You can now upload a copy of your portfolio to MyWebspace. Inside CyberDuck make a directory called 210, and drag your index.html file into it. To make sure it works you can try clicking the link to your name in the Student Work section or navigating to: http://mywebspace.quinnipiac.edu/username/210/
      • This is the most basic example of a working portfolio, I encourage you to explore HTML, CSS, and JavaScript to make it look more interesting!
    • Use Canva Template
      • Open template here. You will need to create an account and save a copy of the portfolio for yourself.
      • Edit the portfolio to include your name, the course title, and your work.
      • Save your Canva as a website
        Share > More... > Website > Standard
      • Email me the URL for your website so I can link your name to it on the Student Work page.
  • Install  Unity Hub . This is a launcher that will help organize your projects and Unity versions over the course of your education and career.
  • Launch Unity Hub and Install 2022.X.X LTS. As long as you find a 2022 version it will work fine.
    • Installs > Install Editor > Unity 2022.X.X.
    • Required Modules: Microsoft Visual Studio 2019, WEBGL Build Support, Windows Build Support. Once you have selected these modules you can begin installation.
  • Join the GDD  Discord Channel  and introduce yourself. This is a place for GDD students to stay in touch outside of the classroom. Ask questions, help each other.
  • Lab 1

    Unity 3D

    Until now you've likely been learning Unity's 2D systems. This typically means working with the X and Y component of a Game Object's position, and the Z component of their rotation. You also have been using Sprite Renderer and RigidBody2D components. In this Lab we start working in 3D by adding Mesh Renderer components to our scene, and moving around in three dimensions of space.

    Goals for Lab 1:

    • Understand how to use a Mesh Renderer component to render 3D models in your games. We will explore this in more detail in Lab 3.
    • Experiment with X/Y/Z components of transform's position, rotation, and scale. Take note of how child game objects are affected by parent game objects changes.
    • Use RigidBody and Collider components to simulate 3D physics. Learn how to control the RigidBodies by adding constant force in the Fixed Update function of a Monobehaviour and how to add impulse forces.
    • Make a simple game using 3D models and 3D physics.

    ! This course requires you to use GitHub to download example projects and to host public repositories for your work. Using GitHub Desktop is the easiest way to do this.

    1. 1. Download the Lab 1 Example Project from GitHub
      • Click the link to open the GitHub repository
      • Open the button and select Open With GitHub Desktop
      • Select a location to copy the example project on your machine and select Clone. This will create a copy of the Unity project on your machine so you can follow along with the lecture
    2. 2. Working in 3D Space
      • Understanding the third dimension: In Unity, the World Space directions are represented by

        X : Left/Right as Red
        Y : Down/Up as Yellow
        Z : Back/Forward as Blue

        These directions are fixed for the orientation of the scene, or World Space, but not for the transform components of Game Objects in your scene. Example: The forward direction of your player (also the transform.forward vector) usually rotates to face the same direction as the player is looking. In this case, the World Space forward direction would be different from the player's forward direction. The transform's orientation is called Local Space.
        It is important to know which orientation your are referring to when manipulating your transform component, the World Space or the Local Space. If you want to move in the direction the player is facing, but move forward in World Space, you may not get the result you desire.
      • We will demonstrate how world/local positions are displayed on a Game Object's Transform component, and how child Game Objects work.
    3. 3. Vectors

      • In Unity, Vectors are used for a few different things so we'll cover them and explore what each means.
      • Vector3 a data type for position, rotation, and scale.
      • Vector3 as a data type for velocity, describing the direction of motion and the speed.
    4. 4. Rotation in 3D
      • In 2D you generally rotate along the Z axis. In 3D, it's likely you will rotate along any axis.
      • Rotation data in Unity is actually stored as a Quaternion
      • Rotation in the inspector is displayed as a Vector3, X Y and Z rotation. This is a simplified, human-readable, representation of the rotation data.
      • To rotate an object, we modify the rotation property of it's transform component.
        • There are several ways to do this, the Rotate function being the most helpful. It is a function of the Transform class, so to use it you should reference a Game Object's transform and call the Rotate() function. There are a few ways to use the function, we'll look at the method that requires a Vector3 of the angles we want to rotate as a parameter.Rotate(Vector3 eulers);:
          transform.Rotate(new Vector3(-90, 0, 180));
                        
          This will rotate our transform's rotation -90 on the X axis and +180 on the Z axis.
      ! Sometimes functions can be used in different ways, by passing in different parameters when called. This is called "Function Overloading". The Rotate function has 6 ways you can call it, in Visual Studio you can place the mouse over the function name to see the overloads.
    5. 5. Collections and Loops
      • Array
      • public int[] LuckyNumbers = new int[3] { 3, 8, 21 };
        
        [SerializeField] private string[] bands = new string[1];
        
        private void Start()
        	{
        		Debug.Log(LuckyNumbers.Length);
        		// Prints: 3
        		Debug.Log(LuckyNumbers[0]);
        		// Prints: 4
        		LuckyNumbers[3] = 25;
        		// ERROR: IndexOutOfRangeException: Index was outside the bounds of the array.NewBehaviourScript.Start()...
        
        
        		Debug.Log(bands[0]);
        		// Prints: "" Empty string
        		bands[0] = "Metallica";
        		Debug.Log(bands[0]);
        		// Prints: "Metallica"
        		Debug.Log($" {bands[0]} RULES! ");
        		// Prints: " Metallica RULES! "
        	}
                      
      • List
      • public List<string> StudentNames = new List<string>(); // Declare and initialize a new list
        
        private List<bool> coinFlipsLandOnHeads;
        
        private void Start()
        {
          coinFlipsLandOnHeads.Add(false);
          // ERROR: NullReferenceException: Object reference not set to an instance of an objectNewBehaviourScript.Start()...
        
          StudentNames.Add("Alice");
          StudentNames.Add("Bob");
          StudentNames.Add("Chuck");
          StudentNames.Add("Dave");
        
          if (StudentNames.Contains("Alice"))
          {
            Debug.Log("Alice is here today!");
          }
          else
          {
            Debug.Log("Alice is missing!");
          }
          // Prints: Alice is here today!
        
          StudentNames.Remove("Bob");
          // List now has length of 3: {"Alice", "Chuck", "Dave"}
        
          StudentNames[1] = "Charles";
          // List: {"Alice", "Charles", "Dave"}
        
          string aStudent = StudentNames.Find(x => x.StartsWith("D"));
          if (aStudent != null)
          {
            Debug.Log($"{aStudent} starts with 'D'!");
          }
          else
          {
            Debug.Log("No student's name starts with 'D'!");
          }
          // Prints: Dave starts with 'D'!
        }
                      
      • For Loop
      •                 public GameObject[] Enemies = new GameObject[10]; // Declare and initialize a new array of gameobjects
        	public List StudentNames = new List(); // Declare and initialize a new list of strings
        
        	private void Start()
        	{
        		for (int i = 0; i < Enemies.Length; i++)
        		{
        			Enemies[i].name = $"Enemy {i}";
        		}
        		//Set each enemies name in the hierarchy to "Enemy 1", "Enemy 2", etc.
        
        		StudentNames.Add("Alice");
        		StudentNames.Add("Bob");
        		StudentNames.Add("Chuck");
        		StudentNames.Add("Dave");
        
        		for (int i = 0; i < StudentNames.Count; i++) //NOTE: Lists use Count instead of Length
        		{
        			Debug.Log($"Welcome {StudentNames[i]}!");
        		}
        		// Prints: Welcome Alice
        		// Prints: Welcome Bob
        		// etc.
        	}
                      
        ! To automatically fill in a for loop in Visual Studio try typing "for" and then hitting Tab.
        This will generate a generic for loop template you can then edit to fit your script.
      • For Each Loop
      • public GameObject[] Enemies = new GameObject[10]; // Declare and initialize a new array of gameobjects
        public List StudentNames = new List(); // Declare and initialize a new list of strings
        
        private void Start()
        {
          foreach(variablType nameInsideLoop in collectionName)
          {
            //Inside the loop we use nameInsideLoop to reference each item in the collection
            // Each time the loop runs, nameInsideLoop refers to the next item in the array/list, until we've referenced each one once.
          }
        
          foreach (GameObject g in Enemies)
          {
            Destroy(g);
          }
          // Destroy each enemy GameObject
        
          StudentNames.Add("Alice");
          StudentNames.Add("Bob");
          StudentNames.Add("Charles");
          StudentNames.Add("Dave");
        
          foreach (string name in StudentNames)
          {
            if (name == "Bob")
              continue;
        
            Debug.Log($"Hello {name}");
            
            if (name == "Charles")
              break;
          }
          // Prints: Alice
          // Skips Bob
          // Prints: Charles, then exits the loop
          // Never gets to Dave... poor Dave
        }
                      
    6. 6. Physics in 3D
      • Rigidbody Component
        • This component contains data about physics properties like mass, velocity, and angularVelocity
        • .
      • Physics Material
        • These assets contain data about how the material of the object should behave, including friction and bounciness.
        • .
      • Force
        • Adding a force to a RigidBody requires a Vector3 which indicates the direction of the force, and the magnitude, or strength, of the force.
      • Angular Velocity
        • A Vector3 describing the rotational speed on each axis of a RigidBody.
      • Collisions
        • Collisions occur between GameObjects with Collider components. Usually, at least one GameObject in the collision must have a RigidBody. Check the collision chart below to see which types of collisions will call a "collision" message.

        • Unity Manual
      • Triggers
        • Triggers occur between GameObjects with Collider components where at least one is marked IsTrigger.
        • Triggers will call "trigger" messages to your scripts but will not impact the physics of the RigidBody. Consider picking up a HealthPack item in a game: You need to detect when the player touches it, but you don't want the player to get stuck on it when they touch it.

    Lab 1 Project

    Your goal for Lab 1 is to create a 3D minigame that allows the player to utilize three dimensions. This could mean flying in outer space, walking around a city, riding a unicycle through a haunted mansion, delivering pizzas in a zombie apocalypse, etc. Get creative! Build something that challenges you, pushes the limits of your abilities and forces you to explore beyond what you already know into what you want to know.
    Feel free to focus on an area of game development that you enjoy: if you want to be a 3D artist you can make a very simple game mechanic and spend your time making it look amazing. If you want to focus on sound design create a game that makes the audio component an important aspect of the game.

    Requirements

    • 3D Game World: Gameplay should take place in 3D space.
    • Physical Interaction: You should make use of collisions or triggers in some way. Opening doors, picking up coins, triggering a dialog with an NPC, etc. Something that calls a function from a physical interaction.
    Check the Grading page for more information about what is required.

    Lab 1 by James R - 2022

    Recording of Lab 1 lecture available as a resource for you to see and hear the lesson again.


    ! If we are unable to get through all of the material in class you will need to watch the recorded lecture and complete the lesson on your own. Please ask me questions via email/Discord and schedule meetings during my office hours as needed!

    Lab 2 Character Controller Raycasting

    Character Controllers & Raycasting

    We will also cover creating Git repositories and backing up our work on GitHub.

    Now that we have some experience operating in Unity 3D we can begin building out more compelling systems to navigate these spaces. A Character Controller refers to a script, or scripts, that govern the movement for a player controlled character in a game.

    Goals for Lab 2:

    • Learn how to use GitHub and GitHub Desktop to create backups of your work online.
    • Understand how to create several types of 3D character controllers so you can create one for your own games.
    • Learn how to utilize the raycast function for various game mechanics.
  • Download the Lab 2 Example Project from GitHub
    • Click the link to open the GitHub repository
    • Open the button and select Open With GitHub Desktop
    • Select a location to copy the example project on your machine and select Clone. This will create a copy of the Unity project on your machine so you can follow along with the lecture

    Character Controllers


  • When designing a character controller you must first figure out what movement and rotation functions and limits are required. A free-floating flying character, or vehicle, might be able to accelerate off into any direction at any angle. A first-person character usually rotates their body around the Y axis of the world, and their head on it's local X axis.
  • Raycasting


  • A Raycast is a function which sends out a virtual ray from one position in our game world in a direction we set. As this ray moves through the world, we can pull out details about colliders which it encounters. We can check to see if the collider it hit was attached to an enemy or a friend, we can see how far away the collision was from us, and we can find out the angle of the surface which the ray contacted, and more.
  • Raycasting is done several different ways, depending on the goal of the raycast and the available information to pass into the function. Here is an example of a simple raycast that, if it hits a collider, will draw a line in the Unity editor from the "Camera" to the point the ray hit.
    RaycastHit hit;
    if (Physics.Raycast(CamTransform.position, CamTransform.forward, out hit))
    {
        Debug.DrawLine(CamTransform.position + new Vector3(0f, -1f, 0f), hit.point, Color.green, 5f);
        Debug.Log("Simple Raycast: " + hit.collider.gameObject.name);
    }
              
    hit.point is a Vector3 of the position in the scene where the raycast hit.
    We can also get the name of the GameObject we hit with hit.collider.gameObject.name.
  • Sometimes we want a raycast that doesn't stop at the first collider it hits, but continues through it and gives us information about everything that it hit. Using the RaycastAll function we can get an array of RayCastHit data. By calling the RaycastAll function, we fill RayCastHit[] hits with each hit that occurs. We can then iterate on that array and look at each RayCastHit individually.
    RaycastHit[] hits = Physics.RaycastAll(CamTransform.position, CamTransform.forward);
    
    if (hits.Length > 0)
    {
      for (int i = 0; i < hits.Length; i++)
      {
        Debug.DrawLine(CamTransform.position + new Vector3(0f, -1f, 0f), hits[i].point, Color.green, 5f);
        Debug.Log("Raycast All hit " + i + ": " + hits[i].collider.gameObject.name);
      }
    }
              
  • One of the most powerful use cases for a raycast is getting a reference to a script attached to a collider we hit with a raycast. Consider a First Person Shooter, where we can inflict damage upon enemies. We would first perform our raycast to determine if we hit something, but then we need find what we hit if we want to do something to it. And not only what, but likely a specific instance of what. In the case of an enemy, we would want to reduce the health value of some Enemy script attached to it's GameObject.
    RaycastHit hit;
    if (Physics.Raycast(CamTransform.position, CamTransform.forward, out hit))
    {
      Debug.DrawLine(CamTransform.position + new Vector3(0f, -1f, 0f), hit.point, Color.green, 5f);
    
      Enemy e = hit.collider.gameObject.GetComponent();
      if(e != null)
      {
        e.TakeDamage(5);
      }
      else
      {
        Debug.Log("Hit something that wasn't an enemy!");
      }
    }
              
  • Lab 2 Project

    Your goal for Lab 2 is to create a 3D First/Third person game using a Character Controller component and utilizing raycasting for a mechanic in the game.
    Some possible ways to use raycasting: Shooting targets, collecting items, pushing objects, inspecting clues, opening doors, petting animals, hiding from enemies view.

    Requirements

    • 3D Game World: Gameplay should take place in 3D space.
    • Character Controller: Create a character controller that allows you to navigate the world. Do not use a RigidBody to control the player movement.
    • Raycast Mechanic: A raycast should be part of one of your game's core mechanics.
    Check the Grading page for more information about what is required.

    Lab 1 by Donovan B - 2020

    Recording of Lab 2 lecture available as a resource for you to see and hear the lesson again.


    ! If we are unable to get through all of the material in class you will need to watch the recorded lecture and complete the lesson on your own. Please ask me questions via email/Discord and schedule meetings during my office hours as needed!

    Lab 3

    Lighting & Materials

    In this section we will be discussing the various visual elements of game development in Unity and covering how to utilize these areas to enhance the visual fidelity of your games, bringing your game worlds to life.
    We start with a look at what a 3D model, or mesh, is made up of by opening up some 3D modeling software and analyzing the process of creating a new model for use in our games.
    We then bring our model into Unity and explore how it is rendered in our game.
    Next, we analyze how Unity uses materials to apply textures to our mesh.
    This will lead us into learning about the lighting system in Unity, where we will explore the use of realtime and baked lights.

    Goals for Lab 3:

    • Understand what makes a 3D mesh, and how it's rendered in Unity.
    • Be able to create materials to suit your games art style.
    • Understand realtime and baked lighting so you can use it in your games.

    - Exploring the 3D Model
    - Lighting
    - Materials

    - Lab 3 Project
    ! This course requires you to use GitHub to download example projects and to host public repositories for your work. Using GitHub Desktop is the easiest way to do this.

    • Download the Lab 3 Example Project from GitHub
      • Click the link to open the GitHub repository
      • Open the button and select Open With GitHub Desktop
      • Select a location to copy the example project on your machine and select Clone. This will create a copy of the Unity project on your machine so you can follow along with the lecture
      • If GitHub Desktop does not open when you click the "Open With GitHub Desktop button on GitHub, you will need to clone the repository manually.
        - In the menu, copy the URL.
        - Open GitHub Desktop
        - Clone the repository with File > Clone Repository > URL
        - Be sure to select an appropriate location for the project on your machine. After the project is cloned, you will have a copy of the Unity project on your computer.

    Exploring the 3D Model

    • To render a 3D model, or mesh, Unity requires two components: The Mesh Filter and Mesh Renderer components handle displaying a mesh in our scene.
      The Mesh Filter component has a field for a selecting a mesh, holding that as a reference for the Mesh Renderer component.
      The Mesh Renderer component renders the mesh in the scene by utilizing the properties of the selected material (and shader), and the properties of how it should interact with light and light probes.

    • Components of a mesh:

    Lighting

    • Lighting in Unity is controlled by Light components.
      - Point Light: Emits light in a sphere from a point like a lightbulb
      - Spot Light: Emits light in a cone from a point, where the angle of the cone can be adjusted.
      - Directional Light: Emits light in the direction of the transform's forward vector across the whole scene, light the sun.
      - Area Light: Emits light from a surface, instead of a point. Only available as a baked light. Creates softer lighting profiles than point lights. - Emissive Materials: Emit light from the faces of a mesh.
    • Realtime Lighting - Lighting and shadow casting can be computationally expensive, so using realtime lights only when needed is advised.
    • Baked Lighting - Allows the lighting to be baked into the static geometry of the scene, no longer requiring it to be rendered in realtime.

    Materials

    • A Unity material is an asset that can be added to a renderer to control how it's displayed in a game. The Unity Standard Shader is the default shader for a new material. It can be used to create very high quality assets by layering textures to add color, lighting, and depth effects.
    • Unity's standard particle shader can be used to generate particle materials.

    Continued Learning

    • Using lighting effectively, to create the world you want to create, can be challenging. I recommend following this Unity lesson to continue learning about lighting in Unity.

    Lab 3 Project

    For Lab 3 you have two options:
    1: Create a 3D minigame that utilizes lighting and custom materials. Try to use these to build a compelling theme for your game.

    Requirements

    • 3D Game World: Gameplay should take place in 3D space.
    • Lighting: Utilize at least 3 lights. Be careful of the limits of realtime lighting on WebGL builds.
    • Materials: Create and apply at least 3 new materials, applying at least a albedo and normal map.
    2: Create a scene which utilizes custom materials, lighting, and cinemachine, to block out a cutscene. You can use the example cinemachine triggers or make your own system.

    Requirements

    • Lighting: Utilize at least 3 lights. Be careful of the limits of realtime lighting on WebGL builds.
    • Materials: Create and apply at least 3 new materials, applying at least a albedo and normal map.
    • Cinemachine: Use Cinemachine plugin to create a cutscene / story.
    Check the Grading page for more information about what is required.

    Lab 3 by Omar R - 2022

    Recording of Lab 1 lecture available as a resource for you to see and hear the lesson again.


    ! If we are unable to get through all of the material in class you will need to watch the recorded lecture and complete the lesson on your own. Please ask me questions via email/Discord and schedule meetings during my office hours as needed!

    Section 1 Section 2

    • Team 1:
      Jesse D, Ross F, Ethan L, Jack A
    • Team 2:
      Ryan, John, Brian, Alex
    • Spooky 4:
      Atlas M, Khila S, Nicholas L, Taylor J
    • Dream Team:
      Zachary M, Aleena G, Jared L, Stephen R
    • Jared, Richard, James Aleena, John, Matthew

    Project 1

    Project 1 is designed to give students the opportunity to work on teams and develop a game that interests them.


    In the Design Phase of the project, teams are encouraged to put great thought into what game they will make. Use brainstorming techniques and assess the viability of each idea based on the team's skill set and timeline for the project. After a high level concept is selected, teams should start a design document where they begin to fully detail every element of the game. This document should provide enough detail that everyone on the team can look at the document and derive the same understanding about any element of the game from it.


    In the Development Phase, teams will start a rapid prototyping sprint, then begin completing tasks in weekly sprints. Teams should conduct daily and weekly scrum where team leaders will assign tasks for team members to complete.

    At the end of each sprint (1 week) teams should meet to discuss what they were and were not able to complete, to prepare for the following weeks tasks.




    Page Under Construction

    This page will become available soon.