【问题标题】:I wrote a script for movement and mouse look, movement works but mouse look does not我为移动和鼠标外观编写了一个脚本,移动有效,但鼠标外观不起作用
【发布时间】:2022-03-13 18:20:08
【问题描述】:

我正在为移动和鼠标查看编写脚本,移动有效,但鼠标查看没有。我开始游戏,光标锁定在游戏屏幕上,我可以移动但不能环顾四周,也没有错误。有人可以帮忙吗?

这是我的脚本:

    using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player_Controller : MonoBehaviour
{
    [SerializeField]private float _speed = 7f;
    [SerializeField]private float _mouseSensitivity = 50f;
    [SerializeField]private float _minCameraview = -70f, _maxCameraview = 80f;
    private CharacterController _charController;
    private Camera _camera;
    private float xRotation = 0f;

    // Start is called before the first frame update
    void Start()
    {
        _charController = GetComponent<CharacterController>();
        _camera = Camera.main;

        if(_charController == null)
        Debug.Log("No Character Controller Attached to Player");

        Cursor.lockState = CursorLockMode.Locked;
    }

    // Update is called once per frame
    void Update()
    {
        //Get WASD Input for Player
        float vertical = Input.GetAxis("Vertical");
        float horizontal = Input.GetAxis("Horizontal");
        //move player based on WASD Input
        Vector3 movement = Vector3.forward * vertical + Vector3.right * horizontal;
        _charController.Move(movement * Time.deltaTime * _speed);


        
        //Get Mouse position Input
        float mouseX = Input.GetAxis("Mouse X") * _mouseSensitivity * Time.deltaTime;
        float mouseY = Input.GetAxis("Mouse Y") * _mouseSensitivity * Time.deltaTime;
          //Rotate the camera based on the Y input of the mouse
          xRotation -= mouseY;
          //clamp the camera rotation between 80 and -70 degrees
          xRotation = Mathf.Clamp(xRotation, _minCameraview, _maxCameraview);

          _camera.transform.localRotation = Quaternion.Euler(xRotation, 0, 0);
          //Rotate the player based on the X input of the mouse
          transform.Rotate(Vector3.up * mouseX * 3);

    }
}

【问题讨论】:

  • 它的移动是否有问题,或者根本不旋转?
  • 它没有马车运动,但它不旋转也不环顾四周。

标签: unity3d


【解决方案1】:

问题是您将鼠标输入乘以Time.deltaTimeTime.deltaTime 用于当您想要具有不同帧速率的不同设备时。这是因为当乘以Time.deltaTime 时,你得到的恒定速度是每秒一个单位:

float speed = 10f;
float movement = speed * Time.deltaTime;

如果您的帧速率为 10fps(希望您没有),那么您将在 0.1 秒内获得每一帧。每帧为 0.1 秒,因此当将其乘以 10(速度)时,您得到的值为 1。如果您加快帧速率,您还将获得每秒 10 个单位 (1 x 10 = 10)。

鼠标移动不需要这个,因为鼠标移动不是由计算机处理的。换句话说,当你移动鼠标时,它并没有随着帧率的变化而变化,所以你不需要'Time.deltaTime`。

我还注意到你的动作是基于Vector3。我的意思是您使用的是全局坐标而不是本地坐标(变换)。这意味着如果比赛轮换,Vector3.forward 将不同于球员的前锋。您应该使用transform.forward 而不是使用本地坐标。

你应该把脚本改成这样:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player_Controller : MonoBehaviour
{
    [SerializeField]private float _speed = 7f;
    [SerializeField]private float _mouseSensitivity = 50f;
    [SerializeField]private float _minCameraview = -70f, _maxCameraview = 80f;
    private CharacterController _charController;
    private Camera _camera;
    private float xRotation = 0f;

    // Start is called before the first frame update
    void Start()
    {
        _charController = GetComponent<CharacterController>();
        _camera = Camera.main;

        if(_charController == null)
        Debug.Log("No Character Controller Attached to Player");

        Cursor.lockState = CursorLockMode.Locked;
    }

    // Update is called once per frame
    void Update()
    {
        //Get WASD Input for Player
        float vertical = Input.GetAxis("Vertical");
        float horizontal = Input.GetAxis("Horizontal");
        //move player based on WASD Input
        Vector3 movement = transform.forward * vertical + transform.right * horizontal; //changed this line.
        _charController.Move(movement * Time.deltaTime * _speed);


        
        //Get Mouse position Input
        float mouseX = Input.GetAxis("Mouse X") * _mouseSensitivity; //changed this line.
        float mouseY = Input.GetAxis("Mouse Y") * _mouseSensitivity; //changed this line.
          //Rotate the camera based on the Y input of the mouse
          xRotation -= mouseY;
          //clamp the camera rotation between 80 and -70 degrees
          xRotation = Mathf.Clamp(xRotation, _minCameraview, _maxCameraview);

          _camera.transform.localRotation = Quaternion.Euler(xRotation, 0, 0);
          //Rotate the player based on the X input of the mouse
          transform.Rotate(Vector3.up * mouseX * 3);

    }
}

