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

Unity中如何从其他脚本读取变量?低血触发红屏实现需求

解决Unity低血量红屏激活的优化方案

我想在玩家血量较低时,激活一个带有循环动画的红屏GameObject(动画自动播放,只需激活对象即可)。之前尝试把血量值写入文本文件,再用另一个脚本读取的方式实现,但这个方案既不优化也无法正常运行,我的代码如下:

第一个脚本代码:

public void CreateText()
{
    string path = Application.dataPath + "/Datas/data";
    if (!File.Exists(path))
    {
        File.WriteAllText(path, "" + health);
    }
    else
    {
        File.Delete(path);
        File.WriteAllText(path, "" + health);
    }
}

另一脚本代码:

public int health = 1000;
public string health0;
public string path = Application.dataPath + "/Datas/data";
public GameObject healthbar;

void Update()
{
    Int32.TryParse(health0, out health);
    File.ReadLines(path);
    if (health <= 600)
    {
        healthbar.SetActive(true);
    }
    else
    {
        if (healthbar.activeInHierarchy == true)
        {
            healthbar.SetActive(false);
        }
    }
}

优化方案及问题修复

  • 彻底抛弃文件读写方案
    用文件传递跨脚本数据完全没必要,Update里每帧读写文件不仅性能拉胯,还会出现数据不同步的问题,绝对是下下策。

  • 直接引用脚本实例(最简单高效)

    1. 把管理血量的脚本里的health字段设为公开:
      public int health; // 原脚本里的血量字段,改成public
      
    2. 红屏控制脚本里直接引用血量脚本,不用碰文件:
      // 拖拽绑定你的血量管理脚本所在的GameObject
      public HealthManager healthManager; 
      public GameObject redScreenEffect;
      
      void Update()
      {
          if (healthManager.health <= 600)
          {
              redScreenEffect.SetActive(true);
          }
          else
          {
              if (redScreenEffect.activeInHierarchy)
              {
                  redScreenEffect.SetActive(false);
              }
          }
      }
      
  • 事件驱动(解耦更优雅)
    如果不想让两个脚本直接绑定(比如后期要改结构),可以用事件通知状态变化:

    1. 血量管理脚本里定义事件:
      using UnityEngine.Events;
      
      public class HealthManager : MonoBehaviour
      {
          public int health;
          // 血量变化时触发的事件
          public UnityEvent<int> OnHealthChanged;
      
          void Awake()
          {
              // 初始化事件
              OnHealthChanged ??= new UnityEvent<int>();
          }
      
          // 假设这是你修改血量的方法,每次血量变化都调用这个
          public void ChangeHealth(int delta)
          {
              health += delta;
              // 通知所有订阅者血量变了
              OnHealthChanged.Invoke(health);
          }
      }
      
    2. 红屏控制脚本订阅事件:
      public class RedScreenController : MonoBehaviour
      {
          public GameObject redScreenEffect;
          public HealthManager healthManager;
      
          void OnEnable()
          {
              // 订阅血量变化事件
              healthManager.OnHealthChanged.AddListener(CheckHealthState);
          }
      
          void OnDisable()
          {
              // 取消订阅,防止内存泄漏
              healthManager.OnHealthChanged.RemoveListener(CheckHealthState);
          }
      
          // 血量变化时检查是否要激活红屏
          void CheckHealthState(int currentHealth)
          {
              redScreenEffect.SetActive(currentHealth <= 600);
          }
      }
      
  • 原代码的问题(仅作参考,不推荐用)
    你原代码读文件的部分根本没把内容赋值给health0,所以永远读不到正确的血量。修改如下,但还是不建议用:

    void Update()
    {
        if (File.Exists(path))
        {
            // 读取文件内容到health0
            health0 = File.ReadAllText(path);
            Int32.TryParse(health0, out health);
        }
        // 后面的激活逻辑不变
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 13:10:23