添加插件

This commit is contained in:
2025-11-10 00:08:26 +08:00
parent 4059c207c0
commit 76f80db694
2814 changed files with 436400 additions and 178 deletions

View File

@@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Obvious.Soap.Attributes;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Obvious.Soap
{
public static class SoapRuntimeUtils
{
/// <summary>
/// Creates a new instance of a ScriptableVariableBase subclass with the given name.
/// </summary>
/// <typeparam name="T">The type of the ScriptableVariableBase subclass to create.</typeparam>
/// <param name="name">The name of the new ScriptableVariableBase instance.</param>
/// <returns>The newly created ScriptableVariableBase instance.</returns>
public static T CreateRuntimeInstance<T>(string name = "") where T : ScriptableVariableBase
{
var runtimeVariable = CreateInstance<T>(name);
runtimeVariable.ResetType = ResetType.None;
return runtimeVariable;
}
/// <summary>
/// Creates a new instance of a ScriptableObject subclass with the given name.
/// </summary>
/// <param name="name"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T CreateInstance<T>(string name = "") where T : ScriptableObject
{
var instance = ScriptableObject.CreateInstance<T>();
instance.name = string.IsNullOrEmpty(name) ? typeof(T).Name : name;
return instance;
}
/// <summary>
/// Creates a new instance of a ScriptableEvent subclass with the given name.
/// </summary>
/// <param name="name"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T CreateRuntimeEventInstance<T>(string name = "") where T : ScriptableEventBase
{
return CreateInstance<T>(name);
}
/// <summary>
/// Create a deep copy of the template
/// </summary>
/// <typeparam name="T">The type of the subclass to create.</typeparam>
/// <param name="template">Template to copy.</param>
/// <returns>The newly created or copied instance.</returns>
public static T CreateCopy<T>(T template) where T : ScriptableObject
{
// Create a deep copy of the template
T copy = Object.Instantiate(template);
return copy;
}
private static readonly Dictionary<(Type, string), List<FieldInfo>> _cachedInjectableFields =
new Dictionary<(Type, string), List<FieldInfo>>();
public static void InjectInChildren<TVariable>(GameObject gameObject,
TVariable runtimeVariable, string id, bool debugLogEnabled)
where TVariable : ScriptableObject
{
var components = gameObject.GetComponentsInChildren<MonoBehaviour>();
foreach (var component in components)
{
if (component == null)
continue;
var type = component.GetType();
var cacheKey = (type, variableName: id);
if (!_cachedInjectableFields.TryGetValue(cacheKey, out var fields))
{
fields = new List<FieldInfo>();
foreach (var field in type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic |
BindingFlags.Public))
{
if (Attribute.IsDefined(field, typeof(RuntimeInjectableAttribute)) &&
field.FieldType == typeof(TVariable))
{
// Check if the field has the correct variable name
var attribute = field.GetCustomAttribute<RuntimeInjectableAttribute>();
if (attribute.Id != id || string.IsNullOrEmpty(attribute.Id))
continue;
fields.Add(field);
}
}
_cachedInjectableFields[cacheKey] = fields;
}
foreach (var field in fields)
{
field.SetValue(component, runtimeVariable);
if (debugLogEnabled)
{
Debug.Log(
$"<color=#f75369>[Injected]</color> {runtimeVariable.name} into {component.GetType().Name}.{field.Name}");
}
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ca4d627fedfbb3946bb2553a6169a16a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,207 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
namespace Obvious.Soap
{
//TODO: Rename to SoapTypeUtils when doing major Update
public static class SoapUtils
{
private static readonly Dictionary<string, string> intrinsicToSystemTypeMap = new Dictionary<string, string>
{
{ "byte", "System.Byte" },
{ "sbyte", "System.SByte" },
{ "char", "System.Char" },
{ "decimal", "System.Decimal" }, //not serializable by unity [DO NOT USE]. Use float or double instead.
{ "double", "System.Double" },
{ "uint", "System.UInt32" },
{ "nint", "System.IntPtr" },
{ "nuint", "System.UIntPtr" },
{ "long", "System.Int64" },
{ "ulong", "System.UInt64" },
{ "short", "System.Int16" },
{ "ushort", "System.UInt16" },
{ "int", "System.Int32" },
{ "float", "System.Single" },
{ "string", "System.String" },
{ "object", "System.Object" },
{ "bool", "System.Boolean" }
};
private static readonly HashSet<Type> unityTypes = new HashSet<Type>()
{
typeof(string), typeof(Vector4), typeof(Vector3), typeof(Vector2), typeof(Rect),
typeof(Quaternion), typeof(Color), typeof(Color32), typeof(LayerMask), typeof(Bounds),
typeof(Matrix4x4), typeof(AnimationCurve), typeof(Gradient), typeof(RectOffset),
typeof(bool[]), typeof(byte[]), typeof(sbyte[]), typeof(char[]),
typeof(double[]), typeof(float[]), typeof(int[]), typeof(uint[]), typeof(long[]),
typeof(ulong[]), typeof(short[]), typeof(ushort[]), typeof(string[]),
typeof(Vector4[]), typeof(Vector3[]), typeof(Vector2[]), typeof(Rect[]),
typeof(Quaternion[]), typeof(Color[]), typeof(Color32[]), typeof(LayerMask[]), typeof(Bounds[]),
typeof(Matrix4x4[]), typeof(AnimationCurve[]), typeof(Gradient[]), typeof(RectOffset[]),
typeof(List<bool>), typeof(List<byte>), typeof(List<sbyte>), typeof(List<char>),
typeof(List<double>), typeof(List<float>), typeof(List<int>), typeof(List<uint>), typeof(List<long>),
typeof(List<ulong>), typeof(List<short>), typeof(List<ushort>), typeof(List<string>),
typeof(List<Vector4>), typeof(List<Vector3>), typeof(List<Vector2>), typeof(List<Rect>),
typeof(List<Quaternion>), typeof(List<Color>), typeof(List<Color32>), typeof(List<LayerMask>),
typeof(List<Bounds>),
typeof(List<Matrix4x4>), typeof(List<AnimationCurve>), typeof(List<Gradient>), typeof(List<RectOffset>),
typeof(Vector3Int), typeof(Vector2Int), typeof(RectInt), typeof(BoundsInt),
typeof(Vector3Int[]), typeof(Vector2Int[]), typeof(RectInt[]), typeof(BoundsInt[]),
typeof(List<Vector3Int>), typeof(List<Vector2Int>), typeof(List<RectInt>), typeof(List<BoundsInt>),
};
private static readonly HashSet<string> unityTypesAsString = new HashSet<string>()
{
"string", "Vector4", "Vector3", "Vector2", "Rect",
"Quaternion", "Color", "Color32", "LayerMask", "Bounds",
"Matrix4x4", "AnimationCurve", "Gradient", "RectOffset",
"GameObject", "Transform", "Material", "Texture", "Sprite",
"AudioClip", "Mesh", "Shader", "Font", "TextAsset",
"Rigidbody", "Rigidbody2D", "Camera", "Light", "AudioSource",
"Vector2Int", "Vector3Int", "Collider", "Collider2D", "BoundsInt",
"RectInt", "MeshRenderer", "SpriteRenderer", "BoxCollider",
"BoxCollider2D", "CircleCollider2D", "PolygonCollider2D", "CapsuleCollider",
"CapsuleCollider2D", "MeshCollider", "MeshCollider2D", "SphereCollider",
"SphereCollider2D", "TerrainCollider", "WheelCollider", "WheelCollider2D",
"CharacterController", "CharacterJoint", "ConfigurableJoint", "FixedJoint",
"HingeJoint", "SpringJoint", "SliderJoint", "TargetJoint2D",
"AnimationCurve", "AnimationClip", "Animator", "AnimatorController",
};
public static bool IsIntrinsicType(string typeName)
{
if (intrinsicToSystemTypeMap.TryGetValue(typeName.ToLower(), out var qualifiedName))
typeName = qualifiedName;
Type type = Type.GetType(typeName);
if (type?.Namespace != null && type.Namespace.StartsWith("System"))
return true;
return false;
}
public static string GetIntrinsicType(string systemType)
{
return intrinsicToSystemTypeMap.FirstOrDefault(x =>
x.Value == $"System.{systemType}").Key ?? systemType;
}
public static bool IsUnityType(Type type) => unityTypes.Contains(type);
public static bool IsUnityType(string type) => unityTypesAsString.Contains(type);
internal static bool CanBeCreated(string typeName)
{
if (IsIntrinsicType(typeName) || IsUnityType(typeName))
return false;
return true;
}
public static bool IsSerializable(Type type)
{
if (type == null)
return false;
if (typeof(UnityEngine.Object).IsAssignableFrom(type) || type.IsEnum)
return true;
if (type.IsArray)
{
//dont support multi-dimensional arrays
if (type.GetArrayRank() != 1)
return false;
return IsSerializable(type.GetElementType());
}
if (type.IsGenericType)
{
var genericDefinition = type.GetGenericTypeDefinition();
if (genericDefinition == typeof(Nullable<>)
|| genericDefinition == typeof(List<>))
{
return IsSerializable(type.GetGenericArguments()[0]);
}
// Generic types are allowed on 2020.1 and later
#if !UNITY_2020_1_OR_NEWER
return false;
#endif
}
return Attribute.IsDefined(type, typeof(SerializableAttribute), false);
}
// public static bool IsSerializableLazy(Type type)
// {
// var isSerializable = false;
// isSerializable |= type.IsSerializable;
// isSerializable |= type.Namespace == "UnityEngine";
// isSerializable |= type.IsSubclassOf(typeof(MonoBehaviour));
// return isSerializable;
// }
internal static Type GetTypeByName(string name)
{
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (Type type in assembly.GetTypes())
{
if (string.Equals(type.Name, name, StringComparison.OrdinalIgnoreCase))
{
return type;
}
}
}
return null;
}
public static bool IsCollection(Type type)
{
if (type == null)
throw new ArgumentNullException(nameof(type));
if (type.IsArray)
return true;
if (type.IsGenericType && type.GetInterfaces().Any(i =>
i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>)))
return true;
// Check if it's a non-generic collection
if (typeof(IEnumerable).IsAssignableFrom(type))
return true;
return false;
}
public static bool InheritsFromOpenGeneric(Type type, Type openGenericBase)
{
if (type == null || openGenericBase == null) return false;
// walk class hierarchy
for (var t = type; t != null && t != typeof(object); t = t.BaseType)
{
var candidate = t.IsGenericType ? t.GetGenericTypeDefinition() : t;
if (candidate == openGenericBase)
return true;
}
// optionally check interfaces as well (useful if your base is an interface)
if (openGenericBase.IsInterface)
{
foreach (var itf in type.GetInterfaces())
{
var candidate = itf.IsGenericType ? itf.GetGenericTypeDefinition() : itf;
if (candidate == openGenericBase)
return true;
}
}
return false;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cf7a2d5b4db6ed14fb41e4f1d73d62a9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: