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.