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

如何在多个GameObject上复用同一张WebCamTexture?

解决Unity中WebCamTexture无法在多个GameObject上渲染的问题

首先,先指出你代码里的一个小疏漏:你定义了cameraNumber变量,但实际创建WebCamTexture时用的是devices[0],没有用到这个参数,先把这个小问题修正,避免后续混淆。

回到核心问题:你遇到的并不是“单个WebCamTexture只能被一个GameObject渲染”的限制——Unity的WebCamTexture是可以被多个材质共享的,问题出在材质实例化和纹理赋值的方式上。当你直接给Renderer.material.mainTexture赋值时,Unity会自动为该GameObject创建一个材质实例(防止修改原始材质资源),但如果多个物体没有正确关联到同一个纹理实例,或者Shader没有正确采样纹理,就会出现只有一个物体显示的情况。

下面提供两种可行的解决方案:

方案一:使用全局管理类统一控制纹理和渲染目标

创建一个专门的管理脚本,负责初始化WebCamTexture,并将其赋值给所有需要显示的物体。这种方式更易于维护,尤其适合多个物体需要共享同一相机画面的场景。

using UnityEngine;

public class CameraFeedManager : MonoBehaviour
{
    public int cameraNumber = 0;
    public Renderer[] targetRenderers; // 在Inspector中拖入所有需要显示相机画面的物体的Renderer组件
    private WebCamTexture _webcamTexture;

    void Start()
    {
        WebCamDevice[] devices = WebCamTexture.devices;
        if (devices.Length <= cameraNumber)
        {
            Debug.LogError($"No camera found with index {cameraNumber}");
            return;
        }

        // 初始化WebCamTexture
        _webcamTexture = new WebCamTexture(devices[cameraNumber].name, 1280, 720);
        
        // 为每个目标Renderer创建独立的材质实例并赋值纹理
        foreach (Renderer renderer in targetRenderers)
        {
            // 复制原有材质的属性,避免修改原始材质资源
            Material materialInstance = new Material(renderer.material);
            materialInstance.mainTexture = _webcamTexture;
            renderer.material = materialInstance;
        }

        _webcamTexture.Play();
    }

    void OnDestroy()
    {
        // 销毁纹理,释放相机资源
        if (_webcamTexture != null)
        {
            _webcamTexture.Stop();
            Destroy(_webcamTexture);
        }
    }
}

使用步骤:

  1. 创建一个空GameObject,将这个脚本挂载上去。
  2. 在Inspector面板中,把你的两个半球和测试平面的Renderer组件拖入targetRenderers数组。
  3. 设置正确的cameraNumber,运行测试。

方案二:在每个显示物体的脚本中复用全局WebCamTexture

如果你不想用管理类,可以将WebCamTexture设为静态变量,让所有挂载该脚本的物体共享同一个纹理实例,同时为每个物体创建独立的材质实例。

using UnityEngine;

public class CameraDisplay : MonoBehaviour
{
    public int cameraNumber = 0;
    private static WebCamTexture _sharedWebcamTexture;

    void Start()
    {
        // 仅在第一次初始化时创建纹理
        if (_sharedWebcamTexture == null)
        {
            WebCamDevice[] devices = WebCamTexture.devices;
            if (devices.Length <= cameraNumber)
            {
                Debug.LogError($"No camera found with index {cameraNumber}");
                return;
            }

            _sharedWebcamTexture = new WebCamTexture(devices[cameraNumber].name, 1280, 720);
            _sharedWebcamTexture.Play();
        }

        // 为当前物体创建材质实例并赋值共享纹理
        Material materialInstance = new Material(GetComponent<Renderer>().material);
        materialInstance.mainTexture = _sharedWebcamTexture;
        GetComponent<Renderer>().material = materialInstance;
    }

    void OnDestroy()
    {
        // 确保只有最后一个销毁的物体释放相机资源
        if (_sharedWebcamTexture != null && FindObjectsOfType<CameraDisplay>().Length == 1)
        {
            _sharedWebcamTexture.Stop();
            Destroy(_sharedWebcamTexture);
        }
    }
}

额外排查点

如果以上方案仍未解决问题,需要检查你的自定义Shader:

  • 确保Shader中使用了正确的纹理属性名(默认是_MainTex,对应mainTexture)。
  • 切换到Unity内置的Standard Shader测试,如果Standard Shader能正常显示,说明你的自定义Shader在纹理采样上存在问题,需要检查采样逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:41:48