角色移动
[RequireComponent(typeof(CharacterController))]
[AddComponentMenu("Control Scprit/PalyerMove")]
public class PalyerMove : MonoBehaviour
{
public float gravity = -6;
private float speed=15;
public CharacterController _character;
void Start()
{
_character = GetComponent<CharacterController>();
}
void Update()
{
Move();
}
#region 键盘移动不能检测碰撞
public void KeyMove()
{
float z = Input.GetAxis("Horizontal");
float x = Input.GetAxis("Vertical");
if (z > 1)
{
transform.Translate(-speed*z*Time.deltaTime,0,0);
}else if (z < 1)
{
transform.Translate(speed*z*Time.deltaTime,0,0);
}
if (x > 1)
{
transform.Translate(0,0,-speed*x*Time.deltaTime);
}else if (x < 1)
{
transform.Translate(0,0,speed*x*Time.deltaTime);
}
}
#endregion
//键盘移动并检测碰撞
public void Move()
{
float x = Input.GetAxis("Horizontal") * speed;
float z = Input.GetAxis("Vertical") * speed;
Vector3 movement = new Vector3(x, 0, z);
movement = Vector3.ClampMagnitude(movement, speed);
movement.y = gravity;
movement *= Time.deltaTime;
movement = transform.TransformDirection(movement);
_character.Move(movement);
}
}
代码解释
把必需的组件添加到物体上[RequireComponent(类型 组件名)]
把脚本添加到Unity编辑器的组件菜单中[AddComponentMenu("Control Scprit/脚本名")]
CharacterController组件:检测碰撞,可以调用控制器的Move方法,在_character.Move(一个向量Vector);
Vector3.ClampMagnitude(一个向量Vector,移动速度maxLength);
:把向量的大小限制为移动速度,返回vector的副本,其大小限制为maxLength。
设定一个重力值,使玩家在地面上,让y轴使用这个重力值movement.y = gravity;
将方向从本地空间向量转换为全局空间transform.TransformDirection(向量)
跟随鼠标旋转
public class MouseRota : MonoBehaviour
{
public enum MouseR
{
MouseX=0,
MouseY=1,
MouseXY=2
}
public MouseR axes = MouseR.MouseXY;
public float RotationH = 9.0f;
public float RotationV = 9.0f;
public float minE = -45.0f;
public float maxE = 45.0f;
private float RotationX = 0;
private void Start()
{
Rigidbody body = GetComponent<Rigidbody>();
if (body != null)
{
body.freezeRotation = true;
}
}
void Update()
{
if (Input.GetKey(KeyCode.E))
{
ChooseRotation();
}
}
public void ChooseRotation()
{
//左右转
if (axes == MouseR.MouseX)
{
transform.Rotate(0,Input.GetAxis("Mouse X")*RotationH,0);
}else if (axes == MouseR.MouseY)
{
RotationX -= Input.GetAxis("Mouse Y") * RotationV;
RotationX = Mathf.Clamp(RotationX, minE, maxE);
float rotaY = transform.localEulerAngles.y;
transform.localEulerAngles = new Vector3(RotationX, rotaY, 0);
}
else
{
RotationX -= Input.GetAxis("Mouse Y") * RotationH;
RotationX = Mathf.Clamp(RotationX, minE, maxE);
float roationY = Input.GetAxis("Mouse X") * RotationV;
float RotationY = transform.localEulerAngles.y+roationY;
transform.localEulerAngles = new Vector3(RotationX,RotationY,0);
}
}
}
代码解释
body.freezeRotation
控制物理是否会改变对象的旋转。
transform.localEulerAngles
旋转作为欧拉角度相对于父变换的旋转度。
Mathf.Clamp(要限制的值, 要比较的最小值, 要比较的最大值)
将给定的值夹在给定的最小浮点数和最大浮点数之间。如果给定值在最小和最大范围内,则返回给定值(最小值和最大值之间的浮点结果)。
摄像机代码优化
正常情况下摄像机跟随玩家移动,当按下E键可以以玩家当前位置为中心旋转场景界面。
private float rotaY;
private Vector3 _offset;
private void Start()
{
//_rotY = transform.localEulerAngles.y;
//角色和摄像机的初始偏移量
_offset = target.position - transform.position;
}
void Update()
{
if (Input.GetKey(KeyCode.E))
{
ChooseRotation();
}
if (!Input.GetKey(KeyCode.E))
{
Quaternion rotation = Quaternion.Euler(0, rotaY, 0);
//rotation * _offset将一个四元数*偏移向量,得到将向量做旋转操作后的偏移量
//将目标位置-偏移量得到摄像机的当前位置
transform.position = target.position - (rotation * _offset);
transform.LookAt(target);
}
}
给玩家添加跳跃技能
private float jumpSpeed = 15f;
private float terminalVelocity = -7;//终止速度
private float minFall = -1.5f;//最小降落速度
private float veriSpeed;//垂直速度
void Start()
{
_character = GetComponent<CharacterController>();
//将垂直速度初始化为最小降落速度
veriSpeed = minFall;
}
void Update()
{
Move();
Jump();
}
public void Jump()
{
//检测是否接触地面
if (_character.isGrounded)
{
//当按下空格键,在地面上就垂直速度=跳跃速度(跳跃),不在地面上则下落(应用重力直到垂直速度达到终止速度
if (Input.GetButtonDown("Jump"))
{
veriSpeed = jumpSpeed;
}
else
{
veriSpeed = minFall;
}
}
else
{
veriSpeed += gravity *5* Time.deltaTime;
if (veriSpeed < terminalVelocity)
{
veriSpeed = terminalVelocity;
}
}
movement.y = veriSpeed;
movement *= Time.deltaTime;
movement = transform.TransformDirection(movement);
_character.Move(movement);
}