300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Unity 角色控制和视角

Unity 角色控制和视角

时间:2019-10-21 10:32:05

相关推荐

Unity 角色控制和视角

目录

零.参考资料1.文章2.视频 一.角色控制 - 不含视角控制1.单轴移动1.1.直接改变位置1.2.使用 Character Controller 组件1.x.效果 2.双轴移动2.1.直接改变位置2.2.使用 Character Controller 组件2.x.效果 二.角色控制 - 含视角控制1.第三人称视角2.俯视角(鼠标控制方向)3.等距俯视视角 ❀.使用 Character Controller组件时模拟重力、跳跃❀.1.模拟重力❀.2.跳跃 ☽.细节知识点☽.1.使用`Input.GetAxis()`获取轴向上的向量时需要进行归一化☽.2.游戏角色跳跃所需的垂直速度取决于重力和高度

零.参考资料

1.文章

第三人称视角 - 手动实现

第三人称视角 +鼠标滚轮缩放视野+视角拖拽

2.视频

角色移动方式汇总

第三人称视角+双轴移动 - 使用Cinemachine

第三人称视角+俯视视角+单/双轴移动+鼠标控制方向 - 使用Cinemachine

等距俯视视角+双轴移动

一.角色控制 - 不含视角控制

注:单轴移动指在一个轴向(包含正反两个方向)上移动,在另一个轴向上进行旋转。双轴移动是指两个轴向均可控制角色移动。

1.单轴移动

1.1.直接改变位置

