Unity3D自学笔记——架构应用(八)人物移动与角色相机的跟随
来源:互联网 发布:php strip_tags 编辑:程序博客网 时间:2024/05/02 01:30
人物移动与角色相机的跟随
人物移动
获取键盘方向输入值,然后再利用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; }
0 0
- Unity3D自学笔记——架构应用(八)人物移动与角色相机的跟随
- Unity3d相机跟随角色移动
- Unity3D自学笔记——架构应用(六)角色创建
- Unity3D自学笔记——架构应用(七)客户端识别角色是否已经创建
- Unity3D自学笔记——架构应用(九)加载角色数据
- Unity3D自学笔记——架构应用(十)角色属性
- u3d简单的第三人称人物移动与相机跟随
- 游戏开发学习笔记(五)人物的移动及相机的跟随
- unity相机跟随人物移动
- Unity3D 人物移动 摄像机跟随
- Unity3D自学笔记——UGUI背包系统(八)物品的分类与整理
- 基于Unity3D的相机功能的实现(五)—— 相机跟随
- 转载他人:角色移动和相机跟随
- Unity3D自学笔记——架构应用(一)用户登录
- Unity3D自学笔记——架构应用(二)选择英雄界面
- Unity3D自学笔记——架构应用(三)JsonToEntity帮助类
- Unity3D自学笔记——架构应用(四)JsonToEntity帮助类更新
- Unity3D自学笔记——架构应用(五)Loading场景及持久化场景
- 约瑟夫环问题
- uva 1641 Ascii Area 多边形面积
- 微信公众帐号开发教程第1篇-引言
- Amsterdam is a beautiful city
- python之if __name__=='__main__'解析
- Unity3D自学笔记——架构应用(八)人物移动与角色相机的跟随
- session入库
- Visualizing Concurrency Patterns in Go
- Android 判断某Activity是否在前台/栈顶
- iOS ScrollView下拉留白处理
- JS实现密码加密
- Linux Network Troubleshooting
- binder机制,很不错的解析,值得收藏
- mysql中文乱码解决