【讨论】:

  • 嗨,肯,它并没有为我解决鼠标问题,我改变了你要求的行,但还是一样,我没有收到任何错误
  • 您的游戏中还有其他脚本吗?我实际上做了一个包含这段代码的统一项目,它对我有用。您可能正在从其他地方控制相机。你的层次结构是什么样的?
  • 它有地图、FPS 播放器、主要原型地点的灯光、地形、出口舱室地图地形、画布、Snaps_level、场景灯光、岩石网格。
  • 但它说 NullReferenceException: Object reference not set to an instance of an object Player_Controller.Update () (at Assets/Player_Controller.cs:46)
  • 好的,当您尝试访问未定义的变量时会发生 NullReferenceException。您可能没有在检查器中设置_camera 变量。我不知道你为什么没有设置它,因为它是在开始时设置的。你有多个摄像头吗?尝试将_camera 变量设置为public,然后将inspector 中的右侧摄像头拖到插槽中。
【解决方案2】:

这是一个既能移动又能看的脚本

[RequireComponent(typeof(CharacterController))]

public class NewBehaviourScript : MonoBehaviour
{

    public float walkingSpeed = 7.5f;
    public float runningSpeed = 11.5f;
    public float jumpSpeed = 8.0f;
    public float gravity = 20.0f;
    public Camera playerCamera;
    public float lookSpeed = 2.0f;
    public float lookXLimit = 45.0f;

    CharacterController characterController;
    Vector3 moveDirection = Vector3.zero;
    float rotationX = 0;

    [HideInInspector]
    public bool canMove = true;

    // Start is called before the first frame update
    void Start()
    {
        characterController = GetComponent<CharacterController>();

        // Lock cursor
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
    }



// Update is called once per frame
void Update()
    {
        // We are grounded, so recalculate move direction based on axes
        Vector3 forward = transform.TransformDirection(Vector3.forward);
        Vector3 right = transform.TransformDirection(Vector3.right);
        // Press Left Shift to run
        bool isRunning = Input.GetKey(KeyCode.LeftShift);
        float curSpeedX = canMove ? (isRunning ? runningSpeed : walkingSpeed) * Input.GetAxis("Vertical") : 0;
        float curSpeedY = canMove ? (isRunning ? runningSpeed : walkingSpeed) * Input.GetAxis("Horizontal") : 0;
        float movementDirectionY = moveDirection.y;
        moveDirection = (forward * curSpeedX) + (right * curSpeedY);

        if (Input.GetButton("Jump") && canMove && characterController.isGrounded)
        {
            moveDirection.y = jumpSpeed;
        }
        else
        {
            moveDirection.y = movementDirectionY;
        }

        // Apply gravity. Gravity is multiplied by deltaTime twice (once here, and once below
        // when the moveDirection is multiplied by deltaTime). This is because gravity should be applied
        // as an acceleration (ms^-2)
        if (!characterController.isGrounded)
        {
            moveDirection.y -= gravity * Time.deltaTime;
        }

        // Move the controller
        characterController.Move(moveDirection * Time.deltaTime);

        // Player and Camera rotation
        if (canMove)
        {
            rotationX += -Input.GetAxis("Mouse Y") * lookSpeed;
            rotationX = Mathf.Clamp(rotationX, -lookXLimit, lookXLimit);
            playerCamera.transform.localRotation = Quaternion.Euler(rotationX, 0, 0);
            transform.rotation *= Quaternion.Euler(0, Input.GetAxis("Mouse X") * lookSpeed, 0);
        }
    }
}
   

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    • 1970-01-01
    相关资源
    最近更新 更多