公共静态 Dictionary<String,GameObject> 中的游戏对象在 Unity 中的场景更改时被销毁
Posted
技术标签:
【中文标题】公共静态 Dictionary<String,GameObject> 中的游戏对象在 Unity 中的场景更改时被销毁【英文标题】:GameObjects in a public static Dictionary<String,GameObject> are destroyed on scene changes in Unity 【发布时间】:2017-06-23 12:23:53 【问题描述】:第一次正式声明: 编程语言:Unity 中的 C#(MonoBehavior) 我的技能水平:有点菜鸟(不到半年的 c# 经验)。
我正在制作一个方块破坏游戏(Arkanoid)并且正在制作一个成就系统。游戏是一次性的,当您关闭网络构建时,所有内容都会被删除(没有缓存,没有文件保存,没有可序列化的类)。
成就系统包含: “成就”类:很多变量和一些跟踪进度的方法。它附加到具有相同名称的空游戏对象的脚本。普通班。
“AManager”类。初始化“成就”类的一堆副本的类,给它们单独的值并将它们添加到下面提到的字典中。辛格尔顿班。
“AcheivementDictionary”类:只包含私有静态字典和访问方法。也是单例类
问题:
成就是在第一个场景的“开始”时制作和添加的。添加它们后,我检索游戏对象并测试它们的标签是否有效,一切都很好。然后从我的“levelManager”类中,我从下一个场景调用相同的方法,并收到一条消息,即游戏对象已被销毁。如果我测试它们,它们也会返回 null。
所以...我真正的问题是:
如何使我的成就游戏对象的实例化副本在 Unity 中的所有场景更改中持续存在?
代码参考:
我不认为“成就”是有任何问题的类,如果您需要该类的代码,只需大声疾呼。
“经理”
public class Amanager : MonoBehaviour
public static Amanager acheivementManager = null;
public GameObject myAchObject;
void Awake ()
if (acheivementManager != null)
Destroy(gameObject);
else
acheivementManager = this;
GameObject.DontDestroyOnLoad(gameObject);
void Start ()
myAchObject.AddComponent<Acheivement>();
initAcheivements ("completeLevelThree", "Level 3", "Complete level 3","Level", 3,5);
initAcheivements ("completeLevelOne", "Level 1", "Complete level 1","Level", 1,5);
private void initAcheivements(string inAch, string inNavn, string inHow, string inCountType, int goalVal, int Reward)
Vector3 loc = new Vector3 (0f, 0f,0f);
GameObject testAch;
testAch = Instantiate(myAchObject, loc, Quaternion.identity) as GameObject;
//testLives.SetActive (true);
//testLives.gameObject.tag = "clone";
testAch.GetComponent<Acheivement>().setName(inNavn);
testAch.GetComponent<Acheivement>().setHowToGet(inHow);
testAch.GetComponent<Acheivement>().setCountType(inCountType);
testAch.GetComponent<Acheivement>().setGoalVal(goalVal);
testAch.GetComponent<Acheivement>().setReward(Reward);
testAch.tag = inCountType;
Debug.Log ("InitiAch did run");
AcheivementDictionary._Instance.achRegAdder(inNavn,testAch);
成就词典代码:
public class AcheivementDictionary : MonoBehaviour
public static AcheivementDictionary _Instance;
private static Dictionary<string,GameObject> AchReg = new Dictionary<string,GameObject>();
void Awake ()
if (_Instance != null)
Destroy(gameObject);
else
_Instance = this;
GameObject.DontDestroyOnLoad(gameObject);
public void achRegAdder (string inName, GameObject theAch)
AchReg.Add(inName,theAch);
Debug.Log ("achRegAdded did run");
readThisString = inName;
tryRead = true;
private void readIt()
Debug.Log ("readItRan");
GameObject testShit;
AchReg.TryGetValue("Level 1",out testShit);
Debug.Log("if it works level should stand there ---> " + testShit.tag);
tryRead = false;
public void achRegReader ()
readIt ();
运行时,控制台中会出现以下消息:
initAch 确实运行了
achRegAdded 确实运行了
initAch 确实运行了
achRegAdded 确实运行了
readItRan
如果它工作水平应该站在那里 ---> 水平
readitRan
MissingReferenceException:“GameObject”类型的对象已被销毁,但您仍在尝试访问它。您的脚本应该检查它是否为空,或者您不应该销毁对象。
(这个错误是在尝试访问存储对象的标签时出现的,并发生在以下方法调用中:Debug.Log("如果它工作级别应该站在那里 ---> " + testShit.tag);)
这是用于在 achRegReader 失败时调用的代码行(来自另一个类): AcheivementDictionary._Instance.achRegReader();
另外:如果我计算字典中对象的数量,它确实返回 2。它们只是被破坏了,我真的不明白为什么。我的程序中没有任何代码可以破坏这些。
我的猜测是这样的:
关于在 Singelton 类中放置静态字典有一些我不明白的问题。 Acheivements 的实例化副本不会在场景中持续存在,因为它们不是 dontDestroyOnLoad,即使处理它们的两个类都是。 无论哪种方式,在过去的 6 个小时的斗争中,我都没有设法隔离或解决问题,请帮助!
【问题讨论】:
忘了提一下:我在所有场景变化上都调用了“读取”消息。我在进行初始化的开始菜单中没有收到任何错误消息,但之后在所有场景加载时我都会收到相同的错误消息。 我的猜测是场景变化之类的东西会破坏游戏对象。尝试在initAcheivements
中添加testAch.transform.parent = transform;
成功了,我爱你!另外...为什么它起作用了?我怎么给你解决它的功劳,我没有看到“他解决了这个问题”按钮:D
您的问题是实例化的对象从未被告知 DontDestroyOnLoad,只有实例化它们的对象。您要么必须在实例化对象上调用 DontDestroyOnLoad,要么使它们成为您使用 DontDestroyOnLoad 的初始对象的子对象,如 Bijan 建议的那样。
太好了,谢谢 :) 我在遗产方面还有很多东西要学!我确实尝试过(非常努力地)对实例化对象进行 dontDestroyOnLoad,但他们不会听到它。即使它们只在上面一行被制作成 GameObjects,他们仍然说我不能在 Objects 上使用“DontDestroyOnLoad”,并且我不能显式或隐式地将我的“Object”转换为“GameObject”(甚至认为它是一个 GameObject 开头)。
【参考方案1】:
在 initAcheivements 函数中,要么
testAch.transform.setParent(transform);
或
DontDestroyOnLoad(testAch);
您的问题是由于 testAch 不是不会被销毁的对象的子对象,或者 testAch 不是不会被销毁的对象本身。
针对您的评论,我迅速编写了这段代码,它没有给我任何问题,我可能遗漏了什么吗?
Vector3 loc = new Vector3(0f, 0f, 0f);
var testAch = Instantiate(myAchObject, loc, Quaternion.identity) as GameObject;
DontDestroyOnLoad(testAch);
【讨论】:
以上是关于公共静态 Dictionary<String,GameObject> 中的游戏对象在 Unity 中的场景更改时被销毁的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Dictionary<string, string> 变量从后面的代码传递到 asp.net?
将 [Dictionary<String,Any?>] 转换为 [Dictionary<String,Any!>] ?迅速 3
如何在 C# 中将 Dictionary<string, object> 转换为 Dictionary<string, string>
如何将 List<Dictionary<string, byte[]> 对象添加到 Dictionary<string, byte[]> [重复]
检查 List<Dictionary<string,object>> 中是不是存在 Dictionary<string,object>? [关闭]