[[TOC]]



tutorial link

demo link

Observations

  • Something i really like about this format is they insist you watch the whole video first, then try it out after.
    • Usually with these things try to be as efficient as I can, so I try to keep up and get frustrated when it doesn’t work. I often get so hung up that I might not get to the end of the video. This way you get 2 modes of experience: watching, then actually doing.
      • The thinking that it needs to be efficient is part of the problem. I’m learning a skill. That takes time. It’s really not something that should be rushed. I think previously I felt like I had to reach some goal to be validated/I was too eager to just have the skill. Now I have other skills and I can take my time learning additional things, because I’m doing it for me, not necessarily for my career (those things can be the same though).
    • I still get the urge to be doing what they’re explaining as they explain it, like I’m going to miss it or fall behind, as with in-person training.

Lesson 1.1

Topics

2021-10-06

New Functionality

  • Project set up with assets imported
  • Vehicle positioned at the start of the road
  • Obstacle positioned in front of the vehicle
  • Camera positioned behind vehicle

New Concepts & Skills

  • Create a new project
  • Import assets
  • Add objects to the scene
  • Game vs Scene view
  • Project, Hierarchy, Inspector windows
  • Navigate 3D space
  • Move and Rotate tools
  • Customize the layout

1.1.1 - setup

1.1.2 - assets and scenes

  • asset packages
    • imports
    • asset location
    • view in the explorer
  • scenes
    • scene location
    • load the scene view
    • move the scene view
    • the scene does not have any functional objects: good
      • the camera is stationary at the side of the road
      • no player-controllable object is set up

notes on packages:

I used package export/import when I migrated from the 3D village sim to the 2D UI version

  • actually thinking I might abandon the mobile version of the village sim and work on the desktop version exclusively.
    • colony-sim-pygame covers a lot of the same elements, so may make sense to just focus there, but that’s not as portable yet, and C# will be more performant
    • The data file loading on mobile is what blocked me for a while, but I did eventually figure it out.
    • I think it’s currently blocked by element positioning, with the dynamic elements not tiling correctly.

1.1.3 - moving around the scene

  • WASD with right-click hold can zoom (W, S) and pan (A, D)
  • Skybox is used for mountains/horizon stuff, neat. I always assumed textures were needed.
    • looks like it’s flat on the floor level and spikes upward around the edges
  • alt + mouse left click will allow rotating around (this feels familiar, probably knew this)
  • F key does focus or ‘frame back in’ the selected object

1.1.4 - adding assets to the scene

  • dropping assets into the scene
  • object coordinates
    • reset option, now in a vertical … in the top right of the element in the inspector, used to be gear
  • renaming objects

1.1.5 - camera select

camera select

  • preview pane when camera selected shows what player will see
  • when objects are changed in the scene during play mode, the changes are no saved when play mode is exited

1.1.6 - positioning the camera

repositioning the camera

  • scene manipulation tools
    • QWERTY to select the tools
    • rotate tool allows us to grab the object and rotate it
    • default tool is select; rotate tool is right next to it, looks like 2 arrows going in a circle
    • pan tool seems to have minimal usefulness, behaves like scene drag via mouse button clicks
    • scale tool is 4 arrows pointing away from a square
    • rect tool combines move, rotate, and scale tools for 2D
    • last tool combines move, rotate, and scale tools for 3D
  • can click on the compass arrows to shift perspective relative to the selected object
  • hold ctrl to move an object by whole units

1.1.7 - tweaking the unity editor layout

unity editor layout

  • preset organization options
  • top-right button that says ‘default’ (or ‘layout’ if customization has been done)
  • project view can be changed to a one-column layout using the vertical …
  • can save layout to be used in other projects

Lesson 1.2

2021-10-08 Lesson 1.2 - Pedal to the Metal - Adding code and physics

Topics

New Functionality

  • Vehicle moves down the road at a constant speed
  • When the vehicle collides with obstacles, they fly into the air

New Concepts & Skills

  • C# Scripts
  • Start vs Update
  • Comments
  • Methods
  • Pass parameters
  • Time.deltaTime
  • Multiply (*) operator
  • Components
  • Collider and RigidBody

1.2.1 - first C# script

tutorial link

  • project window > right click assets > create > folder, name it Scripts
    • same level as Scenes
  • right click scripts folder > Create > C# Script > PlayerController
    • Camel case is naming convention for unity objects
    • NOTE: Name in unity is not tied to name of public class after the default code is generated
  • drag script onto object in hierarchy to attach it
    • attaches the PlayerController script to the object as a component
    • can also drag the script into the inspector pane to create the component
    • can also click “Add Component” in the inspector and find the script in the list of options
    • can also drag the script onto the target object in scene, but there’s no visual indicator that it worked, other than the script appearing in the list of components on the object

