C# 加载场景时协同路由错误行为
好的,我有一个共同计划:C# 加载场景时协同路由错误行为,c#,unity3d,C#,Unity3d,好的,我有一个共同计划: IEnumerator ShowCharTraits() { while(!hasPlayerChosen) { yield return null; traitPanel.SetActive(true); } hasPlayerChosen = false; traitPanel.SetActive(false); //
IEnumerator ShowCharTraits()
{
while(!hasPlayerChosen)
{
yield return null;
traitPanel.SetActive(true);
}
hasPlayerChosen = false;
traitPanel.SetActive(false);
// Debug.Log("Got called! job done");
}
在myGameManager
中,它是通过唤醒方法这样调用的:
players = GameObject.FindGameObjectsWithTag("Player");
foreach (GameObject g in players)
{
ui_Controller.StartShowCharTraits();
g.GetComponent<PlayerToken>().isTurn = false;
}
现在,我已经检查了标记,没有空引用异常,实际上没有抛出错误或警告。如果我在编辑器中加载场景,然后播放它,一切正常<代码>traitPanel.SetActive(真)代码>呼叫,我的面板显示。但是,当我使用
SceneManager.LoadScene(1)从另一个场景加载场景时代码>从未到达上述行。你知道为什么会这样吗?好的,我该怎么解释呢。我有一个作为数据持有者的单例。在使用GameManager开发场景时,我将singleton附加到GameManager对象,该对象包含一组脚本。现在,当我制作主菜单时,我将我的单件添加到其中,这样我就可以将信息带到游戏场景中,因此我的整个游戏管理器对象被删除。这是来自数据持有者的罪魁祸首:
void Awake()
{
if (instance == null)
instance = this;
else if (instance != this)
Destroy(gameObject);//This right here.
DontDestroyOnLoad(gameObject);
}
因此,我将该行更改为Destroy(gameObject.GetComponent(instance.GetType())代码>假设您希望在Unity项目中有一个“像独生子女一样”的中心位置。例如
SoundEffects
LapTimer
Scores
SocialMediaConnections
你所做的就是这样
制作脚本SoundEffects.cs
回想一下,每个Unity项目都必须有一个“预加载”场景。(不可能没有一个)
在预加载场景中,有一个名为“holder”的空游戏对象。确保其标记为“DontDestroyOnLoad”
将SoundEffects.cs连接到该支架上
你完了
没什么了
你完了
“就这么简单”
所以,任何特定的脚本,在任何特定的场景中,碰巧连接到任何特定的对象,可能需要访问“SoundEffects”
要做到这一点,只需在唤醒状态下执行以下操作:
SoundEffects soundEffects = Object.FindObjectOfType<SoundEffects>();
或者别的什么
团结是简单的。难以置信的简单。就这么简单
写你的脚本,LapTimer.cs
或任何东西
将它放在预加载场景中的一个支架对象上(它还能在哪里?)
没有“3”,这就是全部。就是这么简单
请注意。。。
在Unity的早期,有人不幸地在某个QA板上提到了“单身”。(在ECS系统中不能有“单身”,这是毫无意义的。)当时,这引发了关于如何在Unity中制造“单身般的东西”的巨大讨论,这是一个又一个混乱。不幸的是,从那天起到现在,人们开始学习Unity,他们看到网上到处都提到“singleton”,这导致了无尽的混乱
再一次,请注意,“管理者”的概念在统一性上是不可能简单的——如上所述。这很琐碎。这简直太容易了。
注意,上面我提到,您可能需要语法糖果来避免键入Laps-Laps=Object.FindObjectOfType()的繁琐工作代码>
很不幸,Unity/c中没有宏,因此需要另一种方法
您所要做的就是使用一个在Unity中流行多年的“Grid”脚本
但老实说,使用Scores=Object.FindObjectOfType()非常简单
我现在通常就是这么做的。你能告诉我哪一行没有被呼叫吗?你能至少做一个debug.log来检查协程是否工作吗?我能告诉你哪一行没有被调用。我已经回答了我自己的问题。问题是让我们换一个地方说。我已经给你一个激动人心的答案@uripopov!单身汉?在Unity dude里没有单身汉。你不可能真的拥有它们。在C#中,你可以吗?我在音乐控制器中使用了一个@JoeBlow wait我的脚本保证DataHolder对象只有一个实例,这难道不是使它成为一个单例吗?在Unity中,保证场景中只有一个给定组件是绝对不可能的。在Unity这样的ECS系统中,试图制造“类似于单例的东西”是完全没有意义的。这就像说你希望photoshop场景中的像素或文本编辑器场景中的字母是。。。“单身人士”。这没什么意义,谢谢你一如既往的回答。我已经在做了。在我的第一个场景中,有一个对象是DontDestroyOnLoad()。问题来自于这样一个事实,即连接到它的数据持有者查看是否存在它的任何其他实例,并在它进入场景时销毁它们。这导致另一个保存特定场景脚本的对象被销毁,因为不幸的是,它在测试中附加了一个DataHolder实例。因此,发生的情况是,一个脚本的Awake()正在调用角色的协同程序,而在运行时,来自DataHodler的Awake正在删除整个objectMy主菜单场景。问题是我忘记了另一个场景中游戏对象上的数据保持器组件。该游戏对象正在从主菜单场景的数据保持器中销毁。场景的相同游戏对象帮助脚本。这就是为什么所有东西都坏了。在主菜单上来回走动不是问题。我已经通过改变数据保持器的唤醒()解决了我的问题。我不知道如何更好地解释发生了什么。让我们来看看。
SoundEffects soundEffects = Object.FindObjectOfType<SoundEffects>();
Laps laps = Object.FindObjectOfType<Laps>();
Social social = Object.FindObjectOfType<Social>();
AI ai = Object.FindObjectOfType<AI>();