赞
踩
获取键盘方向输入值,然后再利用Charactor实现人物的移动
1.首先向模型添加CharactorController, 并调整它的大小和中心位置
2.添加PlayerController脚本,控制其移动
在移动前,需要先让角色平缓旋转,添加一个Roating方法
旋转的方向就是角色到键盘输入点的方向,然后利用插值进行平滑旋转,
private void Rotating(float horizontal, float vertical)
{
var targetDirection = new Vector3(-horizontal, 0, -vertical);
var targetRotation = Quaternion.LookRotation(targetDirection, Vector3.up);
transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, this.rotaionSpeed);
}
添加Move方法
因为CharactorController并不使用刚体效果,所以为了使它接触地面,需要在y方向上持续给一个力
private void Move(float horizontal, float vertical)
{
if (Mathf.Abs(horizontal) > 0.5 || Mathf.Abs(vertical) > 0.5)
{
//播放Run动画
this.m_Animator.SetBool("IsRun", true);
Rotating(horizontal, vertical);
Vector3 direct = Vector3.zero;
if (m_Controller.isGrounded)
{
//角色面向的方向,忽略Y轴
direct = new Vector3(transform.forward.x, -1, transform.forward.z);
}
//持续向下的力
direct.y -= 20 * Time.deltaTime;
m_Controller.Move(direct * speed * Time.deltaTime);
}
else
{
//停止Run,进入Idle动画
this.m_Animator.SetBool("IsRun", false);
}
}
然后在Update里调用Move方法
这里horzontal 和Vertical为负,是因为角色坐标系和世界坐标系相反
void Update()
{
Move(-Input.GetAxis("Horizontal"), -Input.GetAxis("Vertical"));
}
自身坐标系
实际坐标系
完整代码
public class PlayerController : MonoBehaviour {
public float rotaionSpeed = 0.5f;
public float speed = 3.6f;
private CharacterController m_Controller;
private Animator m_Animator;
void Start()
{
this.m_Controller = this.GetComponent<CharacterController>();
this.m_Animator = this.GetComponent<Animator>();
}
void Update()
{
Move(-Input.GetAxis("Horizontal"), -Input.GetAxis("Vertical"));
}
private void Move(float horizontal, float vertical)
{
if (Mathf.Abs(horizontal) > 0.5 || Mathf.Abs(vertical) > 0.5)
{
this.m_Animator.SetBool("IsRun", true);
Rotating(horizontal, vertical);
Vector3 direct = Vector3.zero;
if (m_Controller.isGrounded)
{
direct = new Vector3(transform.forward.x, -1, transform.forward.z);
}
direct.y -= 20 * Time.deltaTime;
m_Controller.Move(direct * speed * Time.deltaTime);
}
else
{
this.m_Animator.SetBool("IsRun", false);
}
}
private void Rotating(float horizontal, float vertical)
{
var targetDirection = new Vector3(horizontal, 0, vertical);
var targetRotation = Quaternion.LookRotation(targetDirection, Vector3.up);
transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, this.rotaionSpeed);
}
}
角色相机初始位置,与X平面成45度夹角,因为坐标系和世界坐标系相反,所以与Y平面成180度,即相反方向
相机和目标保持相对位置,且与目标在X平面的角度不会改变,一直保持45度,但是能通过鼠标滚轮,对相机进行接近或远离,就是调整相机的Posion.z。
相机初始化
获取绑定的目标
void Start () {
if(target == null)
{
target = GameObject.FindGameObjectWithTag("Player");
if(target == null)
{
Debug.LogWarning("Don't found player tag please change player tag to Player");
}
}
//当前距离为缩放的最大距离
distance = zoomMax;
//用于平滑移动相机
distanceLerp = distance;
//移动到指定位置
MoveCamera();
}
相机的移动
void MoveCamera()
{
//相机当前的Rotation
Quaternion rotation = Quaternion.Euler(transform.eulerAngles.x, transform.eulerAngles.y, 0);
//当前与目标位置的距离
Vector3 calPos = new Vector3(0, 0, -distanceLerp);
//相机的应该移动到的位置
position = rotation * calPos + target.transform.position;
transform.rotation = rotation;
transform.position = position;
}
rotation * calPos 就是让calPos旋转rotation角度,即到达红线位置
相机缩放
调整distance,即上图蓝线的长度
void ScrollMouse()
{
distanceLerp = Mathf.Lerp(distanceLerp,distance,Time.deltaTime * 5);
if (Input.GetAxis("Mouse ScrollWheel") != 0)
{
distance = Vector3.Distance (transform.position , target.transform.position);
distance = ScrollLimit(distance - Input.GetAxis("Mouse ScrollWheel")*scrollSpeed, zoomMin, zoomMax);
}
}
完整代码
public class FollowTargetCamera : MonoBehaviour {
[HideInInspector]
public GameObject target;
public float scrollSpeed;
public float zoomMin;
public float zoomMax;
private float distance;
private float distanceLerp;
private Vector3 position;
void Start () {
if(target == null)
{
target = GameObject.FindGameObjectWithTag("Player");
if(target == null)
{
Debug.LogWarning("Don't found player tag please change player tag to Player");
}
}
distance = zoomMax;
distanceLerp = distance;
MoveCamera();
}
//角色移动放在Update方法里,在角色移动后处理
void LateUpdate () {
ScrollMouse();
MoveCamera();
}
void MoveCamera()
{
Quaternion rotation = Quaternion.Euler(transform.eulerAngles.x, transform.eulerAngles.y, 0);
Vector3 calPos = new Vector3(0, 0, -distanceLerp);
position = rotation * calPos + target.transform.position;
transform.rotation = rotation;
transform.position = position;
}
//鼠标滚动后重新计算镜头和目标的距离
void ScrollMouse()
{
distanceLerp = Mathf.Lerp(distanceLerp,distance,Time.deltaTime * 5);
if (Input.GetAxis("Mouse ScrollWheel") != 0)
{
distance = Vector3.Distance (transform.position , target.transform.position);
distance = ScrollLimit(distance - Input.GetAxis("Mouse ScrollWheel")*scrollSpeed, zoomMin, zoomMax);
}
}
//滚动距离大小限制
float ScrollLimit(float dist, float min, float max)
{
if (dist < min)
dist= min;
if (dist > max)
dist= max;
return dist;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。