- 最后登录
- 2022-10-8
- 注册时间
- 2010-12-6
- 阅读权限
- 100
- 积分
- 14150
  
- 纳金币
- 76544
- 精华
- 23
|
我想做一个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/ )
|
|