[SerializeField] private float moveSpeed = 5f;[SerializeField] private float rotateSpeed = 1f;void Update(){//获取输入var horizontalInput = Input.GetAxis("Horizontal");var verticalInput = Input.GetAxis("Vertical");//Position累加//transform.Translate(Vector3.forward * verticalInput * moveSpeed * Time.deltaTime, Space.Self);transform.position += transform.forward * verticalInput * moveSpeed * Time.deltaTime;//角色旋转transform.Rotate(Vector3.up, horizontalInput * rotateSpeed);}

1.2.使用 Character Controller 组件

[SerializeField] private float moveSpeed = 5f;[SerializeField] private float rotateSpeed = 1f;private CharacterController characterController;private void Start(){characterController = GetComponent<CharacterController>();}void Update(){//获取输入var horizontalInput = Input.GetAxis("Horizontal");var verticalInput = Input.GetAxis("Vertical");//计算包含方向和速度的向量 var move = transform.forward * verticalInput * moveSpeed * Time.deltaTime;//移动角色characterController.Move(move);//角色旋转transform.Rotate(Vector3.up, horizontalInput * rotateSpeed);}

1.x.效果

2.双轴移动

2.1.直接改变位置

[SerializeField] float moveSpeed = 5f;[SerializeField] float smoothTime = 0.1f;//旋转平滑时间private Vector3 input;private void Update(){//移动input = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical")).normalized;if (input.magnitude == 0)return;transform.Translate(input * moveSpeed * Time.deltaTime, Space.World);//transform.position += input * moveSpeed * Time.deltaTime;//旋转Quaternion newQuaternion = Quaternion.LookRotation(input, transform.up);transform.rotation = Quaternion.Slerp(transform.rotation, newQuaternion, smoothTime);}

2.2.使用 Character Controller 组件

[SerializeField] float moveSpeed = 5f;[SerializeField] float smoothTime= 0.1f;//旋转平滑时间private Vector3 input;private CharacterController characterController;private void Start(){characterController = GetComponent<CharacterController>();}private void Update(){//获取输入input = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")).normalized;if (input.magnitude == 0)return;var move = input * moveSpeed * Time.deltaTime;//移动角色characterController.Move(move);//旋转Quaternion newQuaternion = Quaternion.LookRotation(input, transform.up);transform.rotation = Quaternion.Slerp(transform.rotation,newQuaternion,smoothTime);}}

2.x.效果

二.角色控制 - 含视角控制

注:以下视角控制有些使用了Cinemachine插件。

1.第三人称视角

[SerializeField] private float moveSpeed = 5f;[SerializeField] private Transform camera;[SerializeField] private float rotateSpeed = 1f;private CharacterController characterController;private float turnSmoothVelocity;void Start(){characterController = GetComponent<CharacterController>();}void Update(){//获取输入Vector3 input = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical")).normalized;if (input.magnitude >= 0.1f){float targetAngle = Mathf.Atan2(input.x, input.z) * Mathf.Rad2Deg + camera.eulerAngles.y;float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, rotateSpeed);transform.rotation = Quaternion.Euler(0f, angle, 0f);Vector3 moveDir = Quaternion.Euler(0, targetAngle, 0f) * Vector3.forward;characterController.Move(moveDir.normalized * moveSpeed * Time.deltaTime);}}

1.1.玩家层级结构

ThirdPersonPlayer:空物体,角色控制脚本以及CharacterController组件均挂载在该空物体上。

Player:玩家。

CM FreeLook1:虚拟相机(FreeLook Camera)。

1.2.虚拟相机参数设置

FollowLook At均设置为Player。设置Orbits - Binding ModeWord Space。调整上中下视角轨道(Orbits - TopRig/MiddleRig/BottomRig)的位置和大小。(根据需要设置)调整视角旋转速度(X/YAxis - Speed)或者鼠标是否反转(X/Y Axis - InputAxisValue - Invert)。(根据需要设置)

1.3.玩家控制脚本参数设置

注:Camera属性为Unity中的MainCamera,而不是虚拟相机。

1.x.效果

2.俯视角(鼠标控制方向)

[SerializeField] private float moveSpeed = 5f;private CharacterController characterController;void Start(){characterController = GetComponent<CharacterController>();}void Update(){//计算包含方向和速度的向量 var input = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical")).normalized;var move = input * moveSpeed * Time.deltaTime;//移动角色characterController.Move(move);//转换玩家坐标系var playerScreenPoint = Camera.main.WorldToScreenPoint(transform.position);//计算旋转角度var point = Input.mousePosition - playerScreenPoint;var angle = Mathf.Atan2(point.x, point.y) * Mathf.Rad2Deg;transform.eulerAngles = new Vector3(transform.eulerAngles.x, angle, transform.eulerAngles.z);}

2.1.玩家层级结构

Player:玩家,玩家控制脚本和CharacterController组件均挂载在此物体上。

CM vcam1:虚拟相机(Virtual Camera)。

2.2.虚拟相机参数设置

FollowLook At均设置为Player。修改Body - Follow Offset属性和Aim - Tracked Object Offect属性,将相机视角设置为俯视视角。修改Body - Binding ModeLock To Target On Assign修改Aim后的属性为Do nothing。修改Body - X/Y/ZDamping调整视角跟随延迟。(根据需要修改)

2.x.效果

3.等距俯视视角

3.1.玩家层级结构 / 设置相机视角

红框部分为必须进行的设置,黄框部分根据实际需要进行调整。Player:玩家。IsoViewCamera:空物体,在该物体上设置相机的倾斜角度。Main Camera:主相机。

3.2.编写辅助脚本旋转输入向量

public static class IsoViewPlayerControllerHelpers{private static Matrix4x4 isoMatrix = Matrix4x4.Rotate(Quaternion.Euler(0, 45, 0));//给Vector3增加扩展方法public static Vector3 ToIso(this Vector3 input) => isoMatrix.MultiplyPoint3x4(input);}

3.3.控制玩家移动

[SerializeField] private float moveSpeed = 5f;[SerializeField] private float turnSpeed = 360;private CharacterController characterController;private void Start(){characterController = GetComponent<CharacterController>();}private void Update(){//获取输入向量并转换成等距视图向量(Isometry View,将输入向量倾斜45度),再将其归一化。Vector3 input = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical")).ToIso().normalized;if (input.magnitude > 0){//通过输入向量获取一个方向仅指向玩家正前方,大小由输入控制的增向量。Vector3 move = transform.forward * input.magnitude * moveSpeed * Time.deltaTime;//移动玩家characterController.Move(move);//旋转玩家(有两种方式)Quaternion newQuaternion = Quaternion.LookRotation(input, transform.up);//transform.rotation = Quaternion.Slerp(transform.rotation, newQuaternion, 0.1f);transform.rotation = Quaternion.RotateTowards(transform.rotation, newQuaternion, turnSpeed * Time.deltaTime);}}

注:在以上代码中,控制玩家移动是采用玩家朝正前方移动 + 旋转的结果 = 自由移动。而不是玩家朝任意方向移动 + 旋转表现 = 自由移动旋转表现可有可无,即使玩家没有旋转,也不影响玩家自由移动。我觉得第一种方式比较真实,所以就采用这种方式移动角色。

3.x.效果

❀.使用 Character Controller组件时模拟重力、跳跃

注:Character Controller组件没有包含物理效果,如果想要重力效果则需要自己实现。

❀.1.模拟重力

[SerializeField] private Transform groundCheck;//用于与地面碰撞检测的物体(位置在玩家模型底部)[SerializeField] private float checkRadius = 0.2f;//检测半径[SerializeField] private LayerMask groundlayerMask;//检测的层[SerializeField] private float gravity = -9.8f;//重力private Vector3 velocity = Vector3.zero;//速度,重力(垂直方向)所影响的向量private bool isGround;//是否接触地面void Update(){isGround = Physics.CheckSphere(groundCheck.position, checkRadius, groundlayerMask);if (isGround && velocity.y < 0)velocity.y = 0;velocity.y += gravity * Time.deltaTime;characterController.Move(velocity * Time.deltaTime);}

❀.2.跳跃

[SerializeField] private Transform groundCheck;//用于与地面碰撞检测的物体(位置在玩家模型底部)[SerializeField] private float checkRadius = 0.2f;//检测半径[SerializeField] private LayerMask groundlayerMask;//检测的层[SerializeField] private float gravity = -9.8f;//重力private Vector3 velocity = Vector3.zero;//速度,重力(垂直方向)所影响的向量private bool isGround;//是否接触地面void Update(){isGround = Physics.CheckSphere(groundCheck.position, checkRadius, groundlayerMask);if (isGround && Input.GetButtonDown("Jump"))velocity.y += Mathf.Sqrt(jumpHeight * -2 * gravity);velocity.y += gravity * Time.deltaTime;characterController.Move(velocity * Time.deltaTime);}

☽.细节知识点

☽.1.使用Input.GetAxis()获取轴向上的向量时需要进行归一化

使用Input.GetAxis()获取到的值在-1~1之间,假如同时按下WD,获取到的水平和垂直轴的值均为1,根据勾股定理,斜向上方向量大小≈1.41,这样会导致斜向上的速度偏快。

Vector3 input = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")).normalized;

☽.2.游戏角色跳跃所需的垂直速度取决于重力和高度

g:重力(一般为-9.8f)h:跳跃高度

velocity.y += Mathf.Sqrt(-2f * gravity * jumpHeight);

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。