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

Unity中ScreenToWorldPoint失效问题求助

解决2D游戏中ScreenToWorldPoint失效导致枪不跟随鼠标的问题

1. 修正ScreenToWorldPoint的Z轴设置逻辑

你当前的代码顺序完全错误:先调用ScreenToWorldPoint再修改z值,等于白改。ScreenToWorldPoint需要传入的Vector3的z分量来计算世界坐标(代表相机到目标平面的距离),而不是修改返回结果。

修改代码如下:

void Update()
{
    if (!IsOwner) return;
    
    // 先构建包含正确Z值的屏幕坐标
    Vector3 mouseScreenPos = Input.mousePosition;
    // Z值取相机与枪所在位置的Z轴距离绝对值(确保转换到枪的平面)
    mouseScreenPos.z = Mathf.Abs(Camera.main.transform.position.z - transform.position.z);
    // 再执行坐标转换
    Vector3 mousePosition = Camera.main.ScreenToWorldPoint(mouseScreenPos);
    
    Vector2 direction = mousePosition - transform.position;
    float angle = Vector2.SignedAngle(Vector2.right, direction);
    transform.eulerAngles = new Vector3(0, 0, angle);
    
    // 射击逻辑保持不变...
}

2. 确保Camera.main在联机场景中有效

多人场景下Camera.main可能失效(比如存在多个相机、未标记MainCamera标签),建议直接引用玩家相机:

[SerializeField] private Camera playerCamera;

public override void OnNetworkSpawn()
{
    base.OnNetworkSpawn();
    characterTransform = transform.parent;
    //  fallback到Camera.main,避免空引用
    if(playerCamera == null) playerCamera = Camera.main;
}

之后把所有Camera.main替换为playerCamera,确保每个客户端用自己的相机计算。

3. 修复联机场景下的初始化时机

Start()可能在网络对象同步完成前执行,导致transform.parent获取错误。改用NetworkBehaviour的OnNetworkSpawn()方法初始化:

public override void OnNetworkSpawn()
{
    base.OnNetworkSpawn();
    characterTransform = transform.parent;
    if(playerCamera == null) playerCamera = Camera.main;
}

这能保证对象在网络生成完成后再获取父对象,避免位置计算错误。

4. 调试验证坐标转换结果

添加日志确认转换后的坐标是否正确:

Debug.Log($"屏幕坐标:{Input.mousePosition} → 世界坐标:{mousePosition}");

如果输出的世界坐标始终是相机中心,说明相机引用错误或者Z值计算仍有问题。

内容的提问来源于stack exchange,提问作者Tom Gaillard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 18:33:11