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

Unity 2023中射线检测命中对象时相机跳动问题求助

Unity 2023相机跳动问题:Raycast命中特定Layer时相机异常抖动

我在Unity 2023中遇到问题:从玩家相机视角发射基础Raycast,当命中特定Layer的目标时,相机无故发生跳动。有其他用户也遇到相同问题,现象可对应参考相关视频的43秒处。

PlayerViewTrigger脚本

public static PlayerViewTrigger Instance { get; private set; }

[SerializeField] private Transform viewTriggerPos;
private bool eleanorCamp;

private void Awake()
{
    if (Instance != null && Instance != this) { Destroy(this); }
    else { Instance = this; }
}

private void Update()
{
    ViewTrigger();
}

private void ViewTrigger()
{
    if (Physics.Raycast(viewTriggerPos.position, viewTriggerPos.TransformDirection(Vector3.forward), out RaycastHit hit, 50f))
    {
        if (hit.collider.CompareTag("EleanorCamp") && !eleanorCamp)
        {
            eleanorCamp = true;
            SceneManager_02_Camp.Instance.EleanorSpot();
        }
    }
}

SceneManager脚本

public void EleanorSpot()
{
    BackgroundAudio.Instance.audioDarkForest.Play();
    horrorAudioSource1.PlayOneShot(horrorAudioClip1);
    Invoke("HideEleanor", 3f);

    jessyWaterDialogTrigger.SetActive(false);
    jessyWaterDialogStartTrigger.SetActive(false);
}

private void HideEleanor()
{
    horrorAudioSource2.PlayOneShot(horrorAudioClip2);
    fireParticles.SetActive(false);

    eleanor.SetActive(false);
    eleanorTrigger = false;

    Invoke("JessyScream1", 5f);
}

private void JessyScream1()
{
    ShowJessy(5);
    jessy_bathroom1_AudioSource.PlayOneShot(jessy_scream1_AudioClip);
    JessyGoesToBathroom_LimitMovementTrigger.SetActive(false);
    Invoke("HenryShout1", .8f);
}

private void HenryShout1()
{
    PlayerSounds.Instance.voiceAudioSource.PlayOneShot(PlayerSounds.Instance.jessyBathroom_2);
    JessyGoesToBathroom_Scream2.SetActive(true);
}

相机旋转代码

private void PlayerCameraRotate()
{
    rotationXAxis += Input.GetAxis(mouseYInput) * cameraSensitivity * Time.deltaTime;
    rotationYAxis += Input.GetAxis(mouseXInput) * cameraSensitivity * Time.deltaTime;

    rotationXAxis = Mathf.Clamp(rotationXAxis, -upDownLookRange, upDownLookRange + 20f);

    hand.rotation = Quaternion.Euler(-rotationXAxis, rotationYAxis, 0f);

    transform.localRotation = Quaternion.Lerp(transform.localRotation, Quaternion.Euler(0f, rotationYAxis, 0f), cameraAcceleration * Time.deltaTime);
    playerCamera.localRotation = Quaternion.Lerp(playerCamera.localRotation, Quaternion.Euler(-rotationXAxis, 0f, 0f), cameraAcceleration * Time.deltaTime);
}

问题排查与修复方案

可能的触发原因

  • Raycast触发的后续逻辑中,存在修改相机旋转参数(如cameraSensitivity、cameraAcceleration)的代码,导致插值速度突变
  • HideEleanor()中直接关闭对象的SetActive(false),如果对象Collider与玩家/相机有物理交互,会引发物理引擎瞬间计算异常
  • Raycast未限制检测Layer,可能误触其他带有物理组件的对象,间接影响相机
  • 相机旋转的Lerp逻辑中,rotationXAxis/rotationYAxis被意外重置或修改

快速修复尝试

  1. 限制Raycast检测范围:给Raycast添加LayerMask,只检测目标Layer,避免误触其他对象
// 在PlayerViewTrigger中添加
[SerializeField] private LayerMask targetLayer;

// 修改ViewTrigger中的Raycast调用
if (Physics.Raycast(viewTriggerPos.position, viewTriggerPos.TransformDirection(Vector3.forward), out RaycastHit hit, 50f, targetLayer))
  1. 避免直接关闭对象引发物理异常:在关闭eleanor前先禁用其Collider
// 修改HideEleanor方法
private void HideEleanor()
{
    horrorAudioSource2.PlayOneShot(horrorAudioClip2);
    fireParticles.SetActive(false);

    // 先禁用Collider再关闭对象
    if(eleanor.TryGetComponent<Collider>(out var col))
        col.enabled = false;
    eleanor.SetActive(false);
    eleanorTrigger = false;

    Invoke("JessyScream1", 5f);
}
  1. 锁定相机参数:在EleanorSpot触发时,强制重置相机旋转相关参数为初始值,避免突变
// 提前在相机脚本中保存初始参数
private float originalSensitivity;
private float originalAcceleration;

private void Start()
{
    originalSensitivity = cameraSensitivity;
    originalAcceleration = cameraAcceleration;
}

// 在SceneManager的EleanorSpot中添加调用(需要获取相机脚本引用)
public void EleanorSpot()
{
    // 重置相机参数
    CameraController.Instance.cameraSensitivity = CameraController.Instance.originalSensitivity;
    CameraController.Instance.cameraAcceleration = CameraController.Instance.originalAcceleration;

    BackgroundAudio.Instance.audioDarkForest.Play();
    horrorAudioSource1.PlayOneShot(horrorAudioClip1);
    Invoke("HideEleanor", 3f);

    jessyWaterDialogTrigger.SetActive(false);
    jessyWaterDialogStartTrigger.SetActive(false);
}

内容的提问来源于stack exchange,提问作者Damian Budzak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 03:44:55