【问题标题】:Making instantiated objects permanent and making game objects... disappear forever in Unity使实例化对象永久化并使游戏对象...在 Unity 中永久消失
【发布时间】:2018-09-06 13:05:08
【问题描述】:

我编写了一个脚本,在 Start() 上的场景中随机位置生成(实例化)随机游戏对象。但是我有两个问题:

  1. 如果我改变场景并返回,实例化对象不再存在,即它们不是永久的。如何使它们像我通过 Unity 编辑器放置在场景中的那些对象一样永久保存?我不是在谈论dontdestroyonload,它将对象保留在所有场景中并且从不破坏它们。

  2. 我的 spawn 脚本,我只想在第一次加载场景时运行一次,但每次我进入场景时都会运行,即使我在脚本中添加了一行会破坏脚本和父游戏对象。我希望它运行一次并永远消失。如何做到这一点?

【问题讨论】:

    标签: unity3d instance gameobject


    【解决方案1】:

    使用PlayerPrefs保存位置然后读取:

    //Write
    PlayerPrefs.SetFloat("PlayerX", player.transform.position.x);
    PlayerPrefs.SetFloat("PlayerY", player.transform.position.y);
    PlayerPrefs.SetFloat("PlayerZ", player.transform.position.z)
    
    //Read
    var x = PlayerPrefs.GetFloat("PlayerX");
    var y = PlayerPrefs.GetFloat("PlayerY");
    var z = PlayerPrefs.GetFloat("PlayerZ");
    
    //Apply
    Vector3 posVec = new Vector3(x,y,z);
    player.transform.position = posVec;
    

    【讨论】:

    • 您好,感谢您的帮助。添加一些说明,我需要在运行时生成对象,并且对象应该永久保留在那里,因此当玩家更改场景并返回时,对象仍然存在。就像说我在洞穴中生成了一个怪物,当玩家回来时怪物应该在那里。但如果我理解正确,玩家偏好将是:怪物在所有保存游戏中都呆在那里?怪物只需要在他们各自的存档游戏中呆在那里,就像所有其他事情一样。
    【解决方案2】:

    您可以将ExecuteInEditMode 属性添加到您的班级。如果您不希望在加载场景时执行它的逻辑 - 用if(!Application.isPlaying) 包围这个逻辑。

    话虽如此 - 我宁愿制作一个编辑器工具、一个检查器按钮、一个上下文菜单 - 在我看来,任何类似的东西都会更好。

    【讨论】:

      【解决方案3】:

      为什么要在离开场景时保留对象?获得 Unity Editor Extension 来生成随机对象不是更容易吗?然后,您可以随时生成对象并将它们保存到场景中。

      如果您使用编辑器扩展,您也不必担心 Start()。

      编辑: 根据您的 cmets,您似乎需要一个保存/加载系统,您在离开场景时存储生成对象的 ID 和位置,然后在返回场景时将其加载回。无法将运行时场景另存为场景文件,因为它已编译到游戏数据中。

      最简单的方法是从资产商店获取系统,并且基于您自称的缺乏经验,这可能是您的最佳选择。

      否则,您将不得不自己制作。这个问题回答了如何做到这一点: What is the best way to save game state?

      总结那里所说的内容:您必须创建一个允许您将数据保存到文件的类。这可以通过使用 Unity 中的 BinaryFormatter 来完成。尽管还有更多选项,例如 XML。

      【讨论】:

      • 我解决了问题 #2,但问题 #1 仍然存在。添加一些说明,我需要在运行时生成对象,并且对象应该永久保留在那里,因此当玩家更改场景并返回时,对象仍然存在。就像说我在洞穴中生成了一个怪物,当玩家回来时怪物应该在那里。目前我的怪物产生了,但是当我回到现场时,它们已经消失了。我想将它们永久保存在保存游戏中,我不知道该怎么做,我是一个完全的菜鸟。我查看了 playerprefs,但不确定这是否是正确的解决方案。
      • 我编辑了我的答案,其中包含指向另一个涵盖相同问题的问题的链接。您要做的基本上是将所有要保存的对象放在一个列表中,然后将对象 ID 分配给使用的不同预制件,获取所有对象的位置并将该数据保存到文件中。
      • 谢谢,我会调查的。
      【解决方案4】:

      我会在您的资产中创建一个 JSON 文件,其中包含一个 JsonArray,其中每个对象及其场景、文件路径和位置/旋转。每次切换到一个新文件时,它都会循环遍历所有文件,如果它来自的场景不是存储的场景,它就不会存储它。如果是,则解析其中的 json 对象并放置一个具有位置和旋转设置的新对象。

      如果没有意义,这里有一些伪代码:

      加载:

      jsonArray = parseJsonArray
      
      foreach Json object inside of jsonArray
      
        if object["scene"] = currentscene
      
           intantiate new object and set properties to properties that are parsed by the json file
      

      保存:

      Convert Array of all of the gameObjects to jsonArray
      
      Write Json Array => json file
      

      【讨论】:

        【解决方案5】:

        这似乎是解决方案:

        public static void UnpackPrefabInstance(GameObject instanceRoot, PrefabUnpackMode unpackMode, InteractionMode action);    
        

        来自:https://docs.unity3d.com/ScriptReference/PrefabUtility.UnpackPrefabInstance.html

        【讨论】:

        • 请贴出带有四个空格的代码以正确格式化。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-25
        • 2016-06-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多