2571 lines
81 KiB
C#
2571 lines
81 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Reflection;
|
||
using System.Text;
|
||
using System.Text.RegularExpressions;
|
||
using UnityEngine;
|
||
using UnityEngine.Events;
|
||
using UnityEngine.UI;
|
||
|
||
//参考QFramework拓展方法
|
||
namespace Guru
|
||
{
|
||
public static class DelegateExtension
|
||
{
|
||
#region Func Extension
|
||
|
||
/// <summary>
|
||
/// 功能:不为空则调用 Func
|
||
///
|
||
/// 示例:
|
||
/// <code>
|
||
/// Func<int> func = ()=> 1;
|
||
/// var number = func.InvokeGracefully(); // 等价于 if (func != null) number = func();
|
||
/// </code>
|
||
/// </summary>
|
||
/// <param name="selfFunc"></param>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <returns></returns>
|
||
public static T InvokeGracefully<T>(this Func<T> selfFunc)
|
||
{
|
||
return null != selfFunc ? selfFunc() : default(T);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Action
|
||
|
||
/// <summary>
|
||
/// 功能:不为空则调用 Action
|
||
///
|
||
/// 示例:
|
||
/// <code>
|
||
/// System.Action action = () => Log.I("action called");
|
||
/// action.InvokeGracefully(); // if (action != null) action();
|
||
/// </code>
|
||
/// </summary>
|
||
/// <param name="selfAction"> action 对象 </param>
|
||
/// <returns> 是否调用成功 </returns>
|
||
public static bool InvokeGracefully(this Action selfAction)
|
||
{
|
||
if (null != selfAction)
|
||
{
|
||
selfAction();
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 不为空则调用 Action<T>
|
||
///
|
||
/// 示例:
|
||
/// <code>
|
||
/// System.Action<int> action = (number) => Log.I("action called" + number);
|
||
/// action.InvokeGracefully(10); // if (action != null) action(10);
|
||
/// </code>
|
||
/// </summary>
|
||
/// <param name="selfAction"> action 对象</param>
|
||
/// <typeparam name="T">参数</typeparam>
|
||
/// <returns> 是否调用成功</returns>
|
||
public static bool InvokeGracefully<T>(this Action<T> selfAction, T t)
|
||
{
|
||
if (null != selfAction)
|
||
{
|
||
selfAction(t);
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 不为空则调用 Action<T,K>
|
||
///
|
||
/// 示例
|
||
/// <code>
|
||
/// System.Action<int,string> action = (number,name) => Log.I("action called" + number + name);
|
||
/// action.InvokeGracefully(10,"qframework"); // if (action != null) action(10,"qframework");
|
||
/// </code>
|
||
/// </summary>
|
||
/// <param name="selfAction"></param>
|
||
/// <returns> call succeed</returns>
|
||
public static bool InvokeGracefully<T, K>(this Action<T, K> selfAction, T t, K k)
|
||
{
|
||
if (null != selfAction)
|
||
{
|
||
selfAction(t, k);
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 不为空则调用委托
|
||
///
|
||
/// 示例:
|
||
/// <code>
|
||
/// // delegate
|
||
/// TestDelegate testDelegate = () => { };
|
||
/// testDelegate.InvokeGracefully();
|
||
/// </code>
|
||
/// </summary>
|
||
/// <param name="selfAction"></param>
|
||
/// <returns> call suceed </returns>
|
||
public static bool InvokeGracefully(this Delegate selfAction, params object[] args)
|
||
{
|
||
if (null != selfAction)
|
||
{
|
||
selfAction.DynamicInvoke(args);
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
|
||
public static class CSharpObjectExtension
|
||
{
|
||
/// <summary>
|
||
/// 是否相等
|
||
///
|
||
/// 示例:
|
||
/// <code>
|
||
/// if (this.Is(player))
|
||
/// {
|
||
/// ...
|
||
/// }
|
||
/// </code>
|
||
/// </summary>
|
||
/// <param name="selfObj"></param>
|
||
/// <param name="value"></param>
|
||
/// <returns></returns>
|
||
public static bool Is(this object selfObj, object value)
|
||
{
|
||
return selfObj == value;
|
||
}
|
||
|
||
public static bool Is<T>(this T selfObj, Func<T, bool> condition)
|
||
{
|
||
return condition(selfObj);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 表达式成立 则执行 Action
|
||
///
|
||
/// 示例:
|
||
/// <code>
|
||
/// (1 == 1).Do(()=>Debug.Log("1 == 1");
|
||
/// </code>
|
||
/// </summary>
|
||
/// <param name="selfCondition"></param>
|
||
/// <param name="action"></param>
|
||
/// <returns></returns>
|
||
public static bool Do(this bool selfCondition, Action action)
|
||
{
|
||
if (selfCondition)
|
||
{
|
||
action();
|
||
}
|
||
|
||
return selfCondition;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 不管表达成不成立 都执行 Action,并把结果返回
|
||
///
|
||
/// 示例:
|
||
/// <code>
|
||
/// (1 == 1).Do((result)=>Debug.Log("1 == 1:" + result);
|
||
/// </code>
|
||
/// </summary>
|
||
/// <param name="selfCondition"></param>
|
||
/// <param name="action"></param>
|
||
/// <returns></returns>
|
||
public static bool Do(this bool selfCondition, Action<bool> action)
|
||
{
|
||
action(selfCondition);
|
||
|
||
return selfCondition;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 功能:判断是否为空
|
||
///
|
||
/// 示例:
|
||
/// <code>
|
||
/// var simpleObject = new object();
|
||
///
|
||
/// if (simpleObject.IsNull()) // 等价于 simpleObject == null
|
||
/// {
|
||
/// // do sth
|
||
/// }
|
||
/// </code>
|
||
/// </summary>
|
||
/// <param name="selfObj">判断对象(this)</param>
|
||
/// <typeparam name="T">对象的类型(可不填)</typeparam>
|
||
/// <returns>是否为空</returns>
|
||
public static bool IsNull<T>(this T selfObj) where T : class
|
||
{
|
||
return null == selfObj;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 功能:判断不是为空
|
||
/// 示例:
|
||
/// <code>
|
||
/// var simpleObject = new object();
|
||
///
|
||
/// if (simpleObject.IsNotNull()) // 等价于 simpleObject != null
|
||
/// {
|
||
/// // do sth
|
||
/// }
|
||
/// </code>
|
||
/// </summary>
|
||
/// <param name="selfObj">判断对象(this)</param>
|
||
/// <typeparam name="T">对象的类型(可不填)</typeparam>
|
||
/// <returns>是否不为空</returns>
|
||
public static bool IsNotNull<T>(this T selfObj) where T : class
|
||
{
|
||
return null != selfObj;
|
||
}
|
||
|
||
public static void DoIfNotNull<T>(this T selfObj, Action<T> action) where T : class
|
||
{
|
||
if (selfObj != null)
|
||
{
|
||
action(selfObj);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 泛型工具
|
||
///
|
||
/// 实例:
|
||
/// <code>
|
||
/// 示例:
|
||
/// var typeName = GenericExtention.GetTypeName<string>();
|
||
/// typeName.LogInfo(); // string
|
||
/// </code>
|
||
/// </summary>
|
||
public static class GenericUtil
|
||
{
|
||
/// <summary>
|
||
/// 获取泛型名字
|
||
/// <code>
|
||
/// var typeName = GenericExtention.GetTypeName<string>();
|
||
/// typeName.LogInfo(); // string
|
||
/// </code>
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <returns></returns>
|
||
public static string GetTypeName<T>()
|
||
{
|
||
return typeof(T).ToString();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 可枚举的集合扩展(Array、List<T>、Dictionary<K,V>)
|
||
/// </summary>
|
||
public static class IEnumerableExtension
|
||
{
|
||
#region Array Extension
|
||
|
||
/// <summary>
|
||
/// 遍历数组
|
||
/// <code>
|
||
/// var testArray = new[] { 1, 2, 3 };
|
||
/// testArray.ForEach(number => number.LogInfo());
|
||
/// </code>
|
||
/// </summary>
|
||
/// <returns>The each.</returns>
|
||
/// <param name="selfArray">Self array.</param>
|
||
/// <param name="action">Action.</param>
|
||
/// <typeparam name="T">The 1st type parameter.</typeparam>
|
||
/// <returns> 返回自己 </returns>
|
||
public static T[] ForEach<T>(this T[] selfArray, Action<T> action)
|
||
{
|
||
Array.ForEach(selfArray, action);
|
||
return selfArray;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 遍历 IEnumerable
|
||
/// <code>
|
||
/// // IEnumerable<T>
|
||
/// IEnumerable<int> testIenumerable = new List<int> { 1, 2, 3 };
|
||
/// testIenumerable.ForEach(number => number.LogInfo());
|
||
/// // 支持字典的遍历
|
||
/// new Dictionary<string, string>()
|
||
/// .ForEach(keyValue => Log.I("key:{0},value:{1}", keyValue.Key, keyValue.Value));
|
||
/// </code>
|
||
/// </summary>
|
||
/// <returns>The each.</returns>
|
||
/// <param name="selfArray">Self array.</param>
|
||
/// <param name="action">Action.</param>
|
||
/// <typeparam name="T">The 1st type parameter.</typeparam>
|
||
public static IEnumerable<T> ForEach<T>(this IEnumerable<T> selfArray, Action<T> action)
|
||
{
|
||
if (action == null)
|
||
throw new ArgumentException();
|
||
|
||
foreach (var item in selfArray)
|
||
{
|
||
action(item);
|
||
}
|
||
|
||
return selfArray;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region List Extension
|
||
|
||
/// <summary>
|
||
/// 倒序遍历
|
||
/// <code>
|
||
/// var testList = new List<int> { 1, 2, 3 };
|
||
/// testList.ForEachReverse(number => number.LogInfo()); // 3, 2, 1
|
||
/// </code>
|
||
/// </summary>
|
||
/// <returns>返回自己</returns>
|
||
/// <param name="selfList">Self list.</param>
|
||
/// <param name="action">Action.</param>
|
||
/// <typeparam name="T">The 1st type parameter.</typeparam>
|
||
public static List<T> ForEachReverse<T>(this List<T> selfList, Action<T> action)
|
||
{
|
||
if (action == null)
|
||
throw new ArgumentException();
|
||
|
||
for (var i = selfList.Count - 1; i >= 0; --i)
|
||
action(selfList[i]);
|
||
|
||
return selfList;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 倒序遍历(可获得索引)
|
||
/// <code>
|
||
/// var testList = new List<int> { 1, 2, 3 };
|
||
/// testList.ForEachReverse((number,index)=> number.LogInfo()); // 3, 2, 1
|
||
/// </code>
|
||
/// </summary>
|
||
/// <returns>The each reverse.</returns>
|
||
/// <param name="selfList">Self list.</param>
|
||
/// <param name="action">Action.</param>
|
||
/// <typeparam name="T">The 1st type parameter.</typeparam>
|
||
public static List<T> ForEachReverse<T>(this List<T> selfList, Action<T, int> action)
|
||
{
|
||
if (action == null)
|
||
throw new ArgumentException();
|
||
|
||
for (var i = selfList.Count - 1; i >= 0; --i)
|
||
action(selfList[i], i);
|
||
|
||
return selfList;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 遍历列表(可获得索引)
|
||
/// <code>
|
||
/// var testList = new List<int> {1, 2, 3 };
|
||
/// testList.Foreach((number,index)=>number.LogInfo()); // 1, 2, 3,
|
||
/// </code>
|
||
/// </summary>
|
||
/// <typeparam name="T">列表类型</typeparam>
|
||
/// <param name="list">目标表</param>
|
||
/// <param name="action">行为</param>
|
||
public static void ForEach<T>(this List<T> list, Action<int, T> action)
|
||
{
|
||
for (var i = 0; i < list.Count; i++)
|
||
{
|
||
action(i, list[i]);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Dictionary Extension
|
||
|
||
/// <summary>
|
||
/// 合并字典
|
||
/// <code>
|
||
/// // 示例
|
||
/// var dictionary1 = new Dictionary<string, string> { { "1", "2" } };
|
||
/// var dictionary2 = new Dictionary<string, string> { { "3", "4" } };
|
||
/// var dictionary3 = dictionary1.Merge(dictionary2);
|
||
/// dictionary3.ForEach(pair => Log.I("{0}:{1}", pair.Key, pair.Value));
|
||
/// </code>
|
||
/// </summary>
|
||
/// <returns>The merge.</returns>
|
||
/// <param name="dictionary">Dictionary.</param>
|
||
/// <param name="dictionaries">Dictionaries.</param>
|
||
/// <typeparam name="TKey">The 1st type parameter.</typeparam>
|
||
/// <typeparam name="TValue">The 2nd type parameter.</typeparam>
|
||
public static Dictionary<TKey, TValue> Merge<TKey, TValue>(this Dictionary<TKey, TValue> dictionary,
|
||
params Dictionary<TKey, TValue>[] dictionaries)
|
||
{
|
||
return dictionaries.Aggregate(dictionary,
|
||
(current, dict) => current.Union(dict).ToDictionary(kv => kv.Key, kv => kv.Value));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 遍历字典
|
||
/// <code>
|
||
/// var dict = new Dictionary<string,string> {{"name","liangxie},{"age","18"}};
|
||
/// dict.ForEach((key,value)=> Log.I("{0}:{1}",key,value);// name:liangxie age:18
|
||
/// </code>
|
||
/// </summary>
|
||
/// <typeparam name="K"></typeparam>
|
||
/// <typeparam name="V"></typeparam>
|
||
/// <param name="dict"></param>
|
||
/// <param name="action"></param>
|
||
public static void ForEach<K, V>(this Dictionary<K, V> dict, Action<K, V> action)
|
||
{
|
||
var dictE = dict.GetEnumerator();
|
||
|
||
while (dictE.MoveNext())
|
||
{
|
||
var current = dictE.Current;
|
||
action(current.Key, current.Value);
|
||
}
|
||
|
||
dictE.Dispose();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 字典添加新的词典
|
||
/// </summary>
|
||
/// <typeparam name="K"></typeparam>
|
||
/// <typeparam name="V"></typeparam>
|
||
/// <param name="dict"></param>
|
||
/// <param name="addInDict"></param>
|
||
/// <param name="isOverride"></param>
|
||
public static void AddRange<K, V>(this Dictionary<K, V> dict, Dictionary<K, V> addInDict,
|
||
bool isOverride = false)
|
||
{
|
||
var dictE = addInDict.GetEnumerator();
|
||
|
||
while (dictE.MoveNext())
|
||
{
|
||
var current = dictE.Current;
|
||
if (dict.ContainsKey(current.Key))
|
||
{
|
||
if (isOverride)
|
||
dict[current.Key] = current.Value;
|
||
continue;
|
||
}
|
||
|
||
dict.Add(current.Key, current.Value);
|
||
}
|
||
|
||
dictE.Dispose();
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
|
||
/// <summary>
|
||
/// 对 System.IO 的一些扩展
|
||
/// </summary>
|
||
public static class IOExtension
|
||
{
|
||
/// <summary>
|
||
/// 检测路径是否存在,如果不存在则创建
|
||
/// </summary>
|
||
/// <param name="path"></param>
|
||
public static string CreateDirIfNotExists4FilePath(this string path)
|
||
{
|
||
var direct = Path.GetDirectoryName(path);
|
||
|
||
if (!Directory.Exists(direct))
|
||
{
|
||
Directory.CreateDirectory(direct);
|
||
}
|
||
|
||
return path;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 创建新的文件夹,如果存在则不创建
|
||
/// <code>
|
||
/// var testDir = "Assets/TestFolder";
|
||
/// testDir.CreateDirIfNotExists();
|
||
/// // 结果为,在 Assets 目录下创建 TestFolder
|
||
/// </code>
|
||
/// </summary>
|
||
public static string CreateDirIfNotExists(this string dirFullPath)
|
||
{
|
||
if (!Directory.Exists(dirFullPath))
|
||
{
|
||
Directory.CreateDirectory(dirFullPath);
|
||
}
|
||
|
||
return dirFullPath;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 删除文件夹,如果存在
|
||
/// <code>
|
||
/// var testDir = "Assets/TestFolder";
|
||
/// testDir.DeleteDirIfExists();
|
||
/// // 结果为,在 Assets 目录下删除了 TestFolder
|
||
/// </code>
|
||
/// </summary>
|
||
public static void DeleteDirIfExists(this string dirFullPath)
|
||
{
|
||
if (Directory.Exists(dirFullPath))
|
||
{
|
||
Directory.Delete(dirFullPath, true);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 清空 Dir(保留目录),如果存在。
|
||
/// <code>
|
||
/// var testDir = "Assets/TestFolder";
|
||
/// testDir.EmptyDirIfExists();
|
||
/// // 结果为,清空了 TestFolder 里的内容
|
||
/// </code>
|
||
/// </summary>
|
||
public static void EmptyDirIfExists(this string dirFullPath)
|
||
{
|
||
if (Directory.Exists(dirFullPath))
|
||
{
|
||
Directory.Delete(dirFullPath, true);
|
||
}
|
||
|
||
Directory.CreateDirectory(dirFullPath);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 删除文件 如果存在
|
||
/// <code>
|
||
/// // 示例
|
||
/// var filePath = "Assets/Test.txt";
|
||
/// File.Create("Assets/Test);
|
||
/// filePath.DeleteFileIfExists();
|
||
/// // 结果为,删除了 Test.txt
|
||
/// </code>
|
||
/// </summary>
|
||
/// <param name="fileFullPath"></param>
|
||
/// <returns> 是否进行了删除操作 </returns>
|
||
public static bool DeleteFileIfExists(this string fileFullPath)
|
||
{
|
||
if (File.Exists(fileFullPath))
|
||
{
|
||
File.Delete(fileFullPath);
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 合并路径
|
||
/// <code>
|
||
/// // 示例:
|
||
/// Application.dataPath.CombinePath("Resources").LogInfo(); // /projectPath/Assets/Resources
|
||
/// </code>
|
||
/// </summary>
|
||
/// <param name="selfPath"></param>
|
||
/// <param name="toCombinePath"></param>
|
||
/// <returns> 合并后的路径 </returns>
|
||
public static string CombinePath(this string selfPath, string toCombinePath)
|
||
{
|
||
return Path.Combine(selfPath, toCombinePath);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 打开文件夹
|
||
/// </summary>
|
||
/// <param name="path"></param>
|
||
public static void OpenFolder(string path)
|
||
{
|
||
#if UNITY_STANDALONE_OSX
|
||
System.Diagnostics.Process.Start("open", path);
|
||
#elif UNITY_STANDALONE_WIN
|
||
System.Diagnostics.Process.Start("explorer.exe", path);
|
||
#endif
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取文件夹名
|
||
/// </summary>
|
||
/// <param name="fileName"></param>
|
||
/// <returns></returns>
|
||
public static string GetDirectoryName(string fileName)
|
||
{
|
||
fileName = MakePathStandard(fileName);
|
||
return fileName.Substring(0, fileName.LastIndexOf('/'));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取文件名
|
||
/// </summary>
|
||
/// <param name="path"></param>
|
||
/// <param name="separator"></param>
|
||
/// <returns></returns>
|
||
public static string GetFileName(string path, char separator = '/')
|
||
{
|
||
path = MakePathStandard(path);
|
||
return path.Substring(path.LastIndexOf(separator) + 1);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取不带后缀的文件名
|
||
/// </summary>
|
||
/// <param name="fileName"></param>
|
||
/// <param name="separator"></param>
|
||
/// <returns></returns>
|
||
public static string GetFileNameWithoutExtention(string fileName, char separator = '/')
|
||
{
|
||
return GetFilePathWithoutExtention(GetFileName(fileName, separator));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取不带后缀的文件路径
|
||
/// </summary>
|
||
/// <param name="fileName"></param>
|
||
/// <returns></returns>
|
||
public static string GetFilePathWithoutExtention(string fileName)
|
||
{
|
||
if (fileName.Contains("."))
|
||
return fileName.Substring(0, fileName.LastIndexOf('.'));
|
||
return fileName;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 使目录存在,Path可以是目录名必须是文件名
|
||
/// </summary>
|
||
/// <param name="path"></param>
|
||
public static void MakeFileDirectoryExist(string path)
|
||
{
|
||
string root = Path.GetDirectoryName(path);
|
||
if (!Directory.Exists(root))
|
||
{
|
||
Directory.CreateDirectory(root);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 使目录存在
|
||
/// </summary>
|
||
/// <param name="path"></param>
|
||
public static void MakeDirectoryExist(string path)
|
||
{
|
||
if (!Directory.Exists(path))
|
||
{
|
||
Directory.CreateDirectory(path);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取父文件夹
|
||
/// </summary>
|
||
/// <param name="path"></param>
|
||
/// <returns></returns>
|
||
public static string GetPathParentFolder(this string path)
|
||
{
|
||
if (string.IsNullOrEmpty(path))
|
||
{
|
||
return string.Empty;
|
||
}
|
||
|
||
return Path.GetDirectoryName(path);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 使路径标准化,去除空格并将所有'\'转换为'/'
|
||
/// </summary>
|
||
/// <param name="path"></param>
|
||
/// <returns></returns>
|
||
public static string MakePathStandard(string path)
|
||
{
|
||
return path.Trim().Replace("\\", "/");
|
||
}
|
||
|
||
public static List<string> GetDirSubFilePathList(this string dirABSPath, bool isRecursive = true,
|
||
string suffix = "")
|
||
{
|
||
var pathList = new List<string>();
|
||
var di = new DirectoryInfo(dirABSPath);
|
||
|
||
if (!di.Exists)
|
||
{
|
||
return pathList;
|
||
}
|
||
|
||
var files = di.GetFiles();
|
||
foreach (var fi in files)
|
||
{
|
||
if (!string.IsNullOrEmpty(suffix))
|
||
{
|
||
if (!fi.FullName.EndsWith(suffix, System.StringComparison.CurrentCultureIgnoreCase))
|
||
{
|
||
continue;
|
||
}
|
||
}
|
||
|
||
pathList.Add(fi.FullName);
|
||
}
|
||
|
||
if (isRecursive)
|
||
{
|
||
var dirs = di.GetDirectories();
|
||
foreach (var d in dirs)
|
||
{
|
||
pathList.AddRange(GetDirSubFilePathList(d.FullName, isRecursive, suffix));
|
||
}
|
||
}
|
||
|
||
return pathList;
|
||
}
|
||
|
||
public static List<string> GetDirSubDirNameList(this string dirABSPath)
|
||
{
|
||
var di = new DirectoryInfo(dirABSPath);
|
||
|
||
var dirs = di.GetDirectories();
|
||
|
||
return dirs.Select(d => d.Name).ToList();
|
||
}
|
||
|
||
public static string GetFileName(this string absOrAssetsPath)
|
||
{
|
||
var name = absOrAssetsPath.Replace("\\", "/");
|
||
var lastIndex = name.LastIndexOf("/");
|
||
|
||
return lastIndex >= 0 ? name.Substring(lastIndex + 1) : name;
|
||
}
|
||
|
||
public static string GetFileNameWithoutExtend(this string absOrAssetsPath)
|
||
{
|
||
var fileName = GetFileName(absOrAssetsPath);
|
||
var lastIndex = fileName.LastIndexOf(".");
|
||
|
||
return lastIndex >= 0 ? fileName.Substring(0, lastIndex) : fileName;
|
||
}
|
||
|
||
public static string GetFileExtendName(this string absOrAssetsPath)
|
||
{
|
||
var lastIndex = absOrAssetsPath.LastIndexOf(".");
|
||
|
||
if (lastIndex >= 0)
|
||
{
|
||
return absOrAssetsPath.Substring(lastIndex);
|
||
}
|
||
|
||
return string.Empty;
|
||
}
|
||
|
||
public static string GetDirPath(this string absOrAssetsPath)
|
||
{
|
||
var name = absOrAssetsPath.Replace("\\", "/");
|
||
var lastIndex = name.LastIndexOf("/");
|
||
return name.Substring(0, lastIndex + 1);
|
||
}
|
||
|
||
public static string GetLastDirName(this string absOrAssetsPath)
|
||
{
|
||
var name = absOrAssetsPath.Replace("\\", "/");
|
||
var dirs = name.Split('/');
|
||
|
||
return absOrAssetsPath.EndsWith("/") ? dirs[dirs.Length - 2] : dirs[dirs.Length - 1];
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 简单的概率计算
|
||
/// </summary>
|
||
public static class ProbilityHelper
|
||
{
|
||
public static T RandomValueFrom<T>(params T[] values)
|
||
{
|
||
return values[UnityEngine.Random.Range(0, values.Length)];
|
||
}
|
||
|
||
/// <summary>
|
||
/// percent probability
|
||
/// </summary>
|
||
/// <param name="percent"> 0 ~ 100 </param>
|
||
/// <returns></returns>
|
||
public static bool PercentProbability(int percent)
|
||
{
|
||
return UnityEngine.Random.Range(0, 1000) * 0.001f < 50 * 0.01f;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 面向对象扩展(继承、封装、多态)
|
||
/// </summary>
|
||
public static class OOPExtension
|
||
{
|
||
/// <summary>
|
||
/// Determines whether the type implements the specified interface
|
||
/// and is not an interface itself.
|
||
/// </summary>
|
||
/// <returns><c>true</c>, if interface was implementsed, <c>false</c> otherwise.</returns>
|
||
/// <param name="type">Type.</param>
|
||
/// <typeparam name="T">The 1st type parameter.</typeparam>
|
||
public static bool ImplementsInterface<T>(this Type type)
|
||
{
|
||
return !type.IsInterface && type.GetInterfaces().Contains(typeof(T));
|
||
}
|
||
|
||
/// <summary>
|
||
/// Determines whether the type implements the specified interface
|
||
/// and is not an interface itself.
|
||
/// </summary>
|
||
/// <returns><c>true</c>, if interface was implementsed, <c>false</c> otherwise.</returns>
|
||
/// <param name="type">Type.</param>
|
||
/// <typeparam name="T">The 1st type parameter.</typeparam>
|
||
public static bool ImplementsInterface<T>(this object obj)
|
||
{
|
||
var type = obj.GetType();
|
||
return !type.IsInterface && type.GetInterfaces().Contains(typeof(T));
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 程序集工具
|
||
/// </summary>
|
||
public class AssemblyUtil
|
||
{
|
||
/// <summary>
|
||
/// 获取 Assembly-CSharp 程序集
|
||
/// </summary>
|
||
public static Assembly DefaultCSharpAssembly
|
||
{
|
||
get
|
||
{
|
||
return AppDomain.CurrentDomain.GetAssemblies()
|
||
.SingleOrDefault(a => a.GetName().Name == "Assembly-CSharp");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取默认的程序集中的类型
|
||
/// </summary>
|
||
/// <param name="typeName"></param>
|
||
/// <returns></returns>
|
||
public static Type GetDefaultAssemblyType(string typeName)
|
||
{
|
||
return DefaultCSharpAssembly.GetType(typeName);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 反射扩展
|
||
/// </summary>
|
||
public static class ReflectionExtension
|
||
{
|
||
public static Assembly GetAssemblyCSharp()
|
||
{
|
||
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||
foreach (var a in assemblies)
|
||
{
|
||
if (a.FullName.StartsWith("Assembly-CSharp,"))
|
||
return a;
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
public static Assembly GetAssemblyCSharpEditor()
|
||
{
|
||
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||
foreach (var a in assemblies)
|
||
{
|
||
if (a.FullName.StartsWith("Assembly-CSharp-Editor,"))
|
||
return a;
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通过反射方式调用函数
|
||
/// </summary>
|
||
/// <param name="obj"></param>
|
||
/// <param name="methodName">方法名</param>
|
||
/// <param name="args">参数</param>
|
||
/// <returns></returns>
|
||
public static object InvokeByReflect(this object obj, string methodName, params object[] args)
|
||
{
|
||
var methodInfo = obj.GetType().GetMethod(methodName);
|
||
return methodInfo == null ? null : methodInfo.Invoke(obj, args);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通过反射方式获取域值
|
||
/// </summary>
|
||
/// <param name="obj"></param>
|
||
/// <param name="fieldName">域名</param>
|
||
/// <returns></returns>
|
||
public static object GetFieldByReflect(this object obj, string fieldName)
|
||
{
|
||
var fieldInfo = obj.GetType().GetField(fieldName);
|
||
return fieldInfo == null ? null : fieldInfo.GetValue(obj);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通过反射方式获取属性
|
||
/// </summary>
|
||
/// <param name="obj"></param>
|
||
/// <param name="fieldName">属性名</param>
|
||
/// <returns></returns>
|
||
public static object GetPropertyByReflect(this object obj, string propertyName, object[] index = null)
|
||
{
|
||
var propertyInfo = obj.GetType().GetProperty(propertyName);
|
||
return propertyInfo == null ? null : propertyInfo.GetValue(obj, index);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 拥有特性
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public static bool HasAttribute(this PropertyInfo prop, Type attributeType, bool inherit)
|
||
{
|
||
return prop.GetCustomAttributes(attributeType, inherit).Length > 0;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 拥有特性
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public static bool HasAttribute(this FieldInfo field, Type attributeType, bool inherit)
|
||
{
|
||
return field.GetCustomAttributes(attributeType, inherit).Length > 0;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 拥有特性
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public static bool HasAttribute(this Type type, Type attributeType, bool inherit)
|
||
{
|
||
return type.GetCustomAttributes(attributeType, inherit).Length > 0;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 拥有特性
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public static bool HasAttribute(this MethodInfo method, Type attributeType, bool inherit)
|
||
{
|
||
return method.GetCustomAttributes(attributeType, inherit).Length > 0;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取第一个特性
|
||
/// </summary>
|
||
public static T GetFirstAttribute<T>(this MethodInfo method, bool inherit) where T : Attribute
|
||
{
|
||
var attrs = (T[])method.GetCustomAttributes(typeof(T), inherit);
|
||
if (attrs != null && attrs.Length > 0)
|
||
return attrs[0];
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取第一个特性
|
||
/// </summary>
|
||
public static T GetFirstAttribute<T>(this FieldInfo field, bool inherit) where T : Attribute
|
||
{
|
||
var attrs = (T[])field.GetCustomAttributes(typeof(T), inherit);
|
||
if (attrs != null && attrs.Length > 0)
|
||
return attrs[0];
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取第一个特性
|
||
/// </summary>
|
||
public static T GetFirstAttribute<T>(this PropertyInfo prop, bool inherit) where T : Attribute
|
||
{
|
||
var attrs = (T[])prop.GetCustomAttributes(typeof(T), inherit);
|
||
if (attrs != null && attrs.Length > 0)
|
||
return attrs[0];
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取第一个特性
|
||
/// </summary>
|
||
public static T GetFirstAttribute<T>(this Type type, bool inherit) where T : Attribute
|
||
{
|
||
var attrs = (T[])type.GetCustomAttributes(typeof(T), inherit);
|
||
if (attrs != null && attrs.Length > 0)
|
||
return attrs[0];
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 类型扩展
|
||
/// </summary>
|
||
public static class TypeEx
|
||
{
|
||
/// <summary>
|
||
/// 获取默认值
|
||
/// </summary>
|
||
/// <param name="targetType"></param>
|
||
/// <returns></returns>
|
||
public static object DefaultForType(this Type targetType)
|
||
{
|
||
return targetType.IsValueType ? Activator.CreateInstance(targetType) : null;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 字符串扩展
|
||
/// </summary>
|
||
public static class StringExtention
|
||
{
|
||
/// <summary>
|
||
/// Check Whether string is null or empty
|
||
/// </summary>
|
||
/// <param name="selfStr"></param>
|
||
/// <returns></returns>
|
||
public static bool IsNullOrEmpty(this string selfStr)
|
||
{
|
||
return string.IsNullOrEmpty(selfStr);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Check Whether string is null or empty
|
||
/// </summary>
|
||
/// <param name="selfStr"></param>
|
||
/// <returns></returns>
|
||
public static bool IsNotNullAndEmpty(this string selfStr)
|
||
{
|
||
return !string.IsNullOrEmpty(selfStr);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Check Whether string trim is null or empty
|
||
/// </summary>
|
||
/// <param name="selfStr"></param>
|
||
/// <returns></returns>
|
||
public static bool IsTrimNotNullAndEmpty(this string selfStr)
|
||
{
|
||
return selfStr != null && !string.IsNullOrEmpty(selfStr.Trim());
|
||
}
|
||
|
||
public static bool IsTrimNullOrEmpty(this string selfStr)
|
||
{
|
||
return selfStr == null || string.IsNullOrEmpty(selfStr.Trim());
|
||
}
|
||
|
||
/// <summary>
|
||
/// 缓存
|
||
/// </summary>
|
||
private static readonly char[] mCachedSplitCharArray = { '.' };
|
||
|
||
/// <summary>
|
||
/// Split
|
||
/// </summary>
|
||
/// <param name="selfStr"></param>
|
||
/// <param name="splitSymbol"></param>
|
||
/// <returns></returns>
|
||
public static string[] Split(this string selfStr, char splitSymbol)
|
||
{
|
||
mCachedSplitCharArray[0] = splitSymbol;
|
||
return selfStr.Split(mCachedSplitCharArray);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 首字母大写
|
||
/// </summary>
|
||
/// <param name="str"></param>
|
||
/// <returns></returns>
|
||
public static string UppercaseFirst(this string str)
|
||
{
|
||
return char.ToUpper(str[0]) + str.Substring(1);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 首字母小写
|
||
/// </summary>
|
||
/// <param name="str"></param>
|
||
/// <returns></returns>
|
||
public static string LowercaseFirst(this string str)
|
||
{
|
||
return char.ToLower(str[0]) + str.Substring(1);
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="str"></param>
|
||
/// <returns></returns>
|
||
public static string ToUnixLineEndings(this string str)
|
||
{
|
||
return str.Replace("\r\n", "\n").Replace("\r", "\n");
|
||
}
|
||
|
||
public static string ToSpacedCamelCase(this string text)
|
||
{
|
||
var sb = new StringBuilder(text.Length * 2);
|
||
sb.Append(char.ToUpper(text[0]));
|
||
for (var i = 1; i < text.Length; i++)
|
||
{
|
||
if (char.IsUpper(text[i]) && text[i - 1] != ' ')
|
||
{
|
||
sb.Append(' ');
|
||
}
|
||
|
||
sb.Append(text[i]);
|
||
}
|
||
|
||
return sb.ToString();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 有点不安全,编译器不会帮你排查错误。
|
||
/// </summary>
|
||
/// <param name="selfStr"></param>
|
||
/// <param name="args"></param>
|
||
/// <returns></returns>
|
||
public static string FillFormat(this string selfStr, params object[] args)
|
||
{
|
||
return string.Format(selfStr, args);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加前缀
|
||
/// </summary>
|
||
/// <param name="selfStr"></param>
|
||
/// <param name="toAppend"></param>
|
||
/// <returns></returns>
|
||
public static StringBuilder Append(this string selfStr, string toAppend)
|
||
{
|
||
return new StringBuilder(selfStr).Append(toAppend);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加后缀
|
||
/// </summary>
|
||
/// <param name="selfStr"></param>
|
||
/// <param name="toPrefix"></param>
|
||
/// <returns></returns>
|
||
public static string AddPrefix(this string selfStr, string toPrefix)
|
||
{
|
||
return new StringBuilder(toPrefix).Append(selfStr).ToString();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 格式化
|
||
/// </summary>
|
||
/// <param name="selfStr"></param>
|
||
/// <param name="toAppend"></param>
|
||
/// <param name="args"></param>
|
||
/// <returns></returns>
|
||
public static StringBuilder AppendFormat(this string selfStr, string toAppend, params object[] args)
|
||
{
|
||
return new StringBuilder(selfStr).AppendFormat(toAppend, args);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 最后一个单词
|
||
/// </summary>
|
||
/// <param name="selfUrl"></param>
|
||
/// <returns></returns>
|
||
public static string LastWord(this string selfUrl)
|
||
{
|
||
return selfUrl.Split('/').Last();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 解析成数字类型
|
||
/// </summary>
|
||
/// <param name="selfStr"></param>
|
||
/// <param name="defaulValue"></param>
|
||
/// <returns></returns>
|
||
public static int ToInt(this string selfStr, int defaulValue = 0)
|
||
{
|
||
var retValue = defaulValue;
|
||
return int.TryParse(selfStr, out retValue) ? retValue : defaulValue;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 解析到时间类型
|
||
/// </summary>
|
||
/// <param name="selfStr"></param>
|
||
/// <param name="defaultValue"></param>
|
||
/// <returns></returns>
|
||
public static DateTime ToDateTime(this string selfStr, DateTime defaultValue = default(DateTime))
|
||
{
|
||
var retValue = defaultValue;
|
||
return DateTime.TryParse(selfStr, out retValue) ? retValue : defaultValue;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 解析 Float 类型
|
||
/// </summary>
|
||
/// <param name="selfStr"></param>
|
||
/// <param name="defaulValue"></param>
|
||
/// <returns></returns>
|
||
public static float ToFloat(this string selfStr, float defaulValue = 0)
|
||
{
|
||
var retValue = defaulValue;
|
||
return float.TryParse(selfStr, out retValue) ? retValue : defaulValue;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 是否存在中文字符
|
||
/// </summary>
|
||
/// <param name="input"></param>
|
||
/// <returns></returns>
|
||
public static bool HasChinese(this string input)
|
||
{
|
||
return Regex.IsMatch(input, @"[\u4e00-\u9fa5]");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 是否存在空格
|
||
/// </summary>
|
||
/// <param name="input"></param>
|
||
/// <returns></returns>
|
||
public static bool HasSpace(this string input)
|
||
{
|
||
return input.Contains(" ");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 删除特定字符
|
||
/// </summary>
|
||
/// <param name="str"></param>
|
||
/// <param name="target"></param>
|
||
/// <returns></returns>
|
||
public static string RemoveString(this string str, params string[] targets)
|
||
{
|
||
return targets.Aggregate(str, (current, t) => current.Replace(t, string.Empty));
|
||
}
|
||
}
|
||
|
||
public static class BehaviourExtension
|
||
{
|
||
public static T Enable<T>(this T selfBehaviour) where T : Behaviour
|
||
{
|
||
selfBehaviour.enabled = true;
|
||
return selfBehaviour;
|
||
}
|
||
|
||
public static T Disable<T>(this T selfBehaviour) where T : Behaviour
|
||
{
|
||
selfBehaviour.enabled = false;
|
||
return selfBehaviour;
|
||
}
|
||
}
|
||
|
||
public static class CameraExtension
|
||
{
|
||
public static Texture2D CaptureCamera(this Camera camera, Rect rect)
|
||
{
|
||
var renderTexture = new RenderTexture(Screen.width, Screen.height, 0);
|
||
camera.targetTexture = renderTexture;
|
||
camera.Render();
|
||
|
||
RenderTexture.active = renderTexture;
|
||
|
||
var screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false);
|
||
screenShot.ReadPixels(rect, 0, 0);
|
||
screenShot.Apply();
|
||
|
||
camera.targetTexture = null;
|
||
RenderTexture.active = null;
|
||
UnityEngine.Object.Destroy(renderTexture);
|
||
|
||
return screenShot;
|
||
}
|
||
}
|
||
|
||
public static class ColorExtension
|
||
{
|
||
/// <summary>
|
||
/// #C5563CFF -> 197.0f / 255,86.0f / 255,60.0f / 255
|
||
/// </summary>
|
||
/// <param name="htmlString"></param>
|
||
/// <returns></returns>
|
||
public static Color HtmlStringToColor(this string htmlString)
|
||
{
|
||
Color retColor;
|
||
var parseSucceed = ColorUtility.TryParseHtmlString(htmlString, out retColor);
|
||
return parseSucceed ? retColor : Color.black;
|
||
}
|
||
|
||
/// <summary>
|
||
/// unity's color always new a color
|
||
/// </summary>
|
||
public static Color White = Color.white;
|
||
}
|
||
|
||
public static class GraphicExtension
|
||
{
|
||
public static T ColorAlpha<T>(this T selfGraphic, float alpha) where T : Graphic
|
||
{
|
||
var color = selfGraphic.color;
|
||
color.a = alpha;
|
||
selfGraphic.color = color;
|
||
return selfGraphic;
|
||
}
|
||
}
|
||
|
||
public static class ImageExtension
|
||
{
|
||
public static Image FillAmount(this Image selfImage, float fillamount)
|
||
{
|
||
selfImage.fillAmount = fillamount;
|
||
return selfImage;
|
||
}
|
||
}
|
||
|
||
public static class LightmapExtension
|
||
{
|
||
public static void SetAmbientLightHTMLStringColor(string htmlStringColor)
|
||
{
|
||
RenderSettings.ambientLight = htmlStringColor.HtmlStringToColor();
|
||
}
|
||
}
|
||
|
||
public static class ObjectExtension
|
||
{
|
||
#region Instantiate
|
||
|
||
public static T Instantiate<T>(this T selfObj) where T : UnityEngine.Object
|
||
{
|
||
return UnityEngine.Object.Instantiate(selfObj);
|
||
}
|
||
|
||
public static T Instantiate<T>(this T selfObj, Vector3 position, Quaternion rotation)
|
||
where T : UnityEngine.Object
|
||
{
|
||
return UnityEngine.Object.Instantiate(selfObj, position, rotation);
|
||
}
|
||
|
||
public static T Instantiate<T>(this T selfObj, Vector3 position, Quaternion rotation,
|
||
Transform parent) where T : UnityEngine.Object
|
||
{
|
||
return UnityEngine.Object.Instantiate(selfObj, position, rotation, parent);
|
||
}
|
||
|
||
public static T InstantiateWithParent<T>(this T selfObj, Transform parent, bool worldPositionStays)
|
||
where T : UnityEngine.Object
|
||
{
|
||
return (T)UnityEngine.Object.Instantiate((UnityEngine.Object)selfObj, parent, worldPositionStays);
|
||
}
|
||
|
||
public static T InstantiateWithParent<T>(this T selfObj, Transform parent) where T : UnityEngine.Object
|
||
{
|
||
return UnityEngine.Object.Instantiate(selfObj, parent, false);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Name
|
||
|
||
public static T Name<T>(this T selfObj, string name) where T : UnityEngine.Object
|
||
{
|
||
selfObj.name = name;
|
||
return selfObj;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Destroy Self
|
||
|
||
public static void DestroySelf<T>(this T selfObj) where T : UnityEngine.Object
|
||
{
|
||
UnityEngine.Object.Destroy(selfObj);
|
||
}
|
||
|
||
public static T DestroySelfGracefully<T>(this T selfObj) where T : UnityEngine.Object
|
||
{
|
||
if (selfObj)
|
||
{
|
||
UnityEngine.Object.Destroy(selfObj);
|
||
}
|
||
|
||
return selfObj;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Destroy Self AfterDelay
|
||
|
||
public static T DestroySelfAfterDelay<T>(this T selfObj, float afterDelay) where T : UnityEngine.Object
|
||
{
|
||
UnityEngine.Object.Destroy(selfObj, afterDelay);
|
||
return selfObj;
|
||
}
|
||
|
||
public static T DestroySelfAfterDelayGracefully<T>(this T selfObj, float delay) where T : UnityEngine.Object
|
||
{
|
||
if (selfObj)
|
||
{
|
||
UnityEngine.Object.Destroy(selfObj, delay);
|
||
}
|
||
|
||
return selfObj;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Apply Self To
|
||
|
||
public static T ApplySelfTo<T>(this T selfObj, System.Action<T> toFunction) where T : UnityEngine.Object
|
||
{
|
||
toFunction.InvokeGracefully(selfObj);
|
||
return selfObj;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region DontDestroyOnLoad
|
||
|
||
public static T DontDestroyOnLoad<T>(this T selfObj) where T : UnityEngine.Object
|
||
{
|
||
UnityEngine.Object.DontDestroyOnLoad(selfObj);
|
||
return selfObj;
|
||
}
|
||
|
||
#endregion
|
||
|
||
public static T As<T>(this object selfObj) where T : class
|
||
{
|
||
return selfObj as T;
|
||
}
|
||
}
|
||
|
||
public static class RectTransformExtension
|
||
{
|
||
public static Vector2 GetPosInRootTrans(this RectTransform selfRectTransform, Transform rootTrans)
|
||
{
|
||
return RectTransformUtility.CalculateRelativeRectTransformBounds(rootTrans, selfRectTransform).center;
|
||
}
|
||
|
||
public static RectTransform AnchorPosX(this RectTransform selfRectTrans, float anchorPosX)
|
||
{
|
||
var anchorPos = selfRectTrans.anchoredPosition;
|
||
anchorPos.x = anchorPosX;
|
||
selfRectTrans.anchoredPosition = anchorPos;
|
||
return selfRectTrans;
|
||
}
|
||
|
||
public static RectTransform AnchorPosY(this RectTransform selfRectTrans, float anchorPosY)
|
||
{
|
||
var anchorPos = selfRectTrans.anchoredPosition;
|
||
anchorPos.y = anchorPosY;
|
||
selfRectTrans.anchoredPosition = anchorPos;
|
||
return selfRectTrans;
|
||
}
|
||
|
||
public static RectTransform SetSizeWidth(this RectTransform selfRectTrans, float sizeWidth)
|
||
{
|
||
var sizeDelta = selfRectTrans.sizeDelta;
|
||
sizeDelta.x = sizeWidth;
|
||
selfRectTrans.sizeDelta = sizeDelta;
|
||
return selfRectTrans;
|
||
}
|
||
|
||
public static RectTransform SetSizeHeight(this RectTransform selfRectTrans, float sizeHeight)
|
||
{
|
||
var sizeDelta = selfRectTrans.sizeDelta;
|
||
sizeDelta.y = sizeHeight;
|
||
selfRectTrans.sizeDelta = sizeDelta;
|
||
return selfRectTrans;
|
||
}
|
||
|
||
public static Vector2 GetWorldSize(this RectTransform selfRectTrans)
|
||
{
|
||
return RectTransformUtility.CalculateRelativeRectTransformBounds(selfRectTrans).size;
|
||
}
|
||
}
|
||
|
||
public static class SelectableExtension
|
||
{
|
||
public static T EnableInteract<T>(this T selfSelectable) where T : Selectable
|
||
{
|
||
selfSelectable.interactable = true;
|
||
return selfSelectable;
|
||
}
|
||
|
||
public static T DisableInteract<T>(this T selfSelectable) where T : Selectable
|
||
{
|
||
selfSelectable.interactable = false;
|
||
return selfSelectable;
|
||
}
|
||
|
||
// public static T CancalAllTransitions<T>(this T selfSelectable) where T : Selectable
|
||
// {
|
||
// selfSelectable.transition = Selectable.Transition.None;
|
||
// return selfSelectable;
|
||
// }
|
||
}
|
||
|
||
public static class ToggleExtension
|
||
{
|
||
public static void RegOnValueChangedEvent(this Toggle selfToggle, UnityAction<bool> onValueChangedEvent)
|
||
{
|
||
selfToggle.onValueChanged.AddListener(onValueChangedEvent);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Transform's Extension
|
||
/// </summary>
|
||
public static class TransformExtension
|
||
{
|
||
/// <summary>
|
||
/// 缓存的一些变量,免得每次声明
|
||
/// </summary>
|
||
private static Vector3 mLocalPos;
|
||
private static Vector3 mScale;
|
||
private static Vector3 mPos;
|
||
|
||
#region Parent
|
||
|
||
public static T Parent<T>(this T selfComponent, Component parentComponent) where T : Component
|
||
{
|
||
selfComponent.transform.SetParent(parentComponent == null ? null : parentComponent.transform);
|
||
return selfComponent;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置成为顶端 Transform
|
||
/// </summary>
|
||
/// <returns>The root transform.</returns>
|
||
/// <param name="selfComponent">Self component.</param>
|
||
/// <typeparam name="T">The 1st type parameter.</typeparam>
|
||
public static T AsRootTransform<T>(this T selfComponent) where T : Component
|
||
{
|
||
selfComponent.transform.SetParent(null);
|
||
return selfComponent;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region LocalIdentity
|
||
|
||
public static T LocalIdentity<T>(this T selfComponent) where T : Component
|
||
{
|
||
selfComponent.transform.localPosition = Vector3.zero;
|
||
selfComponent.transform.localRotation = Quaternion.identity;
|
||
selfComponent.transform.localScale = Vector3.one;
|
||
return selfComponent;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region LocalPosition
|
||
|
||
public static T LocalPosition<T>(this T selfComponent, Vector3 localPos) where T : Component
|
||
{
|
||
selfComponent.transform.localPosition = localPos;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static Vector3 GetLocalPosition<T>(this T selfComponent) where T : Component
|
||
{
|
||
return selfComponent.transform.localPosition;
|
||
}
|
||
|
||
public static T LocalPosition<T>(this T selfComponent, float x, float y, float z) where T : Component
|
||
{
|
||
selfComponent.transform.localPosition = new Vector3(x, y, z);
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T LocalPosition<T>(this T selfComponent, float x, float y) where T : Component
|
||
{
|
||
mLocalPos = selfComponent.transform.localPosition;
|
||
mLocalPos.x = x;
|
||
mLocalPos.y = y;
|
||
selfComponent.transform.localPosition = mLocalPos;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T LocalPositionX<T>(this T selfComponent, float x) where T : Component
|
||
{
|
||
mLocalPos = selfComponent.transform.localPosition;
|
||
mLocalPos.x = x;
|
||
selfComponent.transform.localPosition = mLocalPos;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T LocalPositionY<T>(this T selfComponent, float y) where T : Component
|
||
{
|
||
mLocalPos = selfComponent.transform.localPosition;
|
||
mLocalPos.y = y;
|
||
selfComponent.transform.localPosition = mLocalPos;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T LocalPositionZ<T>(this T selfComponent, float z) where T : Component
|
||
{
|
||
mLocalPos = selfComponent.transform.localPosition;
|
||
mLocalPos.z = z;
|
||
selfComponent.transform.localPosition = mLocalPos;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T LocalPositionIdentity<T>(this T selfComponent) where T : Component
|
||
{
|
||
selfComponent.transform.localPosition = Vector3.zero;
|
||
return selfComponent;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region LocalRotation
|
||
|
||
public static Quaternion GetLocalRotation<T>(this T selfComponent) where T : Component
|
||
{
|
||
return selfComponent.transform.localRotation;
|
||
}
|
||
|
||
public static T LocalRotation<T>(this T selfComponent, Quaternion localRotation) where T : Component
|
||
{
|
||
selfComponent.transform.localRotation = localRotation;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T LocalRotationIdentity<T>(this T selfComponent) where T : Component
|
||
{
|
||
selfComponent.transform.localRotation = Quaternion.identity;
|
||
return selfComponent;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region LocalScale
|
||
|
||
public static T LocalScale<T>(this T selfComponent, Vector3 scale) where T : Component
|
||
{
|
||
selfComponent.transform.localScale = scale;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static Vector3 GetLocalScale<T>(this T selfComponent) where T : Component
|
||
{
|
||
return selfComponent.transform.localScale;
|
||
}
|
||
|
||
public static T LocalScale<T>(this T selfComponent, float xyz) where T : Component
|
||
{
|
||
selfComponent.transform.localScale = Vector3.one * xyz;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T LocalScale<T>(this T selfComponent, float x, float y, float z) where T : Component
|
||
{
|
||
mScale = selfComponent.transform.localScale;
|
||
mScale.x = x;
|
||
mScale.y = y;
|
||
mScale.z = z;
|
||
selfComponent.transform.localScale = mScale;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T LocalScale<T>(this T selfComponent, float x, float y) where T : Component
|
||
{
|
||
mScale = selfComponent.transform.localScale;
|
||
mScale.x = x;
|
||
mScale.y = y;
|
||
selfComponent.transform.localScale = mScale;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T LocalScaleX<T>(this T selfComponent, float x) where T : Component
|
||
{
|
||
mScale = selfComponent.transform.localScale;
|
||
mScale.x = x;
|
||
selfComponent.transform.localScale = mScale;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T LocalScaleY<T>(this T selfComponent, float y) where T : Component
|
||
{
|
||
mScale = selfComponent.transform.localScale;
|
||
mScale.y = y;
|
||
selfComponent.transform.localScale = mScale;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T LocalScaleZ<T>(this T selfComponent, float z) where T : Component
|
||
{
|
||
mScale = selfComponent.transform.localScale;
|
||
mScale.z = z;
|
||
selfComponent.transform.localScale = mScale;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T LocalScaleIdentity<T>(this T selfComponent) where T : Component
|
||
{
|
||
selfComponent.transform.localScale = Vector3.one;
|
||
return selfComponent;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Identity
|
||
|
||
public static T Identity<T>(this T selfComponent) where T : Component
|
||
{
|
||
selfComponent.transform.position = Vector3.zero;
|
||
selfComponent.transform.rotation = Quaternion.identity;
|
||
selfComponent.transform.localScale = Vector3.one;
|
||
return selfComponent;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Position
|
||
|
||
public static T Position<T>(this T selfComponent, Vector3 position) where T : Component
|
||
{
|
||
selfComponent.transform.position = position;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static Vector3 GetPosition<T>(this T selfComponent) where T : Component
|
||
{
|
||
return selfComponent.transform.position;
|
||
}
|
||
|
||
public static T Position<T>(this T selfComponent, float x, float y, float z) where T : Component
|
||
{
|
||
selfComponent.transform.position = new Vector3(x, y, z);
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T Position<T>(this T selfComponent, float x, float y) where T : Component
|
||
{
|
||
mPos = selfComponent.transform.position;
|
||
mPos.x = x;
|
||
mPos.y = y;
|
||
selfComponent.transform.position = mPos;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T PositionIdentity<T>(this T selfComponent) where T : Component
|
||
{
|
||
selfComponent.transform.position = Vector3.zero;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T PositionX<T>(this T selfComponent, float x) where T : Component
|
||
{
|
||
mPos = selfComponent.transform.position;
|
||
mPos.x = x;
|
||
selfComponent.transform.position = mPos;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T PositionX<T>(this T selfComponent, Func<float, float> xSetter) where T : Component
|
||
{
|
||
mPos = selfComponent.transform.position;
|
||
mPos.x = xSetter(mPos.x);
|
||
selfComponent.transform.position = mPos;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T PositionY<T>(this T selfComponent, float y) where T : Component
|
||
{
|
||
mPos = selfComponent.transform.position;
|
||
mPos.y = y;
|
||
selfComponent.transform.position = mPos;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T PositionY<T>(this T selfComponent, Func<float, float> ySetter) where T : Component
|
||
{
|
||
mPos = selfComponent.transform.position;
|
||
mPos.y = ySetter(mPos.y);
|
||
selfComponent.transform.position = mPos;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T PositionZ<T>(this T selfComponent, float z) where T : Component
|
||
{
|
||
mPos = selfComponent.transform.position;
|
||
mPos.z = z;
|
||
selfComponent.transform.position = mPos;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T PositionZ<T>(this T selfComponent, Func<float, float> zSetter) where T : Component
|
||
{
|
||
mPos = selfComponent.transform.position;
|
||
mPos.z = zSetter(mPos.z);
|
||
selfComponent.transform.position = mPos;
|
||
return selfComponent;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Rotation
|
||
|
||
public static T RotationIdentity<T>(this T selfComponent) where T : Component
|
||
{
|
||
selfComponent.transform.rotation = Quaternion.identity;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T Rotation<T>(this T selfComponent, Quaternion rotation) where T : Component
|
||
{
|
||
selfComponent.transform.rotation = rotation;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static Quaternion GetRotation<T>(this T selfComponent) where T : Component
|
||
{
|
||
return selfComponent.transform.rotation;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region WorldScale/LossyScale/GlobalScale/Scale
|
||
|
||
public static Vector3 GetGlobalScale<T>(this T selfComponent) where T : Component
|
||
{
|
||
return selfComponent.transform.lossyScale;
|
||
}
|
||
|
||
public static Vector3 GetScale<T>(this T selfComponent) where T : Component
|
||
{
|
||
return selfComponent.transform.lossyScale;
|
||
}
|
||
|
||
public static Vector3 GetWorldScale<T>(this T selfComponent) where T : Component
|
||
{
|
||
return selfComponent.transform.lossyScale;
|
||
}
|
||
|
||
public static Vector3 GetLossyScale<T>(this T selfComponent) where T : Component
|
||
{
|
||
return selfComponent.transform.lossyScale;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Destroy All Child
|
||
|
||
[Obsolete("弃用啦 请使用 DestroyChildren")]
|
||
public static T DestroyAllChild<T>(this T selfComponent) where T : Component
|
||
{
|
||
return selfComponent.DestroyChildren();
|
||
}
|
||
|
||
[Obsolete("弃用啦 请使用 DestroyChildren")]
|
||
public static GameObject DestroyAllChild(this GameObject selfGameObj)
|
||
{
|
||
return selfGameObj.DestroyChildren();
|
||
}
|
||
|
||
public static T DestroyChildren<T>(this T selfComponent) where T : Component
|
||
{
|
||
var childCount = selfComponent.transform.childCount;
|
||
|
||
for (var i = 0; i < childCount; i++)
|
||
{
|
||
selfComponent.transform.GetChild(i).DestroyGameObjGracefully();
|
||
}
|
||
|
||
return selfComponent;
|
||
}
|
||
|
||
public static GameObject DestroyChildren(this GameObject selfGameObj)
|
||
{
|
||
var childCount = selfGameObj.transform.childCount;
|
||
|
||
for (var i = 0; i < childCount; i++)
|
||
{
|
||
selfGameObj.transform.GetChild(i).DestroyGameObjGracefully();
|
||
}
|
||
|
||
return selfGameObj;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Sibling Index
|
||
|
||
public static T AsLastSibling<T>(this T selfComponent) where T : Component
|
||
{
|
||
selfComponent.transform.SetAsLastSibling();
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T AsFirstSibling<T>(this T selfComponent) where T : Component
|
||
{
|
||
selfComponent.transform.SetAsFirstSibling();
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T SiblingIndex<T>(this T selfComponent, int index) where T : Component
|
||
{
|
||
selfComponent.transform.SetSiblingIndex(index);
|
||
return selfComponent;
|
||
}
|
||
|
||
#endregion
|
||
|
||
public static Transform FindByPath(this Transform selfTrans, string path)
|
||
{
|
||
return selfTrans.Find(path.Replace(".", "/"));
|
||
}
|
||
|
||
public static Transform SeekTrans(this Transform selfTransform, string uniqueName)
|
||
{
|
||
var childTrans = selfTransform.Find(uniqueName);
|
||
|
||
if (null != childTrans)
|
||
return childTrans;
|
||
|
||
foreach (Transform trans in selfTransform)
|
||
{
|
||
childTrans = trans.SeekTrans(uniqueName);
|
||
|
||
if (null != childTrans)
|
||
return childTrans;
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
public static T ShowChildTransByPath<T>(this T selfComponent, string tranformPath) where T : Component
|
||
{
|
||
selfComponent.transform.Find(tranformPath).gameObject.Show();
|
||
return selfComponent;
|
||
}
|
||
|
||
public static T HideChildTransByPath<T>(this T selfComponent, string tranformPath) where T : Component
|
||
{
|
||
selfComponent.transform.Find(tranformPath).Hide();
|
||
return selfComponent;
|
||
}
|
||
|
||
public static void CopyDataFromTrans(this Transform selfTrans, Transform fromTrans)
|
||
{
|
||
selfTrans.SetParent(fromTrans.parent);
|
||
selfTrans.localPosition = fromTrans.localPosition;
|
||
selfTrans.localRotation = fromTrans.localRotation;
|
||
selfTrans.localScale = fromTrans.localScale;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 递归遍历子物体,并调用函数
|
||
/// </summary>
|
||
/// <param name="tfParent"></param>
|
||
/// <param name="action"></param>
|
||
public static void ActionRecursion(this Transform tfParent, Action<Transform> action)
|
||
{
|
||
action(tfParent);
|
||
foreach (Transform tfChild in tfParent)
|
||
{
|
||
tfChild.ActionRecursion(action);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 递归遍历查找指定的名字的子物体
|
||
/// </summary>
|
||
/// <param name="tfParent">当前Transform</param>
|
||
/// <param name="name">目标名</param>
|
||
/// <param name="stringComparison">字符串比较规则</param>
|
||
/// <returns></returns>
|
||
public static Transform FindChildRecursion(this Transform tfParent, string name,
|
||
StringComparison stringComparison = StringComparison.Ordinal)
|
||
{
|
||
if (tfParent.name.Equals(name, stringComparison))
|
||
{
|
||
//Debug.Log("Hit " + tfParent.name);
|
||
return tfParent;
|
||
}
|
||
|
||
foreach (Transform tfChild in tfParent)
|
||
{
|
||
Transform tfFinal = null;
|
||
tfFinal = tfChild.FindChildRecursion(name, stringComparison);
|
||
if (tfFinal)
|
||
{
|
||
return tfFinal;
|
||
}
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 递归遍历查找相应条件的子物体
|
||
/// </summary>
|
||
/// <param name="tfParent">当前Transform</param>
|
||
/// <param name="predicate">条件</param>
|
||
/// <returns></returns>
|
||
public static Transform FindChildRecursion(this Transform tfParent, Func<Transform, bool> predicate)
|
||
{
|
||
if (predicate(tfParent))
|
||
{
|
||
Log.I("Hit " + tfParent.name);
|
||
return tfParent;
|
||
}
|
||
|
||
foreach (Transform tfChild in tfParent)
|
||
{
|
||
Transform tfFinal = null;
|
||
tfFinal = tfChild.FindChildRecursion(predicate);
|
||
if (tfFinal)
|
||
{
|
||
return tfFinal;
|
||
}
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
public static string GetPath(this Transform transform)
|
||
{
|
||
var sb = new System.Text.StringBuilder();
|
||
var t = transform;
|
||
while (true)
|
||
{
|
||
sb.Insert(0, t.name);
|
||
t = t.parent;
|
||
if (t)
|
||
{
|
||
sb.Insert(0, "/");
|
||
}
|
||
else
|
||
{
|
||
return sb.ToString();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
public static class UnityActionExtension
|
||
{
|
||
/// <summary>
|
||
/// Call action
|
||
/// </summary>
|
||
/// <param name="selfAction"></param>
|
||
/// <returns> call succeed</returns>
|
||
public static bool InvokeGracefully(this UnityAction selfAction)
|
||
{
|
||
if (null != selfAction)
|
||
{
|
||
selfAction();
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Call action
|
||
/// </summary>
|
||
/// <param name="selfAction"></param>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <returns></returns>
|
||
public static bool InvokeGracefully<T>(this UnityAction<T> selfAction, T t)
|
||
{
|
||
if (null != selfAction)
|
||
{
|
||
selfAction(t);
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Call action
|
||
/// </summary>
|
||
/// <param name="selfAction"></param>
|
||
/// <returns> call succeed</returns>
|
||
public static bool InvokeGracefully<T, K>(this UnityAction<T, K> selfAction, T t, K k)
|
||
{
|
||
if (null != selfAction)
|
||
{
|
||
selfAction(t, k);
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获得随机列表中元素
|
||
/// </summary>
|
||
/// <typeparam name="T">元素类型</typeparam>
|
||
/// <param name="list">列表</param>
|
||
/// <returns></returns>
|
||
public static T GetRandomItem<T>(this List<T> list)
|
||
{
|
||
return list[UnityEngine.Random.Range(0, list.Count)];
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据权值来获取索引
|
||
/// </summary>
|
||
/// <param name="powers"></param>
|
||
/// <returns></returns>
|
||
public static int GetRandomWithPower(this List<int> powers)
|
||
{
|
||
var sum = 0;
|
||
foreach (var power in powers)
|
||
{
|
||
sum += power;
|
||
}
|
||
|
||
var randomNum = UnityEngine.Random.Range(0, sum);
|
||
var currentSum = 0;
|
||
for (var i = 0; i < powers.Count; i++)
|
||
{
|
||
var nextSum = currentSum + powers[i];
|
||
if (randomNum >= currentSum && randomNum <= nextSum)
|
||
{
|
||
return i;
|
||
}
|
||
|
||
currentSum = nextSum;
|
||
}
|
||
|
||
Log.E("权值范围计算错误!");
|
||
return -1;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据权值获取值,Key为值,Value为权值
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <param name="powersDict"></param>
|
||
/// <returns></returns>
|
||
public static T GetRandomWithPower<T>(this Dictionary<T, int> powersDict)
|
||
{
|
||
var keys = new List<T>();
|
||
var values = new List<int>();
|
||
|
||
foreach (var key in powersDict.Keys)
|
||
{
|
||
keys.Add(key);
|
||
values.Add(powersDict[key]);
|
||
}
|
||
|
||
var finalKeyIndex = values.GetRandomWithPower();
|
||
return keys[finalKeyIndex];
|
||
}
|
||
}
|
||
|
||
public static class AnimatorExtension
|
||
{
|
||
public static void AddAnimatorParameterIfExists(this Animator animator, string parameterName,
|
||
AnimatorControllerParameterType type, List<string> parameterList)
|
||
{
|
||
if (animator.HasParameterOfType(parameterName, type))
|
||
{
|
||
parameterList.Add(parameterName);
|
||
}
|
||
}
|
||
|
||
// <summary>
|
||
/// Updates the animator bool.
|
||
/// </summary>
|
||
/// <param name="self">Animator.</param>
|
||
/// <param name="parameterName">Parameter name.</param>
|
||
/// <param name="value">If set to <c>true</c> value.</param>
|
||
public static void UpdateAnimatorBool(this Animator self, string parameterName, bool value,
|
||
List<string> parameterList)
|
||
{
|
||
if (parameterList.Contains(parameterName))
|
||
{
|
||
self.SetBool(parameterName, value);
|
||
}
|
||
}
|
||
|
||
public static void UpdateAnimatorTrigger(this Animator self, string parameterName, List<string> parameterList)
|
||
{
|
||
if (parameterList.Contains(parameterName))
|
||
{
|
||
self.SetTrigger(parameterName);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Triggers an animator trigger.
|
||
/// </summary>
|
||
/// <param name="self">Animator.</param>
|
||
/// <param name="parameterName">Parameter name.</param>
|
||
/// <param name="value">If set to <c>true</c> value.</param>
|
||
public static void SetAnimatorTrigger(this Animator self, string parameterName, List<string> parameterList)
|
||
{
|
||
if (parameterList.Contains(parameterName))
|
||
{
|
||
self.SetTrigger(parameterName);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Updates the animator float.
|
||
/// </summary>
|
||
/// <param name="self">Animator.</param>
|
||
/// <param name="parameterName">Parameter name.</param>
|
||
/// <param name="value">Value.</param>
|
||
public static void UpdateAnimatorFloat(this Animator self, string parameterName, float value,
|
||
List<string> parameterList)
|
||
{
|
||
if (parameterList.Contains(parameterName))
|
||
{
|
||
self.SetFloat(parameterName, value);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Updates the animator integer.
|
||
/// </summary>
|
||
/// <param name="self">self.</param>
|
||
/// <param name="parameterName">Parameter name.</param>
|
||
/// <param name="value">Value.</param>
|
||
public static void UpdateAnimatorInteger(this Animator self, string parameterName, int value,
|
||
List<string> parameterList)
|
||
{
|
||
if (parameterList.Contains(parameterName))
|
||
{
|
||
self.SetInteger(parameterName, value);
|
||
}
|
||
}
|
||
|
||
|
||
// <summary>
|
||
/// Updates the animator bool without checking the parameter's existence.
|
||
/// </summary>
|
||
/// <param name="self">self.</param>
|
||
/// <param name="parameterName">Parameter name.</param>
|
||
/// <param name="value">If set to <c>true</c> value.</param>
|
||
public static void UpdateAnimatorBool(this Animator self, string parameterName, bool value)
|
||
{
|
||
self.SetBool(parameterName, value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Updates the animator trigger without checking the parameter's existence
|
||
/// </summary>
|
||
/// <param name="self">self.</param>
|
||
/// <param name="parameterName">Parameter name.</param>
|
||
public static void UpdateAnimatorTrigger(this Animator self, string parameterName)
|
||
{
|
||
self.SetTrigger(parameterName);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Triggers an animator trigger without checking for the parameter's existence.
|
||
/// </summary>
|
||
/// <param name="self">self.</param>
|
||
/// <param name="parameterName">Parameter name.</param>
|
||
/// <param name="value">If set to <c>true</c> value.</param>
|
||
public static void SetAnimatorTrigger(this Animator self, string parameterName)
|
||
{
|
||
self.SetTrigger(parameterName);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Updates the animator float without checking for the parameter's existence.
|
||
/// </summary>
|
||
/// <param name="self">self.</param>
|
||
/// <param name="parameterName">Parameter name.</param>
|
||
/// <param name="value">Value.</param>
|
||
public static void UpdateAnimatorFloat(this Animator self, string parameterName, float value)
|
||
{
|
||
self.SetFloat(parameterName, value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Updates the animator integer without checking for the parameter's existence.
|
||
/// </summary>
|
||
/// <param name="self">self.</param>
|
||
/// <param name="parameterName">Parameter name.</param>
|
||
/// <param name="value">Value.</param>
|
||
public static void UpdateAnimatorInteger(this Animator self, string parameterName, int value)
|
||
{
|
||
self.SetInteger(parameterName, value);
|
||
}
|
||
|
||
|
||
// <summary>
|
||
/// Updates the animator bool after checking the parameter's existence.
|
||
/// </summary>
|
||
/// <param name="self">Animator.</param>
|
||
/// <param name="parameterName">Parameter name.</param>
|
||
/// <param name="value">If set to <c>true</c> value.</param>
|
||
public static void UpdateAnimatorBoolIfExists(this Animator self, string parameterName, bool value)
|
||
{
|
||
if (self.HasParameterOfType(parameterName, AnimatorControllerParameterType.Bool))
|
||
{
|
||
self.SetBool(parameterName, value);
|
||
}
|
||
}
|
||
|
||
public static void UpdateAnimatorTriggerIfExists(this Animator self, string parameterName)
|
||
{
|
||
if (self.HasParameterOfType(parameterName, AnimatorControllerParameterType.Trigger))
|
||
{
|
||
self.SetTrigger(parameterName);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Triggers an animator trigger after checking for the parameter's existence.
|
||
/// </summary>
|
||
/// <param name="self">Animator.</param>
|
||
/// <param name="parameterName">Parameter name.</param>
|
||
/// <param name="value">If set to <c>true</c> value.</param>
|
||
public static void SetAnimatorTriggerIfExists(this Animator self, string parameterName)
|
||
{
|
||
if (self.HasParameterOfType(parameterName, AnimatorControllerParameterType.Trigger))
|
||
{
|
||
self.SetTrigger(parameterName);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Updates the animator float after checking for the parameter's existence.
|
||
/// </summary>
|
||
/// <param name="self">Animator.</param>
|
||
/// <param name="parameterName">Parameter name.</param>
|
||
/// <param name="value">Value.</param>
|
||
public static void UpdateAnimatorFloatIfExists(this Animator self, string parameterName, float value)
|
||
{
|
||
if (self.HasParameterOfType(parameterName, AnimatorControllerParameterType.Float))
|
||
{
|
||
self.SetFloat(parameterName, value);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Updates the animator integer after checking for the parameter's existence.
|
||
/// </summary>
|
||
/// <param name="self">Animator.</param>
|
||
/// <param name="parameterName">Parameter name.</param>
|
||
/// <param name="value">Value.</param>
|
||
public static void UpdateAnimatorIntegerIfExists(this Animator self, string parameterName, int value)
|
||
{
|
||
if (self.HasParameterOfType(parameterName, AnimatorControllerParameterType.Int))
|
||
{
|
||
self.SetInteger(parameterName, value);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Determines if an animator contains a certain parameter, based on a type and a name
|
||
/// </summary>
|
||
/// <returns><c>true</c> if has parameter of type the specified self name type; otherwise, <c>false</c>.</returns>
|
||
/// <param name="self">Self.</param>
|
||
/// <param name="name">Name.</param>
|
||
/// <param name="type">Type.</param>
|
||
public static bool HasParameterOfType(this Animator self, string name, AnimatorControllerParameterType type)
|
||
{
|
||
if (string.IsNullOrEmpty(name))
|
||
{
|
||
return false;
|
||
}
|
||
|
||
var parameters = self.parameters;
|
||
return parameters.Any(currParam => currParam.type == type && currParam.name == name);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// GameObject's Util/Static This Extension
|
||
/// </summary>
|
||
public static class GameObjectExtension
|
||
{
|
||
#region Show
|
||
|
||
public static GameObject Show(this GameObject selfObj)
|
||
{
|
||
selfObj.SetActive(true);
|
||
return selfObj;
|
||
}
|
||
|
||
public static T Show<T>(this T selfComponent) where T : Component
|
||
{
|
||
selfComponent.gameObject.Show();
|
||
return selfComponent;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Hide
|
||
|
||
public static GameObject Hide(this GameObject selfObj)
|
||
{
|
||
selfObj.SetActive(false);
|
||
return selfObj;
|
||
}
|
||
|
||
public static T Hide<T>(this T selfComponent) where T : Component
|
||
{
|
||
selfComponent.gameObject.Hide();
|
||
return selfComponent;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region DestroyGameObj
|
||
|
||
public static void DestroyGameObj<T>(this T selfBehaviour) where T : Component
|
||
{
|
||
selfBehaviour.gameObject.DestroySelf();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region DestroyGameObjGracefully
|
||
|
||
public static void DestroyGameObjGracefully<T>(this T selfBehaviour) where T : Component
|
||
{
|
||
if (selfBehaviour && selfBehaviour.gameObject)
|
||
{
|
||
selfBehaviour.gameObject.DestroySelfGracefully();
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region DestroyGameObjGracefully
|
||
|
||
public static T DestroyGameObjAfterDelay<T>(this T selfBehaviour, float delay) where T : Component
|
||
{
|
||
selfBehaviour.gameObject.DestroySelfAfterDelay(delay);
|
||
return selfBehaviour;
|
||
}
|
||
|
||
public static T DestroyGameObjAfterDelayGracefully<T>(this T selfBehaviour, float delay) where T : Component
|
||
{
|
||
if (selfBehaviour && selfBehaviour.gameObject)
|
||
{
|
||
selfBehaviour.gameObject.DestroySelfAfterDelay(delay);
|
||
}
|
||
|
||
return selfBehaviour;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Layer
|
||
|
||
public static GameObject Layer(this GameObject selfObj, int layer)
|
||
{
|
||
selfObj.layer = layer;
|
||
return selfObj;
|
||
}
|
||
|
||
public static T Layer<T>(this T selfComponent, int layer) where T : Component
|
||
{
|
||
selfComponent.gameObject.layer = layer;
|
||
return selfComponent;
|
||
}
|
||
|
||
public static GameObject Layer(this GameObject selfObj, string layerName)
|
||
{
|
||
selfObj.layer = LayerMask.NameToLayer(layerName);
|
||
return selfObj;
|
||
}
|
||
|
||
public static T Layer<T>(this T selfComponent, string layerName) where T : Component
|
||
{
|
||
selfComponent.gameObject.layer = LayerMask.NameToLayer(layerName);
|
||
return selfComponent;
|
||
}
|
||
|
||
public static bool IsInLayerMask(this GameObject selfObj, LayerMask layerMask)
|
||
{
|
||
return LayerMaskUtility.IsInLayerMask(selfObj, layerMask);
|
||
}
|
||
|
||
public static bool IsInLayerMask<T>(this T selfComponent, LayerMask layerMask) where T : Component
|
||
{
|
||
return LayerMaskUtility.IsInLayerMask(selfComponent.gameObject, layerMask);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Component
|
||
|
||
public static T GetOrAddComponent<T>(this GameObject selfComponent) where T : Component
|
||
{
|
||
var comp = selfComponent.gameObject.GetComponent<T>();
|
||
return comp ? comp : selfComponent.gameObject.AddComponent<T>();
|
||
}
|
||
|
||
public static T GetOrAddComponent<T>(this Component component) where T : Component
|
||
{
|
||
return component.gameObject.GetOrAddComponent<T>();
|
||
}
|
||
|
||
public static Component GetOrAddComponent(this GameObject selfComponent, Type type)
|
||
{
|
||
var comp = selfComponent.gameObject.GetComponent(type);
|
||
return comp ? comp : selfComponent.gameObject.AddComponent(type);
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
|
||
public static class LayerMaskExtension
|
||
{
|
||
public static bool ContainsGameObject(this LayerMask selfLayerMask, GameObject gameObject)
|
||
{
|
||
return LayerMaskUtility.IsInLayerMask(gameObject, selfLayerMask);
|
||
}
|
||
}
|
||
|
||
public static class LayerMaskUtility
|
||
{
|
||
public static bool IsInLayerMask(GameObject gameObj, LayerMask layerMask)
|
||
{
|
||
// 根据Layer数值进行移位获得用于运算的Mask值
|
||
var objLayerMask = 1 << gameObj.layer;
|
||
return (layerMask.value & objLayerMask) == objLayerMask;
|
||
}
|
||
}
|
||
|
||
public static class MaterialExtension
|
||
{
|
||
/// <summary>
|
||
/// 参考资料: https://blog.csdn.net/qiminixi/article/details/78402505
|
||
/// </summary>
|
||
/// <param name="self"></param>
|
||
public static void SetStandardMaterialToTransparentMode(this Material self)
|
||
{
|
||
self.SetFloat("_Mode", 3);
|
||
self.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
|
||
self.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
|
||
self.SetInt("_ZWrite", 0);
|
||
self.DisableKeyword("_ALPHATEST_ON");
|
||
self.EnableKeyword("_ALPHABLEND_ON");
|
||
self.DisableKeyword("_ALPHAPREMULTIPLY_ON");
|
||
self.renderQueue = 3000;
|
||
}
|
||
}
|
||
|
||
public static class TextureExtensions
|
||
{
|
||
public static Sprite CreateSprite(this Texture2D self)
|
||
{
|
||
return Sprite.Create(self, new Rect(0, 0, self.width, self.height), Vector2.one * 0.5f);
|
||
}
|
||
}
|
||
} |