Added scriptable objects architecture pack
https://assetstore.unity.com/packages/tools/utilities/scriptableobject-architecture-131520
This commit is contained in:
parent
da88241204
commit
749c390161
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4e0fc3cb1c477c34bbbeea156de76c38
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a55c02bbd97ff0740995575a3e48ed89
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,4 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
|
||||
// Expose internal members to editor assembly for inspectors, other editor windows or functions
|
||||
[assembly: InternalsVisibleTo("ScriptableObject-Architecture.Editor")]
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e00e4c8cc9a36d34e974afdacc9e034f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2aa6d979e0421eb49a4d097f166ef439
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,6 @@
|
|||
using System;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class MultiLine : Attribute
|
||||
{
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f8d8a61d6b1b0ba458f5398006ca7fb0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f74279b4ac40f2144bcc976992eb6214
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "AnimationCurveCollection.asset",
|
||||
menuName = SOArchitecture_Utility.ADVANCED_VARIABLE_COLLECTION + "AnimationCurve",
|
||||
order = 120)]
|
||||
public class AnimationCurveCollection : Collection<AnimationCurve>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7ad7f20ff642cbc418ac6531143b174e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: c5b62729a840f56448ed99e6fee68b6e, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "AudioClipCollection.asset",
|
||||
menuName = SOArchitecture_Utility.ADVANCED_VARIABLE_COLLECTION + "AudioClip",
|
||||
order = 120)]
|
||||
public class AudioClipCollection : Collection<AudioClip>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d289013f46a3b234986332177bde3edf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: f305724bfe41a0241b47fbc4efcdd6d6, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,34 @@
|
|||
using System.Collections;
|
||||
using Type = System.Type;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
public abstract class BaseCollection : SOArchitectureBaseObject, IEnumerable
|
||||
{
|
||||
public object this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return List[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
List[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Count { get { return List.Count; } }
|
||||
|
||||
public abstract IList List { get; }
|
||||
public abstract Type Type { get; }
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return List.GetEnumerator();
|
||||
}
|
||||
public bool Contains(object obj)
|
||||
{
|
||||
return List.Contains(obj);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c80fa5d349585dd45bc2532a8744c5af
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "BoolCollection.asset",
|
||||
menuName = SOArchitecture_Utility.COLLECTION_SUBMENU + "bool",
|
||||
order = SOArchitecture_Utility.ASSET_MENU_ORDER_COLLECTIONS + 5)]
|
||||
public class BoolCollection : Collection<bool>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 916693505e56c0e458b96d6de46fec18
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: d4d11961dbf1cc64bae0ef7f13dc0ed7, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "ByteCollection.asset",
|
||||
menuName = SOArchitecture_Utility.ADVANCED_VARIABLE_COLLECTION + "byte",
|
||||
order = SOArchitecture_Utility.ASSET_MENU_ORDER_COLLECTIONS + 6)]
|
||||
public class ByteCollection : Collection<byte>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c80696004aaeefd4581c66b60262ce40
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 824f6df5e20a8e54ebdcf1293a4d1783, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "CharCollection.asset",
|
||||
menuName = SOArchitecture_Utility.ADVANCED_VARIABLE_COLLECTION + "char",
|
||||
order = SOArchitecture_Utility.ASSET_MENU_ORDER_COLLECTIONS + 7)]
|
||||
public class CharCollection : Collection<char>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: bfe6b2c3c89b7f44bbd064c0c24da0b5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: ab7acc2ba41f8d24597f973d09b3a13b, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,86 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
public class Collection<T> : BaseCollection, IEnumerable<T>
|
||||
{
|
||||
public new T this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return _list[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
_list[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private List<T> _list = new List<T>();
|
||||
|
||||
public override IList List
|
||||
{
|
||||
get
|
||||
{
|
||||
return _list;
|
||||
}
|
||||
}
|
||||
public override Type Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return typeof(T);
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(T obj)
|
||||
{
|
||||
if (!_list.Contains(obj))
|
||||
_list.Add(obj);
|
||||
}
|
||||
public void Remove(T obj)
|
||||
{
|
||||
if (_list.Contains(obj))
|
||||
_list.Remove(obj);
|
||||
}
|
||||
public void Clear()
|
||||
{
|
||||
_list.Clear();
|
||||
}
|
||||
public bool Contains(T value)
|
||||
{
|
||||
return _list.Contains(value);
|
||||
}
|
||||
public int IndexOf(T value)
|
||||
{
|
||||
return _list.IndexOf(value);
|
||||
}
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
_list.RemoveAt(index);
|
||||
}
|
||||
public void Insert(int index, T value)
|
||||
{
|
||||
_list.Insert(index, value);
|
||||
}
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
return _list.GetEnumerator();
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return "Collection<" + typeof(T) + ">(" + Count + ")";
|
||||
}
|
||||
public T[] ToArray() {
|
||||
return _list.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 86767a9f6ab228c4ea5db8d47a39b046
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "Color32Collection.asset",
|
||||
menuName = SOArchitecture_Utility.COLLECTION_SUBMENU + "Structs/Color32",
|
||||
order = 120)]
|
||||
public class Color32Collection : Collection<Color32>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ff2975a5cdeda4a4ea898a97a00b1245
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 1067bbf7144445045982a772e570db4c, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "ColorCollection.asset",
|
||||
menuName = SOArchitecture_Utility.COLLECTION_SUBMENU + "Structs/Color",
|
||||
order = 120)]
|
||||
public class ColorCollection : Collection<Color>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b70196d7b105d854286b774167fa3a58
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 1067bbf7144445045982a772e570db4c, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "DoubleCollection.asset",
|
||||
menuName = SOArchitecture_Utility.ADVANCED_VARIABLE_COLLECTION + "double",
|
||||
order = SOArchitecture_Utility.ASSET_MENU_ORDER_COLLECTIONS + 8)]
|
||||
public class DoubleCollection : Collection<double>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ddebc6dac1a8f914b9b59d5ebb3f8dd1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: a7e3ab68e5b9b2d4796e3a138b43e81b, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "FloatCollection.asset",
|
||||
menuName = SOArchitecture_Utility.COLLECTION_SUBMENU + "float",
|
||||
order = SOArchitecture_Utility.ASSET_MENU_ORDER_COLLECTIONS + 3)]
|
||||
public class FloatCollection : Collection<float>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0c34b51965a63624385c5d47f4ac333f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 090c91e3b1c62cd4188ca24b83260a43, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "GameObjectCollection.asset",
|
||||
menuName = SOArchitecture_Utility.COLLECTION_SUBMENU + "GameObject",
|
||||
order = SOArchitecture_Utility.ASSET_MENU_ORDER_COLLECTIONS + 0)]
|
||||
public class GameObjectCollection : Collection<GameObject>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 156f4052644faf645bba864aa1fd4e16
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 016eddd7ec2347a41b4b265778d9501d, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "IntCollection.asset",
|
||||
menuName = SOArchitecture_Utility.COLLECTION_SUBMENU + "int",
|
||||
order = SOArchitecture_Utility.ASSET_MENU_ORDER_COLLECTIONS + 4)]
|
||||
public class IntCollection : Collection<int>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: dba6f7bc1140ccb439039e265858770b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: f3ef3e85511a9cd4f8868d3a7c752bd4, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "LongCollection.asset",
|
||||
menuName = SOArchitecture_Utility.ADVANCED_VARIABLE_COLLECTION + "long",
|
||||
order = SOArchitecture_Utility.ASSET_MENU_ORDER_COLLECTIONS + 9)]
|
||||
public class LongCollection : Collection<long>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ceacfe10610defb42b3dea63dcaaa5e9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: dfebd677c27ca5543b6ffa552f8f4538, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "ObjectCollection.asset",
|
||||
menuName = SOArchitecture_Utility.COLLECTION_SUBMENU + "Object",
|
||||
order = SOArchitecture_Utility.ASSET_MENU_ORDER_COLLECTIONS + 1)]
|
||||
public class ObjectCollection : Collection<Object>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 294e8bbb40af68441a293e00fdc5548b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 1a7cfceb598958d4588af67b5592b54f, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "QuaternionCollection.asset",
|
||||
menuName = SOArchitecture_Utility.COLLECTION_SUBMENU + "Structs/Quaternion",
|
||||
order = SOArchitecture_Utility.ASSET_MENU_ORDER_COLLECTIONS + 13)]
|
||||
public class QuaternionCollection : Collection<Quaternion>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 376c15839ad34eb4788c493b6b34c89d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 039e9190b2371d84ab3d8c3b9ce65380, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "SByteCollection.asset",
|
||||
menuName = SOArchitecture_Utility.ADVANCED_VARIABLE_COLLECTION + "sbyte",
|
||||
order = SOArchitecture_Utility.ASSET_MENU_ORDER_COLLECTIONS + 15)]
|
||||
public class SByteCollection : Collection<sbyte>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 800757c0caa7c454caae4475e6d601c0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 00bbbbfeeb8421343be2a4d0325288ca, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,13 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "SceneCollection.asset",
|
||||
menuName = SOArchitecture_Utility.ADVANCED_VARIABLE_COLLECTION + "Scene",
|
||||
order = 120)]
|
||||
public class SceneCollection : Collection<SceneInfo>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: baec154247b223d4a9b1afe90aa2cf2c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 2914869b4bf78e2498ede5504e93b705, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "ShortCollection.asset",
|
||||
menuName = SOArchitecture_Utility.ADVANCED_VARIABLE_COLLECTION + "short",
|
||||
order = SOArchitecture_Utility.ASSET_MENU_ORDER_COLLECTIONS + 14)]
|
||||
public class ShortCollection : Collection<short>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f1b528d0c64418e479123029aeae7230
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: c0a478b6dd67927488ed74dba04f5eb2, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "StringCollection.asset",
|
||||
menuName = SOArchitecture_Utility.COLLECTION_SUBMENU + "string",
|
||||
order = SOArchitecture_Utility.ASSET_MENU_ORDER_COLLECTIONS + 2)]
|
||||
public class StringCollection : Collection<string>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fb12e3ad1486e2e4496d2933bc2e5456
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: f3400829b3bc23a4a87d7b8bf425bfd3, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "UIntCollection.asset",
|
||||
menuName = SOArchitecture_Utility.ADVANCED_VARIABLE_COLLECTION + "uint",
|
||||
order = SOArchitecture_Utility.ASSET_MENU_ORDER_COLLECTIONS + 16)]
|
||||
public class UIntCollection : Collection<uint>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b2ece7577c39e6d42b87c39735ed0bcb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 87156f2d93700f84a8a38e414e8d312f, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "ULongCollection.asset",
|
||||
menuName = SOArchitecture_Utility.ADVANCED_VARIABLE_COLLECTION + "ulong",
|
||||
order = SOArchitecture_Utility.ASSET_MENU_ORDER_COLLECTIONS + 17)]
|
||||
public class ULongCollection : Collection<ulong>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: db08965a2cf1822409af7548df816116
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: dfebd677c27ca5543b6ffa552f8f4538, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "UShortCollection.asset",
|
||||
menuName = SOArchitecture_Utility.ADVANCED_VARIABLE_COLLECTION + "ushort",
|
||||
order = SOArchitecture_Utility.ASSET_MENU_ORDER_COLLECTIONS + 18)]
|
||||
public class UShortCollection : Collection<ushort>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 68f8f730ac4eb7a46b32e0c3319ab540
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 2716b51a57087c34db2b9b6fa1523f93, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "Vector2Collection.asset",
|
||||
menuName = SOArchitecture_Utility.COLLECTION_SUBMENU + "Structs/Vector2",
|
||||
order = SOArchitecture_Utility.ASSET_MENU_ORDER_COLLECTIONS + 10)]
|
||||
public class Vector2Collection : Collection<Vector2>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d06ceb6f5b9494247a47b2b9639f1fa4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 8cbf47eb8d6a6734799ebc975a1ed553, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "Vector3Collection.asset",
|
||||
menuName = SOArchitecture_Utility.COLLECTION_SUBMENU + "Structs/Vector3",
|
||||
order = SOArchitecture_Utility.ASSET_MENU_ORDER_COLLECTIONS + 11)]
|
||||
public class Vector3Collection : Collection<Vector3>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2a166c222ab884c40a383e3d630076e1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 14d8d52dcb7b258409d4f6447738836e, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "Vector4Collection.asset",
|
||||
menuName = SOArchitecture_Utility.COLLECTION_SUBMENU + "Structs/Vector4",
|
||||
order = SOArchitecture_Utility.ASSET_MENU_ORDER_COLLECTIONS + 12)]
|
||||
public class Vector4Collection : Collection<Vector4>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3f851553b3485f64b882c79368923ca7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: f4151cbde4520b1469e166be72ed9aa3, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 455133d0da7e9da4593718f176eb07e9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,23 @@
|
|||
## Introduction
|
||||
Collections quite simply contain objects, just like we expect from a C# collection, but serialized in an asset inside your project
|
||||
|
||||
Note that Unity **realy** doesn't like it if you reference scene objects in assets, and as such have made certain editor functions incompatible with them. Therefore if any object in the collection is not persistent, they're disabled as you can see below, although you can still reorder, delete and click on them to see them in your scene view. Note that none of these conditions affect how they work under the hood, these precautions are merely related to the editor
|
||||
|
||||
## Script Reference
|
||||
There are various ways to interact with the collection. Available are the following members
|
||||
|
||||
T this[int index]
|
||||
|
||||
IList List { get; }
|
||||
int Count { get; }
|
||||
Type Type { get; }
|
||||
|
||||
void Add(T)
|
||||
void Remove(T)
|
||||
RemoveAt(int)
|
||||
void Clear()
|
||||
bool Contains(T)
|
||||
int IndexOf(T)
|
||||
Insert(int, T)
|
||||
|
||||
T[] ToArray()
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f6b9ad255f8e4204cb0e058e803c375d
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,10 @@
|
|||
## Introduction
|
||||
Event Listeners are components that listen to a specific Event and then provides a response in the form on a UnityEvent. Note that the type of event listener must match the event type, so if a bool event is expected, you must use an EventListener of type bool as well. Typed events listeners also supports forwarding the raise parameter as a dynamic response
|
||||
|
||||
Event listeners are also fully debuggable through a variety of features. A fully featured stacktrace window is available. You can also simulate an incoming event through the inspector, and even select a debug value if the listener is typed. When an event is raised, a gizmo is also drawn to visualize responses
|
||||
|
||||
## Script Reference
|
||||
The class has a singular function for responding to an event. It differs depending on if a type is expected or not
|
||||
|
||||
void OnEventRaised(T)
|
||||
void OnEventRaised()
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cc77cef44faff4c409633e38c9b27011
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,16 @@
|
|||
## Introduction
|
||||
|
||||
Events also exist as ScriptableObjects in your project. They can contain any single parameter when raising or none. Events are also fully debuggable through the editor using the stacktrace window and the raise button functionality, which also supports the ability to raise events with parameters. If a parameter is specified, a field will be present which allows you to select which value will be passed.
|
||||
|
||||
## Script Reference
|
||||
Note that you must provide an Event Listener in order to subscribe to events
|
||||
|
||||
The base class differs depending on whether an argument is expected or not
|
||||
|
||||
void Raise(T)
|
||||
void RegisterListener(IGameEventListener<T>)
|
||||
void UnregisterListener(IGameEventListener<T>)
|
||||
|
||||
void Raise()
|
||||
void RegisterListener(IGameEventListener)
|
||||
void UnregisterListener(IGameEventListener)
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7f5aa2b6331cdd94186d9bf08807bd4b
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,16 @@
|
|||
## Introduction
|
||||
References are how we expose fields in MonoBehaviour scripts that allow us to assign a variable ScriptableObject. They're wrapped in a separate class because you can also choose not to use a ScriptableObject at all, and instead write a constant value in the inspector.
|
||||
|
||||
## Script Reference
|
||||
To create a Reference field in your MonoBehaviour script, simply declare it like you would any other field
|
||||
|
||||
public BoolReference boolValue;
|
||||
|
||||
Or use the [SerializeField] attribute if it's not public
|
||||
|
||||
[SerializeField]
|
||||
private BoolReference boolValue;
|
||||
|
||||
You don't have to care whether the Reference is using a constant or a variable, simply reference the Value property
|
||||
|
||||
T Value { get; set; }
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 43e78e08d09b4cd4681af36f8cc03e6d
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,16 @@
|
|||
## Introduction
|
||||
Variable ScriptableObject's share a lot of similarities with C# variables. They can be named and contain values of different types. Since they're embedded into a ScriptableObject, which exists as an asset within Unity, modifying both the name and value is very simple and intuitive.
|
||||
|
||||
## Script Reference
|
||||
Variables have a single property and a couple of functions we can use to modify its value.
|
||||
|
||||
Value { get; set; }
|
||||
|
||||
SetValue(T)
|
||||
SetValue(BaseVariable<T>)
|
||||
|
||||
Variables also have a single operator
|
||||
|
||||
implicit operator T(BaseVariable<T>)
|
||||
|
||||
The reason why you can't implicitly or explicitly assign any value, is because Variables are objects themselves, so it must be clear whether you're changing the reference or the value.
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 88af777236d645b45a7bf9fd42d6dd95
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9380ea5fbea0666478a788b3c3b2d2c7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,37 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System.Reflection;
|
||||
using Type = System.Type;
|
||||
|
||||
public static class BaseReferenceHelper
|
||||
{
|
||||
private const BindingFlags NonPublicBindingsFlag = BindingFlags.Instance | BindingFlags.NonPublic;
|
||||
private const string ConstantValueName = "_constantValue";
|
||||
|
||||
public static Type GetReferenceType(FieldInfo fieldInfo)
|
||||
{
|
||||
return fieldInfo.FieldType;
|
||||
}
|
||||
public static Type GetValueType(FieldInfo fieldInfo)
|
||||
{
|
||||
Type referenceType = GetReferenceType(fieldInfo);
|
||||
|
||||
if(referenceType.IsArray)
|
||||
{
|
||||
referenceType = referenceType.GetElementType();
|
||||
}
|
||||
else if(IsList(referenceType))
|
||||
{
|
||||
referenceType = referenceType.GetGenericArguments()[0];
|
||||
}
|
||||
|
||||
FieldInfo constantValueField = referenceType.GetField(ConstantValueName, NonPublicBindingsFlag);
|
||||
|
||||
return constantValueField.FieldType;
|
||||
}
|
||||
private static bool IsList(Type referenceType)
|
||||
{
|
||||
return referenceType.IsGenericType;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5294f4d0d03bb714e900e3a4777ca6cb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2249188d2069be24494255b754a33950
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,162 @@
|
|||
using UnityEditor;
|
||||
using UnityEditor.AnimatedValues;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture.Editor
|
||||
{
|
||||
public class SO_CodeGenerationWindow : EditorWindow
|
||||
{
|
||||
/* --------- DEPENDENCY GRAPH ---------*
|
||||
* [1] Game Event Listener
|
||||
* [2] Game Event
|
||||
* [3] Reference
|
||||
* [4] Collection
|
||||
* [5] Unity Event
|
||||
* [6] Variable
|
||||
*
|
||||
* / 1 2 3 4 5 6 7
|
||||
* 1 X X
|
||||
* 2 X
|
||||
* 3 X
|
||||
* 4
|
||||
* 5
|
||||
* 6
|
||||
*/
|
||||
|
||||
private readonly bool[,] _dependencyGraph = new bool[SO_CodeGenerator.TYPE_COUNT, SO_CodeGenerator.TYPE_COUNT]
|
||||
{
|
||||
{ false, true, false, false, true, false, },
|
||||
{ false, false, true, false, false, false, },
|
||||
{ false, false, false, false, false, true, },
|
||||
{ false, false, false, false, false, false, },
|
||||
{ false, false, false, false, false, false, },
|
||||
{ false, false, false, false, false, false, },
|
||||
};
|
||||
|
||||
private readonly bool[] _states = new bool[SO_CodeGenerator.TYPE_COUNT];
|
||||
private readonly string[] _names = new string[SO_CodeGenerator.TYPE_COUNT]
|
||||
{
|
||||
"Event Listener",
|
||||
"Game Event",
|
||||
"Reference",
|
||||
"Collection",
|
||||
"Unity Event",
|
||||
"Variable",
|
||||
};
|
||||
|
||||
private readonly bool[] _menuRequirement = new bool[SO_CodeGenerator.TYPE_COUNT]
|
||||
{
|
||||
false, true, false, true, false, true
|
||||
};
|
||||
|
||||
private int _order;
|
||||
private string _typeName;
|
||||
private string _menuName;
|
||||
private AnimBool _menuAnim;
|
||||
private AnimBool _clampedValueHelpBoxAnim;
|
||||
|
||||
[MenuItem("Window/SO Code Generation")]
|
||||
private static void ShowWindow()
|
||||
{
|
||||
GetWindow(typeof(SO_CodeGenerationWindow), true, "SO Code Generation");
|
||||
}
|
||||
private void OnEnable()
|
||||
{
|
||||
_menuAnim = new AnimBool();
|
||||
_menuAnim.valueChanged.AddListener(Repaint);
|
||||
|
||||
_clampedValueHelpBoxAnim = new AnimBool();
|
||||
_clampedValueHelpBoxAnim.valueChanged.AddListener(Repaint);
|
||||
|
||||
_order = SOArchitecture_Settings.Instance.DefaultCreateAssetMenuOrder;
|
||||
}
|
||||
private void OnGUI()
|
||||
{
|
||||
TypeSelection();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
DataFields();
|
||||
|
||||
if (GUILayout.Button("Generate"))
|
||||
{
|
||||
SO_CodeGenerator.Data data = new SO_CodeGenerator.Data()
|
||||
{
|
||||
Types = _states,
|
||||
TypeName = _typeName,
|
||||
MenuName = RequiresMenu() ? _menuName : default(string),
|
||||
Order = _order,
|
||||
};
|
||||
|
||||
SO_CodeGenerator.Generate(data);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
private void TypeSelection()
|
||||
{
|
||||
EditorGUILayout.LabelField("Select Type(s)", EditorStyles.boldLabel);
|
||||
|
||||
for (int i = 0; i < SO_CodeGenerator.TYPE_COUNT; i++)
|
||||
{
|
||||
bool isDepending = IsDepending(i);
|
||||
|
||||
if (isDepending)
|
||||
{
|
||||
_states[i] = true;
|
||||
}
|
||||
|
||||
EditorGUI.BeginDisabledGroup(isDepending);
|
||||
|
||||
_states[i] = EditorGUILayout.Toggle(_names[i], _states[i]);
|
||||
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
}
|
||||
private void DataFields()
|
||||
{
|
||||
EditorGUILayout.LabelField("Information", EditorStyles.boldLabel);
|
||||
|
||||
// Type name.
|
||||
_typeName = EditorGUILayout.TextField(new GUIContent("Type Name", "Case sensitive, ensure exact match with actual type name"), _typeName);
|
||||
|
||||
// Menu name.
|
||||
_menuAnim.target = RequiresMenu();
|
||||
EditorGUILayout.BeginFadeGroup(_menuAnim.faded);
|
||||
|
||||
if (_menuAnim.value)
|
||||
_menuName = EditorGUILayout.TextField("Menu Name", _menuName);
|
||||
|
||||
EditorGUILayout.EndFadeGroup();
|
||||
|
||||
// Order.
|
||||
_order = EditorGUILayout.IntField(new GUIContent("Order", "Use default if unsure"), _order);
|
||||
}
|
||||
/// <summary>
|
||||
/// Polls the currently selected state types to determine whether any require menus
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private bool RequiresMenu()
|
||||
{
|
||||
for (int i = 0; i < SO_CodeGenerator.TYPE_COUNT; i++)
|
||||
{
|
||||
if (_states[i] && _menuRequirement[i])
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// Given an index, polls the dependency graph, and returns whether anyone is depending on it
|
||||
/// </summary>
|
||||
private bool IsDepending(int index)
|
||||
{
|
||||
for (int i = 0; i < SO_CodeGenerator.TYPE_COUNT; i++)
|
||||
{
|
||||
if (_states[i] && _dependencyGraph[i, index])
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2d3d837455319ab469a5741ba1e0eb76
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,159 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture.Editor
|
||||
{
|
||||
public static class SO_CodeGenerator
|
||||
{
|
||||
static SO_CodeGenerator()
|
||||
{
|
||||
CreateTargetDirectories();
|
||||
GatherFilePaths();
|
||||
}
|
||||
private static void CreateTargetDirectories()
|
||||
{
|
||||
_targetDirectories = new string[TYPE_COUNT]
|
||||
{
|
||||
Application.dataPath + "/" + SOArchitecture_Settings.Instance.CodeGenerationTargetDirectory + "/Events/Listeners",
|
||||
Application.dataPath + "/" + SOArchitecture_Settings.Instance.CodeGenerationTargetDirectory + "/Events/Game Events",
|
||||
Application.dataPath + "/" + SOArchitecture_Settings.Instance.CodeGenerationTargetDirectory + "/References",
|
||||
Application.dataPath + "/" + SOArchitecture_Settings.Instance.CodeGenerationTargetDirectory + "/Collections",
|
||||
Application.dataPath + "/" + SOArchitecture_Settings.Instance.CodeGenerationTargetDirectory + "/Events/Responses",
|
||||
Application.dataPath + "/" + SOArchitecture_Settings.Instance.CodeGenerationTargetDirectory + "/Variables",
|
||||
};
|
||||
}
|
||||
private static void GatherFilePaths()
|
||||
{
|
||||
string assetPath = Application.dataPath;
|
||||
string folderToStartSearch = Directory.GetParent(assetPath).FullName;
|
||||
|
||||
Queue<string> foldersToCheck = new Queue<string>();
|
||||
foldersToCheck.Enqueue(folderToStartSearch);
|
||||
|
||||
while (foldersToCheck.Count > 0)
|
||||
{
|
||||
string currentDirectory = foldersToCheck.Dequeue();
|
||||
|
||||
foreach (string filePath in Directory.GetFiles(currentDirectory))
|
||||
{
|
||||
string fileName = Path.GetFileName(filePath);
|
||||
|
||||
for (int i = 0; i < TYPE_COUNT; i++)
|
||||
{
|
||||
if (_templateNames[i] == fileName)
|
||||
_templatePaths[i] = filePath;
|
||||
}
|
||||
}
|
||||
foreach (string subDirectory in Directory.GetDirectories(currentDirectory))
|
||||
{
|
||||
foldersToCheck.Enqueue(subDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
//Double check that all filepaths were found
|
||||
for (int i = 0; i < TYPE_COUNT; i++)
|
||||
{
|
||||
if (_templatePaths[i] == default(string))
|
||||
{
|
||||
Debug.LogError("Couldn't find path for " + _templatePaths[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public const int TYPE_COUNT = 6;
|
||||
|
||||
public struct Data
|
||||
{
|
||||
public bool[] Types;
|
||||
public string TypeName;
|
||||
public string MenuName;
|
||||
public int Order;
|
||||
}
|
||||
|
||||
private static string[] _templateNames = new string[TYPE_COUNT]
|
||||
{
|
||||
"GameEventListenerTemplate",
|
||||
"GameEventTemplate",
|
||||
"ReferenceTemplate",
|
||||
"CollectionTemplate",
|
||||
"UnityEventTemplate",
|
||||
"VariableTemplate",
|
||||
};
|
||||
|
||||
private static string[] _targetFileNames = new string[TYPE_COUNT]
|
||||
{
|
||||
"{0}GameEventListener.cs",
|
||||
"{0}GameEvent.cs",
|
||||
"{0}Reference.cs",
|
||||
"{0}Collection.cs",
|
||||
"{0}UnityEvent.cs",
|
||||
"{0}Variable.cs",
|
||||
};
|
||||
|
||||
private static string[] _targetDirectories = null;
|
||||
private static string[] _templatePaths = new string[TYPE_COUNT];
|
||||
private static string[,] _replacementStrings = null;
|
||||
|
||||
private static string TypeName { get { return _replacementStrings[1, 1]; } }
|
||||
|
||||
public static void Generate(Data data)
|
||||
{
|
||||
_replacementStrings = new string[4, 2]
|
||||
{
|
||||
{ "$TYPE$", data.TypeName },
|
||||
{ "$TYPE_NAME$", CapitalizeFirstLetter(data.TypeName) },
|
||||
{ "$MENU_NAME$", data.MenuName },
|
||||
{ "$ORDER$", data.Order.ToString() },
|
||||
};
|
||||
|
||||
for (int i = 0; i < TYPE_COUNT; i++)
|
||||
{
|
||||
if (data.Types[i])
|
||||
{
|
||||
GenerateScript(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
private static void GenerateScript(int index)
|
||||
{
|
||||
string targetFilePath = GetTargetFilePath(index);
|
||||
string contents = GetScriptContents(index);
|
||||
|
||||
if (File.Exists(targetFilePath) && !SOArchitecture_Settings.Instance.CodeGenerationAllowOverwrite)
|
||||
{
|
||||
Debug.Log("Cannot create file at " + targetFilePath + " because a file already exists, and overwrites are disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log("Creating " + targetFilePath);
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(targetFilePath));
|
||||
File.WriteAllText(targetFilePath, contents);
|
||||
}
|
||||
private static string GetScriptContents(int index)
|
||||
{
|
||||
string templatePath = _templatePaths[index];
|
||||
string templateContent = File.ReadAllText(templatePath);
|
||||
|
||||
string output = templateContent;
|
||||
|
||||
for (int i = 0; i < _replacementStrings.GetLength(0); i++)
|
||||
{
|
||||
output = output.Replace(_replacementStrings[i, 0], _replacementStrings[i, 1]);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
private static string GetTargetFilePath(int index)
|
||||
{
|
||||
return _targetDirectories[index] + "/" + string.Format(_targetFileNames[index], TypeName);
|
||||
}
|
||||
private static string CapitalizeFirstLetter(string input)
|
||||
{
|
||||
return input.First().ToString().ToUpper() + input.Substring(1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c0e8a480b3d95b8499804393d1ab3ea1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 85ea16b70b071a9498d307b160e902f0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[CreateAssetMenu(
|
||||
fileName = "$TYPE_NAME$Collection.asset",
|
||||
menuName = SOArchitecture_Utility.COLLECTION_SUBMENU + "$MENU_NAME$",
|
||||
order = $ORDER$)]
|
||||
public class $TYPE_NAME$Collection : Collection<$TYPE$>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c37df815504227545bf3c909a86f6ee6
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,9 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[AddComponentMenu(SOArchitecture_Utility.EVENT_LISTENER_SUBMENU + "$TYPE$")]
|
||||
public sealed class $TYPE_NAME$GameEventListener : BaseGameEventListener<$TYPE$, $TYPE_NAME$GameEvent, $TYPE_NAME$UnityEvent>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 322335fb95ca09546bfb78b78147144b
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,13 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[System.Serializable]
|
||||
[CreateAssetMenu(
|
||||
fileName = "$TYPE_NAME$GameEvent.asset",
|
||||
menuName = SOArchitecture_Utility.GAME_EVENT + "$MENU_NAME$",
|
||||
order = $ORDER$)]
|
||||
public sealed class $TYPE_NAME$GameEvent : GameEventBase<$TYPE$>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 340cff775918ddf4b97cdb4fdba1294e
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,11 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[System.Serializable]
|
||||
public sealed class $TYPE_NAME$Reference : BaseReference<$TYPE$, $TYPE_NAME$Variable>
|
||||
{
|
||||
public $TYPE_NAME$Reference() : base() { }
|
||||
public $TYPE_NAME$Reference($TYPE$ value) : base(value) { }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5bb692329aca5084da7363c2ad67846e
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,10 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[System.Serializable]
|
||||
public sealed class $TYPE_NAME$UnityEvent : UnityEvent<$TYPE$>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5dc00cc2e2d948945a8fe03a1cf7a068
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,16 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace ScriptableObjectArchitecture
|
||||
{
|
||||
[System.Serializable]
|
||||
public class $TYPE_NAME$Event : UnityEvent<$TYPE_NAME$> { }
|
||||
|
||||
[CreateAssetMenu(
|
||||
fileName = "$TYPE_NAME$Variable.asset",
|
||||
menuName = SOArchitecture_Utility.VARIABLE_SUBMENU + "$MENU_NAME$",
|
||||
order = $ORDER$)]
|
||||
public class $TYPE_NAME$Variable : BaseVariable<$TYPE$, $TYPE_NAME$Event>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 574fca2de3eaa454e9f1f32258e3dda6
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b2f16d300cdb67047b8223015cc0477c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,187 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Type = System.Type;
|
||||
|
||||
namespace ScriptableObjectArchitecture.Editor
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(BaseReference), true)]
|
||||
public sealed class BaseReferenceDrawer : PropertyDrawer
|
||||
{
|
||||
/// <summary>
|
||||
/// Options to display in the popup to select constant or variable.
|
||||
/// </summary>
|
||||
private static readonly string[] popupOptions =
|
||||
{
|
||||
"Use Constant",
|
||||
"Use Variable"
|
||||
};
|
||||
|
||||
private const float MultilineThreshold = 20;
|
||||
|
||||
// Property Names
|
||||
private const string VARIABLE_PROPERTY_NAME = "_variable";
|
||||
private const string CONSTANT_VALUE_PROPERTY_NAME = "_constantValue";
|
||||
private const string USE_CONSTANT_VALUE_PROPERTY_NAME = "_useConstant";
|
||||
|
||||
// Warnings
|
||||
private const string COULD_NOT_FIND_VALUE_FIELD_WARNING_FORMAT =
|
||||
"Could not find FieldInfo for [{0}] specific property drawer on type [{1}].";
|
||||
|
||||
private Type ValueType { get { return BaseReferenceHelper.GetValueType(fieldInfo); } }
|
||||
private bool SupportsMultiLine { get { return SOArchitecture_EditorUtility.SupportsMultiLine(ValueType); } }
|
||||
|
||||
private SerializedProperty property;
|
||||
private SerializedProperty useConstant;
|
||||
private SerializedProperty constantValue;
|
||||
private SerializedProperty variable;
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
// Get properties
|
||||
this.property = property;
|
||||
useConstant = property.FindPropertyRelative("_useConstant");
|
||||
constantValue = property.FindPropertyRelative("_constantValue");
|
||||
variable = property.FindPropertyRelative("_variable");
|
||||
|
||||
int oldIndent = ResetIndent();
|
||||
|
||||
Rect fieldRect = DrawLabel(position, property, label);
|
||||
Rect valueRect = DrawField(position, fieldRect);
|
||||
DrawValue(position, valueRect);
|
||||
|
||||
EndIndent(oldIndent);
|
||||
|
||||
property.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
private bool IsConstantValueMultiline(SerializedProperty property)
|
||||
{
|
||||
return GenericPropertyDrawer.GetHeight(property, ValueType) > MultilineThreshold;
|
||||
}
|
||||
private Rect DrawLabel(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
return EditorGUI.PrefixLabel(position, label);
|
||||
}
|
||||
private Rect DrawField(Rect position, Rect fieldRect)
|
||||
{
|
||||
Rect buttonRect = GetPopupButtonRect(fieldRect);
|
||||
Rect valueRect = GetValueRect(fieldRect, buttonRect);
|
||||
|
||||
int result = DrawPopupButton(buttonRect, useConstant.boolValue ? 0 : 1);
|
||||
useConstant.boolValue = result == 0;
|
||||
|
||||
return valueRect;
|
||||
}
|
||||
private void DrawValue(Rect position, Rect valueRect)
|
||||
{
|
||||
if (useConstant.boolValue)
|
||||
{
|
||||
DrawGenericPropertyField(position, valueRect);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.PropertyField(valueRect, variable, GUIContent.none);
|
||||
}
|
||||
}
|
||||
private void DrawGenericPropertyField(Rect position, Rect valueRect)
|
||||
{
|
||||
if (IsConstantValueMultiline(constantValue))
|
||||
{
|
||||
using (new EditorGUI.IndentLevelScope())
|
||||
{
|
||||
position.y += EditorGUIUtility.singleLineHeight;
|
||||
position.height = GenericPropertyDrawer.GetHeight(constantValue, ValueType);
|
||||
|
||||
GenericPropertyDrawer.DrawPropertyDrawer(position, constantValue, ValueType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GenericPropertyDrawer.DrawPropertyDrawer(valueRect, constantValue, ValueType, false);
|
||||
}
|
||||
}
|
||||
private Rect GetConstantMultilineRect(Rect position, Rect valueRect)
|
||||
{
|
||||
return new Rect(position.x, valueRect.y + EditorGUIUtility.singleLineHeight, position.width, GenericPropertyDrawer.GetHeight(constantValue, ValueType));
|
||||
}
|
||||
private Rect GetMultiLineFieldRect(Rect position)
|
||||
{
|
||||
return EditorGUI.IndentedRect(new Rect
|
||||
{
|
||||
position = new Vector2(position.x, position.y + EditorGUIUtility.singleLineHeight),
|
||||
size = new Vector2(position.width, EditorGUI.GetPropertyHeight(constantValue) + EditorGUIUtility.singleLineHeight)
|
||||
});
|
||||
}
|
||||
private bool ShouldDrawMultiLineField()
|
||||
{
|
||||
return useConstant.boolValue && SupportsMultiLine && EditorGUI.GetPropertyHeight(constantValue) > EditorGUIUtility.singleLineHeight;
|
||||
}
|
||||
private int ResetIndent()
|
||||
{
|
||||
// Store old indent level and set it to 0, the PrefixLabel takes care of it
|
||||
int indent = EditorGUI.indentLevel;
|
||||
EditorGUI.indentLevel = 0;
|
||||
|
||||
return indent;
|
||||
}
|
||||
private void EndIndent(int indent)
|
||||
{
|
||||
EditorGUI.indentLevel = indent;
|
||||
}
|
||||
private int DrawPopupButton(Rect rect, int value)
|
||||
{
|
||||
return EditorGUI.Popup(rect, value, popupOptions, Styles.PopupStyle);
|
||||
}
|
||||
private Rect GetValueRect(Rect fieldRect, Rect buttonRect)
|
||||
{
|
||||
Rect valueRect = new Rect(fieldRect);
|
||||
valueRect.x += buttonRect.width;
|
||||
valueRect.width -= buttonRect.width;
|
||||
|
||||
return valueRect;
|
||||
}
|
||||
private Rect GetPopupButtonRect(Rect fieldrect)
|
||||
{
|
||||
Rect buttonRect = new Rect(fieldrect);
|
||||
buttonRect.yMin += Styles.PopupStyle.margin.top;
|
||||
buttonRect.width = Styles.PopupStyle.fixedWidth + Styles.PopupStyle.margin.right;
|
||||
buttonRect.height = Styles.PopupStyle.fixedHeight + Styles.PopupStyle.margin.top;
|
||||
|
||||
return buttonRect;
|
||||
}
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
SerializedProperty useConstant = property.FindPropertyRelative(USE_CONSTANT_VALUE_PROPERTY_NAME);
|
||||
SerializedProperty constantValue = property.FindPropertyRelative(CONSTANT_VALUE_PROPERTY_NAME);
|
||||
|
||||
if (useConstant.boolValue)
|
||||
{
|
||||
if (IsConstantValueMultiline(constantValue))
|
||||
{
|
||||
return GenericPropertyDrawer.GetHeight(constantValue, ValueType) + EditorGUIUtility.singleLineHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
return EditorGUIUtility.singleLineHeight;
|
||||
}
|
||||
}
|
||||
|
||||
return EditorGUIUtility.singleLineHeight;
|
||||
}
|
||||
|
||||
static class Styles
|
||||
{
|
||||
static Styles()
|
||||
{
|
||||
PopupStyle = new GUIStyle(GUI.skin.GetStyle("PaneOptions"))
|
||||
{
|
||||
imagePosition = ImagePosition.ImageOnly,
|
||||
};
|
||||
}
|
||||
|
||||
public static GUIStyle PopupStyle { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3fc5390498e256d48bba75f1f835c028
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,104 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace ScriptableObjectArchitecture.Editor
|
||||
{
|
||||
public static class GenericPropertyDrawer
|
||||
{
|
||||
private const string DefaultErrorLabelText = "Type is not drawable! Please implement property drawer";
|
||||
private const string NullPropertyText = "SerializedProperty is null. Your custom type is probably missing the [Serializable] attribute";
|
||||
|
||||
public static void DrawPropertyDrawer(Rect rect, SerializedProperty property, Type type, bool drawLabel = true)
|
||||
{
|
||||
if (property == null)
|
||||
{
|
||||
Debug.LogError(NullPropertyText);
|
||||
return;
|
||||
}
|
||||
|
||||
if (SOArchitecture_EditorUtility.HasPropertyDrawer(type))
|
||||
{
|
||||
if(drawLabel)
|
||||
{
|
||||
EditorGUI.PropertyField(rect, property);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.PropertyField(rect, property, GUIContent.none);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PropertyDrawIterator iter = new PropertyDrawIterator(rect, property.Copy(), drawLabel);
|
||||
|
||||
DrawPropertyDrawerInternal(iter);
|
||||
}
|
||||
}
|
||||
public static void DrawPropertyDrawerLayout(SerializedProperty property, Type type, bool drawLabel = true)
|
||||
{
|
||||
if(property == null)
|
||||
{
|
||||
Debug.LogError(NullPropertyText);
|
||||
return;
|
||||
}
|
||||
|
||||
if (SOArchitecture_EditorUtility.HasPropertyDrawer(type))
|
||||
{
|
||||
if (drawLabel)
|
||||
{
|
||||
EditorGUILayout.PropertyField(property);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.PropertyField(property, GUIContent.none);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PropertyDrawIteratorLayout iter = new PropertyDrawIteratorLayout(property.Copy(), drawLabel);
|
||||
|
||||
DrawPropertyDrawerInternal(iter);
|
||||
}
|
||||
}
|
||||
private static void DrawPropertyDrawerInternal(IPropertyDrawIterator iter)
|
||||
{
|
||||
do
|
||||
{
|
||||
iter.Draw();
|
||||
}
|
||||
while (iter.Next());
|
||||
|
||||
iter.End();
|
||||
}
|
||||
public static float GetHeight(SerializedProperty property, Type type)
|
||||
{
|
||||
if (SOArchitecture_EditorUtility.HasPropertyDrawer(type))
|
||||
{
|
||||
return EditorGUI.GetPropertyHeight(property);
|
||||
}
|
||||
else
|
||||
{
|
||||
property = property.Copy();
|
||||
|
||||
int elements = 0;
|
||||
|
||||
PropertyIterator iter = new PropertyIterator(property);
|
||||
do
|
||||
{
|
||||
++elements;
|
||||
}
|
||||
while (iter.Next());
|
||||
|
||||
iter.End();
|
||||
|
||||
float spacing = (elements - 1) * EditorGUIUtility.standardVerticalSpacing;
|
||||
float elementHeights = elements * EditorGUIUtility.singleLineHeight;
|
||||
|
||||
return spacing + elementHeights;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a2175771da1196e418cdf5f11735236e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,26 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace ScriptableObjectArchitecture.Editor
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(Quaternion))]
|
||||
public class QuaternionDrawer : PropertyDrawer
|
||||
{
|
||||
private const float Height = 20;
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
Vector4 vector = property.quaternionValue.ToVector4();
|
||||
|
||||
vector = EditorGUI.Vector4Field(position, label, vector);
|
||||
|
||||
property.quaternionValue = new Quaternion(vector.x, vector.y, vector.z, vector.w);
|
||||
}
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
return Height;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 508c2da9a3d5d5c478a016c104a0a36d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,76 @@
|
|||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ScriptableObjectArchitecture.Editor
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(SceneInfo))]
|
||||
internal sealed class SceneInfoPropertyDrawer : PropertyDrawer
|
||||
{
|
||||
private const string SCENE_PREVIEW_TITLE = "Preview (Read-Only)";
|
||||
private const string SCENE_NAME_PROPERTY = "_sceneName";
|
||||
private const string SCENE_INDEX_PROPERTY = "_sceneIndex";
|
||||
private const string SCENE_ENABLED_PROPERTY = "_isSceneEnabled";
|
||||
private const int FIELD_COUNT = 5;
|
||||
|
||||
public override void OnGUI(Rect propertyRect, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
var sceneNameProperty = property.FindPropertyRelative(SCENE_NAME_PROPERTY);
|
||||
var sceneIndexProperty = property.FindPropertyRelative(SCENE_INDEX_PROPERTY);
|
||||
var enabledProperty = property.FindPropertyRelative(SCENE_ENABLED_PROPERTY);
|
||||
|
||||
EditorGUI.BeginProperty(propertyRect, new GUIContent(property.displayName), property);
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
// Draw Object Selector for SceneAssets
|
||||
var sceneAssetRect = new Rect
|
||||
{
|
||||
position = propertyRect.position,
|
||||
size = new Vector2(propertyRect.width, EditorGUIUtility.singleLineHeight)
|
||||
};
|
||||
|
||||
var oldSceneAsset = AssetDatabase.LoadAssetAtPath<SceneAsset>(sceneNameProperty.stringValue);
|
||||
var sceneAsset = EditorGUI.ObjectField(sceneAssetRect, oldSceneAsset, typeof(SceneAsset), false);
|
||||
var sceneAssetPath = AssetDatabase.GetAssetPath(sceneAsset);
|
||||
if (sceneNameProperty.stringValue != sceneAssetPath)
|
||||
{
|
||||
sceneNameProperty.stringValue = sceneAssetPath;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(sceneNameProperty.stringValue))
|
||||
{
|
||||
sceneIndexProperty.intValue = -1;
|
||||
enabledProperty.boolValue = false;
|
||||
}
|
||||
|
||||
// Draw preview fields for scene information.
|
||||
var titleLabelRect = sceneAssetRect;
|
||||
titleLabelRect.y += EditorGUIUtility.singleLineHeight;
|
||||
|
||||
EditorGUI.LabelField(titleLabelRect, SCENE_PREVIEW_TITLE);
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
var nameRect = titleLabelRect;
|
||||
nameRect.y += EditorGUIUtility.singleLineHeight;
|
||||
|
||||
var indexRect = nameRect;
|
||||
indexRect.y += EditorGUIUtility.singleLineHeight;
|
||||
|
||||
var enabledRect = indexRect;
|
||||
enabledRect.y += EditorGUIUtility.singleLineHeight;
|
||||
|
||||
EditorGUI.PropertyField(nameRect, sceneNameProperty);
|
||||
EditorGUI.PropertyField(indexRect, sceneIndexProperty);
|
||||
EditorGUI.PropertyField(enabledRect, enabledProperty);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
property.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
return EditorGUIUtility.singleLineHeight * FIELD_COUNT + ((FIELD_COUNT - 1) * EditorGUIUtility.standardVerticalSpacing);
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue