Module 2 Examples: Object Control/Interaction + User Interface
Link to GitHub
Unity specific skills you will need,
practice, and demonstrate include:
·
Finding
GameObjects and accessing Components
·
Setting
a Component reference in the editor
·
Working
with Unity Prefab
o
Create
a prefab in the editor
o
Create/Delete
objects at run time
·
Continue
working with Transform of GameObject
o
Set
positions
o
Set
object rotation/orientation
·
Object
collisions and responses
·
User
Interface
o
Getting
world position from the mouse
o
Assign
a component of a GameObject to a script-variable
o
Sharing
the editor between the GameObject world and the UI coordinate system
o
Working
with UI RectTransform
o
Event
vs Polling
·
Packages:
create and import
·
Useful
Unity API knowledge (not covered in the examples)
o
GameObject.GetComponent<DataType>()
Concepts
you will explore and understand include
·
Direct
object control: driving an object
·
Frame
update time vs wall-clock real time
·
System
and component re-use
·
Approximating
object bounds with colliders
·
Coordinate
systems for game play and user interactions
·
Event
vs Polling user interactions
1. Object navigation: All in GreenArrowBehavior.cs
o
Run Behavior: green arrow follow mouse, or
<Space> and navigate with WASD
§ Space bar: to toggle mouse
positioning vs keyboard WASD
§ Note:
Color change
between mouse and keyboard
o
Public variables: show up in Inspector and you
can change these during runtime via the editor!
§ WATCH OUT: changes made during runtime in the editor WILL NOT be saved!
§ mTheCamera: Reference to the Camera
component on the Main Camera (must be set in the editor)!
§ Mouse vs Keyboard control can
be toggled
§ Travel speed/rotation speed
can be controlled
o
Speed: Distance per unit time. Update() function is called at
about 60 times per second!
§ mHeroSpeed: is units per second (Unity defines: Time.smoothDeltaTime) to convert frame update time period to wall
clock time
§ Remember total
height of the world is 200 units. Verify travel from top to bottom is about 10
seconds
§ mHeroRotateSpeed: 45-degree/second, takes
about 8 seconds to do a 360-degree rotation
o
Mouse position: must translate pixel position to camera space
§ Make sure to zero out the
z-component
§ Note: actual position must be
transformed by the Camera (Main Camera)
§ The alternate ways to access
the Main Camera: Camera.main, and via GameObject.Find()
o
GetKey vs GetKeyDown:
§ State of a key vs. transition
(event) of a key went from up to down state
§ Many time
vs only once!
o
Navigation:
§ Move towards the original
y-direction: this is transform.up
newPosition = oldPosition + (Speed * Time.smoothDeltaTime * transform.up)
§ Rotate left/right: rotation
with respect to the z-axis or the transform.forward
Transform.Rotate(transform.forward,
RotateSpeed * Time.smoothDeltaTime)
o
Learned:
§ Public variables show up in
the Inspector window: Convenient!
§ WATCH OUT: The configuration of these
variables in the editor when the game is running will NOT be saved!
§ [SerializeField]:
Note that mHeroRotateSpeed is private and yet is
visible in the editor.
§ Frame rate vs real time wall
clock
§ Unity variable: Time.smoothDeltaTime
§ Access mouse position (via
the camera!)
§ Navigate an object by
keyboard
§ How
to move forward: transform.up/forward/right variables
1.
Note:
these directions updates as you change the objects
orientation
§ How
to rotate: transform.rotate function changes the transform.up (forward/right) directions!
2. Pre fab: Editor create prefabs and
instantiate at runtime
3. Collision
+ Color + Texture: there
is no WebGL link for this example as object manipulation must be performed via
the editor window!
4. Game Manager + Simple UI Text
o
Run Behavior: space-bar
to spawn eggs, see the echo count on screen
o
Create UI:
§ RMB: UI => Text (Canvas and EventSystems created
automatically if not already there)
§ UI elements MUST BE child of
Canvas, otherwise, will not show
§ Zoom out to see two spaces:
Camera and UI
§ UI elements are in pixel
space! (NOT camera space)
§ Size of UI space corresponds
1:1 to Game Window
§ Use Layer manager show/hide
UI
o
UI Text Mesh Pro (TMP): Always use TextMeshPro, LMB => UI => Text – TextMeshPro
§ TextMeshPro is a package addition to
Unity, you will have to import the
package.
§ The first time you try to
create a TMP-Text, you will encounter the TMP-Importer:
§ Import the Essentials (click
on Import TMP Essentials), I do not import the Examples and Extra. I have no
need for those.
§ In your script, e.g., in GameManager.cs:
using
TMPro; // The library
to use
public
TMP_Text mEggCountEcho = null; //
The variable data type to use
o
GreenArrowBehavior: includes an int to keep
track of number of eggs on screen
§ OnMouseDown: a method on MonoBehavior that
can be over-written to receive calls when right mouse
button goes down on the game object. You can take a look
at this function.
o
EggBehavior:
§ Static variable: refer to GreenArrowBehavior
§ What is a
“static” variable?
§ Tells GreenArrowBehavior
when an egg is destroyed
o
GameManager: central object to
coordinate the entire game state
§ Hang off the MainCamera (always there), can also hang off an empty
object
§ Two public variables must be
set in the editor before game starts
§ GreeArrowBehavior and
§ TMP_Text for echoing egg status
(UI-CanvasàEggStatusEcho [a TMP_Text
object])
§ Singleton pattern: One
instance in the world, “well-known”
§ What is a
“static” variable?
§ This is a GLOBAL variable!
§ Note: Play the important role
of “central coordinator”
§ Connect GreenArrowBehavior
to EggBehavior
§ Central place for echoing
state of the game
o
Learned:
§ GameManager: Need to a central
coordinator, often enforce to only have one
§ static declaration in a class
§ Class Variable persist for
the entire process life time
§ Will persist over different
levels (scenes)
§ UI: Two objects created
automatically:
§ A Canvas object will be created, all UI objects must be a child of
this canvas
1. All UI elements must be a
child to this object! (otherwise will not be visible)
§ An EventSystem object, I drag the EventSystem to be a child of the Canvas (for organization
purpose).
§ Default UI-Layer: to see or
not to see
5. User Interface and Packages:
o
Run Behavior: press-space bar to launch egg
at slider-bar-value interval
o
Packet Import:
§ Assets èImport Package: select SliderWithEcho.unitypackage
§ From the github
look for ClassExample/Packages
§ PreFab: UI-SliderWithEcho
§ Scripts/UI/SliderWithEcho.cs
§ To
create your own package, do the reverse: AssetsèExport and
select the appropriate components (remember to select the necessary scripts)
o
UI:
Using the imported package
§ Remember,
first your scene must have a Canvas (create by: UIàCanvas)
§ To
use: drag SliderWithEcho pre-fab
into the Canvas:
1. Align
anchor: lower-left
§ Rename
to: SpawnRate
§ Must configure: (Select SpawnRate and look in the Inspector Window)
1. mLabelText
2. SliderValue: (this is a Text UI object)
1. Customize the text detail,
e.g., color
3. SliderBar (in the Slider component)
1. Set: Min Value, Max Value, Init Value
§ Careful: when adjusting
positions of the SliderWithEcho object, do not adjust
the children positions!
o
GreenArrowBehavior: reference an SliderWithEcho
§ In the editor: drag the
entire SliderWithEcho (SpawnRate)
to the GreenArrowBehaivor object
§ The value()
of SpwanRate is how many seconds to wait in between
spawning new eggs
§ Note: Time.time amount
of seconds elapsed since the beginning of the game
o
Learned:
§ Almost all Unity specific:
§ Time.time: time (in seconds) after
game began
§ Package: import/export of
prefab watch to check all dependent components
§ Note the logic in GreeArrowBehavior::Update() on check for spawn rate.
o
Alternate implementation:
§ SpawnRateèSliderBar has a call back (event
handler)
§ Can define a function in GreenArrowBehavior and add the function here.
1. Pros: Receives value change
via event, no need to refer in update()
2. Cons: Implicit
references (via event service functions), can be challenging to figure
out all event handlers.
§ I usually poll UI events in Update() function.
§ Exercise:
§ Implement this alternative.
Here is a self-practice exercise to
practice some of the above coverage. Once again, my solution is available at
the end of the document.