- 最后登录
- 2014-10-23
- 注册时间
- 2011-7-19
- 阅读权限
- 90
- 积分
- 81303
- 纳金币
- -1
- 精华
- 11
|
初始项目文件在附件中
My original version of doing movement was a pretty sloppy hacked version. I provided the source, but it was almost impossible to really figure out what was going on. I didn’t really know what was happening, but felt good because it worked. I went back and really cut down all the code to the minimum and explained it with a lot more comments. This post explains some of the basic elements to get that 3rd person character moving and rotating.
On the 3rd person character controller script with the 3D platform tutorial that Unity provides, there is over 450+ lines of code describing how the character moves around. After studying it for a while, the most important parts of the script can be hard to spot with all of the different variables and other functionality. For this post, I just wanted to narrow it down to basic movement and rotation.
My example still has about 30 lines of code for the basics (over 40 with commenting).
Controls: W,A,S,D move OR arrow keys
效果请下载附件查看
Setup:
If you want to start from scratch, you can start a new project and add an object you want to control and move. You can also start with a setup project that I made. There is no gravity, physics, or collisions implemented with this explanation/tutorial, so you don’t have to create a ground plane for your character to fall on. Just add a gameObject to the stage and add a script to the object. Add a character controller component to your character game object. If you are using my set up file, just open the charactermovement.js script and you’re ready.
Nothing happens if you play the game now, since there is only one script and it is empty. Everything from this point on will be dealing with the script attached to the game object you want to move.
private var controller :CharacterController; controller = gameObject.GetComponent(CharacterController); private var moveDirection = Vector3.zero; private var forward = Vector3.zero; private var right = Vector3.zero;
These first lines are declared at the top of the script. They aren’t in any functions or classes. This is so that any function inside of the script can access the variables. Making them private means they can’t be accessed by the inspector.
The first line creates a variables of type CharacterController. This is a class that is used to manage movement of your controllable character. The second line sets the controller variable to the character controller component. “gameObject” is used to access the current gameobject that the script is attached to. The “GetComponent” method searches the game object for components that are attached to it. We can reference “controller” any where in the script if we want to use any character controller functions or methods.
The last three lines are setting up the movement direction and forward directions to “Vector3.zero”. This is shorthand for making a new vector3 object with the value (0,0,0). These will store the absolute move direction along with the relative forward direction.
Update function
Since movement is constantly changing, all movement and directions need to be calculated every frame. This is perfect for Unity’s predefined Update function. There are many different parts to movement so there needs to be a few different variables defining and monitoring each aspect.
function Update() { forward = transform.forward; right = Vector3(forward.z, 0, -forward.x);
The first two lines are assigning the direction that the character is facing forward and right. I will explain why we need these in a little bit. The second two statements create variables that will store input values. These values will constantly change based off if you are pressing the up/down keys (vertical) or right/left keys (horizontal). The “GetAxisRaw” method is used instead of the “GetAxis” because the latter applies smoothing which will make our rotations less responsive. Add the next few lines after the previous two. Keep everything inside the Update function.
var targetDirection = horizontalInput * right + verticalInput * forward; moveDirection = Vector3.RotateTowards(moveDirection, targetDirection, 200 * Mathf.Deg2Rad * Time.deltaTime, 1000); var movement = moveDirection * Time.deltaTime * 2; controller.Move(movement);
var horizontalInput = Input.GetAxisRaw("Horizontal"); var verticalInput = Input.GetAxisRaw("Vertical");
the first part creates a targetDirection variable that makes a direction that is currently being pressed. Your horizontalInput and verticalInput variables will return values between -1 and 1. They are the magnitudes of the direction. The right and forward variables return directions as vectors.
Since your character will be rotating when you press the left/right keys, its forward position will be changing a lot. Since the forward variable is changing based off your orientation, the verticalInput needs to know which direction is facing forward. That is why the targetDirection multiplies the forward and verticalInput variables.
The right variable value is dependent on the forward variable. It takes parts of the forward direction and can calculate the angle 90 degrees to the right of it. This gives a local x axis based off the rotation. That is why the horizontalInput is multiplied by the right direction.
This is a little conceptually heavy, so you might need to think about this for a little while.
The “moveDirection” variable stores a rotation value. It gets the current rotation and goes to the target rotation over so many seconds. The third parameter in the RotateTowards method is the rotation speed. Higher value equals means faster rotation.
The “movement” variable takes the direction and multiplies it by Time.deltaTime * 2. This will slow down the movement to rotate by seconds instead of by frames. The last line actually moves the character controller by the amount. |
|