Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unity3d 可脚本化对象在重命名时对父/子对象重新排序_Unity3d_Scriptable Object - Fatal编程技术网

Unity3d 可脚本化对象在重命名时对父/子对象重新排序

Unity3d 可脚本化对象在重命名时对父/子对象重新排序,unity3d,scriptable-object,Unity3d,Scriptable Object,我是如何做到这一点的:我一直在开发一个工具,该工具使用具有子脚本对象的脚本对象。系统运行得非常好,但是当我重命名时,父/子关系在统一中中断 我现在已经设法把这归结为一个非常简单的案例研究 使用下面的代码,您可以创建一个容器SO资产。然后使用MyMenu创建容器的子级数据。所有这些都按预期进行,项目中的关系如下: 容器->数据 但是,一旦您将容器重命名为其他名称,Unity将对父-子对象重新排序,使数据现在为父对象,容器为子对象: 数据->容器 下面是应该复制此问题的代码(Unity 2020.1

我是如何做到这一点的:我一直在开发一个工具,该工具使用具有子脚本对象的脚本对象。系统运行得非常好,但是当我重命名时,父/子关系在统一中中断

我现在已经设法把这归结为一个非常简单的案例研究

使用下面的代码,您可以创建一个容器SO资产。然后使用MyMenu创建容器的子级数据。所有这些都按预期进行,项目中的关系如下:

容器->数据

但是,一旦您将容器重命名为其他名称,Unity将对父-子对象重新排序,使数据现在为父对象,容器为子对象:

数据->容器

下面是应该复制此问题的代码(Unity 2020.1.17f1-在2020.1.8上也有相同的结果)

Container.cs

using UnityEngine;

[CreateAssetMenu]
public class Container : ScriptableObject
{
}
using UnityEngine;

public class Data : ScriptableObject
{
}
using UnityEditor;
using UnityEngine;

public class CustomEditor : Editor
{
    [MenuItem("MyMenu/Create Data for Container")]
    static void CreateDataForContainer()
    {
        Container container = Selection.activeObject as Container;
        if (container != null)
        {
            Data data = ScriptableObject.CreateInstance(typeof(Data)) as Data;
            data.name = data.GetType().Name;
            if (!string.IsNullOrEmpty(AssetDatabase.GetAssetPath(container)))
            {
                AssetDatabase.AddObjectToAsset(data, container);
            }
            AssetDatabase.SaveAssets();
        }
    }
}
Data.cs

using UnityEngine;

[CreateAssetMenu]
public class Container : ScriptableObject
{
}
using UnityEngine;

public class Data : ScriptableObject
{
}
using UnityEditor;
using UnityEngine;

public class CustomEditor : Editor
{
    [MenuItem("MyMenu/Create Data for Container")]
    static void CreateDataForContainer()
    {
        Container container = Selection.activeObject as Container;
        if (container != null)
        {
            Data data = ScriptableObject.CreateInstance(typeof(Data)) as Data;
            data.name = data.GetType().Name;
            if (!string.IsNullOrEmpty(AssetDatabase.GetAssetPath(container)))
            {
                AssetDatabase.AddObjectToAsset(data, container);
            }
            AssetDatabase.SaveAssets();
        }
    }
}
CustomEditor.cs

using UnityEngine;

[CreateAssetMenu]
public class Container : ScriptableObject
{
}
using UnityEngine;

public class Data : ScriptableObject
{
}
using UnityEditor;
using UnityEngine;

public class CustomEditor : Editor
{
    [MenuItem("MyMenu/Create Data for Container")]
    static void CreateDataForContainer()
    {
        Container container = Selection.activeObject as Container;
        if (container != null)
        {
            Data data = ScriptableObject.CreateInstance(typeof(Data)) as Data;
            data.name = data.GetType().Name;
            if (!string.IsNullOrEmpty(AssetDatabase.GetAssetPath(container)))
            {
                AssetDatabase.AddObjectToAsset(data, container);
            }
            AssetDatabase.SaveAssets();
        }
    }
}
注释

  • 起初我认为这是名称空间的问题,但事实并非如此
  • 我认为这可能是一个程序集问题,但现在基本类的情况并非如此
  • 关闭/打开项目结果相同
  • 重命名后,资产文件相同

如果你有过这样的经历,我很想知道我做错了什么,我的工具几乎完成了,这阻止了我把它推出去。谢谢

Unity端的Bug修复:


我对编辑器脚本不太了解,但查看文档,他们建议重新导入已更改的资产,以使用
AssetDatabase.importaset(AssetDatabase.GetAssetPath(data))提交更改AssetDatabase.SaveAssets()在最后保存并使资产可供使用。(如果不存在保存,子数据将不会显示在编辑器中)。@Ruzihm从您发布的线程看,似乎他们对未显示有问题。现在它会出现,但出于某种原因,Unity决定将子组件作为主要资产,将主要资产作为子资产。它还将子部件的名称更改为新名称,并在主部件变为子部件时保留旧名称(希望这有意义)。我还尝试了
AssetDatabase.AddObjectToAsset(数据,AssetDatabase.GetAssetPath(容器))
@Ruzihm看起来像是刚在一个新版本中修复好的,将要进行测试。