1.2.2 - the guts of a unity script

tutorial link

  • class
  • comments
  • keywords
  • methods

1.2.3 - give the vehicle forward motion

tutorial link

In Translate, the number is how many meters per second.

1
transform.Translate(0, 0, 0.1f);
  • transform is transform component of current object (vehicle)
  • Traslate is a method on the transform component
  • 0, 0, 0.1f means it will translate in the Z direction by 0.1 units

1.2.4 - use builtin Vector3.forward

Use builtin Vector3.forward for 0,0,1

1
2
3
4
5
    void Update()
    {
        // We'll move the vehicle forward
        transform.Translate(Vector3.forward);
    }

Tried to get extensions in vscode that would give method definitions, but could not find one. Ended up with duplicate method suggestions, like Awake() 4 times in the intellisense dropdown when hitting ctrl+space

1.2.5 - Time.deltaTime

Slow down the vehicle

Time.deltaTime changes the update from updating every frame to updating over time every second. This helps account for discrepancies between hardware that might render frames at different speeds, which means the experience would not be the same between devices. This is the change in time between all frames.

From the docs: The interval in seconds from the last frame to the current one (Read Only).

https://docs.unity3d.com/ScriptReference/Time-deltaTime.html

transform.Translate(Vector3.forward * Time.deltaTime * 20);

This translates (hah) to 20 m/s

1.2.6 - RigidBody

Need this on both truck and crate to get expected behavior

1.2.7 - duplicating objects

ctrl+D duplicates selected object

a shorter shortcut than ctrl+c/ctrl+v, so not much use

can copy and paste multiple obstacles, and move obstacles as a group via multiselect

Lesson 1.3

2021-10-09 Lesson 1-3 - High Speed Chase - camera following

Topics

New Functionality

  • Vehicle moves down the road at a constant speed
  • When the vehicle collides with obstacles, they fly into the air

New Concepts & Skills

  • C# Scripts
  • Start vs Update
  • Comments
  • Methods
  • Pass parameters
  • Time.deltaTime
  • Multiply (*) operator
  • Components
  • Collider and RigidBody

1.3.1 - public variables

new trick: can click and drag the variable name in the inspector to change its value

it turns blue

1.3.2 - camera script

create GameObject public var, and drag target game object into it via the inspector

set the transform.position variable to equal the vehicle’s transform.position

1.3.3/1.3.4 - add an offset

1.3.5 - LateUpdate to fix stuttering

the built-in LateUpdate method on the camera object causes the camera to update after the vehicle, fixing the stutter

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
    /// <summary>
    /// LateUpdate is called every frame, if the Behaviour is enabled.
    /// It is called after all Update functions have been called.
    /// </summary>
    void LateUpdate()
    {
        // offset the camera using the player's position
        transform.position = player.transform.position + offset;
    }
}

1.3.6 - unity color tint modes

Edit > Preferences > Colors > General > Playmode tint

Lesson 1.4

2021-10-11 Lesson 1-4 - Player Input

Topics

New Functionality

  • When the player presses the up/down arrows, the vehicle will move forward and backward
  • When the player presses the left/right arrows, the vehicle turns

New Concepts & Skills

  • Empty objects
  • Get user input
  • Translate vs Rotate

1.4.1 - moving the vehicle left or right

  • add a translate var to update transform using Vector3.right

1.4.2 - use input for movement

  • input is automatically mapped by unity
  • horizontalInput = Input.GetAxis("Horizontal");
    • this gets input from arrows or from dpad left axis joystick
    • Edit > Project Settings > Input Manager > Axes > Horizontal

1.4.3 - vary vehicle speed

  • did this on my own before watching video, made a bunch of changes
  • of course the solution they use is a lot simpler: just get Vertical axis and multiply speed by that value in the forward movement Translate input
