【发布时间】:2020-11-24 21:05:45
【问题描述】:
抱歉,如果我再次提出与代表相关的愚蠢问题... 我会尽量准确。 我有这种情况: 对象 A + 脚本 A, 对象 B、D、E... + 脚本 B。 脚本 B 有一个委托,并且应该通过作为订阅者的脚本 A 在对象 A 中触发反应。 例如
public class ScriptA : MonoBehaviour
{
void Start() {
FindObjectOfType<ScriptB>().onScriptBEvent += DoSomethingInA;
}
void DoSomethingInA (string s, float q) {
print("String: "+s+"; Float: "+q);
}
}
和
public class ScriptB : MonoBehaviour
{
public delegate void ScriptBDelegate(string name, float q);
public event ScriptBDelegate onScriptBEvent;
void Start() {
}
void RandomMethodInB (string s, float q) {
if(onScriptBEvent != null){
onScriptBEvent (s, q);
}
}
}
但它不起作用。 添加一些 Debug 代码我注意到尽管订阅了脚本 A,但 onScriptBEvent 没有通过无效测试。
在我的程序中,我已经编写了许多其他代表,并且每个代表都工作得很好。 我尝试将脚本 A 订阅给其他代表,他们工作得很好。 我看到的唯一区别是脚本 B 被添加到许多对象(B、C、D..)中,而其他带有委托的脚本总是被实例化一次。
有什么提示吗?
将解决方案编辑为 Ruzihm: 问题是 FindObjectOfType 找到第一个实例化的对象,不一定是发送消息的对象。 最简单的解决方案(对我来说)是创建一个脚本 B 数组,然后订阅它们中的每一个:
public class ScriptA : MonoBehaviour
{
private ScriptB[] scriptList = new ScriptB[100];
void Start() {
scriptList = FindObjectOfType<ScriptB>();
foreach (var script in scpritList){
script.onScriptBEvent += DoSomethinInA;
}
}
void DoSomethingInA (string s, float q) {
print("String: "+s+"; Float: "+q);
}
}
它有效!
【问题讨论】:
-
你有
OnScriptBEvent和onScriptBEvent,只是大小写不同。这是一个错字,还是你两者都有?如果两者兼而有之,则您没有订阅要解雇的那个。 -
听起来您没有通过
FindObjectOfType<ScriptB>()获得您正在寻找的实例。 ^ 哦,好收获 -
@madreflection 这只是一个例子
-
@Ruzihm 是的!这就是问题!太简单!在每个实例化的脚本 B 中,我无法找到正确的发送消息的人!我该如何解决?
-
ScriptA 的 Start 运行后是否正在实例化 B?如果没有,只需遍历
FindObjectsOfType<ScriptB>()的结果并将委托附加到每个onScriptBEvent