Saturday, September 6, 2014

Simple Third Person Character Movement in Unity 3d (with Mecanim) - I

Hi, welcome back readers. Many a people want to make a third person game in unity. Here is simple third person movement tutorial with my project folder too. In next tutorials, we'll add jumping, sprinting and some other basic moves.Have a look at this video of the completed tutorial in action.





This is what we will make after the tutorial.

Be patient because it may seem to be a long tutorial but it is as informative as long it is. Also it is so user friendly and easy to understand that a person not knowing anything about Unity may also give it a try.

To make a third person game you will need a 3d character model and some basic animations like walk, idle etc. You can use your own models but if you don't have it I will provide you the sample assets which are used in this tutorial here -

http://www.4shared.com/file/0R8OkHHhce/Free_Assets.html

The model used is the free soldier model made by Mixamo and the animations are provided by unity in their raw mocap data unitypackage. And that crappy environment is made by me it's not much good cause i'm not a 3d modeller.

1. So first of all we will open unity and make a new project. So go to File --> create new project to make a new project and under 'import the following packages' select scripts.unitypackage as need the camera orbit script contained in it And name the project of your choice. you will see something like this.-


Now we will import the Free assets package (link are provided above) by going Assets --> import package --> custom package and then import the file which you downloaded. Select all items and click import.
Now you will see a soldier model, idle and walk animations and the crappy environment i was talking about. (notice that it looks like a simple box in project view but it's actually a interior model)

2. So now we will prepare our scene for our use. So drag the 'dfdf' model (the crappy environment) into the scene area and you will see the model int the scene view (now you will see the interior part)


As the environment looks very dull now we will add a light to illuminate it. So add a point light and place it in the center of room just below the ceiling to get a decent lighting


You can play with the range, colour and intensity of lights to get the lighting as you want. Now drag the soldier also and place it at any place in the interior. Now save your scene.

3. As our scene preperation is done now we will make the animating part done. Go to the animation folder in project view and you will see an idle and walk animation. The mecanim system uses animator controller for the logical creation of animation states So, create a new animator controller by right click --> create --> Animator controller and name it and double click it to open the animator window like this -


If you don't know the very basics of animator controller please take a look at unity Docs they have  lot of information about it. Basically, in mecanim you create states (animation clips) for different animation like walking, standing, running and then you connect them with transition with some conditions. And if that condition is met the transition will occour from one state to another othewise it will loop in the present state.

So click on the tiny arrow in the idle animation icon and it will show you the content and you will see a 'playing' icon with name 'idleR...' (it's actually the animation part of the Fbx file) and Drag it into the animator window and it will create a new state with it. like this -



Now also drag the walk animation in animator. You will notice that the idle animation is of yellow colour because it's the default state that will be played after starting game. You can change the default state by right clicking on state --> 'Set as default'. Now click the + icon just ahead the parameters to add a new parameter and set its type as float and then name it speed. Now we will create transitions from idle to walk.
For that right click idle state and click on make transition and then click on the walk state like this.


Now click on transition and you will see its properties in inspector. There you will see a property called condition. when the conditions specifies under this field met, the transition will  occour. By default a transition occours when the animation completes one loop ie. exit time. But we need it to be changed by speed parameter so change the exit time to speed. Now there is a field for a greater than or less than value which specify the condition for the transition, We need the walk animation at value of speed 1 and the idle at 0 so change its value to greater than 0.5.
Similarly make a transition from walk to idle, now with parameter speed less than 0.5

Now go back to the scene and select player gameobject, In the inspector under the Animator there will be a property called controller So, drag the animator controller we just made into that field and our animation part is done.

4.LOGIC Behind our third person shooter. Like in most of the third person games present today like max payne, gta 4. The player rotation system is relative to camera and user inputs eg. when user press right arrow, first the player rotates in the exactly right direction as viewed by user (or you can say camera) in other words the player rotates in the direction of camera + 90 degrees and start walking in that direction  similarly if he presses down arrow the new rotation will be camera +180 degrees and if player presses both right and up arrow the direction will be camera + 45 degrees. Here is a diagram of all possible values of The new Rotations.

 

5. Now we will do the scripting part so make a new C# script and name it playerscript or whatever you like And then open the script in editor.


It will show some template for you to start with. We will first declare some variables which are essential for our need. So write this above all methods but inside the class just below the line that declare your class playerscript : Monobehavior like this -

public class playerscript : MonoBehaviour{
Animator anim;
public Quaternion newrotation;
public float smooth = 0.05f;
public Transform camera;

anim is the animator that will take care of assigning the speed parameter we created in animator window through user inputs. Next we declare a quaternion, As this tutorial is for beginners i will not talk much about them because they are not easy to understand i also not use them very much because of that. As in general we all know that quaternions store rotations and the newrotation variable will store the current rotation the input keys shows. Later we will slerp the player rotation from its rotation to this newrotation which I was telling about when explaining the logic of third person shooter.
The third variable smooth specify how smoothly player rotates in the intended direction. And the last variable specify the Transform of camera, As you know all the rotations will be relative to this cameras rotation, so this is also very important for us.

Now under the void start write this -

anim = GetComponent<Animator>(); 

This will access the animator from the player through scripting.
Then we will take the user input through Axis So, write this under void Fixed Update

 float v = Input.GetAxis ("Vertical");
 float h = Input.GetAxis ("Horizontal");
 movement(v,h);

These will store user horizontal and vertical inputs in variables To be used  later. And the next line will get error at this  time because we havn't made any fucntion. Next we will create that function we called earlier that will move our player according to inputs. The basic syntax for a function in C#  is return type function-name(arguments){main body} so above all methods but inside the class create a new function for movement which take Input Axis as arguments like this -

  void movement (float v, float h) {
        }


Now under this function write this -

    if (h != 0f || v != 0f) {
    //checking if the user pressed any keys
            rotate(v,h);

    //rotates the player in the intended direction
            anim.SetFloat ("speed",1);

    //then move the player in that direction
        }
        else {
            anim.SetFloat ("speed",0);

    //Stop the player if user is not pressing any key
        }


Here we again called another function rotate we do not created which we will do next. First of all it checks if their is an input from user and then sets the speed of animator to 1 (remember we aplied the condition from idle to walk with greater than 0.5, thus the condition is met and player will start moving).
Now comes the main thing of rotating the player in relative to camera. We have already invoked the rotate function so now we will create that function.

  void rotate(float v,float h) {
     }

Add this whole code under this function

    if (v > 0)
        {
            if (h > 0)
            {
                newrotation = Quaternion.Euler(0,camera.eulerAngles.y+45,0);
            }
            else if (h < 0)
            {
            newrotation = Quaternion.Euler(0,camera.eulerAngles.y+305,0);
            }
            else
            {
            newrotation = Quaternion.Euler(0,camera.eulerAngles.y,0);
            }
        }
        else if (v < 0)
        {
            if (h > 0)
            {
                newrotation = Quaternion.Euler(0,camera.eulerAngles.y+135,0);
            }
            else if (h < 0)
            {
                newrotation = Quaternion.Euler(0,camera.eulerAngles.y+225,0);
            }
            else {
                newrotation = Quaternion.Euler(0,camera.eulerAngles.y+180,0);
            }
        }
        else
        {
            if (h > 0)
            {
            newrotation = Quaternion.Euler(0,camera.eulerAngles.y+90,0);
            }
            else if (h < 0)
            {
            newrotation = Quaternion.Euler(0,camera.eulerAngles.y+270,0);
            }
            else {
                newrotation = transform.rotation;
            }
        }

     

Don't think this code is too big this code is also as easy understand as big it is. In short what it does sets the new rotation's value according to user's input and relative to camera. Remember the diagram -


Now so that the new rotation's value is specified we will slerp it into player rotation so add this code below code above;

newrotation.x = 0;
newrotation.z = 0;
//We only want player to rotate in y axis
 transform.rotation = Quaternion.Slerp (transform.rotation,newrotation, smooth);

//Slerp from player's current rotation to the new intended rotaion smoothly 

Now, with that our scripting part is done and our tutorial is almost finished.

 6. Go back to the Unity Editor and assign this script on the the player. And in the inspector assign the camera Transform field with the main camera. Now assign the Mouse orbit script to our main camera and assign the target to our player and set the distance to 1.3. 

Then hit play and you will observe a realistic third person character movement. Your character is moving as it should but there is one problem that rotates around the legs of character because pivot point of character is at legs.
To solve that problem just click on gameObject --> create empty and a new game object is created, now rename it as target and place it just at the chest of our soldier (Place it in character carefully and check it from all views so that it is at correct position.) now make this object a child of player by simply dragging the object onto the player's gameobject in hierarchy. Now in the target field of Orbit script of main camera drag this newly created target object and then hit play and enjoy your created Third person game.

To add the physics to the player and increase the realism simplay add a capsule collider and rigidbody to player see it in action You can also bake the environment with unity's lightmapper to add more realism. 

Here is the link to our project folder 

http://www.4shared.com/rar/ziw5DVrSce/Simple_TPS_Character_movement.html 
 
Thank you for reading my this very long tutorial, feel free to give any suggestions or complaints. Keep checking for further updates to this tutorial in which we would be trying to add jumping, sprinting and some cool basic moves. One more time thank you and have a good day.

No comments:

Post a Comment