我有以下可编写脚本的对象:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CreateAssetMenu(fileName = "Data", menuName = "ScriptableObjects/SpawnManagerScriptableObject", order = 1)]
public class Style : ScriptableObject
{
public Texture2D[] textures;
public Sprite[] sprites;
public AnimationCurve animationCurve;
Sprite[] MakeSprites(Texture2D[] baseTextures){
Sprite[] output = new Sprite[baseTextures.Length];
for (int i = 0; i < baseTextures.Length; i++)
{
output[i] = MakeSprite(baseTextures[i]);
}
return output;
}
Sprite MakeSprite(Texture2D baseTexture)
{
Sprite sprite = Sprite.Create(baseTexture, new Rect(0, 0, baseTexture.width, baseTexture.height), new Vector2(baseTexture.width / 2f, baseTexture.height / 2f), Mathf.Max(baseTexture.width, baseTexture.height));
return sprite;
}
public void UpdateSprites()
{
sprites = MakeSprites(textures);
}
}
[CustomEditor(typeof(Style))]
public class customStyleEditor : Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
Style style = (Style) target;
if (GUILayout.Button("Update Sprites"))
{
style.UpdateSprites();
EditorUtility.SetDirty(target);
}
}
}
这如我所期望的那样工作,但是当我进入play模式时,sprites
字段重置为空,我很确定这与我的自定义编辑器脚本有关,但是我尝试了几次修复,但都没有成功。包括:serializedObject.ApplyModifiedProperties();
,EditorUtility.SetDirty(target)
,我尝试过的其他一切都导致了一个错误。
那么,这里的问题是什么,我该如何解决呢?
发布于 2022-05-28 20:40:49
看起来,精灵被保存为对统一资产的引用,而不是序列化。因此,它似乎需要是一个保存在项目中的雪碧,以这种方式保存它。
这意味着,如果生成一个没有存储在项目中的sprite,那么它将失去引用,因为它将存储在内存中,而内存在启动播放模式时会被擦除。
如果您查看资产文件,您将看到它是如何存储的。这就是如果我在纹理和精灵中拖拽图像的样子。确保guid和fileId都是相同的,并引用它在项目中的图像。(这将在播放模式和编辑模式之间进行维护)
textures:
- {fileID: 2800000, guid: e8a45d89f3b96e44e82022b97a4860a3, type: 3}
- {fileID: 2800000, guid: e8a45d89f3b96e44e82022b97a4860a3, type: 3}
sprites:
- {fileID: 21300000, guid: e8a45d89f3b96e44e82022b97a4860a3, type: 3}
- {fileID: 21300000, guid: e8a45d89f3b96e44e82022b97a4860a3, type: 3}
但是,当我运行所提供的代码并保存它时,将保存以下内容:
textures:
- {fileID: 2800000, guid: e8a45d89f3b96e44e82022b97a4860a3, type: 3}
- {fileID: 2800000, guid: e8a45d89f3b96e44e82022b97a4860a3, type: 3}
sprites:
- {fileID: 0}
- {fileID: 0}
它不是拯救雪碧,而是一种不存在的对它的引用。当该对象在内存重置后不再存在时,它现在有一个丢失的引用,该引用将被转换为null。
因此,要解决这个问题,您可以保存sprites以分离文件,也可以只在开始时生成它们。sprite类型不能正确序列化,因此如果您想要缓存它,就必须将它存储在不同的数据类型中。
这就是如何在项目中保存精灵缓存的方法。请注意,您必须对精灵做一些管理,以确保旧的被删除。
Sprite[] MakeSprites(Texture2D[] baseTextures){
Sprite[] output = new Sprite[baseTextures.Length];
for (int i = 0; i < baseTextures.Length; i++)
{
output[i] = MakeSprite(baseTextures[i]);
}
//Now save the sprites to the project
List<Sprite> savedSprites = new List<Sprite>();
foreach (Sprite sprite in output)
{
//Create a sprite name, make sure it's prefixed with Assets/ as the assetDatabase won't like it otherwise
string spriteName = "Assets/" + Guid.NewGuid().ToString() + ".asset";
//Create the asset
AssetDatabase.CreateAsset(sprite, spriteName);
//Load the asset back in so we have a reference to the asset that exists in the project and not the reference to the sprite in memory
Sprite newSavedSprite = (Sprite)AssetDatabase.LoadAssetAtPath(spriteName, typeof(Sprite));
savedSprites.Add(newSavedSprite);
}
return savedSprites.ToArray();
}
https://stackoverflow.com/questions/72418762
复制相似问题