Unity 实现对摄像机位置移动(前后左右平移,左转右转,俯仰)的两种方案
在实现这个功能的过程中走了很多歪路,特别是借鉴的一个博主的代码会出现平移之后立即复位的问题。
最后也没确定问题出在哪,解决问题的方法是将本来用于旋转的欧拉角的乘算改成建立一个新向量进行加算并最后使用transform.Rotate指令进行旋转。
并不排除是其他地方导致的这个bug。
最后得到的两个方案一个是在【Unity】通过2种方法实现摄像机的移动,旋转,放缩_unity摄像机移动-CSDN博客这篇的基础上改动,单纯使用键盘进行控制。
wasd控制前后左右平移,qe控制左右视角旋转,rf控制视角升降。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class camera_controller : MonoBehaviour { // Start is called before the first frame update Transform cameraTrans; public int panSpeed; public int rotationAmount; public Vector3 zoomAmount; public int moveTime; Vector3 newZoom; void Start() { cameraTrans = this.GetComponent<Transform>(); } // Update is called once per frame void Update() { var newPos = new Vector3(0, 0, 0); var newRotation = new Vector3(0, 0, 0); newZoom = new Vector3(0, 0, 0); if (Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.W)) { Debug.Log("W or up"); newPos += transform.forward * panSpeed * Time.deltaTime; } if (Input.GetKey(KeyCode.DownArrow) || Input.GetKey(KeyCode.S)) { Debug.Log("S or down"); newPos -= transform.forward * panSpeed * Time.deltaTime; } if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D)) { Debug.Log("D or right"); newPos += transform.right * panSpeed * Time.deltaTime; } if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.A)) { Debug.Log("A or left"); newPos -= transform.right * panSpeed * Time.deltaTime; } if (Input.GetKey(KeyCode.Q)) { Debug.Log("Q"); newRotation += Vector3.up * rotationAmount; } if (Input.GetKey(KeyCode.E)) { Debug.Log("E"); newRotation += Vector3.down * rotationAmount; } if (Input.GetKey(KeyCode.R)) { Debug.Log("R"); newPos += Vector3.up * panSpeed * Time.deltaTime; } if (Input.GetKey(KeyCode.F)) { Debug.Log("F"); newPos += Vector3.down * panSpeed * Time.deltaTime; } transform.Translate(newPos, Space.Self); transform.Rotate(newRotation*moveTime * Time.deltaTime, Space.Self); } }
第二个方案是在吕毅大佬这篇博客的基础上Unity3D 入门:最简单的控制视角,以及控制角色前进、转向的脚本 - walterlv进行添加。
使用wasd控制平移,使用鼠标移动控制绕x、y轴旋转,添加逻辑判断,防止视角在z轴上倾斜,同时使用左shift作为鼠标控制的开关,点按开启,再次点按关闭。
using UnityEngine; public class PlayerController : MonoBehaviour { private new Transform transform; public float moveSpeed = 10f; public float rotateSpeed = 500f; private bool can_move_mouse; void Start() { transform = GetComponent<Transform>(); can_move_mouse = false; } void Update() { float adValue = Input.GetAxis("Horizontal"); float wsValue = Input.GetAxis("Vertical"); float mxValue,myValue; if(Input.GetButtonDown("Fire3")) { can_move_mouse = !can_move_mouse; } if(can_move_mouse) { mxValue = Input.GetAxis("Mouse X"); myValue = Input.GetAxis("Mouse Y"); transform.Rotate(new Vector3(0, 1 * rotateSpeed * Time.deltaTime * mxValue, 0)); transform.Rotate(new Vector3(1 * rotateSpeed * Time.deltaTime * myValue, 0, 0)); } var moveDirection = (Vector3.forward * wsValue) + (Vector3.right * adValue); transform.Translate(moveDirection.normalized * moveSpeed * Time.deltaTime, Space.Self); Vector3 currentRotation = transform.rotation.eulerAngles; transform.rotation = Quaternion.Euler(currentRotation.x, currentRotation.y, 0f); } }