Module 5 Examples: Unity Specific Tools
Link to GitHub
Coverage
Unity specific skills you will need,
practice, and demonstrate include:
·
Platformer
support: RigidBody2D::Dynamic
·
Near-term
fixed number periodic actions: Coroutines
·
Templated
graphical interface to data: Scriptable Objects
·
TilePallete and Tilemap: for
creating (by painting) levels
·
Particle
Systems: beginning of creating effects
Concepts
you will explore and understand include
·
Nothing
much here, mostly simply about how to use Unity to accomplish specific tasks
- Support for
Platformers:
- Run Behavior:
- D: slides towards the right
- Watch out can move right
movement is only possible on the ThePlatform
(upper Brown platform) or in the air
- CANNOT move
right on TheFloor (Black platform)
- This is awkward to
control and no fun, but makes the point that you can have different
behaviors on different (types of) platform
- A: moves the left
- W: strange seemingly
wanting to jump
- Space: flies upwards
- Make sure to look at the
Console print out: differentiate “Collision” from
“Trigger”!!
- Brown(ThePlatform)/Black(TheFloor)/Orange(StationaryObsticle): Simple platforms
- White
(Collide-And-Overlap): Only detects collision (allows overlap)
- Pink
(Collide-And-Push): Detects and maintain collision (no overlapping)
- Scene setup:
- Hero: simple Sprite
with
- BoxCollider2D: (for
collision detection)
- IsTrigger:
is off, which means this is NOT just for detecting collision, it is
more
- Try: switch on
triggering and see the hero free falls
- When on: only
interested in knowing there is a collision
- RigidBody2D: this
object is the active party in
collisions, this object collide with others
- Type: Dynamic
(things moves under gravity now)
- Constraints: Freeze
rotation in Z (object will _not_ rotate as a result of collision)
- HeroMovement:
script, refer to the following
- Platforms:
Brown/Black/Orange
- DO NOT have
RigidBody2D, as not active collider. These objects are expected to be
collided by other active objects (objects with RigidBody2D)
- Have: BoxCollider2D
- Collide-and-Overlap:
White
- DO NOT have
RigidBody2D
- BoxCollider2D:
- IsTrigger:
set to On (only for detecting collision)
- That’s why
Hero can detect when colliding with this object and can overlap
- Collide-and-Push:
Pink
- BoxCollider2D:
- RigidBody2D:
- Type: Dynamic
- Type: Kinematic
- Scripts::HeroMovement
- mHeroPhysics: is reference to the RigidBody2D
component
- SerializeField: Notice this keyword, allow private
datatype access from the editor
- Update():
- A/W
keys: tries to change position direction
- Notice:
“W” key does not work well at all, fighting with the
physics after first y-movement!
- Lesson:
when Dynamic is on, changing position may not work (moving right seem
to work as Physics is not operating when Hero is resting on platform)
- Space:
changing the traveling velocity (goes back to zero because of gravity)
- D: only allows
right-ward movement when touching the Brown platform or not touching anything (in
the Default layer)
- OnCollision:
Enter/Stay/Exit
- Collision with
objects with Colliders’s IsTrigger set to OFF
- Default: Collide
and stay (e.g., standing on platform) unless
- Push: other object
has RigidBody2D, and type is Dynamic
- OnTrigger:
Enter/Stay/Exit
- Will overlap: detecting
a collision with no behavior assumption
- Learned:
- How to for a platformer with Collider2D and RigidBody
- Collider2D::IsTrigger:
- On: only triggers, objects will overlap
- Off: will trigger and with RigidBody::Dynamic-type, will push the object
- RigidBody
- Type: Dynamic for simulating gravitational physics
- Kinematic: for stationary
- Constraints: freeze relevant rotations in physics simulation
- Coroutines: Short term, fixed
(usually) number periodic actions
- Same scene and control
as above, the only thing interesting is the White block
- Run behavior:
- move the Hero to
collide the White block from the left/right to see the block changing
color
- Collide from the
Right: White block blinks yellow/magenta
- Collide from the
Left: White block goes through a series of color changes
- Scene Setup:
- Identical to above
- Recall that White
block
- Does NOT have a
RigidBody2D (not able to be actively colliding with another object)
- Does have a
Collider2D with IsTrigger set to On
- Can report on
collision (by OnTrigger-functions)
- Scripts::WhiteMagic on the White block
- mColorChanging:
data type is Coroutine when not null, means White cube in color
changing mode
- OnTriggerEnger:
attempt to go into color changing mode
- OnTriggerExist:
attempt to exit from color changing mode
- ColorChangeFromLeft/Right()
- Note the yield
return statement ß this is
where the function will yield execution until later
- EnterColorChageMode()
- rightFunc:
data type is IEnumerator
capable of holding the address of a function
- Calls StarCorotuine() to star either the left or the right color
changing mode
- ExitColorChangeMode()
- Note: StopCoroutine(argument of Coroutine data type)
- Meaning, you can
have many coroutines running
and you can select specific one to stop
- StopAllCorotuines():
will stop every single coroutine
- WATCH OUT:
- Coroutine is run synchronously
(e.g., at the end of the
Update() calls of all exponents)
- This is powerful and
can be confusing, and very importantly is VERY challenging to debug!
- Use with care, do not miss use.
- Reference: https://docs.unity3d.com/Manual/Coroutines.html
- Scriptable
Objects: Templated graphical interface to data
- Run Behavior:
- D: slides towards the right
- A: moves the left
- Space: flies upwards
- Pay attention to the
colors:
- White/Black/Red
block:
- Collide from the
left Blinks between two colors,
- Collide from right
goes through a series of color changes
- Pink/Orange: When
collide, spawns an egg at Hero location that behaves like a Red-Block
- Scene setup:
- Similar to above
- Take note of the
Resources folder
- A Sprite: Egg
- ColorBlocks-folder:
Three ColorBlock (these are ScriptableObject to be discussed)
- ScriptableObject/ColorsForBlock
- Think: MonoBehavior is for modifying behaviors,
then, ScriptableObject
is for providing data to the behavior
- How it works: Refer
to ColorsForBlocks.cs
- Create a new C#
class, subclass from ScriptableObject
- Take note of: [CreateAssetMenu() ]
- fileName:
default file name
- menuName:
what shows in create
- WARNING: if you change the
argument-strings for these variables, you will probably have to
re-start Unity
- Now, you can code
any data you want to provide, in this case, defining the colors for the
WhiteMagic behavior from previous example
- Notice, only
providing data and no behavior and no modification to the data
- How to use:
- Now, in the Asset
folder, you can create an instance of ColorsForBlock!!
(RMB: Right-Mouse-Button)
- Think: ColorsForBlock is like a Sprite
- Egg: You create a new
Sprite (by dragging in an image), rename the Sprite to Egg
- RedBlock: You create a new ColorsForBlock
by RMB and rename the created
- Egg: drag to any GameObject::SpriteRenderer to
provide the look of a new object
- RedBlock: drag to any ColorBlock
to provide the colors for block color-changing
- Egg: if you change
the image, ALL gameobject refer to Egg will
change appearance
- RedBlock: if you change the colors in RedBlock, ALL ColorBlock
referring to RedBlock will have different
colors!
- The three Resources/ColorBlocks are three instances of ColorsForBlocks with modified color values
- These are data for ColorBlock-script
- Scripts::ColorBlock.cs
- This was the WhiteMagic.cs script, instead of defining the color
data in code, now, it has a reference to the ColorsForBlocks, so,
- ColorBlock:
defines the behavior without the actual color data
- ColorsForBlocks:
defines the data
- Think:
- SpriteRenderer:
defines how to show an image on a GameObject
without the actual image
- Sprite: defines the
image
- Notice:
- BlackBlock
vs WhiteBlock vs RedBlock:
they have very different colors defined
- The ColorBlock-White/ColorBlock-Red/ColorBlock-Black: these objects all have the same ColorBlock component, but the components are with
different ColorsForBlocks, so, these gameObjects have the same behavior but different
data.
- They all blinks,
but blinks with different colors
- Scripts::DynamicBlock.cs
- Shows/Verifies: how
to create a ColorBlock from scratch
- The Pink/Organge: blocks have this component
- References:
§
A step by step tutorial: https://www.youtube.com/watch?v=aPXvoWVabPY
- Tile
Palettes and Tilemap
- What:
- Create a level by painting it: three main topics
- Tile sprite sheet:
this is like the color, choice of colors to be used in a painting
- Tilemap:
this is like the canvas (target to be painted on)
- TilePalette:
this is like the color to be painted on a canvas, in this case, a
“color” is a
selected tile from the tile sprite sheet
- Run Behavior:
- WASD and Space to
control the HeroKnight
- Tile Sprite sheet:
- Turn a tile sprite
sheet into individual sprites (usually with Auto Slicing)
- Remember: the
size of each sprite element:
- Controlled/refined by Texture Pixels Per Unit
- TilePalette:
- Tilemap:
- Example paint operation:
- Tile sprite sheet sutup: Drag in your tile spritesheet,
make Multiple, slice into individual tiles
- Open TilePalette, create the new palette using your tile
sprite sheet
- Create a Tilemap object (will create with a Grid and one Map
child): name the child Background
- Refine tile pixel
size (this is what I do): paint a tile in the grid, adjust the tile
sprite sheet Pixels Per Unit (or grid size) until each tile covers
exactly one grid.
- Now, paint the Background
- When done, get ready
to pain platforms (with colliders)
- Firstly, disable
Background (make it inactive)
- Create a new tilemap (RMB over Grid-> 2D Object->Tilemap->Rectangular)
- New name the new map
to Platforms
- In the TilePlatte: select Platforms as target to work on
- Now, paint the
platforms
- Repeat for MovableTiles map
- Collision support:
- Idea: separate
collide-able tiles in separate layers of maps. In our case, the Platform
map.
- After drawing, can
switch on collision for individual maps by adding TilemapCollider2D
component: (Add Component->Tilemap->Tilemap Collider 2D)
- Note: all defined
tiles in the layer will have Collider2D defined and can detect collision
- For more
accurate/smooth collision support: on MovableTiles
- CompositeCollider2D:
can add a CompositeCollider2D to the Tilemap’s
map to smooth out issues
involved with too many colliders
- Here is a short
discussion on the issue: https://www.youtube.com/watch?v=Z0O59mWbq1E
- Note:
- A RigidBody2D
component will be automatically added to the map, you probably want to
change the type to Kinematic.
- The TileMapCollider2D::Used by Composite switch!
- Note:
- Remember: Collider2D
size can be adjusted (e.g., to be larger or smaller than the actual
object)
- For collision to
occur, one of the parties must
have RigidBody2D defined (everything learned about collision in
Unity applies here). So, if hero wants to walk over the tiles, the Hero
should have RigidBody2D (and at least one Collider2D) defined. Recall:
- Dynamic: will be
move according to Physics (try setting Gravity Scale to 0)
- Kinematic: only for
collision but cannot response (no movement after colliding)
- Player/TileMap Layering: https://www.youtube.com/watch?v=rVBzTKvoStk
- Control: Renderer->Additional
Setting: Order in layers
- Layers: 2: HeroKnight, 1: Platform, 0:Background
- Learned: again mostly Unity tools
- TilePlatte:
how to create, how to paint on different maps
- Tilemap:
separate maps for separate characteristics, including colliders
- Collisions: probably
always use Composite Colliders for platformers
- Credits:
5.
Particle Systems
o Take
a look at Unity Manual: https://docs.unity3d.com/Manual/ParticleSystems.html
o Focus
on Build-in Particle System
o Imaging
a collection of points following a pseudo random function