Skip to content

Commit 1ea45db

Browse files
authored
Merge pull request #185 from brunomikoski/feature/fix-picker-not-respecting-inheritance
Feature/fix picker not respecting inheritance
2 parents 8c502e0 + c1e47a8 commit 1ea45db

File tree

9 files changed

+159
-85
lines changed

9 files changed

+159
-85
lines changed

Scripts/Editor/Core/CodeGenerationUtility.cs

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using UnityEditor.Compilation;
88
using UnityEditorInternal;
99
using UnityEngine;
10+
using Object = UnityEngine.Object;
1011
#if ADDRESSABLES_ENABLED
1112
using UnityEditor.AddressableAssets;
1213
using UnityEditor.AddressableAssets.Settings;
@@ -330,9 +331,28 @@ public static bool CheckIfCanBePartial(ScriptableObjectCollection collection, st
330331

331332
public static void GenerateIndirectAccessForCollectionItemType(Type collectionItemType)
332333
{
333-
string baseClassPath = AssetDatabase.GetAssetPath(MonoScript.FromScriptableObject(ScriptableObject.CreateInstance(collectionItemType)));
334-
string parentFolder = Path.GetDirectoryName(baseClassPath);
335-
GenerateIndirectAccessForCollectionItemType(collectionItemType.Name, collectionItemType.Namespace, parentFolder);
334+
List<Type> targetTypes = new List<Type>();
335+
foreach (Type t in TypeCache.GetTypesDerivedFrom(collectionItemType))
336+
{
337+
targetTypes.Add(t);
338+
}
339+
340+
targetTypes.Add(collectionItemType);
341+
342+
foreach (Type type in targetTypes)
343+
{
344+
if (type == null)
345+
continue;
346+
347+
if (!ScriptUtility.TryGetFolderOfClass(type, out string parentFolder))
348+
{
349+
Debug.LogError($"Could not find the script path for the collection item type '{collectionItemType.FullName}', " +
350+
$"cannot generate indirect access class.");
351+
continue;
352+
}
353+
354+
GenerateIndirectAccessForCollectionItemType(type.Name, type.Namespace, parentFolder);
355+
}
336356
}
337357

338358
public static void GenerateIndirectAccessForCollectionItemType(string collectionName, string collectionNamespace,
@@ -377,6 +397,12 @@ public static void GenerateIndirectAccessForCollectionItemType(string collection
377397
AppendLine(writer, indentation,
378398
$"public {collectionName}IndirectReference({collectionName} collectionItemScriptableObject) : base(collectionItemScriptableObject) {{}}");
379399

400+
AppendLine(writer, indentation,
401+
$"public static implicit operator {collectionName}IndirectReference({collectionName} item) => item == null ? null : new {collectionName}IndirectReference(item);");
402+
403+
AppendLine(writer, indentation,
404+
$"public static implicit operator ScriptableObjectCollectionItem({collectionName}IndirectReference reference) => reference?.Ref;");
405+
380406
indentation--;
381407
AppendFooter(writer, ref indentation, collectionNamespace);
382408
}
@@ -536,9 +562,19 @@ private static void WriteDirectAccessCollectionStatic(ScriptableObjectCollection
536562

537563
AppendLine(writer, indentation);
538564

565+
Type itemType = collection.GetItemType();
566+
bool writeAsPartial = SOCSettings.Instance.GetWriteAsPartialClass(collection);
567+
bool hasBaseTypeCollection = false;
539568

540-
AppendLine(writer, indentation,
541-
$"public static {collection.GetType().FullName} {PublicValuesName}");
569+
if (itemType != null && itemType.BaseType != null)
570+
{
571+
List<ScriptableObjectCollection> baseCollections = CollectionsRegistry.Instance.GetCollectionsByItemType(itemType.BaseType);
572+
hasBaseTypeCollection = baseCollections != null && baseCollections.Count > 0;
573+
}
574+
575+
bool addNewModifier = writeAsPartial && hasBaseTypeCollection;
576+
577+
AppendLine(writer, indentation, $"public {(addNewModifier ? "new " : string.Empty)}static {collection.GetType().FullName} {PublicValuesName}");
542578

543579
AppendLine(writer, indentation, "{");
544580
indentation++;

Scripts/Editor/CustomEditors/CollectionCustomEditor.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,10 @@ private void OnKeyUpOnCollectionListView(KeyUpEvent evt)
304304
{
305305
if (currentRenamingLabel != null)
306306
return;
307-
307+
308+
if (EditorGUIUtility.editingTextField)
309+
return;
310+
308311
switch (evt.keyCode)
309312
{
310313
case KeyCode.F2:

Scripts/Editor/Extensions/SerializedPropertyExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public static void SetValue(this SerializedProperty serializedProperty, object v
9898
serializedProperty.objectReferenceValue = (UnityEngine.Object)value;
9999
break;
100100
case SerializedPropertyType.LayerMask:
101-
serializedProperty.intValue = (LayerMask)value;
101+
serializedProperty.intValue = ((LayerMask)value).value;
102102
break;
103103
case SerializedPropertyType.Enum:
104104
serializedProperty.intValue = (int)value;
@@ -158,6 +158,7 @@ public static void SetValue(this SerializedProperty serializedProperty, object v
158158
case SerializedPropertyType.Generic:
159159
serializedProperty.SetValueReflective(value);
160160
break;
161+
161162
default:
162163
Debug.LogWarning(
163164
$"Tried to copy value '{value}' from a template to an SOC item but apparently that's not supported.");

Scripts/Editor/Generators/CollectionGenerators.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ private static void CopyFieldToSerializedProperty(
289289
}
290290

291291
serializedProperty.SetValue(value);
292+
serializedProperty.serializedObject.ApplyModifiedProperties();
292293
}
293294
}
294295
}

Scripts/Editor/PropertyDrawers/CollectionItemIndirectReferencePropertyDrawer.cs

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ public sealed class CollectionItemIndirectReferencePropertyDrawer : PropertyDraw
1717

1818
private Type collectionItemType;
1919
private CollectionItemPropertyDrawer collectionItemPropertyDrawer;
20-
21-
private SerializedProperty drawingProperty;
20+
2221
private SerializedProperty itemGUIDValueASerializedProperty;
2322
private SerializedProperty itemGUIDValueBSerializedProperty;
2423
private SerializedProperty itemLastKnowNameSerializedProperty;
@@ -43,7 +42,6 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
4342
if (collectionItemPropertyDrawer == null)
4443
CreateCollectionItemPropertyDrawer(property);
4544

46-
drawingProperty = property;
4745
itemGUIDValueASerializedProperty = property.FindPropertyRelative(COLLECTION_ITEM_GUID_VALUE_A_PROPERTY_PATH);
4846
itemGUIDValueBSerializedProperty = property.FindPropertyRelative(COLLECTION_ITEM_GUID_VALUE_B_PROPERTY_PATH);
4947
itemLastKnowNameSerializedProperty = property.FindPropertyRelative(COLLECTION_ITEM_LAST_KNOW_NAME_PROPERTY_PATH);
@@ -66,41 +64,47 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
6664
{
6765
collectionItemPropertyDrawer.DrawCollectionItemDrawer(ref position, property, collectionItem, label, item =>
6866
{
69-
SetSerializedPropertyGUIDs(item);
70-
drawingProperty.serializedObject.ApplyModifiedProperties();
67+
var element = property.serializedObject.FindProperty(property.propertyPath);
68+
SetSerializedPropertyGUIDs(element, item);
69+
property.serializedObject.ApplyModifiedProperties();
7170
});
7271
return;
7372
}
7473

7574
EditorGUI.PropertyField(position, property, label, true);
7675
}
7776

78-
private void SetSerializedPropertyGUIDs(ScriptableObject item)
77+
private void SetSerializedPropertyGUIDs(SerializedProperty element, ScriptableObject item)
7978
{
79+
SerializedProperty itemA = element.FindPropertyRelative(COLLECTION_ITEM_GUID_VALUE_A_PROPERTY_PATH);
80+
SerializedProperty itemB = element.FindPropertyRelative(COLLECTION_ITEM_GUID_VALUE_B_PROPERTY_PATH);
81+
SerializedProperty itemName = element.FindPropertyRelative(COLLECTION_ITEM_LAST_KNOW_NAME_PROPERTY_PATH);
82+
SerializedProperty colA = element.FindPropertyRelative(COLLECTION_GUID_VALUE_A_PROPERTY_PATH);
83+
SerializedProperty colB = element.FindPropertyRelative(COLLECTION_GUID_VALUE_B_PROPERTY_PATH);
84+
SerializedProperty colName = element.FindPropertyRelative(COLLECTION_LAST_KNOW_NAME_PROPERTY_PATH);
85+
8086
if (item == null)
8187
{
82-
itemGUIDValueASerializedProperty.longValue = 0;
83-
itemGUIDValueBSerializedProperty.longValue = 0;
84-
collectionGUIDValueASerializedProperty.longValue = 0;
85-
collectionGUIDValueBSerializedProperty.longValue = 0;
86-
itemLastKnowNameSerializedProperty.stringValue = string.Empty;
87-
collectionLastKnowNameSerializedProperty.stringValue = string.Empty;
88-
88+
itemA.longValue = 0;
89+
itemB.longValue = 0;
90+
colA.longValue = 0;
91+
colB.longValue = 0;
92+
itemName.stringValue = string.Empty;
93+
colName.stringValue = string.Empty;
94+
return;
8995
}
90-
else
96+
97+
if (item is ISOCItem socItem)
9198
{
92-
if (item is ISOCItem socItem)
93-
{
94-
(long, long) itemGUIDValues = socItem.GUID.GetRawValues();
95-
itemGUIDValueASerializedProperty.longValue = itemGUIDValues.Item1;
96-
itemGUIDValueBSerializedProperty.longValue = itemGUIDValues.Item2;
97-
itemLastKnowNameSerializedProperty.stringValue = socItem.name;
98-
99-
(long, long) collectionGUIDValues = socItem.Collection.GUID.GetRawValues();
100-
collectionGUIDValueASerializedProperty.longValue = collectionGUIDValues.Item1;
101-
collectionGUIDValueBSerializedProperty.longValue = collectionGUIDValues.Item2;
102-
collectionLastKnowNameSerializedProperty.stringValue = socItem.Collection.name;
103-
}
99+
(long ia, long ib) = socItem.GUID.GetRawValues();
100+
itemA.longValue = ia;
101+
itemB.longValue = ib;
102+
itemName.stringValue = socItem.name;
103+
104+
(long ca, long cb) = socItem.Collection.GUID.GetRawValues();
105+
colA.longValue = ca;
106+
colB.longValue = cb;
107+
colName.stringValue = socItem.Collection.name;
104108
}
105109

106110
}
@@ -152,4 +156,4 @@ private SOCItemEditorOptionsAttribute GetOptionsAttribute()
152156
return null;
153157
}
154158
}
155-
}
159+
}
Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.IO;
23
using UnityEditor;
34
using UnityEngine;
45

