纳金网

标题: [问答分享]脚本-无法保存编辑后的自定义asset [打印本页]

作者: 铁锹    时间: 2012-11-23 15:19
标题: [问答分享]脚本-无法保存编辑后的自定义asset
我想做一个texture atlas编辑器,首先我创建一个自定义的atlas asset,它派生自ScriptableObject。然后创建一个空的atlas asset,然后打开编辑器对这个atlas asset进行编辑,编辑完后都没问题,问题出在每次重启Unity后atlas asset都呈现出未修改过的状态,就是说上次在编辑器中做的操作都没有保存下来。我用二进制查看了atlas asset在硬盘中的文件,发现在整个修改过程中,asset文件都没有更改过,也就是说对asset的修改没有被保存回硬盘。



我已经试过 EditorUtility.SetDirty(target);AssetDatabase.Refresh();AssetDatabase.SaveAssets() 但都没有用。下面是我的一些代码摘录。





自定义的atlas asset



    //////ScriptableObject Class////////
    [System.Serializable]
    public s***ct TextureAtlasItem
    {
        public string     _fileName;    // PNG file name
        public Rect       _uv;          // uv coordinate in Atlas
        public TextureAtlasItem(string path, string fileName, Rect uv)
        {
            _fileName = fileName;
            _uv       = uv;
        }
    }
    [System.Serializable]
    public class TextureAtlas :ScriptableObject
    {
        pirvate Dictionary<string, TextureAtlasItem> _atlasItems;
        private  Texture2D  _atlas;
        private bool       _isInit = false;
    ...
    ...
    ...
    }






一个Inspector Window,用来预览和创建atlas asset



    [CustomEditor(typeof(TextureAtlas))]
    public class AtlasInspector : Editor
    {
     
        // Create a Atlas asset in selection folder and named newAtlas.asset.
        [MenuItem("MyTools/Atlas")]
        static public void CreateNewAtlas()
        {
            TextureAtlas newAtlas = ScriptableObject.CreateInstance<TextureAtlas>();
            AssetDatabase.CreateAsset(newAtlas, GetSelectionPath() + "newAtlas.asset");
        }
     
        private void OpenAtlasWindowEditor()
        {
            AtlasWindowEditor windowEditor = EditorWindow.GetWindow(typeof(AtlasWindowEditor)) as AtlasWindowEditor;
            windowEditor.title = "Atlas Editor";
            windowEditor.Init(target as TextureAtlas);
     
            string assetPath = AssetDatabase.GetAssetPath(target);
            string[] tmpList = assetPath.Split('/');
            assetPath = string.Join("/", tmpList, 0, tmpList.Length - 1);
        }
     
        // save the asset
        private void Save()
        {
            EditorUtility.SetDirty(target);
            AssetDatabase.Refresh();
            AssetDatabase.SaveAssets();
        }
    ...
    ...
    ...
    }






一个EditorWindow,修改选中的asset


    public class AtlasWindowEditor : EditorWindow
    {
        private TextureAtlas  _currentAtlas;
        private Texture2D     _atlasTexture;
        private Vector2       _atlasTextureSize;
        private Texture2D     _selectedTexture;
        private int           _selectedSize;
        private List<Texture2D>  _atlasTextureList;
        private bool          _isInit;
        private string        _selectedFolder;
     
       // pass the target asset to editor window
       public void Init(TextureAtlas atlas)
        {
            _currentAtlas = atlas;
            _atlasTexture = atlas.AtlasTexutre2D;
            _atlasTextureSize.x = _atlasTexture.width;
            _atlasTextureSize.y = _atlasTexture.height;
            _selectedSize       = (int)_atlasTextureSize.y;
            
            // Get all the texuture
            int textureNum = atlas.TextureNum;
            _atlasTextureList = new List<Texture2D>();
     
            foreach (Texture2D item in atlas.FindTexture())
            {
                _atlasTextureList.Add(item);
            }
            _isInit = ***e;
        }
    ...
    ...
    }



————————————————————————————————————————

解答:

问题出在没有把private的字段设置为SerializeField。

默认情况下private的字段不会被序列化,public字段会被序列化。我的类中所有的字段都是private,所以虽然设置了setdirty,但还是没有被存储。



Unity中可以使用[SerializeField] 或[NonSerialized]来控制要进行序列化的字段。所以我只要将private字段前加上[SerializeField]进能正常进行存储了。(更多3D纳金网http://www.narkii.com/ )







作者: 铁锹    时间: 2012-11-23 15:23
这个很给力的。




欢迎光临 纳金网 (http://go.narkii.com/club/) Powered by Discuz! X2.5