【问题标题】:How to assign TextAssets to a scene gameobject via editor script?如何通过编辑器脚本将 TextAssets 分配给场景游戏对象?
【发布时间】:2019-07-22 20:31:36
【问题描述】:

我有一个带有关卡的场景。这个场景有 1000 个级别。它的关卡有一个TextAsset。我想运行一个 EditorScript 并通过脚本而不是通过将 1.000 个 TextAssets 拖放到场景中来分配这些 TextAssets。然后自动保存场景。

Scene mainScene = SceneManager.GetSceneByName("Main");
GameObject[] gameObjects = mainScene.GetRootGameObjects();
GameManager gameManager = gameObjects[0].GetComponent<GameManager>();
List<LanguageCategory> languageCategories = new List<LanguageCategory>();
LanguageCategoryPackInfo l1 = new LanguageCategoryPackInfo();
l1.displayName = "t1";
LanguageCategoryPackInfo l2 = new LanguageCategoryPackInfo();
l2.displayName = "t2";
languageCategories.Add(l1);
languageCategories.Add(l2);
gameManager.LanguageCategoryPackInfos = languageCategories;
//do the same assignment again, but with no luck
mainScene.GetRootGameObjects()[0].GetComponent<GameManager>().LanguageCategoryPackInfos = languageCategories;
EditorSceneManager.SaveScene(mainScene);

运行上述代码后,场景似乎没有改变。

【问题讨论】:

    标签: unity3d unity3d-editor unity-editor


    【解决方案1】:

    直接在组件中进行一些更改的问题不会将其标记为dirty,因此不会保存更改! (另见SerializedObject 中的解释和下面的解决方案。)

    您可以使用EditorUtility.SetDirty 手动执行此操作。如前所述,您应该始终将其与首先调用 Undo.RecordObject 结合使用。

    如果您不关心撤消/重做功能,您也可以简单地使用EditorSceneManager.MarkSceneDirty

    Scene mainScene = SceneManager.GetSceneByName("Main");
    GameObject[] gameObjects = mainScene.GetRootGameObjects();
    GameManager gameManager = gameObjects[0].GetComponent<GameManager>();
    
    List<LanguageCategory> languageCategories = new List<LanguageCategory>();
    
    LanguageCategoryPackInfo l1 = new LanguageCategoryPackInfo();
    l1.displayName = "t1";
    LanguageCategoryPackInfo l2 = new LanguageCategoryPackInfo();
    l2.displayName = "t2";
    languageCategories.Add(l1);
    languageCategories.Add(l2);
    
    // record an undo point
    Undo.RecordObject(gameManager, "languages added");
    gameManager.LanguageCategoryPackInfos = languageCategories;
    // mark the object dirty so it will be saved
    EditorUtility.SetDirty(gameManager);
    
    // or simply directly
    EditorSceneManager.MarkSceneDirty();
    EditorSceneManager.SaveScene(mainScene);
    

    作为替代方案,尽管它更复杂,但始终建议转而使用 SerializedObjectSerializedPropertys,它们会自动为您处理所有标记 dirty 和撤消/重做功能。

    Scene mainScene = SceneManager.GetSceneByName("Main");
    GameObject[] gameObjects = mainScene.GetRootGameObjects();
    GameManager gameManager = gameObjects[0].GetComponent<GameManager>();
    
    SerializedObject serializedObject = new SerializedObject(gameManager);
    
    SerializedProperty languageCategories = serializedObject.FindProperty("LanguageCategoryPackInfos");
    
    // load the current real values into the serializedObject
    serializedObject.Update();
    
    languageCategories.arraySize = 2;
    
    SerializedProperty l1 = languageCategories.GetArrayElementAtIndex(0);
    l1.FindPropertyRelative("displayName").stringValue = "t1";
    SerializedProperty l2 = languageCategories.GetArrayElementAtIndex(1);
    l2.FindPropertyRelative("displayName").stringValue= "t2";
    
    // writes the changes bakc to the actual properties and marks them as dirty etc
    serializedObject.ApplyModifiedProperties();
    
    EditorSceneManager.SaveScene(mainScene);
    

    注意:在智能手机上打字所以没有保修,但我希望这个想法能清楚

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-24
      • 2022-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多