You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity第一人称视角游戏启动时玩家视角朝下问题排查

第一人称视角启动时朝下的问题解决

问题现象

  • 游戏启动时,玩家第一人称视角朝向地面(注:参考图中角色为NPC,玩家以第一人称视角观察)
    • 异常状态:游戏启动时玩家视角朝下
    • 恢复状态:禁用主相机上挂载的脚本后,玩家视角恢复正常朝前
  • 玩家对象由胶囊体构成,主相机位于胶囊体顶部,作为其子物体。

原相机控制脚本

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

public class camMouseLook : MonoBehaviour
{
    Vector2 mouseLook;
    Vector2 smoothV;

    public float sensitivity = 5.0f;
    public float smoothing = 2.0f;
    public bool mouseDown = false;
    public bool cursorLock = false;
    public HandleMouseCursor handleMouseCursor;

    GameObject character;

    // 初始化
    void Start()
    {
        Cursor.lockState = cursorLock ? CursorLockMode.Locked : CursorLockMode.None;
        character = transform.parent.gameObject;
    }
    
    void Update ()
    {
        if (Input.GetMouseButton(0) && mouseDown == true)
        {
            MouseLook();
        }
        else
        {
            if (mouseDown == false)
            {
                MouseLook();
            }
        }
    }

    private void MouseLook()
    {
        Cursor.lockState = cursorLock ? CursorLockMode.Locked : CursorLockMode.None;

        var md = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));

        md = Vector2.Scale(md, new Vector2(sensitivity * smoothing, sensitivity * smoothing));
        smoothV.x = Mathf.Lerp(smoothV.x, md.x, 1f / smoothing);
        smoothV.y = Mathf.Lerp(smoothV.y, md.y, 1f / smoothing);
        mouseLook += smoothV;

        mouseLook.y = Mathf.Clamp(mouseLook.y, -90f, 90f);

        transform.localRotation = Quaternion.AngleAxis(-mouseLook.y, Vector3.right);
        character.transform.localRotation = Quaternion.AngleAxis(mouseLook.x, character.transform.up);
    }
}

尝试过的修改(效果不佳)

using UnityEngine;

public class camMouseLook : MonoBehaviour
{
    Vector2 mouseLook;
    Vector2 smoothV;

    public float sensitivity = 5.0f;
    public float smoothing = 2.0f;

    GameObject character;
    private bool initialRotationSet = false;

    void Start()
    {
        Cursor.lockState = CursorLockMode.Locked;  // 启动时锁定光标
        character = transform.parent.gameObject;
    }

    void Update()
    {
        if (!initialRotationSet)
        {
            SetInitialCameraRotation();
            initialRotationSet = true;
        }

        MouseLook();
    }

    private void SetInitialCameraRotation()
    {
        // 设置相机初始朝前
        transform.localRotation = Quaternion.Euler(Vector3.zero);
    }

    private void MouseLook()
    {
        var md = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));

        md = Vector2.Scale(md, new Vector2(sensitivity * smoothing, sensitivity * smoothing));
        smoothV.x = Mathf.Lerp(smoothV.x, md.x, 1f / smoothing);
        smoothV.y = Mathf.Lerp(smoothV.y, md.y, 1f / smoothing);
        mouseLook += smoothV;

        mouseLook.y = Mathf.Clamp(mouseLook.y, -90f, 90f);

        transform.localRotation = Quaternion.AngleAxis(-mouseLook.y, Vector3.right);
        character.transform.localRotation = Quaternion.AngleAxis(mouseLook.x, character.transform.up);
    }
}

问题根源与修复方案

问题出在mouseLook变量的初始化和相机旋转的同步上:

  1. 原脚本中mouseLook默认是Vector2.zero,若场景内相机初始旋转不是朝前,或启动时读取到鼠标输入的初始偏移,会导致视角被强制拉到错误位置;
  2. 修改版仅设置了相机旋转,但未同步更新mouseLook的初始值,后续鼠标控制会基于错误基准值计算,引发视角异常。

修复方案一:同步初始旋转与变量

让mouseLook初始值匹配相机和角色的初始旋转,确保逻辑与场景状态一致:

using UnityEngine;

public class camMouseLook : MonoBehaviour
{
    Vector2 mouseLook;
    Vector2 smoothV;

    public float sensitivity = 5.0f;
    public float smoothing = 2.0f;

    GameObject character;

    void Start()
    {
        Cursor.lockState = CursorLockMode.Locked;
        character = transform.parent.gameObject;

        // 初始化mouseLook,匹配当前相机和角色的初始旋转
        mouseLook.y = -transform.localEulerAngles.x;
        mouseLook.x = character.transform.localEulerAngles.y;
    }

    void Update()
    {
        MouseLook();
    }

    private void MouseLook()
    {
        var md = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));

        md = Vector2.Scale(md, new Vector2(sensitivity * smoothing, sensitivity * smoothing));
        smoothV.x = Mathf.Lerp(smoothV.x, md.x, 1f / smoothing);
        smoothV.y = Mathf.Lerp(smoothV.y, md.y, 1f / smoothing);
        mouseLook += smoothV;

        mouseLook.y = Mathf.Clamp(mouseLook.y, -90f, 90f);

        transform.localRotation = Quaternion.AngleAxis(-mouseLook.y, Vector3.right);
        character.transform.localRotation = Quaternion.AngleAxis(mouseLook.x, character.transform.up);
    }
}

修复方案二:强制初始朝前

若需强制相机启动时朝向正前方,同时重置mouseLook变量:

using UnityEngine;

public class camMouseLook : MonoBehaviour
{
    Vector2 mouseLook;
    Vector2 smoothV;

    public float sensitivity = 5.0f;
    public float smoothing = 2.0f;

    GameObject character;

    void Start()
    {
        Cursor.lockState = CursorLockMode.Locked;
        character = transform.parent.gameObject;

        // 强制初始视角朝前,同时重置控制变量
        transform.localRotation = Quaternion.Euler(Vector3.zero);
        character.transform.localRotation = Quaternion.Euler(Vector3.zero);
        mouseLook = Vector2.zero;
    }

    void Update()
    {
        MouseLook();
    }

    private void MouseLook()
    {
        var md = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));

        md = Vector2.Scale(md, new Vector2(sensitivity * smoothing, sensitivity * smoothing));
        smoothV.x = Mathf.Lerp(smoothV.x, md.x, 1f / smoothing);
        smoothV.y = Mathf.Lerp(smoothV.y, md.y, 1f / smoothing);
        mouseLook += smoothV;

        mouseLook.y = Mathf.Clamp(mouseLook.y, -90f, 90f);

        transform.localRotation = Quaternion.AngleAxis(-mouseLook.y, Vector3.right);
        character.transform.localRotation = Quaternion.AngleAxis(mouseLook.x, character.transform.up);
    }
}

两种方案均可解决启动时视角朝下的问题,确保初始视角正常,后续鼠标控制逻辑无偏移。

内容的提问来源于stack exchange,提问作者Daniel Lip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 14:26:02