赞
踩
知识点记录(希望是以后要用到了是可以直接拿来复制粘贴)
标准功能:按下WASD移动,空格键跳跃,Shift加速,鼠标右键控制摄像机旋转视角
角色移动部分代码
public float walkSpeed = 5;//移动 public float runSpeed = 10;//奔跑 public float turnSmoothTime = 0.13f;//角色转向平滑时间 float turnSmoothVelocity; public Camera cameraT; private Rigidbody rb; public Animator ani;//动画控制器,没有的可以不加,在下面脚本里删掉就行 private void Awake() { rb = transform.GetComponent<Rigidbody>(); cameraT = Camera.main; } void FixedUpdate() { PlayerMoveThirdPerson(); } //主要脚本 public void PlayerMoveThirdPerson() { float h = Input.GetAxisRaw("Horizontal"); float v = Input.GetAxisRaw("Vertical"); Vector3 m_CamForward = Vector3.Scale(cameraT.transform.forward, new Vector3(1, 0, 1)).normalized; Vector3 m_Move = v * m_CamForward + h * cameraT.transform.right; if (m_Move.magnitude > 1f) m_Move = m_Move.normalized; Vector2 m_Input = new Vector2(h, v).normalized;//获取输入 float targetSpeed = Input.GetKey(KeyCode.LeftShift) ? runSpeed : walkSpeed;//加速或匀速 transform.Translate(m_Move * targetSpeed * Time.deltaTime, Space.World); //rb.MovePosition(rb.position+m_Move * targetSpeed * Time.deltaTime);//另一种移动方式 if (m_Input != Vector2.zero) { ani.SetInteger("AnimationPar", 1);//动画部分,可删减 float targetRotation = Mathf.Atan2(h, v) * Mathf.Rad2Deg + cameraT.transform.eulerAngles.y; transform.eulerAngles = Vector3.up * Mathf.SmoothDampAngle(transform.eulerAngles.y, targetRotation, ref turnSmoothVelocity, turnSmoothTime); } else { ani.SetInteger("AnimationPar", 0); } if (Input.GetKey(KeyCode.Space)) { if (ani.GetInteger("AnimationPar") == 1) { ani.SetBool("FreeFall", true); ani.SetBool("Grounded", true); ani.SetBool("JumpRun", true); } else { ani.SetBool("JumpRun", false); ani.SetBool("IsJump", true); ani.SetBool("Grounded", true); } } else { ani.SetBool("IsJump", false); ani.SetBool("FreeFall", false); } transform.GetComponent<Rigidbody>().velocity = Vector3.zero; Physics.gravity = new Vector3(0, -45, 0); }
摄像机控制部分
public Transform target;//角色 public Vector3 targetOffset; public float distance = 5.0f; public float maxDistance = 20;//缩放 public float minDistance = .6f;//缩放 public float xSpeed = 200.0f;//速度 public float ySpeed = 200.0f; public int yMinLimit = -80;//限定角度 public int yMaxLimit = 80; public int zoomRate = 40; public float zoomDampening = 5.0f; public float xDeg = 0.0f;//自身的角度记录 public float yDeg = 0.0f;//自身的角度 public float currentDistance;//缩放记录 public float desiredDistance;//缩放 private Quaternion currentRotation; private Quaternion desiredRotation; public Quaternion rotation; private Vector3 position; public float X;//初始化角度X轴 public float Y;//初始化角度Y轴 public bool isCameraChange = false; private bool Rot = false; void LateUpdate() { if (Input.GetMouseButton(1)) { xDeg += (Input.GetAxis("Mouse X") * xSpeed * 0.01f); yDeg -= (Input.GetAxis("Mouse Y") * ySpeed * 0.01f); } yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit); // 设置相机旋转 desiredRotation = Quaternion.Euler(yDeg, xDeg, 0); currentRotation = transform.rotation;//记录初始角度 rotation = Quaternion.Lerp(currentRotation, desiredRotation, Time.deltaTime * zoomDampening); transform.rotation = rotation; //这里多加了一个鼠标滚轮控制相机缩放的功能(其实是控制相机的距离) if (!isCameraChange) { desiredDistance -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs(desiredDistance); //变焦最小/最大 desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance); //平滑变焦 currentDistance = Mathf.Lerp(currentDistance, desiredDistance, Time.deltaTime * zoomDampening); } position = new Vector3(target.position.x, 0, target.position.z) - (rotation * Vector3.forward * currentDistance + targetOffset); transform.position = position; //这个脚本是角色和摄像机之间有遮挡时改变相机位置,但是有时候会比较突兀,可删减 ProcessMode2(); } private static float ClampAngle(float angle, float min, float max) { if (angle < -360) angle += 360; if (angle > 360) angle -= 360; return Mathf.Clamp(angle, min, max); } public float distanceAway;//相机到角色距离 public Vector3 DisOffset; /// <summary> /// 从摄像机到角色 /// </summary> public void ProcessMode2() { RaycastHit hit; distanceAway = Vector3.Distance(transform.position, target.position); if (Physics.Linecast(target.position + Vector3.up, transform.position, out hit)) { string name = hit.collider.gameObject.tag; if (name != "MainCamera") { //如果射线碰撞的不是相机,那么就取得射线碰撞点到玩家的距离 float currentDistance = Vector3.Distance(hit.point, target.position); if (currentDistance < distanceAway) { //Debug.Log("角色遮挡"); transform.position = hit.point + DisOffset; } } } }
(移动端这里是学习了林新发大佬的方法)
因为是移动端,所以这里使用了摇杆,左摇杆控制角色移动,右摇杆控制摄像机
关于摇杆制作的部分,大家可以看看这篇文章摇杆制作
角色控制代码
public float speed = 1f; // 转向速度 public float turnSpeed = 20f; public Animator anim; // 跟节点 public Transform rootTrans; // 模型节点 public Transform modelTrans; // 是否在移动 private bool moving = false; // 移动向量 private Vector3 moveDirection = Vector3.zero; // 是否可移动 private bool canMove = true; void Update() { if (canMove && moving) { anim.SetInteger("AnimationPar", 1); rootTrans.position += moveDirection * speed * Time.deltaTime; modelTrans.forward = Vector3.Lerp(modelTrans.forward, moveDirection, turnSpeed * Time.deltaTime); } else { anim.SetInteger("AnimationPar", 0); } } public void Move(Vector3 direction) { moveDirection = direction; moving = true; } public void Stand() { moving = false; }
相机控制部分代码
// 限制摄像机角度范围 private const float Y_ANGLE_MIN = 10f; private const float Y_ANGLE_MAX = 50.0f; // 摄像机看向的物体 public Transform lookAt; // 摄像机Transform public Transform camTransform; // 摄像机距离目标物体的距离 public float distance = 1.2f; // 原始距离 private float originalDistance; // 旋转速度 public float rotateSpeed = 0.01f; private float currentX = 0.0f; private float currentY = 20.0f; private bool rotating; private Vector2 rotateDelta; private void Start() { camTransform = transform; originalDistance = distance; } private void Update() { if (rotating) { currentX += rotateDelta.x; currentY += rotateDelta.y; currentY = Mathf.Clamp(currentY, Y_ANGLE_MIN, Y_ANGLE_MAX); } } public void RotateCam(Vector2 delta) { rotateDelta = delta * rotateSpeed; rotating = true; } public void StopRotate() { rotating = false; } private void LateUpdate() { Vector3 dir = new Vector3(0, 0, -distance); Quaternion rotation = Quaternion.Euler(currentY, currentX, 0); camTransform.position = lookAt.position + rotation * dir; camTransform.LookAt(lookAt.position); } /// <summary> /// 修改distnace 镜头调整 /// </summary> /// <param name="args"></param> private void OnEventChangeCamDistance(params object[] args) { var offset = (float)args[0]; distance = originalDistance + offset * 20f; }
摇杆控制器脚本
public class GamCtrl : MonoBehaviour { private static GamCtrl instance; public static GamCtrl Instance { get { if (instance==null) { instance = new GamCtrl(); } return instance; } } public PlayerActionComp2 player;//角色控制脚本 public CameraControl2 cameraCtrl;//摄像机控制脚本 public Rocker rocker;左摇杆 public Rocker world;右摇杆 private void Start() { //拖动摇杆 rocker.onDragPcak = (direction) => { var realDirect = cameraCtrl.transform.localToWorldMatrix * new Vector3(direction.x, 0, direction.y); realDirect.y = 0; realDirect = realDirect.normalized; player.Move(realDirect); }; //停止拖动 rocker.onStopDrag = () => { player.Stand(); }; world.onDragPcak = (direction) => { cameraCtrl.RotateCam(direction); }; world.onStopDrag = () => { cameraCtrl.StopRotate(); }; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。