@@ -9,20 +10,45 @@ namespace BrunoMikoski.ScriptableObjectCollections
910
/// </summary>
1011
public static class ScriptUtility
1112
{
13+
public static bool TryGetFolderOfClass(Type classType, out string folderPath)
14+
{
15+
folderPath = null;
16+
17+
if (!TryGetScriptOfClass(classType, out MonoScript script))
18+
return false;
19+
20+
string scriptPath = AssetDatabase.GetAssetPath(script);
21+
if (string.IsNullOrEmpty(scriptPath))
22+
return false;
23+
24+
folderPath = Path.GetDirectoryName(scriptPath);
25+
return true;
26+
}
27+
1228
public static bool TryGetScriptOfClass(Type classType, out MonoScript script)
1329
{
1430
string[] scriptGuids = AssetDatabase.FindAssets($"t:script {classType.Name}");
1531
if (scriptGuids.Length == 0)
1632
{
1733
Debug.LogWarning($"Could not find corresponding script for class '{classType.Name}'. " +
18-
$"Check that the script is called '{classType.Name}'.");
34+
$"Check that the script file name matches the class name.");
1935
script = null;
2036
return false;
2137
}
2238

23-
string scriptPath = AssetDatabase.GUIDToAssetPath(scriptGuids[0]);
24-
script = AssetDatabase.LoadAssetAtPath<MonoScript>(scriptPath);
25-
return true;
39+
foreach (string guid in scriptGuids)
40+
{
41+
string path = AssetDatabase.GUIDToAssetPath(guid);
42+
MonoScript candidate = AssetDatabase.LoadAssetAtPath<MonoScript>(path);
43+
if (candidate != null && candidate.GetClass() == classType)
44+
{
45+
script = candidate;
46+
return true;
47+
}
48+
}
49+
50+
script = null;
51+
return false;
2652
}
2753
}
2854
}

Scripts/Runtime/Core/CollectionItemIndirectReference.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,21 @@ public TObject Ref
8282
return cachedRef;
8383
}
8484
}
85+
86+
public static implicit operator TObject(CollectionItemIndirectReference<TObject> reference)
87+
{
88+
return reference?.Ref;
89+
}
90+
91+
public static implicit operator ScriptableObjectCollectionItem(CollectionItemIndirectReference<TObject> reference)
92+
{
93+
return reference?.Ref as ScriptableObjectCollectionItem;
94+
}
95+
96+
public static implicit operator CollectionItemIndirectReference<TObject>(TObject item)
97+
{
98+
return item == null ? null : new CollectionItemIndirectReference<TObject>(item);
99+
}
85100

86101
private bool TryResolveReference(out TObject result)
87102
{
@@ -153,4 +168,4 @@ public void SetCollection(ScriptableObjectCollection targetCollection)
153168
collectionLastKnowName = targetCollection.name;
154169
}
155170
}
156-
}
171+
}

0 commit comments

Comments
 (0)