< Return to Video

(Unity 4) Collecting and Counting - 05 - Roll-a-ball - Unity Official Tutorials

  • 0:01 - 0:04
    We want to be able to pick up our collectable game
  • 0:04 - 0:07
    objects when our player game object collides with them.
  • 0:07 - 0:09
    To do this we need to detect our collisions
  • 0:09 - 0:11
    between the player game object and
  • 0:11 - 0:13
    the PickUp game objects.
  • 0:13 - 0:15
    We will need to have these collisions
  • 0:15 - 0:17
    trigger a new behaviour and we will need to
  • 0:17 - 0:19
    test these collisions to make sure we are
  • 0:19 - 0:20
    picking up the correct objects.
  • 0:21 - 0:23
    The PickUp objects, the player's sphere,
  • 0:23 - 0:25
    the ground plane and the walls all have
  • 0:25 - 0:28
    colliders that inform us about collisions.
  • 0:28 - 0:30
    If we didn't test our collisions to find out
  • 0:30 - 0:32
    which objects we have collided with
  • 0:32 - 0:34
    we could collect the wrong objects.
  • 0:34 - 0:37
    We could collect the floor, or the wall.
  • 0:37 - 0:40
    As a matter of face if we didn't test out collisions
  • 0:40 - 0:42
    on the very first frame of the game we would
  • 0:42 - 0:44
    come in contact with the ground plane
  • 0:44 - 0:45
    and we would collect the ground plane
  • 0:45 - 0:48
    and then we would fall in to the void of the scene space
  • 0:48 - 0:50
    and the game would essentially be over.
  • 0:51 - 0:54
    First, we don't need our player to remain inactive.
  • 0:54 - 0:56
    so let's tick the Active checkbox and
  • 0:56 - 0:58
    bring back our player.
  • 0:59 - 1:02
    Next let's select the PlayerController script
  • 1:02 - 1:04
    and open it for editing.
  • 1:04 - 1:06
    Just a note, we could edit this
  • 1:06 - 1:07
    script regardless of whether the game
  • 1:07 - 1:09
    object is active or not.
  • 1:10 - 1:11
    Now that we have the script open,
  • 1:11 - 1:13
    what code are we going to write?
  • 1:14 - 1:16
    We could write collider
  • 1:16 - 1:18
    and then search the documentation using the
  • 1:18 - 1:19
    hot key combination.
  • 1:20 - 1:23
    But there is a different way that we could do this as well.
  • 1:23 - 1:25
    Let's return to Unity and look at the details
  • 1:25 - 1:27
    of our player game object.
  • 1:28 - 1:30
    What we are interested in here is the
  • 1:30 - 1:32
    sphere collider component.
  • 1:33 - 1:36
    In the header of each component on the left
  • 1:36 - 1:38
    is the component's turndown arrow,
  • 1:38 - 1:40
    the icon, the Enable checkbox
  • 1:40 - 1:44
    if it's available, and the type of the component.
  • 1:45 - 1:48
    On the right is the context sensitive gear gizmo
  • 1:48 - 1:51
    and an icon of a little book with a question mark.
  • 1:52 - 1:53
    Now this is what we need.
  • 1:53 - 1:56
    This is the quick link to the component reference.
  • 1:56 - 1:59
    If we select this icon we are taken
  • 1:59 - 2:01
    not to the scripting reference but to that
  • 2:01 - 2:03
    component reference.
  • 2:04 - 2:06
    We would read this document to find out more
  • 2:06 - 2:08
    about how to use this component in the context
  • 2:08 - 2:09
    of the editor.
  • 2:09 - 2:11
    We, however, want to find out how to
  • 2:11 - 2:13
    script to this component's class.
  • 2:14 - 2:17
    To do this we simply switch to scripting
  • 2:17 - 2:19
    and we are taken to the scripting reference
  • 2:19 - 2:20
    for the sphere collider.
  • 2:21 - 2:24
    We want to detect and test our collisions.
  • 2:24 - 2:26
    For this project we are going to use
  • 2:26 - 2:28
    OnTriggerEnter.
  • 2:29 - 2:32
    Just imagine if we were, say, a daring plumber
  • 2:32 - 2:35
    and we jumped up to collect a perfect arch of coins
  • 2:35 - 2:37
    and bounced off the very first one as we
  • 2:37 - 2:39
    collected it and fell back to the ground.
  • 2:40 - 2:42
    Not very elegant.
  • 2:42 - 2:44
    This code will give us the ability to detect
  • 2:44 - 2:46
    the contact between our player game object
  • 2:46 - 2:48
    and our PickUp game objects
  • 2:48 - 2:51
    without actually creating a physical collision.
  • 2:52 - 2:54
    The code example however is not exactly
  • 2:54 - 2:56
    what we're looking for.
  • 2:56 - 2:58
    But that's okay, we can change that.
  • 2:58 - 3:00
    First, let's copy the code
  • 3:00 - 3:03
    and then let's return to our scripting application.
  • 3:04 - 3:06
    Now that we're back in scripting let's paste the code.
  • 3:07 - 3:09
    As we have copied this code from a webpage
  • 3:09 - 3:11
    let's correct the indents.
  • 3:11 - 3:13
    In this case I'm going to make sure the
  • 3:13 - 3:15
    indents are tabs and that all of the tabs are
  • 3:15 - 3:17
    correctly aligned.
  • 3:17 - 3:19
    Next, let's look at this code.
  • 3:19 - 3:22
    We are using the function OnTriggerEnter.
  • 3:22 - 3:24
    OnTriggerEnter will be called by Unity
  • 3:24 - 3:26
    when our player game object first touches
  • 3:26 - 3:28
    a trigger collider.
  • 3:28 - 3:30
    We are given as an argument
  • 3:30 - 3:33
    a reference to the trigger collider that we have touched.
  • 3:33 - 3:36
    This is the collider called Other.
  • 3:36 - 3:38
    This reference gives us a way to get a
  • 3:38 - 3:40
    hold of the colliders that we touch.
  • 3:41 - 3:43
    With this code, when we touch another trigger
  • 3:43 - 3:45
    collider we will destroy the game object
  • 3:45 - 3:47
    that the trigger collider is attached to
  • 3:47 - 3:50
    through the reference other.gameObject.
  • 3:51 - 3:54
    By destroying that game object the game object,
  • 3:54 - 3:56
    all of it's components and all of it's
  • 3:56 - 3:58
    children and their components are removed
  • 3:58 - 4:00
    from the scene.
  • 4:00 - 4:02
    For the sake of example in this assignment
  • 4:02 - 4:04
    we won't destroy the other game object
  • 4:04 - 4:06
    we will deactivate it.
  • 4:06 - 4:08
    Just like we deactivate the player object
  • 4:08 - 4:10
    when we were creating our PickUp objects.
  • 4:11 - 4:14
    First, let's remove the Destroy(other.gameobject)
  • 4:14 - 4:16
    code from the function.
  • 4:16 - 4:18
    But let's paste it down below our script
  • 4:18 - 4:21
    as a palette to work with.
  • 4:22 - 4:25
    How will we deactivate our PickUp objects?
  • 4:25 - 4:27
    Well what clues do we have?
  • 4:28 - 4:30
    We can address the other collider's game
  • 4:30 - 4:32
    object through other.gameObject.
  • 4:32 - 4:35
    We can see this here in the sample code.
  • 4:35 - 4:37
    And we want to test the other game object
  • 4:37 - 4:39
    and if it's a PickUp object we want to deactivate
  • 4:39 - 4:41
    that game object.
  • 4:42 - 4:44
    So let's look up GameObject
  • 4:44 - 4:46
    with our hot key combination and see what we can find.
  • 4:47 - 4:50
    Now we have the page on GameObject.
  • 4:50 - 4:52
    There are two important items here that we want.
  • 4:52 - 4:54
    They are tag,
  • 4:54 - 4:56
    tag allows us to identify the game object
  • 4:56 - 4:58
    by a tag value.
  • 5:00 - 5:02
    And SetActive.
  • 5:02 - 5:05
    This is how we activate or deactivate a game object.
  • 5:08 - 5:10
    Tag allows us to identify the game object
  • 5:10 - 5:12
    by a tag value
  • 5:12 - 5:14
    and we must declare our tags in the tag
  • 5:14 - 5:16
    manager before using them.
  • 5:16 - 5:18
    Let's copy the sample code and
  • 5:18 - 5:22
    yes it's okay to use Unity's Javascript in this case
  • 5:22 - 5:24
    as it's the same as the C# code,
  • 5:24 - 5:26
    and paste it in to our working pallet.
  • 5:27 - 5:30
    Now GameObject.SetActive,
  • 5:30 - 5:33
    this is how we activate or deactivate a game object.
  • 5:33 - 5:36
    In our case, just like the code snippet,
  • 5:36 - 5:39
    we will call GameObject.SetActive (false)
  • 5:39 - 5:42
    to deactivate our PickUp game objects.
  • 5:42 - 5:46
    Let's copy this code and returning to our script editor
  • 5:46 - 5:48
    paste it in to our palette as well.
  • 5:49 - 5:51
    I feel we have enough pieces to write our code
  • 5:52 - 5:57
    so let's write if(other.gameObject.tag
  • 5:57 - 6:00
    is the same as, and that's the same as two equals signs,
  • 6:01 - 6:03
    the string value of PickUp
  • 6:03 - 6:07
    and we will have to define this tag in Unity later.
  • 6:09 - 6:14
    other.gameObject.SetActive(false)
  • 6:15 - 6:16
    Now this code will be called every time
  • 6:16 - 6:18
    we touch a trigger collider.
  • 6:19 - 6:22
    We are given a reference to the collider we touch,
  • 6:22 - 6:23
    we test it's tag,
  • 6:23 - 6:26
    and if the tag is the same as the string value
  • 6:26 - 6:29
    PickUp we will take the other game object
  • 6:29 - 6:31
    and we will call SetActive false,
  • 6:31 - 6:33
    which will deactivate that game object.
  • 6:34 - 6:37
    Now we don't need this code we've been saving anymore
  • 6:37 - 6:39
    and keeping it will only confuse the compiler
  • 6:39 - 6:41
    so we can delete it.
  • 6:41 - 6:43
    Let's save this script and return to Unity
  • 6:43 - 6:44
    and check for errors.
  • 6:44 - 6:47
    The first thing we need to do it set up the tag value
  • 6:47 - 6:49
    for the PickUp objects.
  • 6:49 - 6:51
    Select the prefab asset for the PickUp object.
  • 6:52 - 6:54
    When we look at the tag list
  • 6:54 - 6:56
    we don't see any tag called PickUp
  • 6:56 - 6:58
    so we need to add one.
  • 6:58 - 7:00
    Select Add Tag.
  • 7:01 - 7:03
    This brings up the Tag Manager.
  • 7:03 - 7:06
    Here we can customise tags and layers.
  • 7:07 - 7:09
    We will turn down the Tags list
  • 7:09 - 7:11
    and note that this list is empty.
  • 7:11 - 7:14
    In the first empty element, in our case element 0,
  • 7:14 - 7:17
    type PickUp, and this is case sensitive
  • 7:17 - 7:18
    and needs to be exactly the same string
  • 7:18 - 7:20
    that we have in our script.
  • 7:20 - 7:23
    And then type return or enter to confirm this tag.
  • 7:23 - 7:25
    When we look back at the prefab asset
  • 7:25 - 7:28
    note that the asset is still untagged.
  • 7:28 - 7:31
    By selecting Add Tag we changed our focus
  • 7:31 - 7:34
    from the prefab asset to the Tag Manager
  • 7:34 - 7:36
    and in the Tag Manager we created our tag.
  • 7:37 - 7:38
    Now we need to apply that tag
  • 7:38 - 7:40
    to the prefab asset.
  • 7:40 - 7:42
    Select the Tag drop down again
  • 7:42 - 7:45
    and see how we now have PickUp in the list.
  • 7:45 - 7:47
    Select this tag from the list and the asset
  • 7:47 - 7:49
    that is now tagged PickUp.
  • 7:49 - 7:52
    And with the power of prefabs
  • 7:52 - 7:54
    all of the instances are now tagged PickUp as well.
  • 7:57 - 7:59
    Now let's test our game.
  • 7:59 - 8:01
    Save the scene and enter play mode.
  • 8:03 - 8:06
    Hmm, okay, our tag is set to PickUp
  • 8:06 - 8:08
    but we are still bouncing off the PickUp cubes
  • 8:08 - 8:11
    just like we are bouncing off the walls.
  • 8:11 - 8:13
    So let's exit play mode.
  • 8:13 - 8:15
    Before we discuss why we are bouncing off
  • 8:15 - 8:17
    the PickUp cubes rather than picking them up
  • 8:17 - 8:19
    we need to have a brief discussion about
  • 8:19 - 8:21
    Unity's physics system.
  • 8:21 - 8:24
    I'm going to enter play mode for this discussion
  • 8:29 - 8:32
    Let's look at one of our cubes and our player.
  • 8:32 - 8:34
    As an aside we can select two or
  • 8:34 - 8:37
    more game objects at the same time
  • 8:37 - 8:38
    and inspect them all.
  • 8:38 - 8:40
    We do this by holding down the command key
  • 8:40 - 8:43
    on the mac or the control key on the PC,
  • 8:43 - 8:45
    and selecting the game objects.
  • 8:45 - 8:48
    When we select multiple game objects
  • 8:48 - 8:50
    note how the inspector changes to show
  • 8:50 - 8:52
    the common components and property
  • 8:52 - 8:54
    values of the selected game objects.
  • 8:54 - 8:57
    The inspector also allows for multi-object editing.
  • 8:57 - 8:59
    Using multi-object editing I'm going to
  • 8:59 - 9:01
    disable the mesh renderer on both the
  • 9:01 - 9:04
    player's sphere and the selected cube with a single click.
  • 9:05 - 9:08
    This leaves us with the two green outlines
  • 9:08 - 9:11
    of the collider volumes for these two objects.
  • 9:11 - 9:14
    How do collisions work in Unity's physics engine?
  • 9:15 - 9:17
    The physics engine does not allow two collider
  • 9:17 - 9:19
    volumes to overlap.
  • 9:19 - 9:21
    When the physics engine detects that any two
  • 9:21 - 9:24
    or more colliders will overlap that frame
  • 9:24 - 9:26
    the physics engine will look at the objects and
  • 9:26 - 9:28
    analyse their speed and rotation and shape
  • 9:28 - 9:30
    and calculate a collision.
  • 9:30 - 9:32
    One of the major factors in this calculation
  • 9:32 - 9:34
    is whether the colliders are static
  • 9:34 - 9:36
    or dynamic.
  • 9:36 - 9:39
    Static colliders are usually non-moving
  • 9:39 - 9:41
    parts of your scene, like the walls, the floor,
  • 9:41 - 9:43
    or the fountain in the courtyard.
  • 9:44 - 9:46
    Dynamic colliders are things that move
  • 9:46 - 9:49
    like the player's sphere or a car.
  • 9:49 - 9:51
    When calculating a collision the static geometry
  • 9:51 - 9:53
    will not be affected by the collision.
  • 9:54 - 9:56
    But the dynamic objects will be.
  • 9:56 - 9:58
    In our case the player's sphere is dynamic,
  • 9:58 - 10:00
    or moving geometry, and it is bouncing
  • 10:00 - 10:03
    off the static geometry of the cubes.
  • 10:03 - 10:05
    Just as it bounces off the static geometry
  • 10:05 - 10:07
    of the walls.
  • 10:07 - 10:09
    The physics engine can however allow the
  • 10:09 - 10:13
    penetration or overlap of collider volumes.
  • 10:13 - 10:15
    When it does this the physics engine
  • 10:15 - 10:17
    still calculates the collider volumes and
  • 10:17 - 10:19
    keeps track of the collider overlap,
  • 10:19 - 10:21
    but it doesn't physically act on the overlapping
  • 10:21 - 10:24
    objects, it doesn't cause a collision.
  • 10:25 - 10:27
    We do this by making our colliders in to
  • 10:27 - 10:29
    triggers, or trigger colliders.
  • 10:30 - 10:31
    When we make our colliders in to a trigger,
  • 10:31 - 10:33
    or trigger collider, we can detect
  • 10:33 - 10:35
    the contact with that trigger through the
  • 10:35 - 10:37
    OnTrigger event messages.
  • 10:38 - 10:40
    When a collider is a trigger you can do
  • 10:40 - 10:42
    clever things like place a trigger in the middle
  • 10:42 - 10:45
    of a doorway in, say, an adventure game,
  • 10:45 - 10:47
    and when the player enters the trigger
  • 10:47 - 10:49
    the mini-map updates and a message plays
  • 10:49 - 10:51
    'you have discovered this room'.
  • 10:51 - 10:53
    Or every time your player walks around
  • 10:53 - 10:56
    that corner spiders drop from the ceiling
  • 10:56 - 10:58
    because the player has walked through a trigger.
  • 10:58 - 11:01
    For more information on OnCollision and on
  • 11:01 - 11:03
    trigger messages see the lessons linked below.
  • 11:04 - 11:06
    We are using OnTriggerEnter in our code
  • 11:06 - 11:08
    rather than OnCollisionEnter
  • 11:08 - 11:10
    so we need to change our collider volumes
  • 11:10 - 11:13
    in to trigger volumes.
  • 11:13 - 11:15
    To do this we must be out of play mode.
  • 11:17 - 11:19
    Let's select the prefab asset and look at
  • 11:19 - 11:21
    the box collider component.
  • 11:22 - 11:24
    Here we select Is Trigger
  • 11:24 - 11:26
    and again the power of prefabs
  • 11:26 - 11:29
    all of our PickUp objects are now using trigger colliders.
  • 11:29 - 11:33
    Let's save our scene, enter play mode and test.
  • 11:33 - 11:35
    And as our player enters the trigger
  • 11:35 - 11:37
    we pickup the objects.
  • 11:37 - 11:38
    Excellent.
  • 11:40 - 11:42
    Let's exit play mode.
  • 11:43 - 11:44
    Everything looks great.
  • 11:45 - 11:47
    We only have one issue.
  • 11:47 - 11:49
    We have made one small mistake,
  • 11:49 - 11:51
    and this is related to how Unity
  • 11:51 - 11:53
    optimises it's physics.
  • 11:53 - 11:55
    As a performance optimisation Unity
  • 11:55 - 11:57
    calculates all the volumes
  • 11:57 - 12:00
    of all the static colliders in a scene
  • 12:00 - 12:02
    and holds this information in a cache.
  • 12:03 - 12:05
    This makes sense as static colliders
  • 12:05 - 12:07
    shouldn't move, and this saves recalculating this
  • 12:07 - 12:09
    information every frame.
  • 12:10 - 12:13
    Where we have made our mistake is by rotating our cubes.
  • 12:13 - 12:16
    Any time we move, rotate our scale a static collider
  • 12:16 - 12:20
    Unity will recalculate all the static colliders again
  • 12:20 - 12:22
    and update the static collider cache.
  • 12:22 - 12:25
    To recalculate the cache takes resources.
  • 12:26 - 12:28
    We can move, rotate or scale dynamic
  • 12:28 - 12:30
    colliders as often as we want and Unity won't
  • 12:30 - 12:32
    recache any collider volumes.
  • 12:33 - 12:35
    Unity expects us to move colliders.
  • 12:35 - 12:37
    We simply need to indicate to Unity which
  • 12:37 - 12:40
    colliders are dynamic before we move them.
  • 12:40 - 12:43
    We do this by using the rigid body component.
  • 12:43 - 12:45
    Any game object with a collider
  • 12:45 - 12:48
    and a rigid body is considered dynamic.
  • 12:49 - 12:51
    Any game object with a collider attached
  • 12:51 - 12:54
    but no physics rigid body is expected to be static.
  • 12:55 - 12:57
    Currently our PickUp game objects have a
  • 12:57 - 13:00
    box collider but no rigid body.
  • 13:00 - 13:02
    So Unity is recalculating our static
  • 13:02 - 13:04
    collider cache every frame.
  • 13:04 - 13:07
    The solution is to add a rigid body
  • 13:07 - 13:09
    to the PickUp objects.
  • 13:09 - 13:11
    This will move the cubes from being static colliders
  • 13:11 - 13:13
    to being dynamic colliders.
  • 13:13 - 13:15
    Let's save and play.
  • 13:16 - 13:19
    And our cubes fall through the floor.
  • 13:19 - 13:22
    Gravity pulls them down, and as they are triggers
  • 13:22 - 13:23
    they don't collide with the floor.
  • 13:24 - 13:26
    Let's exit play mode.
  • 13:26 - 13:29
    If we look at the rigid body component
  • 13:29 - 13:31
    we could simply disable Use Gravity,
  • 13:31 - 13:34
    which would prevent the cubes from being pulled downwards.
  • 13:34 - 13:37
    This is only a partial solution however.
  • 13:37 - 13:39
    If we did this, even though our cubes
  • 13:39 - 13:41
    would not respond to gravity they would still
  • 13:41 - 13:43
    respond to physics forces
  • 13:44 - 13:46
    There is a better solution.
  • 13:46 - 13:49
    And that is to select Is Kinematic.
  • 13:49 - 13:53
    When we do this we set this rigid body component to be
  • 13:53 - 13:55
    a kinematic rigid body.
  • 13:55 - 13:57
    A kinematic rigid body will not react
  • 13:57 - 14:00
    to physics forces and it can be animated
  • 14:00 - 14:02
    and moved by it's transform.
  • 14:02 - 14:05
    This is great for everything from objects with colliders
  • 14:05 - 14:07
    like elevators and moving platforms
  • 14:07 - 14:10
    to objects with triggers, like our collectables
  • 14:10 - 14:13
    that need to be animated or moved by their transform.
  • 14:13 - 14:15
    For more information on the rigid body
  • 14:15 - 14:19
    and Is Kinematic see the lessons linked below.
  • 14:19 - 14:22
    Let's save our scene and enter play mode to test.
  • 14:23 - 14:26
    Now our behaviour is identical and performant.
  • 14:27 - 14:30
    So, static colliders shouldn't move,
  • 14:30 - 14:31
    like walls and floors.
  • 14:31 - 14:33
    Dynamic colliders can move,
  • 14:33 - 14:35
    and have a rigid body attached.
  • 14:35 - 14:39
    Standard rigid bodies are moved using physics forces.
  • 14:39 - 14:41
    Kinematic rigid bodies are moved using
  • 14:41 - 14:43
    their transform.
  • 14:44 - 14:46
    In the next assignment we will count our
  • 14:46 - 14:48
    collectable object and make a simple UI
  • 14:48 - 14:51
    to display our score and messages.
Title:
(Unity 4) Collecting and Counting - 05 - Roll-a-ball - Unity Official Tutorials
Description:

more » « less
Duration:
14:53

English subtitles

Revisions