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

为何给实例化的GameObject添加TextMesh后变量仍为空?

问题:为实例化的GameObject添加TextMesh组件显示旋转速度

需求:给每个实例化生成的GameObject添加TextMesh组件,用于显示其旋转速度。

尝试的代码及问题

代码1

private void CreateObject()
{
    Vector3 position = new Vector3(Random.Range(-10f, 10f), Random.Range(-5f, 5f), Random.Range(-10f, 10f));
    GameObject go = Instantiate(objectPrefab, position, Quaternion.identity);
    createdObjects.Add(go);
    rotationSpeeds.Add(Random.Range(minRotationSpeed, maxRotationSpeed));
    rotationTimers.Add(rotationSpeedChangeInterval);
    currentObjectCount++;

    // Add a TextMesh component to display the rotation speed
    TextMesh textMesh = go.GetComponentInChildren<TextMesh>();
    if (textMesh == null)
    {
        textMesh = go.AddComponent<TextMesh>();
    }
    textMesh.text = rotationSpeeds[currentObjectCount - 1].ToString();
    textMesh.anchor = TextAnchor.MiddleCenter;
    textMesh.alignment = TextAlignment.Center;
    textMesh.fontSize = 12;
    textMesh.color = Color.white;
}

问题:执行GetComponentInChildren<TextMesh>()并添加组件后,textMesh变量仍为空。

代码2

private void CreateObject()
{
    Vector3 position = new Vector3(Random.Range(-10f, 10f), Random.Range(-5f, 5f), Random.Range(-10f, 10f));
    GameObject go = Instantiate(objectPrefab, position, Quaternion.identity);
    createdObjects.Add(go);
    rotationSpeeds.Add(Random.Range(minRotationSpeed, maxRotationSpeed));
    rotationTimers.Add(rotationSpeedChangeInterval);
    currentObjectCount++;

    TextMesh textMesh = go.GetComponentInChildren<TextMesh>();
    if (textMesh == null)
    {
        textMesh = go.AddComponent<TextMesh>();
    }

    textMesh = go.GetComponent<TextMesh>();

    textMesh.text = rotationSpeeds[currentObjectCount - 1].ToString();
    textMesh.anchor = TextAnchor.MiddleCenter;
    textMesh.alignment = TextAlignment.Center;
    textMesh.fontSize = 12;
    textMesh.color = Color.white;
}

问题:编辑器抛出异常:

MissingComponentException: There is no 'TextMesh' attached to the "Cube(Clone)" game object, but a script is trying to access it.
You probably need to add a TextMesh to the game object "Cube(Clone)". Or your script needs to check if the component is attached before using it.

问题原因分析

  1. GetComponentInChildren<TextMesh>()默认仅查找活跃状态的子物体组件,如果prefab中存在非活跃的子物体,可能会漏查;另外,若实例化的GameObject结构复杂,可能出现查找逻辑的意外问题。
  2. 代码2中额外调用textMesh = go.GetComponent<TextMesh>()会覆盖之前的赋值,如果AddComponent操作因某些原因未成功(比如GameObject被锁定、组件依赖缺失),就会导致textMesh变为null,触发异常。

解决方案

方案1:确保组件查找和添加的可靠性

修改组件查找逻辑,明确包含非活跃物体,并且直接使用AddComponent的返回值,避免二次查找覆盖:

private void CreateObject()
{
    Vector3 position = new Vector3(Random.Range(-10f, 10f), Random.Range(-5f, 5f), Random.Range(-10f, 10f));
    GameObject go = Instantiate(objectPrefab, position, Quaternion.identity);
    createdObjects.Add(go);
    float currentSpeed = Random.Range(minRotationSpeed, maxRotationSpeed);
    rotationSpeeds.Add(currentSpeed);
    rotationTimers.Add(rotationSpeedChangeInterval);
    currentObjectCount++;

    // 查找当前物体及所有子物体的TextMesh,包含非活跃物体
    TextMesh textMesh = go.GetComponentInChildren<TextMesh>(includeInactive: true);
    if (textMesh == null)
    {
        // 直接在当前物体添加组件,并将返回值赋值给textMesh
        textMesh = go.AddComponent<TextMesh>();
    }

    // 设置TextMesh属性
    textMesh.text = currentSpeed.ToString();
    textMesh.anchor = TextAnchor.MiddleCenter;
    textMesh.alignment = TextAlignment.Center;
    textMesh.fontSize = 12;
    textMesh.color = Color.white;
}

方案2:创建独立子物体放置TextMesh(推荐)

为了避免和原prefab的组件结构冲突,同时防止文本被物体遮挡,专门创建一个子物体来承载TextMesh:

private void CreateObject()
{
    Vector3 position = new Vector3(Random.Range(-10f, 10f), Random.Range(-5f, 5f), Random.Range(-10f, 10f));
    GameObject go = Instantiate(objectPrefab, position, Quaternion.identity);
    createdObjects.Add(go);
    float currentSpeed = Random.Range(minRotationSpeed, maxRotationSpeed);
    rotationSpeeds.Add(currentSpeed);
    rotationTimers.Add(rotationSpeedChangeInterval);
    currentObjectCount++;

    // 创建专门的子物体用于显示文本
    GameObject textObject = new GameObject("RotationSpeedLabel");
    textObject.transform.SetParent(go.transform);
    textObject.transform.localRotation = Quaternion.identity;

    // 调整文本位置到物体上方,避免遮挡
    Renderer renderer = go.GetComponent<Renderer>();
    if (renderer != null)
    {
        float offsetY = renderer.bounds.extents.y + 0.5f;
        textObject.transform.localPosition = new Vector3(0, offsetY, 0);
    }
    else
    {
        textObject.transform.localPosition = Vector3.up;
    }

    // 添加TextMesh组件并设置属性
    TextMesh textMesh = textObject.AddComponent<TextMesh>();
    textMesh.text = currentSpeed.ToString();
    textMesh.anchor = TextAnchor.MiddleCenter;
    textMesh.alignment = TextAlignment.Center;
    textMesh.fontSize = 12;
    textMesh.color = Color.white;
}

说明

  • 方案1适合需要复用现有TextMesh组件的场景;
  • 方案2更灵活,不会影响原物体的组件结构,且文本显示位置更可控,推荐使用。

内容的提问来源于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.19 00:55:11