Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions Editor/Assigner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public static class Assigner
new ObjectAssigner(),
new ComponentArrayAssigner(),
new ObjectArrayAssigner(),
#if UNITY_ADDRESSABLES
new AssetReferenceTAssigner(),
#endif
};

public static void AssignObjectProperties(SerializedObject obj)
Expand All @@ -24,24 +27,28 @@ public static void AssignObjectProperties(SerializedObject obj)
{
Logger.Log($"Assigning property: {property.propertyPath}");

bool assigned = false;
foreach (ISubAssigner assigner in _assigners)
{
using (new Timer($"Assigner `{assigner.GetType().Name}` for `{property.propertyPath}`"))
{
if (assigner.TryAssign(property))
{
Logger.Log($"Property `{property.propertyPath}` assigned by {assigner.GetType().Name}");
assigned = true;
break;
}
}
}

//because of AssetReferenceTAssigner this function must be called here.
if (assigned)
obj.ApplyModifiedProperties();

if (!property.NextVisible(true))
break;
}
}

obj.ApplyModifiedProperties();
}
}
}
80 changes: 80 additions & 0 deletions Editor/Assigners/AssetReferenceTAssigner.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#if UNITY_ADDRESSABLES
using System;
using AutoAssigner.Providers;
using UnityEditor;
using UnityEngine.AddressableAssets;

namespace AutoAssigner.Assigners
{
public class AssetReferenceTAssigner : ISubAssigner
{
public bool TryAssign(SerializedProperty property)
{
if (property.propertyType != SerializedPropertyType.Generic)
return false;

if (property.isArray || property.IsArrayElement())
return false;

property.GetFieldInfoAndStaticType(out Type fieldType);

if (!IsAssignableToGenericType(fieldType, typeof(AssetReferenceT<>)))
return false;

var obj = property.GetObject();
if (obj is not AssetReference assetRef)
return false;

if (assetRef.editorAsset != null)
return true;

var genericType = GetGenericType(fieldType);
if (genericType == null)
return false;

var targetName = $"{genericType.Name} {property.name}";
var targetObj = ObjectProvider.GetOne(genericType, targetName);
if (targetObj == null)
targetObj = PrefabProvider.GetOne(genericType, targetName);

assetRef.SetEditorAsset(targetObj);
assetRef.SetEditorSubObject(targetObj);

//We must Update SerializedObject to read new values
property.serializedObject.Update();

return true;
}

//It's tricky to detect both AssetReferenceT<Sprite> and AssetReferenceSprite
private bool IsAssignableToGenericType(Type givenType, Type genericType)
{
if (givenType == null || genericType == null)
return false;

if (givenType.IsGenericType &&
genericType.IsAssignableFrom(givenType.GetGenericTypeDefinition()))
return true;

var baseType = givenType.BaseType;
return IsAssignableToGenericType(baseType, genericType);
}

//Return Sprite for both AssetReferenceT<Sprite> and AssetReferenceSprite
private Type GetGenericType(Type givenType)
{
if (givenType == null)
return null;

if (givenType.IsGenericType)
{
var genericArguments = givenType.GetGenericArguments();
return genericArguments.Length == 0 ? null : genericArguments[0];
}

var baseType = givenType.BaseType;
return GetGenericType(baseType);
}
}
}
#endif
3 changes: 3 additions & 0 deletions Editor/Assigners/AssetReferenceTAssigner.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Editor/Assigners/ComponentArrayAssigner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ public bool TryAssign(SerializedProperty property)

List<Component> all;

if (!property.HasPrefabInTheName())
var isComponent = property.serializedObject.targetObject is Component;
if (!property.HasPrefabInTheName() && isComponent)
{
var root = (Component)property.serializedObject.targetObject;
all = root.GetComponentsInChildren(element, true).ToList();
Expand Down
10 changes: 5 additions & 5 deletions Editor/Assigners/ComponentAssigner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,21 @@ public bool TryAssign(SerializedProperty property)
if (property.objectReferenceValue != null)
return true;

if (!property.HasPrefabInTheName())
var isComponent = property.serializedObject.targetObject is Component;
if (!property.HasPrefabInTheName() && isComponent)
{
var root = (Component)property.serializedObject.targetObject;
Component[] children = root.GetComponentsInChildren(fieldType, true);

if (children.Length != 0)
{
(property.objectReferenceValue, _) = NameProcessor.GetMatching(children, property.GetTargetName());
if (property.objectReferenceValue != null)
return true;
}
}
else
{
property.objectReferenceValue = PrefabProvider.GetOne(fieldType, property.GetTargetName());
}

property.objectReferenceValue = PrefabProvider.GetOne(fieldType, property.GetTargetName());
return true;
}
}
Expand Down
17 changes: 13 additions & 4 deletions Editor/AutoAssigner.Editor.asmdef
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,26 @@
"name": "AutoAssigner.Editor",
"rootNamespace": "AutoAssigner",
"references": [
"AutoAssigner"
"AutoAssigner",
"Unity.Addressables"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": true,
"precompiledReferences": [],
"overrideReferences": false,
"precompiledReferences": [
""
],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"versionDefines": [
{
"name": "com.unity.addressables",
"expression": "",
"define": "UNITY_ADDRESSABLES"
}
],
"noEngineReferences": false
}
3 changes: 2 additions & 1 deletion Editor/Providers/PrefabProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ public static Component GetOne(Type t, string targetName)

(string bestPath, _) = NameProcessor.GetMatching(paths, targetName);

return AssetDatabase.LoadAssetAtPath<GameObject>(bestPath).GetComponent(t);
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(bestPath);
return prefab != null ? prefab.GetComponent(t) : null;
}

public static GameObject GetOne(string targetName)
Expand Down
9 changes: 9 additions & 0 deletions Editor/SerializedPropertyExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,14 @@ public static bool IsArrayElement(this SerializedProperty property)
&& property.propertyPath.Contains("[")
&& property.propertyPath.Contains("]");
}

public static object GetObject(this SerializedProperty property)
{
object obj = property.serializedObject.targetObject;
string path = property.propertyPath;
BindingFlags bindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
FieldInfo field = obj.GetType().GetField(path, bindings);
return field != null ? field.GetValue(obj) : default(object);
}
}
}