Placeholder Image

字幕列表 影片播放

  • We want to be able to pick up our collectable game

  • objects when our player game object collides with them.

  • To do this we need to detect our collisions

  • between the player game object and

  • the PickUp game objects.

  • We will need to have these collisions

  • trigger a new behaviour and we will need to

  • test these collisions to make sure we are

  • picking up the correct objects.

  • The PickUp objects, the player's sphere,

  • the ground plane and the walls all have

  • colliders that inform us about collisions.

  • If we didn't test our collisions to find out

  • which objects we have collided with

  • we could collect the wrong objects.

  • We could collect the floor, or the walls.

  • As a matter of face if we didn't test our collisions

  • on the very first frame of the game we would

  • come in contact with the ground plane

  • and we would collect the ground plane

  • and then we would fall in to the void of the scene space

  • and the game would essentially be over.

  • First, we don't need our player to remain inactive.

  • so let's tick the Active checkbox and

  • bring back our player.

  • Next let's select the PlayerController script

  • and open it for editing.

  • Just a note, we could edit this

  • script regardless of whether the game

  • object is active or not.

  • Now that we have the script open,

  • what code are we going to write?

  • We could write collider

  • and then search the documentation using the

  • hot key combination.

  • But there is a different way that we could do this as well.

  • Let's return to Unity and look at the details

  • of our player game object.

  • What we are interested in here is the

  • sphere collider component.

  • In the header of each component on the left

  • is the component's turndown arrow,

  • the icon, the Enable checkbox

  • if it's available, and the type of the component.

  • On the right is the context sensitive gear gizmo

  • and an icon of a little book with a question mark.

  • Now this is what we need.

  • This is the quick link to the component reference.

  • If we select this icon we are taken

  • not to the scripting reference but to the

  • component reference.

  • We would read this document to find out more

  • about how to use this component in the context

  • of the editor.

  • We, however, want to find out how to

  • script to this component's class.

  • To do this we simply switch to scripting

  • and we are taken to the scripting reference

  • for the sphere collider.

  • We want to detect and test our collisions.

  • For this project we are going to use

  • OnTriggerEnter.

  • Just imagine if we were, say, a daring plumber

  • and we jumped up to collect a perfect arch of coins

  • and bounced off the very first one as we

  • collected it and fell back to the ground.

  • Not very elegant.

  • This code will give us the ability to detect

  • the contact between our player game object

  • and our PickUp game objects

  • without actually creating a physical collision.

  • The code example however is not exactly

  • what we're looking for.

  • But that's okay, we can change that.

  • First, let's copy the code,

  • and then let's return to our scripting application.

  • Now that we're back in scripting let's paste the code.

  • As we have copied this code from a webpage

  • let's correct the indents.

  • In this case I'm going to make sure the

  • indents are tabs and that all of the tabs are

  • correctly aligned.

  • Next, let's look at this code.

  • We are using the function OnTriggerEnter.

  • OnTriggerEnter will be called by Unity

  • when our player game object first touches

  • a trigger collider.

  • We are given as an argument

  • a reference to the trigger collider that we have touched.

  • This is the collider called Other.

  • This reference gives us a way to get a

  • hold of the colliders that we touch.

  • With this code, when we touch another trigger

  • collider we will destroy the game object

  • that the trigger collider is attached to

  • through the reference other.gameObject.

  • By destroying that game object, the game object,

  • all of it's components and all of it's

  • children and their components are removed

  • from the scene.

  • For the sake of example in this assignment

  • we won't destroy the other game object

  • we will deactivate it.

  • Just like we deactivated the player object

  • when we were creating our PickUp objects.

  • First, let's remove the Destroy(other.gameobject)

  • code from the function.

  • But let's paste it down below our script

  • as a palette to work with.

  • How will we deactivate our PickUp objects?

  • Well what clues do we have?

  • We can address the other collider's game

  • object through other.gameObject.

  • We can see this here in the sample code.

  • And we want to test the other game object

  • and if it's a PickUp object we want to deactivate

  • that game object.

  • So let's look up GameObject

  • with our hot key combination and see what we can find.

  • Now we have the page on GameObject.

  • There are two important items here that we want.

  • They are tag,

  • tag allows us to identify the game object

  • by comparing the tag value to a string.

  • And SetActive.

  • This is how we activate or deactivate a game object through code.

  • The last item we need to know about is

  • Compare Tag.

  • Compare Tag allows us to efficiently

  • compare the tag of any game object to a sting value.

  • Let's open up these three items, each in their own tab.

  • Tag allows us to identify a game object by a tag value.

  • We must declare our tags in the Tags and Layers Panel before using them.

  • It is possible to test a tag against a string value directly

  • with code like

  • if gameObject.tag is the same as some string value.

  • But there is a more efficient built-in way to do this,

  • and that is CompareTag

  • With CompareTag we can efficiently

  • compare the tag of any game object with a string value.

  • Let's copy the sample code and

  • paste it in to our working palette.

  • Now GameObject.SetActive.

  • This is how we activate or deactivate a game object.

  • This is the code equivalent of clicking

  • the Active check box next to the

  • Name field in the Inspector.

  • In our case, just like the code snippet,

  • we will call GameObject.SetActive (false)

  • to deactivate our PickUp game objects.

  • Let's copy this code and returning to our script editor

  • paste it in to our palette as well.

  • I feel we have enough pieces to write our code

  • so let's write if (other.gameObject.CompareTag

  • with the string value of PickUp

  • and we will have to define this tag in Unity later.

  • other.gameObject.SetActive (false);

  • Now this code will be called every time

  • we touch a trigger collider.

  • We are given a reference to the collider we touch,

  • we test it's tag,

  • and if the tag is the same as the string value

  • PickUp we will take the other game object

  • and we will call SetActive (false),

  • which will deactivate that game object.

  • Now we don't need this code we've been saving anymore

  • and keeping it will only confuse the compiler

  • so we can delete it.

  • Let's save this script and return to Unity

  • and check for errors.

  • The first thing we need to do it set up the tag value

  • for the PickUp objects.

  • Select the prefab asset for the PickUp object.

  • When we look at the tag list

  • we don't see any tag called PickUp

  • so we need to add one.

  • Select Add Tag.

  • This brings up the Tags and Layers Panel.

  • Here we can customise tags and layers.

  • Note that this list is empty.

  • To create a new custom tag select the + button

  • to add a new row to the tags list.

  • In the new empty element, in our case tag 0,

  • type PickUp, and this is case sensitive

  • and needs to be exactly the same string

  • that we have in our script.

  • If in doubt we can copy and paste

  • this string to get the exact value.

  • When we look back at the prefab asset

  • note that the asset is still untagged.

  • By selecting Add Tag we changed our focus

  • from the prefab asset to the Tag Manager

  • and in the Tag Manager we created our tag.

  • Now we need to apply that tag

  • to the prefab asset.

  • Select the Tag drop down again

  • and see how we now have PickUp in the list.

  • Select this tag from the list and the asset

  • is now tagged PickUp.

  • And with the power of prefabs

  • all of the instances are now tagged PickUp as well.

  • Now let's test our game.

  • Save the scene and enter play mode.

  • Hmm, okay, our tag is set to PickUp

  • but we are still bouncing off the PickUp cubes

  • just like we are bouncing off the walls.

  • So let's exit play mode.

  • Before we discuss why we are bouncing off

  • the PickUp cubes rather than picking them up

  • we need to have a brief discussion about

  • Unity's physics system.

  • I'm going to enter play mode for this discussion.

  • Let's look at one of our cubes and our player.

  • As an aside we can select two or

  • more game objects at the same time

  • and inspect them all.

  • We do this by holding down the command key

  • on the mac or the control key on the PC,

  • and selecting the game objects.

  • When we select multiple game objects

  • note how the inspector changes to show

  • the common components and property

  • values of the selected game objects.

  • The inspector also allows for multi-object editing.

  • Using multi-object editing I'm going to

  • disable the mesh renderer on both the

  • player's sphere and the selected cube with a single click.

  • This leaves us with the two green outlines

  • of the collider volumes for these two objects.

  • How do collisions work in Unity's physics engine?

  • The physics engine does not allow two collider

  • volumes to overlap.

  • When the physics engine detects that any two

  • or more colliders will overlap that frame

  • the physics engine will look at the objects and

  • analyse their speed and rotation and shape

  • and calculate a collision.

  • One of the major factors in this calculation

  • is whether the colliders are static

  • or dynamic.

  • Static colliders are usually non-moving

  • parts of your scene, like the walls, the floor,

  • or the fountain in the courtyard.

  • Dynamic colliders are things that move

  • like the player's sphere or a car.

  • When calculating a collision the static geometry

  • will not be affected by the collision.

  • But the dynamic objects will be.

  • In our case the player's sphere is dynamic,

  • or moving geometry, and it is bouncing

  • off the static geometry of the cubes.

  • Just as it bounces off the static geometry

  • of the walls.

  • The physics engine can however allow the

  • penetration or overlap of collider volumes.

  • When it does this the physics engine

  • still calculates the collider volumes and

  • keeps track of the collider overlap.

  • But it doesn't physically act on the overlapping

  • objects, it doesn't cause a collision.

  • We do this by making our colliders in to

  • triggers, or trigger colliders.

  • When we make our colliders in to a trigger,

  • or trigger collider, we can detect

  • the contact with that trigger through the

  • OnTrigger event messages.

  • When a collider is a trigger you can do

  • clever things like place a trigger in the middle

  • of a doorway in, say, an adventure game,

  • and when the player enters the trigger

  • the mini-map updates and a message plays

  • 'you have discovered this room'.

  • Or every time your player walks around

  • that corner spiders drop from the ceiling

  • because the player has walked through a trigger.

  • For more information on OnCollision and on

  • trigger messages see the lessons linked below.

  • We are using OnTriggerEnter in our code

  • rather than OnCollisionEnter.

  • So we need to change our collider volumes

  • in to trigger volumes.

  • To do this we must be out of play mode.

  • Let's select the prefab asset and look at

  • the box collider component.

  • Here we select Is Trigger

  • and again the power of prefabs

  • all of our PickUp objects are now using trigger colliders.

  • Let's save our scene, enter play mode and test.

  • And as our player enters the trigger

  • we pickup the objects.

  • Excellent.

  • Let's exit play mode.

  • Everything looks great.

  • We only have one issue.

  • We have made one small mistake,

  • and this is related to how Unity

  • optimises it's physics.

  • As a performance optimisation Unity

  • calculates all the volumes

  • of all the static colliders in a scene

  • and holds this information in a cache.

  • This makes sense as static colliders

  • shouldn't move, and this saves recalculating this

  • information every frame.

  • Where we have made our mistake is by rotating our cubes.

  • Any time we move, rotate, or scale a static collider

  • Unity will recalculate all the static colliders again

  • and update the static collider cache.

  • To recalculate the cache takes resources.

  • We can move, rotate or scale dynamic

  • colliders as often as we want and Unity won't

  • recache any collider volumes.

  • Unity expects us to move colliders.

  • We simply need to indicate to Unity which

  • colliders are dynamic before we move them.

  • We do this by using the rigid body component.

  • Any game object with a collider

  • and a rigid body is considered dynamic.

  • Any game object with a collider attached

  • but no physics rigid body is expected to be static.

  • Currently our PickUp game objects have a

  • box collider but no rigid body.

  • So Unity is recalculating our static

  • collider cache every frame.

  • The solution is to add a rigid body

  • to the PickUp objects.

  • This will move the cubes from being static colliders

  • to being dynamic colliders.

  • Let's save and play.

  • And our cubes fall through the floor.

  • Gravity pulls them down, and as they are triggers

  • they don't collide with the floor.

  • Let's exit play mode.

  • If we look at the rigid body component

  • we could simply disable Use Gravity,

  • which would prevent the cubes from being pulled downwards.

  • This is only a partial solution however.

  • If we did this, even though our cubes

  • would not respond to gravity they would still

  • respond to physics forces

  • There is a better solution.

  • And that is to select Is Kinematic.

  • When we do this we set this rigid body component to be

  • a kinematic rigid body.

  • A kinematic rigid body will not react

  • to physics forces and it can be animated

  • and moved by it's transform.

  • This is great for everything from objects with colliders

  • like elevators and moving platforms,

  • to objects with triggers, like our collectables

  • that need to be animated or moved by their transform.

  • For more information on the rigid body

  • and Is Kinematic see the lessons linked below.

  • Let's save our scene and enter play mode to test.

  • Now our behaviour is identical and performant.

  • So, static colliders shouldn't move,

  • like walls and floors.

  • Dynamic colliders can move,

  • and have a rigid body attached.

  • Standard rigid bodies are moved using physics forces.

  • Kinematic rigid bodies are moved using

  • their transform.

  • In the next assignment we will count our

  • collectable object and make a simple UI

  • to display our score and messages.

  • Subtitles by the Amara.org community

We want to be able to pick up our collectable game

字幕與單字

單字即點即查 點擊單字可以查詢單字解釋

B2 中高級

Unity 5 - 滾球遊戲--8中6:算點 - Unity官方教程 (Unity 5 - Roll a Ball game - 6 of 8: Counting Points - Unity Official Tutorials)

  • 89 3
    Dunois 發佈於 2021 年 01 月 14 日
影片單字