My PlayerController with acceleration and deceleration with input buttons
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float speed = 5.0f;
    public float turnSpeed;
    public float horizontalInput;
    public float forwardButton;
    public float reverseButton;
    public float maxSpeed = 20.0f;
    public float noInputSpeedChange = 0.5f;
    public float acceleration = 0.2f;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        // get fire button press

        // get horizontal input
        horizontalInput = Input.GetAxis("Horizontal");
        // is GetAxis right here?
        forwardButton = Input.GetAxis("Fire1");
        reverseButton = Input.GetAxis("Fire2");
        // if pressing the forward button (takes priority)
        HandleMovementInput();
        if (speed != 0) {
            transform.Translate(Vector3.forward * Time.deltaTime * speed);
            transform.Translate(Vector3.right * Time.deltaTime * horizontalInput * 2);
        }
    }

    void HandleMovementInput() {
        if (forwardButton > 0) {
            // We'll move the vehicle forward
            // move forward if not at max speed
            if (speed < maxSpeed) {
                speed = speed + acceleration;
            }
            // if over max speed, reset to max speed
            if (speed > maxSpeed) {
                speed = maxSpeed;
            }
        } else if(forwardButton == 0 && reverseButton > 0) {
            // but if reverse is pressed and forward isn't
            // move it backward
            speed = speed - acceleration;
            if (reverseButton > 0 && speed < -maxSpeed) {
                speed = -maxSpeed;
            }
        } else {
            Debug.Log("No press, reducing");
            ReduceSpeed();
        }
    }

    void ReduceSpeed() {
        // reset 
        if (speed > 0) {
            speed -= noInputSpeedChange;
        } else if (speed < 0) {
            speed += noInputSpeedChange;
        }
        // avoid oscillations
        if (Mathf.Abs(speed) < noInputSpeedChange) {
            speed = 0;
        }
    }
}
Tutorial with forward and reverse
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
    // Update is called once per frame
    void Update()
    {
        // get fire button press

        // get horizontal input
        horizontalInput = Input.GetAxis("Horizontal");
        forwardInput = Input.GetAxis("Vertical");
        // GetAxis is a bit of a misnomer here; it's actually a button
        forwardButton = Input.GetAxis("Fire1");
        reverseButton = Input.GetAxis("Fire2");
        // if pressing the forward button (takes priority)
        // HandleMovementInput();
        if (speed != 0) {
            transform.Translate(Vector3.forward * Time.deltaTime * speed * forwardInput);
            transform.Translate(Vector3.right * Time.deltaTime * horizontalInput * 2);
        }
    }

1.4.4 - make vehicle rotate instead of slide

  • uses transform.Rotate instead of translate to handle left/right input
    • [https://docs.unity3d.com/ScriptReference/Transform.Rotate.html](Transform.Rotate API docs)
  • toggling global to local axes helps read the directions on the target object
    • a81ba8421655cd6d9265f308ee303b38.png

1.4.5 - project cleanup

  • empty game objects: game object containers

Script Objects

PlayerController
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    private float acceleration = 0.2f;
    private float forwardInput;
    private float forwardButton;
    private float horizontalInput;
    private float maxSpeed = 20.0f;
    private float noInputSpeedChange = 0.5f;
    private float reverseButton;
    private float speed = 5.0f;
    private float turnSpeed = 25f;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        GetInputs();
        HandleSpeedInput();
        // move the vehicle forward
        transform.Translate(Vector3.forward * Time.deltaTime * speed);
        // turn the vehicle
        transform.Rotate(Vector3.up, turnSpeed * horizontalInput * Time.deltaTime);
    }

    void GetInputs() {
        horizontalInput = Input.GetAxis("Horizontal");
        forwardInput = Input.GetAxis("Vertical");
        // GetAxis is a bit of a misnomer here; it's actually a button
        forwardButton = Input.GetAxis("Fire1");
        reverseButton = Input.GetAxis("Fire2");
    }

    void HandleSpeedInput() {
        if (forwardButton > 0 || forwardInput > 0) {
            // We'll move the vehicle forward
            // move forward if not at max speed
            if (speed < maxSpeed) {
                speed = speed + acceleration;
            }
            // if over max speed, reset to max speed
            if (speed > maxSpeed) {
                speed = maxSpeed;
            }
        } else if((forwardButton == 0 && reverseButton > 0) || forwardInput < 0) {
            // but if reverse is pressed and forward isn't
            // move it backward
            speed = speed - acceleration;
            if (reverseButton > 0 && speed < -maxSpeed) {
                speed = -maxSpeed;
            }
        } else {
            Debug.Log("No press, reducing");
            ReduceSpeed();
        }
    }

    void ReduceSpeed() {
        // reset 
        if (speed > 0) {
            speed -= noInputSpeedChange;
        } else if (speed < 0) {
            speed += noInputSpeedChange;
        }
        // avoid oscillations
        if (Mathf.Abs(speed) < noInputSpeedChange) {
            speed = 0;
        }
    }
}
FollowPlayer
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FollowPlayer : MonoBehaviour
{

    public GameObject player;
    private Vector3 offset = new Vector3(0, 5, -7);

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

    }

    /// <summary>
    /// LateUpdate is called every frame, if the Behaviour is enabled.
    /// It is called after all Update functions have been called.
    /// </summary>
    void LateUpdate()
    {
        // offset the camera using the player's position
        transform.position = player.transform.position + offset;
    }
}