Return to Video

Stealth game tutorial - 204 - Player Movement - Unity Official Tutorials

  • 0:00 - 0:03
    The next stage in creating the player is
  • 0:03 - 0:05
    to make a script to control his movement.
  • 0:05 - 0:07
    Select the player and add a new script
  • 0:07 - 0:09
    to him called Player Movement.
  • 0:13 - 0:15
    Empty the script.
  • 0:17 - 0:19
    Let us start out as usual with the
  • 0:19 - 0:22
    public variables. We need an audio clip
  • 0:22 - 0:24
    to store the sound of the player shouting.
  • 0:24 - 0:26
    We will call the variable shoutingClip.
  • 0:26 - 0:28
    We are going to use a Lerp function
  • 0:28 - 0:30
    for changing the direction of the player.
  • 0:31 - 0:33
    As such we will need a smoothing value.
  • 0:36 - 0:38
    When we set the speed parameter of the player's
  • 0:38 - 0:41
    animator we want to apply damping.
  • 0:41 - 0:44
    We will store the damping time as a public float.
  • 0:46 - 0:48
    We will also need a couple of private variables
  • 0:48 - 0:51
    to store references. Firstly to the
  • 0:51 - 0:52
    animator component
  • 0:53 - 0:57
    and secondly a reference to the hash IDs script.
  • 0:58 - 1:00
    Now we can use the awake function to
  • 1:00 - 1:02
    allocate these references.
  • 1:07 - 1:09
    We are also going to use the awake function
  • 1:09 - 1:11
    to set the weight of the shouting
  • 1:11 - 1:13
    layer in our animator controller.
  • 1:14 - 1:16
    The weight of a layer is it's effectiveness
  • 1:16 - 1:19
    so if set to a value of 1 this layer's
  • 1:19 - 1:21
    animations have the potential to completely
  • 1:21 - 1:23
    override any layers beneath it,
  • 1:23 - 1:25
    such as the base layer.
  • 1:25 - 1:27
    Since we are using an avatar mask
  • 1:27 - 1:28
    and most of the time the Shouting layer
  • 1:28 - 1:30
    will be in an empty state we can
  • 1:30 - 1:32
    set the layer weight of this to 1 with
  • 1:32 - 1:35
    out it effecting the base layer's animation.
  • 1:38 - 1:40
    This function takes 2 arguments.
  • 1:40 - 1:43
    The first is an integer, an index of the layer,
  • 1:43 - 1:45
    for example the base layer is 0,
  • 1:45 - 1:47
    and the Shouting layer is 1.
  • 1:47 - 1:49
    And the second argument is that it's
  • 1:49 - 1:52
    effectiveness. A value of 1 as we stated earlier.
  • 1:52 - 1:54
    The player is a physics object,
  • 1:54 - 1:56
    so we will be dealing with his movement
  • 1:56 - 1:59
    in the fixed update function. Add this now.
  • 2:01 - 2:03
    We are going to start by cashing the inputs
  • 2:03 - 2:05
    that we get from the use.
  • 2:05 - 2:07
    This way we can use them when we need them
  • 2:07 - 2:09
    without having to call any input
  • 2:09 - 2:11
    functions again.
  • 2:16 - 2:18
    Now that we have our input, let us make a
  • 2:18 - 2:20
    function to use that information to
  • 2:20 - 2:22
    manage the movement. We will call it
  • 2:22 - 2:24
    MovementManagement, and it needs to
  • 2:24 - 2:26
    take in parameters of the input variables
  • 2:26 - 2:28
    that we have just cached.
  • 2:30 - 2:32
    First thing we can do here is set the
  • 2:32 - 2:35
    Sneaking animator parameter by using the
  • 2:35 - 2:37
    sneaking variable that we are taking as
  • 2:37 - 2:39
    an argument in this function.
  • 2:40 - 2:42
    We can use a reference to the Hash IDs script
  • 2:42 - 2:44
    to determine the parameter we are setting.
  • 2:46 - 2:48
    The style of movement we are going to have
  • 2:48 - 2:50
    for the player is one in which the player's
  • 2:50 - 2:53
    direction is determined by the axis input.
  • 2:53 - 2:55
    The player turns to that direction and
  • 2:55 - 2:58
    runs forward. We are going to have the
  • 2:58 - 3:00
    rotation of the player changing smoothly
  • 3:00 - 3:02
    but quickly in order to give the controls
  • 3:02 - 3:04
    a responsive feel.
  • 3:04 - 3:06
    To achieve this first we need to determine
  • 3:06 - 3:09
    if there is any directional input.
  • 3:12 - 3:14
    To make the player rotate to the direction
  • 3:14 - 3:16
    defined by the directional inputs
  • 3:16 - 3:18
    we will make a function to handle it.
  • 3:18 - 3:20
    This function will need the horizontal
  • 3:20 - 3:22
    and vertical variables in order to
  • 3:22 - 3:24
    determine a target rotation.
  • 3:26 - 3:28
    If we imagine the new direction we want
  • 3:28 - 3:30
    the player to face as a vector
  • 3:30 - 3:32
    it can be represented by an amount in the
  • 3:32 - 3:35
    X direction of the horizontal input
  • 3:35 - 3:37
    and an amount in the Z direction
  • 3:37 - 3:39
    of the vertical input.
  • 3:39 - 3:42
    So if both horizontal and vertical are 1,
  • 3:42 - 3:44
    that is if up and right are being pressed
  • 3:44 - 3:46
    then the player should head in the positive
  • 3:46 - 3:48
    X and Z directions.
  • 3:48 - 3:50
    We will store this intended direction
  • 3:50 - 3:52
    as a vector3.
  • 4:01 - 4:03
    Now we need to convert this vector to a
  • 4:03 - 4:05
    quaternion so that we can adjust the
  • 4:05 - 4:07
    player's rotation towards this.
  • 4:07 - 4:10
    A quaternion is a way of storing a rotation.
  • 4:10 - 4:13
    This is a more advanced topic but we need this
  • 4:13 - 4:15
    to assign rotation back to our character.
  • 4:15 - 4:17
    Unity has a built-in function that
  • 4:17 - 4:20
    simplifies this process for us, called
  • 4:20 - 4:21
    LookRotation.
  • 4:21 - 4:24
    LookRotation is a static function of the
  • 4:24 - 4:27
    quaternion class. It takes two arguments.
  • 4:27 - 4:29
    Firstly the vector representing the direction
  • 4:29 - 4:32
    you want to convert to a quaternion
  • 4:32 - 4:34
    and secondly a vector representing
  • 4:34 - 4:36
    the up direction.
  • 4:37 - 4:39
    We want to smooth the rotation of the player
  • 4:39 - 4:42
    as he turns. To do so we are going to use
  • 4:42 - 4:45
    Lerp to get a new rotation that is a slight
  • 4:45 - 4:47
    change from the current rotation
  • 4:47 - 4:49
    in the direction of the target rotation.
  • 4:51 - 4:53
    We will use our current rigidbody.rotation
  • 4:53 - 4:55
    as the direction to go from
  • 4:58 - 5:00
    and the target rotation from our
  • 5:00 - 5:02
    key input as the direction to lerp
  • 5:02 - 5:06
    towards, with our turn smoothing variable
  • 5:06 - 5:08
    to control how long this takes over time.
  • 5:08 - 5:11
    We can then set the rigidbody's rotation
  • 5:11 - 5:13
    to this new rotation using
  • 5:13 - 5:16
    rigidbody.MoveRotation.
  • 5:17 - 5:19
    With the rotating function finished
  • 5:19 - 5:21
    we can return to the movement management function
  • 5:21 - 5:23
    to put a call to it.
  • 5:25 - 5:27
    Whilst we are still within this If statement
  • 5:27 - 5:29
    we know that we are receiving input
  • 5:30 - 5:32
    so we know the player should be moving.
  • 5:32 - 5:34
    As such we can set the speed parameter
  • 5:34 - 5:37
    of the animator. We are going to set it to
  • 5:37 - 5:40
    5.5 as this is approximately the speed of the
  • 5:40 - 5:43
    animation as determined by the blend tree.
  • 5:45 - 5:47
    We are going to apply damping to the parameter
  • 5:47 - 5:49
    as we set it. This will ensure
  • 5:49 - 5:51
    transitions are smooth whilst
  • 5:51 - 5:53
    remaining responsive.
  • 5:55 - 5:57
    If however we are not receiving any input
  • 5:57 - 5:59
    then we want to set the speed to 0.
  • 6:03 - 6:05
    With the movement management function finished
  • 6:05 - 6:09
    we can put a call to it in our fixed update function.
  • 6:11 - 6:13
    We have still to add the audio for our player,
  • 6:13 - 6:16
    both his footsteps and the sound of him shouting.
  • 6:16 - 6:19
    For this we will make an audio management function.
  • 6:20 - 6:22
    We only want the footsteps audio clip to
  • 6:22 - 6:24
    play whilst in the Locomotion state.
  • 6:25 - 6:27
    So we should first of all check if that's
  • 6:27 - 6:29
    the state that the player is currently in.
  • 6:29 - 6:31
    We can use the Name hash, since we have the
  • 6:31 - 6:34
    appropriate state stored in our HashIDs script.
  • 6:34 - 6:37
    Here we are using GetCurrentAnimatorStateInfo
  • 6:37 - 6:39
    with a value of 0 to refer to the state
  • 6:39 - 6:42
    that we are in in the base layer.
  • 6:44 - 6:46
    We also only want to play if the
  • 6:46 - 6:48
    clip is not already playing.
  • 6:53 - 6:55
    However when we are no longer in the
  • 6:55 - 6:57
    Locomotion state we do not want the
  • 6:57 - 6:59
    clip to continue on until it is finished
  • 6:59 - 7:01
    so we will stop it here.
  • 7:03 - 7:05
    Because we are using our audio source component
  • 7:05 - 7:07
    to manage the footsteps of the player
  • 7:07 - 7:10
    we will be using the PlayClipAtPoint function
  • 7:10 - 7:13
    to manage the shouting. This is because the
  • 7:13 - 7:15
    audio source will already be playing back
  • 7:15 - 7:17
    the footsteps and we do not want replace it
  • 7:17 - 7:20
    with the shouting. The condition for playing
  • 7:20 - 7:23
    back the shouting clip is that Shout is true.
  • 7:23 - 7:25
    PlayClipAtPoint takes 2 arguments,
  • 7:25 - 7:28
    an audio clip and a vector3 for position.
  • 7:29 - 7:31
    It creates a new object in the world at
  • 7:31 - 7:33
    the specified position and plays a
  • 7:33 - 7:35
    sound there. This object then self-destructs
  • 7:35 - 7:38
    so that it is no longer left in the scene.
  • 7:40 - 7:42
    Now our audio management function is complete.
  • 7:43 - 7:45
    In order to call this function however
  • 7:45 - 7:47
    we need to place it in the update function.
  • 7:47 - 7:49
    We will place this in our script below
  • 7:49 - 7:51
    the fixed update function. We do not need
  • 7:51 - 7:53
    to put update here but it makes the flow
  • 7:53 - 7:55
    of the script slightly easier to understand
  • 7:55 - 7:57
    when reading it. The update function could
  • 7:57 - 8:00
    be anywhere, it is purely a matter of preference.
  • 8:03 - 8:05
    The first thing we want to do is cache
  • 8:05 - 8:07
    the input of the Attract button.
  • 8:09 - 8:11
    Next we are going to parse this input
  • 8:11 - 8:14
    as a parameter to the animator controller
  • 8:14 - 8:17
    so that the player performs the correct animation.
  • 8:18 - 8:20
    Finally we will parse the Shout Bool
  • 8:20 - 8:22
    in to the audio management function
  • 8:22 - 8:24
    as we call it so that this is the
  • 8:24 - 8:27
    triggering input that causes our shout to play.
  • 8:29 - 8:32
    Now we can save the script and return to the editor.
  • 8:33 - 8:35
    The player is now ready to test.
  • 8:35 - 8:37
    But before we do let us tidy up our script
  • 8:37 - 8:39
    folder one more time. We are going to
  • 8:39 - 8:41
    add a new subfolder to the Scripts folder
  • 8:41 - 8:43
    called Player. Select the Scripts folder
  • 8:43 - 8:45
    in the project panel and go to
  • 8:45 - 8:47
    Create - Folder.
  • 8:47 - 8:50
    Call this Player. Select the assets folder
  • 8:50 - 8:52
    and then drag in PlayerMovement in to
  • 8:52 - 8:54
    this Player folder.
  • 8:55 - 8:58
    Do not forget to save the scene and the project now.
  • 9:03 - 9:05
    Then we are ready to test the player.
  • 9:06 - 9:07
    Let us zoom out a little from him in the
  • 9:07 - 9:11
    scene view and rotate our view around
  • 9:11 - 9:12
    to mimic the position of the camera that
  • 9:12 - 9:14
    we will place in later.
  • 9:14 - 9:16
    Before we test we will need to assign the
  • 9:16 - 9:19
    Shouting audio clip to our PlayerMovement script.
  • 9:19 - 9:22
    So select the player character char_ethan
  • 9:22 - 9:24
    again in the hierarchy.
  • 9:25 - 9:27
    You will see that the PlayerMovement script
  • 9:27 - 9:29
    has None Audio Clip next to Shouting clip.
  • 9:29 - 9:32
    So in the audio folder drag
  • 9:32 - 9:34
    PlayerAttractAttention
  • 9:34 - 9:35
    to this variable.
  • 9:36 - 9:38
    Now let us play test. Press play at the top
  • 9:38 - 9:40
    of the interface.
  • 9:41 - 9:43
    You should now be able to drive your character
  • 9:43 - 9:45
    around observing him in the scene panel.
  • 9:47 - 9:49
    You can use the arrow keys or W A S and D
  • 9:49 - 9:51
    on the keyboard.
  • 9:53 - 9:55
    Remember you can use left shift to sneak
  • 9:59 - 10:01
    and you can press X to shout.
  • 10:05 - 10:08
    As we are play testing we notice that the
  • 10:08 - 10:11
    sneaking animation seems rather slow.
  • 10:11 - 10:13
    But we can adjust this very easily.
  • 10:13 - 10:15
    Press the play button to stop testing
  • 10:16 - 10:18
    and return to the animator window.
  • 10:19 - 10:23
    Go to the base layer and select the Sneak state.
  • 10:23 - 10:25
    In the inspector set the speed
  • 10:25 - 10:29
    to something greater, let us try 1.7.
  • 10:30 - 10:33
    Now let us press play again and see the change.
  • 10:35 - 10:36
    Now if we move and hold shift
  • 10:37 - 10:39
    our sneaking is a little faster.
  • 10:43 - 10:44
    These are the kind of tweaks that you can
  • 10:44 - 10:46
    make as you test your game to improve
  • 10:46 - 10:47
    it over time.
  • 10:48 - 10:50
    In the next assignment we will make a script
  • 10:50 - 10:52
    to handle the player's health.
Title:
Stealth game tutorial - 204 - Player Movement - Unity Official Tutorials
Description:

more » « less
Duration:
10:53

English subtitles

Revisions