英文:
How to rotate player camera via script?
问题
我将代码部分翻译如下:
public class FollowPlayer : MonoBehaviour
{
public Transform player;
public Vector3 offset;
public float mouseSensitivity = 100f;
float xRotation = 0f;
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
}
void Update()
{
// 让相机跟随玩家
transform.position = player.position + offset;
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.fixedDeltaTime;
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.fixedDeltaTime;
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -90f, 90f);
transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
player.Rotate(Vector3.up * mouseX);
}
}
请注意,代码中的中文注释已经被保留,不需要额外翻译。
英文:
I had my main camera as a component of my player object but I wanted to keep them separate so I created a script which allows for my camera to follow my player instead, while not keeping my camera as a child of the player object.
However, despite my player object itself being able to rotate properly, the camera does not follow it when I move my mouse horizontally, and only works vertically.
I currently have an empty game object with my main camera attached to it, with a reference to the player body (transform) and this following script:
public class FollowPlayer : MonoBehaviour
{
public Transform player;
public Vector3 offset;
public float mouseSensitivity = 100f;
float xRotation = 0f;
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
}
void Update()
{
// Make the camera follow the player
transform.position = player.position + offset;
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.fixedDeltaTime;
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.fixedDeltaTime;
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -90f, 90f);
transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
player.Rotate(Vector3.up * mouseX);
}
}
If I put this camera back under my player object and take out the line with the 'offset', it works, but with the camera on its own, it doesn't.
答案1
得分: 1
我明白了。
改为
transform.rotation = Quaternion.Euler(xRotation, player.rotation.eulerAngles.y, 0f);
这样摄像机不仅会跟随玩家的位置,还会跟随玩家的Y轴旋转角度。
希望有所帮助!
Alexa
英文:
I think I got it.
Instead of
transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
Try doing
transform.rotation = Quaternion.Euler(xRotation, player.rotation.eulerAngles.y, 0f);
(edited)
So that the camera follows the Y rotation of the player as well, not just the position.
Hope this helps!
Alexa
答案2
得分: 0
相机没有旋转,因为您在脚本中旋转玩家对象,而不是与相机关联的对象。并且在脚本中没有对玩家水平旋转的任何引用。3DartBlade在第一条评论中向您展示了如何使相机和玩家的水平旋转相等[ transform.rotation = Quaternion.Euler(xRotation, player.rotation.euler.y, 0f); ],但如果您与玩家有偏移,以这种方式您将无法获得相机的期望行为。实现期望行为(3D人物相机)的最简单方法是创建一个带有脚本的额外空对象:
public Transform player;
private void LateUpdate() {
transform.position = player.transform.position;
transform.rotation = player.transform.rotation;
}
并且使附有相机的空对象成为前一个对象的子对象,并在其上附加以下脚本:
public Vector3 offset;
public float mouseSensitivity = 100f;
float xRotation = 0f;
void Start() {
transform.position = cube.position + offset;
}
private void LateUpdate() {
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -90f, 90f);
transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
}
完成后,在PlayerController脚本中实现围绕Y轴的玩家旋转。在相机控制脚本中控制玩家没有意义。当然,您可以这样做,但在将来可能会遇到大问题。
几个注意事项:
1)您应该在LateUpdate()方法中移动或旋转相机,而不是Update()。否则,可能会导致相机抖动。
2)不要在Update()或LateUpdate()方法中使用Time.fixedDeltaTime。这没有意义,并可能导致奇怪的行为。在FixedUpdate()方法中使用它-当您使用物理引擎时。在Update()、LateUpdate()中使用Time.deltaTime。
3)对于先进和简单的相机控制-使用Cinemachine包是最佳实践。您会花一些时间来学习这个工具(从15分钟到一小时),但它将使您将来的生活变得更轻松。
英文:
Camera isn't rotating, because You rotate player object in script, not the camera-attached object. And You havn't any references in script on player horizontal rotation.
3DartBlade in first comment shows You how to make camera and player horizontal rotations equal [ transform.rotation = Quaternion.Euler(xRotation, player.rotation.euler.y, 0f); ] , but if You have offset from player, You wouldn't get desired behaviour of camera in such way.
Easyest way to achive desired behaviour (3D-person camera) is creating one more empty object with script:
public Transform player;
private void LateUpdate() {
transform.position = player.transform.position;
transform.rotation = player.transform.rotation;
}
And make Your empty object with attached camera child of previous object, with next script on it:
public Vector3 offset;
public float mouseSensitivity = 100f;
float xRotation = 0f;
void Start() {
transform.position = cube.position + offset;
}
private void LateUpdate() {
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -90f, 90f);
transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
}
And, after that done, You should implement player rotation around Y-axis in PlayerController script. Controlling player in camera-controlling script make no sense. You can, of course, but it can make great problems in future.
And few notes:
- You should move, or rotate Your Camera in LateUpdate() method, not in Update(). Because, otherwise it could lead to camera jittering.
- NOT use Time.fixedDeltaTime in Update() or LateUpdate() methods. It make no sense and can lead to weard behaviours. Use it in FixedUpdate() method - when You work fith physics. In Update(), LateUpdate() use Time.deltaTime.
- For advance and easy camera controll - using Cinemachine package is the best practice. You will loose some time to learn this tool (from 15 minutes to one hour), but it will make Your life much easyer in future.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论