#if UNITY_EDITOR
using System;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEditor;
using System.IO;
namespace Utilities {
public abstract class ScriptableObjectCreator : SerializedScriptableObject where T : ScriptableObject, new() {
protected abstract string SavePath { get; }
protected abstract void AdditionalInitialization(T obj);
protected abstract bool AdditionalValidation();
protected abstract void AdditionalReset();
[ShowInInspector, PropertyOrder(0)]
public string Name { get; set; }
T _item;
[ShowInInspector, PropertyOrder(1), InlineEditor, HideReferenceObjectPicker]
public T item {
get => _item;
set { }
}
void OnEnable() {
AdditionalReset();
_item = CreateInstance();
_item.name = "New";
Name = "";
}
[Button, PropertyOrder(99)]
protected void CreateAsset() {
if (!AdditionalValidation()) { return; }
string path = "";
if (!SavePath.StartsWith("Assets/")) { path += "Assets/"; }
path += SavePath;
if (!SavePath.EndsWith("/")) { path += "/"; }
path += Name;
path += ".asset";
Debug.Log($"Create {Name} at: {path}...");
if (!IsInputValid(path)) { return; }
var obj = item;
AdditionalInitialization(obj);
AssetDatabase.CreateAsset(obj, path);
EditorUtility.SetDirty(obj);
Debug.Log($"{Name} successfully created as {path}");
LastCreatedAsset = obj;
OnEnable();
}
[SerializeField, HideInInspector] T LastCreatedAsset;
[Button, PropertyOrder(100), PropertySpace]
void GoToLastCreatedAsset() {
if (LastCreatedAsset != null) {
ProjectWindowUtil.ShowCreatedAsset(LastCreatedAsset);
}
else { Debug.Log("Last created asset cannot be found."); }
}
#region Path Validation Logic
bool IsInputValid(string path) {
if (!IsStringValid(SavePath, Path.GetInvalidPathChars())) {
Debug.Log("Wrong Save Path");
return false;
}
if (!IsStringValid(Name, Path.GetInvalidFileNameChars())) {
Debug.Log("Wrong Name");
return false;
}
if (!AssetDatabase.IsValidFolder(SavePath)) {
Debug.Log("Wrong Folder");
return false;
}
if (UnityEngine.Windows.File.Exists(path)) {
Debug.Log("File already exists");
return false;
}
return true;
}
bool IsStringValid(string s, char[] invalidCharacters) {
if (String.IsNullOrWhiteSpace(s)) {return false; }
foreach (var character in invalidCharacters) {
if (s.Contains(character.ToString())) {
Debug.Log(character);
return false;
}
}
if (s.Contains(".")) { return false; }
return true;
}
#endregion
}
}
#endif