[英]ScriptableObject not saving data when entering play mode
我有以下可編寫腳本的對象:
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);
}
}
}
這正如我所期望的那樣工作,但是當我進入播放模式時, sprites
字段重置為空,我很確定這與我的自定義編輯器腳本有關,但我嘗試了幾次修復都沒有成功。 包括: serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(target)
我嘗試過的所有其他方法都導致了錯誤。
那么,這里有什么問題,我該如何解決?
看起來精靈被保存為對統一資產的引用,而不是被序列化。 所以看來需要是項目中保存的精靈才可以這樣保存。
這意味着如果您生成一個未存儲在項目中的精靈,那么它將丟失引用,因為它將被存儲在內存中的唯一位置,在開始播放模式時會被擦除。
如果您查看資產文件,您實際上會看到它是如何存儲它的。 如果我在紋理和精靈中拖入圖像,這就是它的外觀。 看到 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。
所以要解決這個問題,您可以將精靈保存到單獨的文件中,或者您可以在開始時生成它們。 類型 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();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.