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里每帧读写文件不仅性能拉胯,还会出现数据不同步的问题,绝对是下下策。直接引用脚本实例(最简单高效)
- 把管理血量的脚本里的
health字段设为公开:public int health; // 原脚本里的血量字段,改成public - 红屏控制脚本里直接引用血量脚本,不用碰文件:
// 拖拽绑定你的血量管理脚本所在的GameObject public HealthManager healthManager; public GameObject redScreenEffect; void Update() { if (healthManager.health <= 600) { redScreenEffect.SetActive(true); } else { if (redScreenEffect.activeInHierarchy) { redScreenEffect.SetActive(false); } } }
- 把管理血量的脚本里的
事件驱动(解耦更优雅)
如果不想让两个脚本直接绑定(比如后期要改结构),可以用事件通知状态变化:- 血量管理脚本里定义事件:
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); } } - 红屏控制脚本订阅事件:
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
相关产品推荐
相关产品推荐

