rabidus-test/Assets/PolyFew/Scripts/NonEditor/Extensions.cs

406 lines
14 KiB
C#
Raw Normal View History

2023-10-20 13:29:44 +03:00
//////////////////////////////////////////////////////
// Copyright (c) BrainFailProductions
//////////////////////////////////////////////////////
#if UNITY_EDITOR
using UnityEngine;
using System.Reflection;
using System;
using UnityEditor;
namespace BrainFailProductions.PolyFew
{
public static class Extensions
{
public static Vector3 TransformPointUnscaled(this Transform transform, Vector3 position)
{
var localToWorldMatrix = Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one);
return localToWorldMatrix.MultiplyPoint3x4(position);
}
public static Vector3 InverseTransformPointUnscaled(this Transform transform, Vector3 position)
{
var worldToLocalMatrix = Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one).inverse;
return worldToLocalMatrix.MultiplyPoint3x4(position);
}
public static T GetCopyOf<T>(this Component comp, T other) where T : Component
{
Type type = comp.GetType();
if (type != other.GetType()) return null; // type mis-match
BindingFlags flags = PrivateValueAccessor.Flags;
PropertyInfo[] pinfos = type.GetProperties(flags);
foreach (var pinfo in pinfos)
{
if (pinfo.CanWrite)
{
try
{
pinfo.SetValue(comp, pinfo.GetValue(other, null), null);
}
catch { } // In case of NotImplementedException being thrown.
}
}
FieldInfo[] finfos = type.GetFields(flags);
foreach (var finfo in finfos)
{
finfo.SetValue(comp, finfo.GetValue(other));
}
return comp as T;
}
public static T AddComponentClone<T>(this GameObject go, T toAdd) where T : Component
{
return go.AddComponent<T>().GetCopyOf(toAdd) as T;
}
public static T MakeSimilarTo<T>(this UnityEngine.Object copyTo, T copyFrom) where T : UnityEngine.Object
{
Type type = copyTo.GetType();
if (type != copyFrom.GetType()) return null; // type mis-match
BindingFlags flags = PrivateValueAccessor.Flags;
PropertyInfo[] pinfos = type.GetProperties(flags);
foreach (var pinfo in pinfos)
{
if (pinfo.CanWrite)
{
//Debug.Log("Propery Name: " + pinfo.Name);
try
{
pinfo.SetValue(copyTo, pinfo.GetValue(copyFrom, null), null);
}
catch { } // In case of NotImplementedException being thrown.
}
}
FieldInfo[] finfos = type.GetFields(flags);
foreach (var finfo in finfos)
{
//Debug.Log("Field Name: " + finfo.Name);
finfo.SetValue(copyTo, finfo.GetValue(copyFrom));
}
return copyTo as T;
}
public static T MakeSimilarToOtherMesh<T>(this Mesh copyTo, T copyFrom) where T : UnityEngine.Object
{
Type type = copyTo.GetType();
if (type != copyFrom.GetType()) return null; // type mis-match
#pragma warning disable
Mesh mesh = new Mesh();
BindingFlags flags = PrivateValueAccessor.Flags;
PropertyInfo[] pinfos = type.GetProperties(flags);
#pragma warning disable
PropertyInfo trianglesProp = type.GetProperty("triangles", flags);
PropertyInfo verticesProp = type.GetProperty("vertices", flags);
PropertyInfo bonesProp = type.GetProperty("boneWeights", flags);
bool vertsFirst = copyTo.triangles.Length <= (copyFrom as Mesh).triangles.Length;
if (!vertsFirst) { trianglesProp.SetValue(copyTo, trianglesProp.GetValue(copyFrom, null), null); }
//bonesProp.SetValue(copyTo, bonesProp.GetValue(copyFrom, null), null);
//mesh.vertices = new Vector3[(copyFrom as Mesh).vertices.Length];
//mesh.triangles = new int[(copyFrom as Mesh).triangles.Length];
//mesh.boneWeights = new BoneWeight[(copyFrom as Mesh).vertices.Length];
for (int a = 0; a < pinfos.Length; a++)
{
PropertyInfo pinfo = pinfos[a];
if (!vertsFirst && pinfo.Name == "triangles") { continue; }
if (pinfo.Name == "boneWeights") { continue; }
if (pinfo.CanWrite)
{
try
{
pinfo.SetValue(copyTo, pinfo.GetValue(copyFrom, null), null);
}
catch { } // In case of NotImplementedException being thrown.
}
}
bonesProp.SetValue(copyTo, bonesProp.GetValue(copyFrom, null), null);
FieldInfo[] finfos = type.GetFields(flags);
foreach (var finfo in finfos)
{
finfo.SetValue(copyTo, finfo.GetValue(copyFrom));
}
return copyTo as T;
}
public static void RemoveNullObjects(this SerializedProperty prop)
{
for (int i = 0; i < prop.arraySize; i++)
{
if (prop.GetAt(i).GetValue() == null)
{
prop.RemoveAt(i);
i--;
}
}
}
public static bool Contains(this SerializedProperty prop, System.Object value)
{
for (int i = 0, size = prop.arraySize; i < size; i++)
{
if (prop.GetAt(i).GetValue() == value)
return true;
}
return false;
}
public static void MoveUp(this SerializedProperty prop, int fromIndex)
{
AssertArray(prop);
AssertNotEmpty(prop);
int previous = fromIndex - 1;
if (previous < 0) previous = prop.arraySize - 1;
prop.Swap(fromIndex, previous);
}
public static void MoveDown(this SerializedProperty prop, int fromIndex)
{
AssertArray(prop);
AssertNotEmpty(prop);
int next = (fromIndex + 1) % prop.arraySize;
prop.Swap(fromIndex, next);
}
public static void Swap(this SerializedProperty prop, int i, int j)
{
AssertArray(prop);
AssertNotEmpty(prop);
var value1 = prop.GetObjectValueAt(i);
var value2 = prop.GetObjectValueAt(j);
System.Object temp = value1;
prop.SetObjectValueAt(i, value2);
prop.SetObjectValueAt(j, temp);
}
public static bool ContainsReferenceTypes(this SerializedProperty prop)
{
AssertArray(prop);
AssertNotEmpty(prop);
return prop.GetFirst().IsReferenceType();
}
public static bool IsReferenceType(this SerializedProperty prop)
{
return prop.propertyType == SerializedPropertyType.ObjectReference;
}
public static void Add(this SerializedProperty prop, UnityEngine.Object value)
{
AssertArray(prop);
prop.arraySize++;
prop.GetAt(prop.arraySize - 1).objectReferenceValue = value;
}
public static void Add(this SerializedProperty prop)
{
AssertArray(prop);
prop.arraySize++;
prop.GetLast().SetToDefault();
}
public static void SetToDefault(this SerializedProperty prop)
{
switch (prop.propertyType)
{
case SerializedPropertyType.Integer:
prop.intValue = default(int);
break;
case SerializedPropertyType.Float:
prop.floatValue = default(float);
break;
case SerializedPropertyType.Boolean:
prop.boolValue = default(bool);
break;
case SerializedPropertyType.Color:
prop.colorValue = default(Color);
break;
case SerializedPropertyType.Bounds:
prop.boundsValue = default(Bounds);
break;
case SerializedPropertyType.Rect:
prop.rectValue = default(Rect);
break;
case SerializedPropertyType.Vector2:
prop.vector2Value = default(Vector2);
break;
case SerializedPropertyType.Vector3:
prop.vector3Value = default(Vector3);
break;
case SerializedPropertyType.ObjectReference:
prop.objectReferenceValue = null;
break;
}
}
public static SerializedProperty GetLast(this SerializedProperty prop)
{
AssertArray(prop);
return prop.GetAt(prop.arraySize - 1);
}
public static SerializedProperty GetFirst(this SerializedProperty prop)
{
AssertArray(prop);
return prop.GetAt(0);
}
public static void AssertArray(this SerializedProperty prop)
{
if (!prop.isArray)
throw new UnityException("SerializedProperty `" + prop.name + "` is not an array. Yet you're trying to index it!");
}
public static void RemoveAt(this SerializedProperty prop, int atIndex)
{
AssertArray(prop);
AssertNotEmpty(prop);
for (int i = atIndex, size = prop.arraySize; i < size - 1; i++)
{
prop.SetObjectValueAt(i, prop.GetObjectValueAt(i + 1));
}
prop.arraySize--;
}
public static void AssertNotEmpty(this SerializedProperty prop)
{
if (prop.arraySize <= 0)
throw new UnityException("Array `" + prop.name + "` is empty. You can't do anything with it!");
}
public static System.Object GetObjectValueAt(this SerializedProperty prop, int i)
{
//AssertArray(prop);
//AssertNotEmpty(prop);
return prop.GetAt(i).GetValue();
}
public static void SetObjectValueAt(this SerializedProperty prop, int i, System.Object toValue)
{
AssertArray(prop);
AssertNotEmpty(prop);
prop.GetAt(i).SetObjectValue(toValue);
}
public static void SetObjectValue(this SerializedProperty prop, System.Object toValue)
{
switch (prop.propertyType)
{
case SerializedPropertyType.Boolean:
prop.boolValue = (bool)toValue;
break;
case SerializedPropertyType.Bounds:
prop.boundsValue = (Bounds)toValue;
break;
case SerializedPropertyType.Color:
prop.colorValue = (Color)toValue;
break;
case SerializedPropertyType.Float:
prop.floatValue = (float)toValue;
break;
case SerializedPropertyType.Integer:
prop.intValue = (int)toValue;
break;
case SerializedPropertyType.ObjectReference:
prop.objectReferenceValue = toValue as UnityEngine.Object;
break;
case SerializedPropertyType.Rect:
prop.rectValue = (Rect)toValue;
break;
case SerializedPropertyType.String:
prop.stringValue = (string)toValue;
break;
case SerializedPropertyType.Vector2:
prop.vector2Value = (Vector2)toValue;
break;
case SerializedPropertyType.Vector3:
prop.vector3Value = (Vector3)toValue;
break;
}
}
public static System.Object GetValue(this SerializedProperty prop)
{
#pragma warning disable
switch (prop.propertyType)
{
case SerializedPropertyType.Boolean:
return prop.boolValue;
break;
case SerializedPropertyType.Bounds:
return prop.boundsValue;
break;
case SerializedPropertyType.Color:
return prop.colorValue;
break;
case SerializedPropertyType.Float:
return prop.floatValue;
break;
case SerializedPropertyType.Integer:
return prop.intValue;
break;
case SerializedPropertyType.ObjectReference:
return prop.objectReferenceValue;
break;
case SerializedPropertyType.Rect:
return prop.rectValue;
break;
case SerializedPropertyType.String:
return prop.stringValue;
break;
case SerializedPropertyType.Vector2:
return prop.vector2Value;
break;
case SerializedPropertyType.Vector3:
return prop.vector3Value;
default: return null;
}
}
public static T GetValue<T>(this SerializedProperty prop)
{
return (T)prop.GetValue();
}
public static SerializedProperty GetAt(this SerializedProperty prop, int i)
{
//AssertArray(prop);
return prop.GetArrayElementAtIndex(i);
}
}
}
#endif