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

Unity中.GetComponent获取StripeNum变量值异常为0的问题

问题描述

StripeNum脚本挂载在按钮对象上,点击红色按钮时,Debug.Log显示stripe1的值为20;但在FinalCalc脚本中,通过GetComponent<StripeNum>()获取该变量时,Debug.Log显示stripe1.stripe1的值为0。两个脚本引用的是同一个游戏对象(该对象同时作为按钮的载体)。

相关代码:

StripeNum.cs

using UnityEngine;

public class StripeNum : MonoBehaviour
{
    public void black()
    {
        stripe1 = 0;
    }
    public void brown()
    {
        stripe1 = 10;
    }
    public void red()
    {
        stripe1 = 20;
        Debug.Log(stripe1);
    }
    public void orange()
    {
        stripe1 = 30;
    }
    public void yellow()
    {
        stripe1 = 40;
    }
    public void green()
    {
        stripe1 = 50;
    }
    public void blue()
    {
        stripe1 = 60;
    }
    public void purple()
    {
        stripe1 = 70;
    }
    public void grey()
    {
        stripe1 = 80;
    }
    public void white()
    {
        stripe1 = 90;
    }
    public float stripe1;
}

FinalCalc.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class FinalCalc : MonoBehaviour
{
    Scene c_scene;
    float TwoStripesAdded;
    float FinalR;
    public Text FinalNum;

        
    void Start(){
        c_scene = SceneManager.GetActiveScene();
        GameObject gameobject =  GameObject.Find("GameObject");
        StripeNum stripe1 = gameobject.GetComponent<StripeNum>();
        Stripe2Num stripe2 = gameobject.GetComponent<Stripe2Num>();
        Stripe3Num stripe3 = gameobject.GetComponent<Stripe3Num>();
        Stripe4Num stripe4 = gameobject.GetComponent<Stripe4Num>();

        if (c_scene.buildIndex == 6){
            
            TwoStripesAdded = stripe1.stripe1 + stripe2.stripe1;
            Debug.Log($"Added {stripe1.stripe1} and {stripe2.stripe1} and got {TwoStripesAdded}");
            FinalR = TwoStripesAdded * stripe3.stripe1;
            
            
            FinalNum.text = FinalR.ToString() + "Ω " + "±" + stripe4.stripe1 + "%";
        }
    }
    
}
问题原因与解决方法

核心原因

FinalCalc的Start()方法在场景加载完成时立即执行,而你点击红色按钮修改stripe1的操作是在Start执行之后发生的,所以此时获取到的是变量的初始默认值0。

解决方法

方法1:延迟计算,通过按钮触发

不在Start()里直接计算,而是在用户完成所有颜色选择后,通过一个“计算”按钮触发计算逻辑:
修改FinalCalc脚本,新增公开方法并绑定到按钮点击事件:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class FinalCalc : MonoBehaviour
{
    Scene c_scene;
    float TwoStripesAdded;
    float FinalR;
    public Text FinalNum;
    // 提前缓存组件引用,避免重复查找
    private StripeNum stripe1;
    private Stripe2Num stripe2;
    private Stripe3Num stripe3;
    private Stripe4Num stripe4;

    void Start(){
        c_scene = SceneManager.GetActiveScene();
        GameObject gameobject =  GameObject.Find("GameObject");
        stripe1 = gameobject.GetComponent<StripeNum>();
        stripe2 = gameobject.GetComponent<Stripe2Num>();
        stripe3 = gameobject.GetComponent<Stripe3Num>();
        stripe4 = gameobject.GetComponent<Stripe4Num>();
    }

    // 新增方法,绑定到计算按钮的点击事件
    public void CalculateFinalValue(){
        if (c_scene.buildIndex == 6){
            TwoStripesAdded = stripe1.stripe1 + stripe2.stripe1;
            Debug.Log($"Added {stripe1.stripe1} and {stripe2.stripe1} and got {TwoStripesAdded}");
            FinalR = TwoStripesAdded * stripe3.stripe1;
            
            FinalNum.text = FinalR.ToString() + "Ω " + "±" + stripe4.stripe1 + "%";
        }
    }
}

方法2:实时监听值变化,自动更新结果

如果需要用户点击颜色按钮时立即更新结果,可以给条纹脚本添加事件通知机制:
首先修改StripeNum脚本(Stripe2Num、Stripe3Num、Stripe4Num同理修改):

using UnityEngine;
using UnityEngine.Events;

public class StripeNum : MonoBehaviour
{
    // 定义值变化事件
    public UnityEvent<float> OnStripeValueChanged;

    public void black()
    {
        UpdateStripeValue(0);
    }
    public void brown()
    {
        UpdateStripeValue(10);
    }
    public void red()
    {
        UpdateStripeValue(20);
    }
    // 其他颜色方法同理替换为UpdateStripeValue调用
    
    private void UpdateStripeValue(float value){
        stripe1 = value;
        Debug.Log(stripe1);
        // 触发事件通知订阅者
        OnStripeValueChanged?.Invoke(value);
    }

    public float stripe1;
}

然后修改FinalCalc脚本监听事件:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class FinalCalc : MonoBehaviour
{
    Scene c_scene;
    float TwoStripesAdded;
    float FinalR;
    public Text FinalNum;
    private StripeNum stripe1;
    private Stripe2Num stripe2;
    private Stripe3Num stripe3;
    private Stripe4Num stripe4;

    void Start(){
        c_scene = SceneManager.GetActiveScene();
        GameObject gameobject =  GameObject.Find("GameObject");
        stripe1 = gameobject.GetComponent<StripeNum>();
        stripe2 = gameobject.GetComponent<Stripe2Num>();
        stripe3 = gameobject.GetComponent<Stripe3Num>();
        stripe4 = gameobject.GetComponent<Stripe4Num>();

        // 订阅所有条纹的值变化事件
        stripe1.OnStripeValueChanged.AddListener(UpdateFinalValue);
        stripe2.OnStripeValueChanged.AddListener(UpdateFinalValue);
        stripe3.OnStripeValueChanged.AddListener(UpdateFinalValue);
        stripe4.OnStripeValueChanged.AddListener(UpdateFinalValue);

        // 初始计算一次
        if (c_scene.buildIndex == 6){
            UpdateFinalValue(0);
        }
    }

    private void UpdateFinalValue(float _){
        if (c_scene.buildIndex != 6) return;
        
        TwoStripesAdded = stripe1.stripe1 + stripe2.stripe1;
        Debug.Log($"Added {stripe1.stripe1} and {stripe2.stripe1} and got {TwoStripesAdded}");
        FinalR = TwoStripesAdded * stripe3.stripe1;
        
        FinalNum.text = FinalR.ToString() + "Ω " + "±" + stripe4.stripe1 + "%";
    }

    // 取消订阅避免内存泄漏
    void OnDestroy(){
        stripe1.OnStripeValueChanged.RemoveListener(UpdateFinalValue);
        stripe2.OnStripeValueChanged.RemoveListener(UpdateFinalValue);
        stripe3.OnStripeValueChanged.RemoveListener(UpdateFinalValue);
        stripe4.OnStripeValueChanged.RemoveListener(UpdateFinalValue);
    }
}

额外优化建议

  • 避免使用GameObject.Find("GameObject"),可以直接在Inspector面板拖拽赋值目标对象,减少性能开销且更可靠。
  • StripeNum、Stripe2Num等脚本结构高度重复,可以合并为一个通用脚本,通过参数区分不同条纹,减少代码冗余。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 22:50:41