Compare commits
2 Commits
b01ada2f40
...
7ae4ddac09
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ae4ddac09 | |||
| 1a9a59ab07 |
56
Runtime/ABase/Extension/Extension/ArrayExtensions.cs
Normal file
56
Runtime/ABase/Extension/Extension/ArrayExtensions.cs
Normal file
@ -0,0 +1,56 @@
|
||||
using UnityEngine;
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static class ArrayExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 从数组中随机取一个元素。
|
||||
/// </summary>
|
||||
public static T Random<T>(this T[] items)
|
||||
{
|
||||
System.Random rnd = new System.Random();
|
||||
if (items.Length > 0)
|
||||
{
|
||||
return items[rnd.Next(0, items.Length)];
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取与目标值最接近的元素索引。
|
||||
/// </summary>
|
||||
public static int ClosestIndex(this int[] array, int value)
|
||||
{
|
||||
int closestIndex = 0;
|
||||
int minDifference = Mathf.Abs(array[0] - value);
|
||||
for (int i = 1; i < array.Length; i++)
|
||||
{
|
||||
int difference = Mathf.Abs(array[i] - value);
|
||||
if (difference < minDifference)
|
||||
{
|
||||
minDifference = difference;
|
||||
closestIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
return closestIndex;
|
||||
}
|
||||
}
|
||||
|
||||
namespace AlicizaX
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static class MinMaxExtensions
|
||||
{
|
||||
public static float Random(this MinMax minMax)
|
||||
{
|
||||
return UnityEngine.Random.Range(minMax.RealMin, minMax.RealMax);
|
||||
}
|
||||
|
||||
public static int Random(this MinMaxInt minMax)
|
||||
{
|
||||
return UnityEngine.Random.Range(minMax.RealMin, minMax.RealMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 74cc512af7309484fa066b16175c6331
|
||||
timeCreated: 1474943113
|
||||
licenseType: Pro
|
||||
guid: ae1b3849ddfb58045a96ac9927218a73
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
@ -145,4 +145,4 @@ namespace System.Collections.Generic
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace AlicizaX
|
||||
{
|
||||
/// <summary>
|
||||
/// 去重。帮助类
|
||||
/// </summary>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static class DistinctHelper
|
||||
public static class EnumerableExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据条件去重
|
||||
/// 根据指定键进行去重。
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="keySelector"></param>
|
||||
/// <typeparam name="TSource"></typeparam>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
|
||||
{
|
||||
var identifiedKeys = new HashSet<TKey>();
|
||||
|
||||
foreach (var item in source)
|
||||
{
|
||||
if (identifiedKeys.Add(keySelector(item)))
|
||||
@ -30,5 +22,13 @@ namespace AlicizaX
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断集合是否包含另一个集合中的所有元素。
|
||||
/// </summary>
|
||||
public static bool ContainsAll<T>(this IEnumerable<T> source, IEnumerable<T> values)
|
||||
{
|
||||
return !source.Except(values).Any();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c7bd0b921d0715a4caa7a59d261e8803
|
||||
timeCreated: 1474942922
|
||||
licenseType: Pro
|
||||
guid: c6d80b4ea1444e5ab93a9ae1dbaa6946
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
@ -198,6 +198,30 @@ public static class StringExtension
|
||||
return string.Format(text, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为标题格式。
|
||||
/// </summary>
|
||||
public static string ToTitleCase(this string str)
|
||||
{
|
||||
return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断字符串是否为空。
|
||||
/// </summary>
|
||||
public static bool IsEmpty(this string str)
|
||||
{
|
||||
return string.IsNullOrEmpty(str);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回当前字符串,若为空则返回备用值。
|
||||
/// </summary>
|
||||
public static string Or(this string str, string otherwise)
|
||||
{
|
||||
return !string.IsNullOrEmpty(str) ? str : otherwise;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将[\n、\t、\r、空格]替换为空,并返回
|
||||
/// </summary>
|
||||
@ -226,6 +250,87 @@ public static class StringExtension
|
||||
return self;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 替换起止字符之间的片段。
|
||||
/// </summary>
|
||||
public static string ReplacePart(this string str, char start, char end, string replace)
|
||||
{
|
||||
int chStart = str.IndexOf(start);
|
||||
int chEnd = str.IndexOf(end);
|
||||
string old = str.Substring(chStart, chEnd - chStart + 1);
|
||||
return str.Replace(old, replace);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 替换指定包裹标记中的内容。
|
||||
/// </summary>
|
||||
public static string RegexReplaceTag(this string str, char start, char end, string tag, string replace)
|
||||
{
|
||||
Regex regex = new Regex($@"\{start}({tag})\{end}");
|
||||
if (regex.Match(str).Success)
|
||||
{
|
||||
return regex.Replace(str, replace);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取起止字符之间的内容。
|
||||
/// </summary>
|
||||
public static bool RegexGet(this string str, char start, char end, out string result)
|
||||
{
|
||||
string escapedStart = Regex.Escape(start.ToString());
|
||||
string escapedEnd = Regex.Escape(end.ToString());
|
||||
string pattern = $"{escapedStart}(.*?){escapedEnd}";
|
||||
|
||||
Match match = Regex.Match(str, pattern);
|
||||
if (match.Success)
|
||||
{
|
||||
result = match.Groups[1].Value;
|
||||
return true;
|
||||
}
|
||||
|
||||
result = string.Empty;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取所有起止字符之间的内容。
|
||||
/// </summary>
|
||||
public static bool RegexGetMany(this string str, char start, char end, out string[] results)
|
||||
{
|
||||
string escapedStart = Regex.Escape(start.ToString());
|
||||
string escapedEnd = Regex.Escape(end.ToString());
|
||||
string pattern = $"{escapedStart}(.*?){escapedEnd}";
|
||||
|
||||
MatchCollection matches = Regex.Matches(str, pattern);
|
||||
if (matches.Count > 0)
|
||||
{
|
||||
var matchList = new List<string>();
|
||||
foreach (Match match in matches)
|
||||
{
|
||||
matchList.Add(match.Groups[1].Value);
|
||||
}
|
||||
|
||||
results = matchList.ToArray();
|
||||
return true;
|
||||
}
|
||||
|
||||
results = Array.Empty<string>();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 以单词为边界替换内容。
|
||||
/// </summary>
|
||||
public static string RegexReplace(this string str, string word, string replace)
|
||||
{
|
||||
string escapedWord = Regex.Escape(word);
|
||||
string pattern = $@"\b{escapedWord}\b";
|
||||
return Regex.Replace(str, pattern, replace);
|
||||
}
|
||||
|
||||
public static int[] SplitToIntArray(this string str, char sep = '+')
|
||||
{
|
||||
if (string.IsNullOrEmpty(str))
|
||||
@ -328,4 +433,4 @@ public static class StringExtension
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,85 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEngine
|
||||
{
|
||||
public static class UnityEngageGameObjectExtension
|
||||
{
|
||||
public static void SafeDestroySelf(
|
||||
this Object obj)
|
||||
{
|
||||
if (obj == null) return;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
Object.DestroyImmediate(obj);
|
||||
else
|
||||
Object.Destroy(obj);
|
||||
#else
|
||||
Object.Destroy(obj);
|
||||
#endif
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取或增加组件。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要获取或增加的组件。</typeparam>
|
||||
/// <param name="gameObject">目标对象。</param>
|
||||
/// <returns>获取或增加的组件。</returns>
|
||||
public static void DestroyComponent<T>(this GameObject gameObject) where T : Component
|
||||
{
|
||||
T component = gameObject.GetComponent<T>();
|
||||
if (component != null)
|
||||
{
|
||||
Object.Destroy(component);
|
||||
}
|
||||
|
||||
// return component;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或增加组件。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要获取或增加的组件。</typeparam>
|
||||
/// <param name="gameObject">目标对象。</param>
|
||||
/// <returns>获取或增加的组件。</returns>
|
||||
public static T GetOrAddComponent<T>(this GameObject gameObject) where T : Component
|
||||
{
|
||||
T component = gameObject.GetComponent<T>();
|
||||
if (component == null)
|
||||
{
|
||||
component = gameObject.AddComponent<T>();
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或增加组件。
|
||||
/// </summary>
|
||||
/// <param name="gameObject">目标对象。</param>
|
||||
/// <param name="type">要获取或增加的组件类型。</param>
|
||||
/// <returns>获取或增加的组件。</returns>
|
||||
public static Component GetOrAddComponent(this GameObject gameObject, Type type)
|
||||
{
|
||||
Component component = gameObject.GetComponent(type);
|
||||
if (component == null)
|
||||
{
|
||||
component = gameObject.AddComponent(type);
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 GameObject 是否在场景中。
|
||||
/// </summary>
|
||||
/// <param name="gameObject">目标对象。</param>
|
||||
/// <returns>GameObject 是否在场景中。</returns>
|
||||
/// <remarks>若返回 true,表明此 GameObject 是一个场景中的实例对象;若返回 false,表明此 GameObject 是一个 Prefab。</remarks>
|
||||
public static bool InScene(this GameObject gameObject)
|
||||
{
|
||||
return gameObject.scene.name != null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
8
Runtime/ABase/Extension/UnityEngine.Common.meta
Normal file
8
Runtime/ABase/Extension/UnityEngine.Common.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a4c9cbd4e6d1ba84fb42b601118e51a1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,148 @@
|
||||
using AlicizaX;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace UnityEngine
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static class ColorExtensions
|
||||
{
|
||||
public static Color Alpha(this Color color, float alpha)
|
||||
{
|
||||
color.a = alpha;
|
||||
return color;
|
||||
}
|
||||
|
||||
public static Color Lightness(this Color color, float lightness)
|
||||
{
|
||||
Color.RGBToHSV(color, out var hue, out var saturation, out var _);
|
||||
return Color.HSVToRGB(hue, saturation, lightness);
|
||||
}
|
||||
}
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static class ImageExtensions
|
||||
{
|
||||
public static void Alpha(this Image image, float alpha)
|
||||
{
|
||||
Color color = image.color;
|
||||
color.a = alpha;
|
||||
image.color = color;
|
||||
}
|
||||
}
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static class AudioSourceExtensions
|
||||
{
|
||||
public static void SetSoundClip(this AudioSource audioSource, SoundClip soundClip, float volumeMul = 1f, bool play = false)
|
||||
{
|
||||
if (soundClip == null || soundClip.audioClip == null || audioSource == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioSource.clip != soundClip.audioClip)
|
||||
{
|
||||
audioSource.clip = soundClip.audioClip;
|
||||
}
|
||||
|
||||
audioSource.volume = soundClip.volume * volumeMul;
|
||||
if (play && !audioSource.isPlaying)
|
||||
{
|
||||
audioSource.Play();
|
||||
}
|
||||
}
|
||||
|
||||
public static void PlayOneShotSoundClip(this AudioSource audioSource, SoundClip soundClip, float volumeMul = 1f)
|
||||
{
|
||||
if (soundClip == null || soundClip.audioClip == null || audioSource == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
audioSource.PlayOneShot(soundClip.audioClip, soundClip.volume * volumeMul);
|
||||
}
|
||||
}
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static class LayerMaskExtensions
|
||||
{
|
||||
public static bool CompareLayer(this LayerMask layerMask, int layer)
|
||||
{
|
||||
return layerMask == (layerMask | (1 << layer));
|
||||
}
|
||||
}
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static class AnimatorExtensions
|
||||
{
|
||||
public static bool IsAnyPlaying(this Animator animator)
|
||||
{
|
||||
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
|
||||
return (stateInfo.length + 0.1f > stateInfo.normalizedTime || animator.IsInTransition(0)) && !stateInfo.IsName("Default");
|
||||
}
|
||||
}
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static class AngleExtensions
|
||||
{
|
||||
public static float FixAngle(this float angle, float min, float max)
|
||||
{
|
||||
if (angle < min)
|
||||
{
|
||||
angle += 360f;
|
||||
}
|
||||
|
||||
if (angle > max)
|
||||
{
|
||||
angle -= 360f;
|
||||
}
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
public static float FixAngle180(this float angle)
|
||||
{
|
||||
if (angle < -180f)
|
||||
{
|
||||
angle += 360f;
|
||||
}
|
||||
|
||||
if (angle > 180f)
|
||||
{
|
||||
angle -= 360f;
|
||||
}
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
public static float FixAngle(this float angle)
|
||||
{
|
||||
if (angle < -360f)
|
||||
{
|
||||
angle += 360f;
|
||||
}
|
||||
|
||||
if (angle > 360f)
|
||||
{
|
||||
angle -= 360f;
|
||||
}
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
public static float FixAngle360(this float angle)
|
||||
{
|
||||
if (angle < 0f)
|
||||
{
|
||||
angle += 360f;
|
||||
}
|
||||
|
||||
if (angle > 360f)
|
||||
{
|
||||
angle -= 360f;
|
||||
}
|
||||
|
||||
return angle;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fdcd89fb0474b6949b197c7da1cb81fa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -5,8 +5,15 @@ namespace UnityEngine
|
||||
/// <summary>
|
||||
/// <see cref="UnityEngine.Component"/>.
|
||||
/// </summary>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static class ComponentExtensions
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void DestroyComponent(this Component component)
|
||||
{
|
||||
component.SafeDestroySelf();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从目标组件中获取一个组件,如果是组件类型不存在,则添加
|
||||
/// </summary>
|
||||
@ -0,0 +1,228 @@
|
||||
using System;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace UnityEngine
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static class GameObjectExtensions
|
||||
{
|
||||
public static void SafeDestroySelf(
|
||||
this Object obj)
|
||||
{
|
||||
if (obj == null) return;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
Object.DestroyImmediate(obj);
|
||||
else
|
||||
Object.Destroy(obj);
|
||||
#else
|
||||
Object.Destroy(obj);
|
||||
#endif
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取或增加组件。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要获取或增加的组件。</typeparam>
|
||||
/// <param name="gameObject">目标对象。</param>
|
||||
/// <returns>获取或增加的组件。</returns>
|
||||
public static void DestroyComponent<T>(this GameObject gameObject) where T : Component
|
||||
{
|
||||
T component = gameObject.GetComponent<T>();
|
||||
if (component != null)
|
||||
{
|
||||
Object.Destroy(component);
|
||||
}
|
||||
|
||||
// return component;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或增加组件。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要获取或增加的组件。</typeparam>
|
||||
/// <param name="gameObject">目标对象。</param>
|
||||
/// <returns>获取或增加的组件。</returns>
|
||||
public static T GetOrAddComponent<T>(this GameObject gameObject) where T : Component
|
||||
{
|
||||
T component = gameObject.GetComponent<T>();
|
||||
if (component == null)
|
||||
{
|
||||
component = gameObject.AddComponent<T>();
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或增加组件。
|
||||
/// </summary>
|
||||
/// <param name="gameObject">目标对象。</param>
|
||||
/// <param name="type">要获取或增加的组件类型。</param>
|
||||
/// <returns>获取或增加的组件。</returns>
|
||||
public static Component GetOrAddComponent(this GameObject gameObject, Type type)
|
||||
{
|
||||
Component component = gameObject.GetComponent(type);
|
||||
if (component == null)
|
||||
{
|
||||
component = gameObject.AddComponent(type);
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 GameObject 是否在场景中。
|
||||
/// </summary>
|
||||
/// <param name="gameObject">目标对象。</param>
|
||||
/// <returns>GameObject 是否在场景中。</returns>
|
||||
/// <remarks>若返回 true,表明此 GameObject 是一个场景中的实例对象;若返回 false,表明此 GameObject 是一个 Prefab。</remarks>
|
||||
public static bool InScene(this GameObject gameObject)
|
||||
{
|
||||
return gameObject.scene.name != null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置对象下所有 MeshRenderer 的 rendering layer。
|
||||
/// </summary>
|
||||
public static void SetRenderingLayer(this GameObject gameObject, uint layer, bool set = true)
|
||||
{
|
||||
if (layer > 31)
|
||||
{
|
||||
Debug.LogError("Invalid layer value. Must be between 0 and 31.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint layerMask = 1u << (int)layer;
|
||||
foreach (MeshRenderer renderer in gameObject.GetComponentsInChildren<MeshRenderer>())
|
||||
{
|
||||
if (set)
|
||||
{
|
||||
renderer.renderingLayerMask |= layerMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer.renderingLayerMask &= ~layerMask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void RemoveChildren(this GameObject gameObject)
|
||||
{
|
||||
for (var i = gameObject.transform.childCount - 1; i >= 0; i--)
|
||||
{
|
||||
gameObject.transform.GetChild(i).gameObject.DestroyObject();
|
||||
}
|
||||
}
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void DestroyObject(this GameObject gameObject)
|
||||
{
|
||||
gameObject.SafeDestroySelf();
|
||||
}
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void Destroy(this GameObject gameObject)
|
||||
{
|
||||
gameObject.DestroyObject();
|
||||
}
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static GameObject FindChildGamObjectByName(string nodeName, string sceneName = null)
|
||||
{
|
||||
Scene scene;
|
||||
if (string.IsNullOrWhiteSpace(sceneName))
|
||||
{
|
||||
scene = SceneManager.GetActiveScene();
|
||||
}
|
||||
else
|
||||
{
|
||||
scene = SceneManager.GetSceneByName(sceneName);
|
||||
if (!scene.isLoaded)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
var rootObjects = scene.GetRootGameObjects();
|
||||
foreach (var rootObject in rootObjects)
|
||||
{
|
||||
var result = rootObject.FindChildGamObjectByName(nodeName);
|
||||
if (result.IsNotNull())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static GameObject FindChildGamObjectByName(this GameObject gameObject, string name)
|
||||
{
|
||||
var transform = gameObject.transform.FindChildName(name);
|
||||
if (transform.IsNotNull())
|
||||
{
|
||||
return transform.gameObject;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static GameObject Create(this Transform parent, string name)
|
||||
{
|
||||
Debug.Assert(!ReferenceEquals(parent, null), nameof(parent) + " == null");
|
||||
var gameObject = new GameObject(name);
|
||||
gameObject.transform.SetParent(parent);
|
||||
return gameObject;
|
||||
}
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static GameObject Create(this GameObject parent, string name)
|
||||
{
|
||||
Debug.Assert(!ReferenceEquals(parent, null), nameof(parent) + " == null");
|
||||
return parent.transform.Create(name);
|
||||
}
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void ResetTransform(this GameObject gameObject)
|
||||
{
|
||||
gameObject.transform.localScale = Vector3.one;
|
||||
gameObject.transform.localPosition = Vector3.zero;
|
||||
gameObject.transform.localRotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void SetSortingGroupLayer(this GameObject gameObject, string sortingLayer)
|
||||
{
|
||||
SortingGroup[] sortingGroups = gameObject.GetComponentsInChildren<SortingGroup>();
|
||||
foreach (SortingGroup sortingGroup in sortingGroups)
|
||||
{
|
||||
sortingGroup.sortingLayerName = sortingLayer;
|
||||
}
|
||||
}
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void SetLayer(this GameObject gameObject, int layer, bool children = true)
|
||||
{
|
||||
if (gameObject.layer != layer)
|
||||
{
|
||||
gameObject.layer = layer;
|
||||
}
|
||||
|
||||
if (children)
|
||||
{
|
||||
Transform[] transforms = gameObject.GetComponentsInChildren<Transform>();
|
||||
foreach (var transform in transforms)
|
||||
{
|
||||
transform.gameObject.layer = layer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
namespace UnityEngine
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static class RectTransformExtensions
|
||||
{
|
||||
//重置为全屏自适应UI
|
||||
public static void ResetToFullScreen(this RectTransform self)
|
||||
{
|
||||
self.anchorMin = Vector2.zero;
|
||||
self.anchorMax = Vector2.one;
|
||||
self.anchoredPosition3D = Vector3.zero;
|
||||
self.pivot = new Vector2(0.5f, 0.5f);
|
||||
self.offsetMax = Vector2.zero;
|
||||
self.offsetMin = Vector2.zero;
|
||||
self.sizeDelta = Vector2.zero;
|
||||
self.localEulerAngles = Vector3.zero;
|
||||
self.localScale = Vector3.one;
|
||||
}
|
||||
|
||||
//重置位置与旋转
|
||||
public static void ResetLocalPosAndRot(this RectTransform self)
|
||||
{
|
||||
self.localPosition = Vector3.zero;
|
||||
self.localRotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
public static void SetWidth(this RectTransform rectTransform, float width)
|
||||
{
|
||||
Vector2 size = rectTransform.sizeDelta;
|
||||
size.x = width;
|
||||
rectTransform.sizeDelta = size;
|
||||
}
|
||||
|
||||
public static void SetHeight(this RectTransform rectTransform, float height)
|
||||
{
|
||||
Vector2 size = rectTransform.sizeDelta;
|
||||
size.y = height;
|
||||
rectTransform.sizeDelta = size;
|
||||
}
|
||||
|
||||
public static void SetAnchoredX(this RectTransform rectTransform, float x)
|
||||
{
|
||||
Vector2 position = rectTransform.anchoredPosition;
|
||||
position.x = x;
|
||||
rectTransform.anchoredPosition = position;
|
||||
}
|
||||
|
||||
public static void SetAnchoredY(this RectTransform rectTransform, float y)
|
||||
{
|
||||
Vector2 position = rectTransform.anchoredPosition;
|
||||
position.y = y;
|
||||
rectTransform.anchoredPosition = position;
|
||||
}
|
||||
|
||||
public static System.Collections.Generic.IEnumerable<RectTransform> GetChildTransforms(this RectTransform rectTransform)
|
||||
{
|
||||
foreach (var item in rectTransform)
|
||||
{
|
||||
yield return item as RectTransform;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,7 @@ using UnityEngine;
|
||||
namespace UnityEngine
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static class UnityEngineTransformExtension
|
||||
public static class TransformExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 查找子节点的名称符合的 <see cref="Transform" />。
|
||||
@ -271,4 +271,4 @@ namespace UnityEngine
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
namespace UnityEngine
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static class UnityEngine_UIExtension
|
||||
{
|
||||
//重置为全屏自适应UI
|
||||
public static void ResetToFullScreen(this RectTransform self)
|
||||
{
|
||||
self.anchorMin = Vector2.zero;
|
||||
self.anchorMax = Vector2.one;
|
||||
self.anchoredPosition3D = Vector3.zero;
|
||||
self.pivot = new Vector2(0.5f, 0.5f);
|
||||
self.offsetMax = Vector2.zero;
|
||||
self.offsetMin = Vector2.zero;
|
||||
self.sizeDelta = Vector2.zero;
|
||||
self.localEulerAngles = Vector3.zero;
|
||||
self.localScale = Vector3.one;
|
||||
}
|
||||
|
||||
//重置位置与旋转
|
||||
public static void ResetLocalPosAndRot(this RectTransform self)
|
||||
{
|
||||
self.localPosition = Vector3.zero;
|
||||
self.localRotation = Quaternion.identity;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,26 +0,0 @@
|
||||
namespace UnityEngine
|
||||
{
|
||||
public static class UnityEngineVector2Extension
|
||||
{
|
||||
/// <summary>
|
||||
/// 取 <see cref="Vector2" /> 的 (x, y) 转换为 <see cref="Vector3" /> 的 (x, 0, y)。
|
||||
/// </summary>
|
||||
/// <param name="vector2">要转换的 Vector2。</param>
|
||||
/// <returns>转换后的 Vector3。</returns>
|
||||
public static Vector3 ToVector3(this Vector2 vector2)
|
||||
{
|
||||
return new Vector3(vector2.x, 0f, vector2.y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取 <see cref="Vector2" /> 的 (x, y) 和给定参数 y 转换为 <see cref="Vector3" /> 的 (x, 参数 y, y)。
|
||||
/// </summary>
|
||||
/// <param name="vector2">要转换的 Vector2。</param>
|
||||
/// <param name="y">Vector3 的 y 值。</param>
|
||||
/// <returns>转换后的 Vector3。</returns>
|
||||
public static Vector3 ToVector3(this Vector2 vector2, float y)
|
||||
{
|
||||
return new Vector3(vector2.x, y, vector2.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
namespace UnityEngine
|
||||
{
|
||||
public static class Vector2Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 取 <see cref="Vector2" /> 的 (x, y) 转换为 <see cref="Vector3" /> 的 (x, 0, y)。
|
||||
/// </summary>
|
||||
/// <param name="vector2">要转换的 Vector2。</param>
|
||||
/// <returns>转换后的 Vector3。</returns>
|
||||
public static Vector3 ToVector3(this Vector2 vector2)
|
||||
{
|
||||
return new Vector3(vector2.x, 0f, vector2.y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取 <see cref="Vector2" /> 的 (x, y) 和给定参数 y 转换为 <see cref="Vector3" /> 的 (x, 参数 y, y)。
|
||||
/// </summary>
|
||||
/// <param name="vector2">要转换的 Vector2。</param>
|
||||
/// <param name="y">Vector3 的 y 值。</param>
|
||||
/// <returns>转换后的 Vector3。</returns>
|
||||
public static Vector3 ToVector3(this Vector2 vector2, float y)
|
||||
{
|
||||
return new Vector3(vector2.x, y, vector2.y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断值是否在向量区间内。
|
||||
/// </summary>
|
||||
public static bool InRange(this Vector2 vector, float value, bool equal = false)
|
||||
{
|
||||
return equal ? value >= vector.x && value <= vector.y : value > vector.x && value < vector.y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断角度是否在向量表示的角度区间内。
|
||||
/// </summary>
|
||||
public static bool InDegrees(this Vector2 vector, float value, bool equal = false)
|
||||
{
|
||||
if (vector.x > vector.y)
|
||||
{
|
||||
return equal ? value >= (vector.x - 360f) && value <= vector.y : value > (vector.x - 360f) && value < vector.y;
|
||||
}
|
||||
|
||||
return equal ? value >= vector.x && value <= vector.y : value > vector.x && value < vector.y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从区间内取随机值。
|
||||
/// </summary>
|
||||
public static float Random(this Vector2 vector)
|
||||
{
|
||||
return UnityEngine.Random.Range(vector.x, vector.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,86 @@
|
||||
using AlicizaX;
|
||||
|
||||
namespace UnityEngine
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static class AxisExtensions
|
||||
{
|
||||
public static Vector3 Convert(this Axis axis) => axis switch
|
||||
{
|
||||
Axis.X => Vector3.right,
|
||||
Axis.X_Negative => Vector3.left,
|
||||
Axis.Y => Vector3.up,
|
||||
Axis.Y_Negative => Vector3.down,
|
||||
Axis.Z => Vector3.forward,
|
||||
Axis.Z_Negative => Vector3.back,
|
||||
_ => Vector3.up,
|
||||
};
|
||||
|
||||
public static Vector3 Direction(this Transform transform, Axis axis)
|
||||
{
|
||||
return axis switch
|
||||
{
|
||||
Axis.X => transform.right,
|
||||
Axis.X_Negative => -transform.right,
|
||||
Axis.Y => transform.up,
|
||||
Axis.Y_Negative => -transform.up,
|
||||
Axis.Z => transform.forward,
|
||||
Axis.Z_Negative => -transform.forward,
|
||||
_ => transform.up,
|
||||
};
|
||||
}
|
||||
|
||||
public static float Component(this Vector3 vector, Axis axis)
|
||||
{
|
||||
return axis switch
|
||||
{
|
||||
Axis.X or Axis.X_Negative => vector.x,
|
||||
Axis.Y or Axis.Y_Negative => vector.y,
|
||||
Axis.Z or Axis.Z_Negative => vector.z,
|
||||
_ => vector.y,
|
||||
};
|
||||
}
|
||||
|
||||
public static Vector3 SetComponent(this Vector3 vector, Axis axis, float value)
|
||||
{
|
||||
switch (axis)
|
||||
{
|
||||
case Axis.X:
|
||||
case Axis.X_Negative:
|
||||
vector.x = value;
|
||||
break;
|
||||
case Axis.Y:
|
||||
case Axis.Y_Negative:
|
||||
vector.y = value;
|
||||
break;
|
||||
case Axis.Z:
|
||||
case Axis.Z_Negative:
|
||||
vector.z = value;
|
||||
break;
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
public static Vector3 Clamp(this Vector3 vector, Axis axis, MinMax limits)
|
||||
{
|
||||
switch (axis)
|
||||
{
|
||||
case Axis.X:
|
||||
case Axis.X_Negative:
|
||||
vector.x = Mathf.Clamp(vector.x, limits.RealMin, limits.RealMax);
|
||||
break;
|
||||
case Axis.Y:
|
||||
case Axis.Y_Negative:
|
||||
vector.y = Mathf.Clamp(vector.y, limits.RealMin, limits.RealMax);
|
||||
break;
|
||||
case Axis.Z:
|
||||
case Axis.Z_Negative:
|
||||
vector.z = Mathf.Clamp(vector.z, limits.RealMin, limits.RealMax);
|
||||
break;
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b282fd247f4930142a14784638083a56
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -3,7 +3,7 @@
|
||||
/// <summary>
|
||||
/// 对 Unity 的扩展方法。
|
||||
/// </summary>
|
||||
public static class UnityEngineVector3Extension
|
||||
public static class Vector3Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 取 <see cref="Vector3" /> 的 (x, y, z) 转换为 <see cref="Vector2" /> 的 (x, z)。
|
||||
@ -25,5 +25,14 @@
|
||||
{
|
||||
return new Vector3(vector3.x, vector3.y, vector3.z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按分量相乘。
|
||||
/// </summary>
|
||||
public static Vector3 Multiply(this Vector3 lhs, Vector3 rhs)
|
||||
{
|
||||
lhs.Scale(rhs);
|
||||
return lhs;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,128 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX
|
||||
{
|
||||
/// <summary>
|
||||
/// 应用帮助类
|
||||
/// </summary>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static class ApplicationHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否是编辑器
|
||||
/// </summary>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static bool IsEditor
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否是安卓
|
||||
/// </summary>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static bool IsAndroid
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_ANDROID
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否是WebGL平台
|
||||
/// </summary>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static bool IsWebGL
|
||||
{
|
||||
get { return Application.platform == RuntimePlatform.WebGLPlayer; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否是Windows平台
|
||||
/// </summary>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static bool IsWindows
|
||||
{
|
||||
get { return Application.platform == RuntimePlatform.WindowsPlayer; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否是Linux平台
|
||||
/// </summary>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static bool IsLinux
|
||||
{
|
||||
get { return Application.platform == RuntimePlatform.LinuxPlayer; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 是否是Mac平台
|
||||
/// </summary>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static bool IsMacOsx
|
||||
{
|
||||
get { return Application.platform == RuntimePlatform.OSXPlayer; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否是iOS 移动平台
|
||||
/// </summary>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static bool IsIOS
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_IOS
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 退出
|
||||
/// </summary>
|
||||
public static void Quit()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.EditorApplication.isPlaying = false;
|
||||
return;
|
||||
#endif
|
||||
Application.Quit();
|
||||
}
|
||||
#if UNITY_IOS
|
||||
[System.Runtime.InteropServices.DllImport("__Internal")]
|
||||
private static extern void open_url(string url);
|
||||
#endif
|
||||
/// <summary>
|
||||
/// 打开URL
|
||||
/// </summary>
|
||||
/// <param name="url">url地址</param>
|
||||
public static void OpenURL(string url)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
Application.OpenURL(url);
|
||||
return;
|
||||
#endif
|
||||
#if UNITY_IOS
|
||||
open_url(url);
|
||||
#else
|
||||
Application.OpenURL(url);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4bb21c08b2dd4b15af73858c5daf4a99
|
||||
timeCreated: 1676885563
|
||||
@ -1,40 +0,0 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace AlicizaX
|
||||
{
|
||||
/// <summary>
|
||||
/// 相机帮助类
|
||||
/// </summary>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static class CameraHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取相机快照
|
||||
/// </summary>
|
||||
/// <param name="main">相机</param>
|
||||
/// <param name="scale">缩放比</param>
|
||||
public static Texture2D GetCaptureScreenshot(Camera main, float scale = 0.5f)
|
||||
{
|
||||
Rect rect = new Rect(0, 0, Screen.width * scale, Screen.height * scale);
|
||||
string name = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss");
|
||||
RenderTexture renderTexture = RenderTexture.GetTemporary((int)rect.width, (int)rect.height, 0);
|
||||
renderTexture.name = SceneManager.GetActiveScene().name + "_" + renderTexture.width + "_" + renderTexture.height + "_" + name;
|
||||
main.targetTexture = renderTexture;
|
||||
main.Render();
|
||||
|
||||
RenderTexture.active = renderTexture;
|
||||
Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false)
|
||||
{
|
||||
name = renderTexture.name
|
||||
};
|
||||
screenShot.ReadPixels(rect, 0, 0);
|
||||
screenShot.Apply();
|
||||
main.targetTexture = null;
|
||||
RenderTexture.active = null;
|
||||
RenderTexture.ReleaseTemporary(renderTexture);
|
||||
return screenShot;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d6f0c95931944448a8c8f1790d20059a
|
||||
timeCreated: 1663323744
|
||||
@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 777c1056a4804d90960109d21275c56e
|
||||
timeCreated: 1670814641
|
||||
@ -1,321 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件帮助类
|
||||
/// </summary>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static class FileHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取目录下的所有文件
|
||||
/// </summary>
|
||||
/// <param name="files">文件存放路径列表对象</param>
|
||||
/// <param name="dir">目标目录</param>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void GetAllFiles(List<string> files, string dir)
|
||||
{
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string[] strings = Directory.GetFiles(dir);
|
||||
foreach (string item in strings)
|
||||
{
|
||||
files.Add(item);
|
||||
}
|
||||
|
||||
string[] subDirs = Directory.GetDirectories(dir);
|
||||
foreach (string subDir in subDirs)
|
||||
{
|
||||
GetAllFiles(files, subDir);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理目录
|
||||
/// </summary>
|
||||
/// <param name="dir">目标路径</param>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void CleanDirectory(string dir)
|
||||
{
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string subDir in Directory.GetDirectories(dir))
|
||||
{
|
||||
Directory.Delete(subDir, true);
|
||||
}
|
||||
|
||||
foreach (string subFile in Directory.GetFiles(dir))
|
||||
{
|
||||
File.Delete(subFile);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 目录复制
|
||||
/// </summary>
|
||||
/// <param name="srcDir">源路径</param>
|
||||
/// <param name="targetDir">目标路径</param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void CopyDirectory(string srcDir, string targetDir)
|
||||
{
|
||||
DirectoryInfo source = new DirectoryInfo(srcDir);
|
||||
DirectoryInfo target = new DirectoryInfo(targetDir);
|
||||
|
||||
if (target.FullName.StartsWith(source.FullName, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
throw new Exception("父目录不能拷贝到子目录!");
|
||||
}
|
||||
|
||||
if (!source.Exists)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!target.Exists)
|
||||
{
|
||||
target.Create();
|
||||
}
|
||||
|
||||
FileInfo[] files = source.GetFiles();
|
||||
|
||||
for (int i = 0; i < files.Length; i++)
|
||||
{
|
||||
File.Copy(files[i].FullName, Path.Combine(target.FullName, files[i].Name), true);
|
||||
}
|
||||
|
||||
DirectoryInfo[] dirs = source.GetDirectories();
|
||||
|
||||
for (int j = 0; j < dirs.Length; j++)
|
||||
{
|
||||
CopyDirectory(dirs[j].FullName, Path.Combine(target.FullName, dirs[j].Name));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 复制文件到目标目录
|
||||
/// </summary>
|
||||
/// <param name="sourceFileName">源路径</param>
|
||||
/// <param name="destFileName">目标路径</param>
|
||||
/// <param name="overwrite">是否覆盖</param>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void Copy(string sourceFileName, string destFileName, bool overwrite = false)
|
||||
{
|
||||
if (!File.Exists(sourceFileName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
File.Copy(sourceFileName, destFileName, overwrite);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除文件
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void Delete(string path)
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断文件是否存在
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static bool IsExists(string path)
|
||||
{
|
||||
#if ENABLE_GAME_FRAME_X_READ_ASSETS
|
||||
if (IsAndroidReadOnlyPath(path, out var readPath))
|
||||
{
|
||||
return BlankReadAssets.BlankReadAssets.IsFileExists(readPath);
|
||||
}
|
||||
#endif
|
||||
return File.Exists(path);
|
||||
}
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
private static bool IsAndroidReadOnlyPath(string path, out string readPath)
|
||||
{
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (PathHelper.NormalizePath(path).Contains(PathHelper.AppResPath))
|
||||
{
|
||||
readPath = path.Substring(PathHelper.AppResPath.Length);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
readPath = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移动文件到目标目录
|
||||
/// </summary>
|
||||
/// <param name="sourceFileName">文件源路径</param>
|
||||
/// <param name="destFileName">目标路径</param>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void Move(string sourceFileName, string destFileName)
|
||||
{
|
||||
if (!File.Exists(sourceFileName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Copy(sourceFileName, destFileName, true);
|
||||
Delete(sourceFileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static byte[] ReadAllBytes(string path)
|
||||
{
|
||||
#if ENABLE_GAME_FRAME_X_READ_ASSETS
|
||||
if (IsAndroidReadOnlyPath((path), out var readPath))
|
||||
{
|
||||
return BlankReadAssets.BlankReadAssets.Read(readPath);
|
||||
}
|
||||
#endif
|
||||
|
||||
return File.ReadAllBytes(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="encoding">编码</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static string ReadAllText(string path, Encoding encoding)
|
||||
{
|
||||
return File.ReadAllText(path, encoding);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static string ReadAllText(string path)
|
||||
{
|
||||
return File.ReadAllText(path, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="encoding">编码</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static string[] ReadAllLines(string path, Encoding encoding)
|
||||
{
|
||||
return File.ReadAllLines(path, encoding);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static string[] ReadAllLines(string path)
|
||||
{
|
||||
return File.ReadAllLines(path, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="buffer">写入内容</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void ReadAllLines(string path, byte[] buffer)
|
||||
{
|
||||
File.WriteAllBytes(path, buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="lines">写入的内容</param>
|
||||
/// <param name="encoding">编码</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void WriteAllLines(string path, string[] lines, Encoding encoding)
|
||||
{
|
||||
File.WriteAllLines(path, lines, encoding);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="lines">写入的内容</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void WriteAllLines(string path, string[] lines)
|
||||
{
|
||||
File.WriteAllLines(path, lines, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="content">写入的内容</param>
|
||||
/// <param name="encoding">编码</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void WriteAllText(string path, string content, Encoding encoding)
|
||||
{
|
||||
File.WriteAllText(path, content, encoding);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入指定路径的文件内容,UTF-8
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="content">写入的内容</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void WriteAllText(string path, string content)
|
||||
{
|
||||
File.WriteAllText(path, content, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="buffer">写入的内容</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void WriteAllBytes(string path, byte[] buffer)
|
||||
{
|
||||
File.WriteAllBytes(path, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -77,15 +77,6 @@ namespace UnityEngine
|
||||
/// </summary>
|
||||
public static string GetGuid() => System.Guid.NewGuid().ToString("N");
|
||||
|
||||
/// <summary>
|
||||
/// Change Cursor States.
|
||||
/// </summary>
|
||||
public static void ShowCursor(bool locked, bool visible)
|
||||
{
|
||||
Cursor.lockState = locked ? CursorLockMode.Locked : CursorLockMode.None;
|
||||
Cursor.visible = visible;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Change the GameObject layer including all children.
|
||||
/// </summary>
|
||||
|
||||
@ -1,205 +0,0 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace UnityEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏对象帮助类
|
||||
/// </summary>
|
||||
public static class GameObjectHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 销毁子物体
|
||||
/// </summary>
|
||||
/// <param name="go"></param>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void RemoveChildren(GameObject go)
|
||||
{
|
||||
for (var i = go.transform.childCount - 1; i >= 0; i--)
|
||||
{
|
||||
Destroy(go.transform.GetChild(i).gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁游戏物体
|
||||
/// </summary>
|
||||
/// <param name="gameObject"></param>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void DestroyObject(this GameObject gameObject)
|
||||
{
|
||||
if (!ReferenceEquals(gameObject, null))
|
||||
{
|
||||
if (Application.isEditor && !Application.isPlaying)
|
||||
{
|
||||
Object.DestroyImmediate(gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
Object.Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁游戏物体
|
||||
/// </summary>
|
||||
/// <param name="gameObject"></param>
|
||||
public static void Destroy(GameObject gameObject)
|
||||
{
|
||||
gameObject.DestroyObject();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁游戏组件
|
||||
/// </summary>
|
||||
/// <param name="component"></param>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void DestroyComponent(UnityEngine.Component component)
|
||||
{
|
||||
if (!ReferenceEquals(component, null))
|
||||
{
|
||||
if (Application.isEditor && !Application.isPlaying)
|
||||
{
|
||||
Object.DestroyImmediate(component);
|
||||
return;
|
||||
}
|
||||
|
||||
Object.Destroy(component);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在指定场景中查找特定名称的节点。
|
||||
/// </summary>
|
||||
/// <param name="sceneName">场景名称。</param>
|
||||
/// <param name="nodeName">节点名称。</param>
|
||||
/// <returns>找到的节点的GameObject实例,如果没有找到返回null。</returns>
|
||||
public static GameObject FindChildGamObjectByName(string nodeName, string sceneName = null)
|
||||
{
|
||||
UnityEngine.SceneManagement.Scene scene;
|
||||
if (sceneName.IsNullOrWhiteSpace())
|
||||
{
|
||||
scene = SceneManager.GetActiveScene();
|
||||
}
|
||||
else
|
||||
{
|
||||
scene = SceneManager.GetSceneByName(sceneName);
|
||||
if (!scene.isLoaded)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
var rootObjects = scene.GetRootGameObjects();
|
||||
foreach (var rootObject in rootObjects)
|
||||
{
|
||||
var result = FindChildGamObjectByName(rootObject, nodeName);
|
||||
if (result.IsNotNull())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据游戏对象名称查询子对象
|
||||
/// </summary>
|
||||
/// <param name="gameObject"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static GameObject FindChildGamObjectByName(GameObject gameObject, string name)
|
||||
{
|
||||
var transform = gameObject.transform.FindChildName(name);
|
||||
if (transform.IsNotNull())
|
||||
{
|
||||
return transform.gameObject;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建游戏对象
|
||||
/// </summary>
|
||||
/// <param name="parent"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static GameObject Create(Transform parent, string name)
|
||||
{
|
||||
Debug.Assert(!ReferenceEquals(parent, null), nameof(parent) + " == null");
|
||||
var gameObject = new GameObject(name);
|
||||
gameObject.transform.SetParent(parent);
|
||||
return gameObject;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建游戏对象
|
||||
/// </summary>
|
||||
/// <param name="parent"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static GameObject Create(GameObject parent, string name)
|
||||
{
|
||||
Debug.Assert(!ReferenceEquals(parent, null), nameof(parent) + " == null");
|
||||
return Create(parent.transform, name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置游戏对象的变换数据
|
||||
/// </summary>
|
||||
/// <param name="gameObject"></param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void ResetTransform(GameObject gameObject)
|
||||
{
|
||||
gameObject.transform.localScale = Vector3.one;
|
||||
gameObject.transform.localPosition = Vector3.zero;
|
||||
gameObject.transform.localRotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置对象的显示排序层
|
||||
/// </summary>
|
||||
/// <param name="gameObject">游戏对象</param>
|
||||
/// <param name="sortingLayer">显示层</param>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void SetSortingGroupLayer(GameObject gameObject, string sortingLayer)
|
||||
{
|
||||
SortingGroup[] sortingGroups = gameObject.GetComponentsInChildren<SortingGroup>();
|
||||
foreach (SortingGroup sg in sortingGroups)
|
||||
{
|
||||
sg.sortingLayerName = sortingLayer;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置对象的层
|
||||
/// </summary>
|
||||
/// <param name="gameObject">游戏对象</param>
|
||||
/// <param name="layer">层</param>
|
||||
/// <param name="children">是否设置子物体</param>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void SetLayer(GameObject gameObject, int layer, bool children = true)
|
||||
{
|
||||
if (gameObject.layer != layer)
|
||||
{
|
||||
gameObject.layer = layer;
|
||||
}
|
||||
|
||||
if (children)
|
||||
{
|
||||
Transform[] transforms = gameObject.GetComponentsInChildren<Transform>();
|
||||
foreach (var sg in transforms)
|
||||
{
|
||||
sg.gameObject.layer = layer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 998123e39155448eb8a773436d34eac8
|
||||
timeCreated: 1666446475
|
||||
@ -1,130 +0,0 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX
|
||||
{
|
||||
/// <summary>
|
||||
/// 数学帮助类
|
||||
/// </summary>
|
||||
public static class MathHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 检查两个矩形是否相交
|
||||
/// </summary>
|
||||
/// <param name="src"></param>
|
||||
/// <param name="target"></param>
|
||||
/// <returns></returns>
|
||||
public static bool CheckIntersect(RectInt src, RectInt target)
|
||||
{
|
||||
int minX = Math.Max(src.x, target.x);
|
||||
int minY = Math.Max(src.y, target.y);
|
||||
int maxX = Math.Min(src.x + src.width, target.x + target.width);
|
||||
int maxY = Math.Min(src.y + src.height, target.y + target.height);
|
||||
if (minX >= maxX || minY >= maxY)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查两个矩形是否相交
|
||||
/// </summary>
|
||||
/// <param name="x1"></param>
|
||||
/// <param name="y1"></param>
|
||||
/// <param name="w1"></param>
|
||||
/// <param name="h1"></param>
|
||||
/// <param name="x2"></param>
|
||||
/// <param name="y2"></param>
|
||||
/// <param name="w2"></param>
|
||||
/// <param name="h2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool CheckIntersect(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)
|
||||
{
|
||||
int minX = Math.Max(x1, x2);
|
||||
int minY = Math.Max(y1, y2);
|
||||
int maxX = Math.Min(x1 + w1, x2 + w2);
|
||||
int maxY = Math.Min(y1 + h1, y2 + h2);
|
||||
if (minX >= maxX || minY >= maxY)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查两个矩形是否相交,并返回相交的区域
|
||||
/// </summary>
|
||||
/// <param name="x1"></param>
|
||||
/// <param name="y1"></param>
|
||||
/// <param name="w1"></param>
|
||||
/// <param name="h1"></param>
|
||||
/// <param name="x2"></param>
|
||||
/// <param name="y2"></param>
|
||||
/// <param name="w2"></param>
|
||||
/// <param name="h2"></param>
|
||||
/// <param name="rect"></param>
|
||||
/// <returns></returns>
|
||||
private static bool CheckIntersect(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2, out RectInt rect)
|
||||
{
|
||||
rect = default;
|
||||
int minX = Math.Max(x1, x2);
|
||||
int minY = Math.Max(y1, y2);
|
||||
int maxX = Math.Min(x1 + w1, x2 + w2);
|
||||
int maxY = Math.Min(y1 + h1, y2 + h2);
|
||||
if (minX >= maxX || minY >= maxY)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
rect.x = minX;
|
||||
rect.y = minY;
|
||||
rect.width = Math.Abs(maxX - minX);
|
||||
rect.height = Math.Abs(maxY - minY);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查两个矩形相交的点
|
||||
/// </summary>
|
||||
/// <param name="x1">A 坐标X</param>
|
||||
/// <param name="y1">A 坐标Y</param>
|
||||
/// <param name="w1">A 宽度</param>
|
||||
/// <param name="h1">A 高度</param>
|
||||
/// <param name="x2">B 坐标X</param>
|
||||
/// <param name="y2">B 坐标Y</param>
|
||||
/// <param name="w2">B 宽度</param>
|
||||
/// <param name="h2">B 高度</param>
|
||||
/// <param name="intersectPoints">交叉点列表</param>
|
||||
/// <returns>返回是否相交</returns>
|
||||
public static bool CheckIntersectPoints(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2, int[] intersectPoints)
|
||||
{
|
||||
Vector2Int dPt = new Vector2Int();
|
||||
|
||||
if (false == CheckIntersect(x1, y1, w1, h1, x2, y2, w2, h2, out var rectInt))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < w1; i++)
|
||||
{
|
||||
for (var n = 0; n < h1; n++)
|
||||
{
|
||||
if (intersectPoints[i * h1 + n] == 1)
|
||||
{
|
||||
dPt.x = x1 + i;
|
||||
dPt.y = y1 + n;
|
||||
if (rectInt.Contains(dPt))
|
||||
{
|
||||
intersectPoints[i * h1 + n] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c10ee3753d16449f96d506192b4652c6
|
||||
timeCreated: 1670988225
|
||||
@ -1,58 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络帮助类
|
||||
/// </summary>
|
||||
public static class NetworkHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取本地的IP列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string[] GetAddressIPs()
|
||||
{
|
||||
//获取本地的IP地址
|
||||
var list = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
|
||||
string[] addressIPs = new string[list.Length];
|
||||
for (var index = 0; index < list.Length; index++)
|
||||
{
|
||||
IPAddress address = list[index];
|
||||
addressIPs[index] = address.ToString();
|
||||
}
|
||||
|
||||
return addressIPs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否有网络
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool IsReachable()
|
||||
{
|
||||
return Application.internetReachability != NetworkReachability.NotReachable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否是WIFI
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool IsWifi()
|
||||
{
|
||||
return Application.internetReachability == NetworkReachability.ReachableViaLocalAreaNetwork;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否是移动网络
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool IsViaCarrierData()
|
||||
{
|
||||
//当用户使用移动网络时
|
||||
return Application.internetReachability == NetworkReachability.ReachableViaCarrierDataNetwork;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: debb4ec407ad464e9aa0cbee452683e1
|
||||
timeCreated: 1666448562
|
||||
@ -1,12 +0,0 @@
|
||||
namespace AlicizaX
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static class ObjectHelper
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void Swap<T>(ref T t1, ref T t2)
|
||||
{
|
||||
(t1, t2) = (t2, t1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41b9276a283a4b6a9afcdde1b884ff70
|
||||
timeCreated: 1667393013
|
||||
@ -1,112 +0,0 @@
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX
|
||||
{
|
||||
public static class PathHelper
|
||||
{
|
||||
/// <summary>
|
||||
///应用程序外部资源路径存放路径(热更新资源路径)
|
||||
/// </summary>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static string AppHotfixResPath
|
||||
{
|
||||
get
|
||||
{
|
||||
string game = Application.productName;
|
||||
string path = $"{Application.persistentDataPath}/{game}/";
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 应用程序内部资源路径存放路径
|
||||
/// </summary>
|
||||
public static string AppResPath
|
||||
{
|
||||
get { return NormalizePath(Application.streamingAssetsPath); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 应用程序内部资源路径存放路径(www/webrequest专用)
|
||||
/// </summary>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static string AppResPath4Web
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_IOS || UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN || UNITY_EDITOR
|
||||
return $"file://{Application.streamingAssetsPath}";
|
||||
#else
|
||||
return NormalizePath(Application.streamingAssetsPath);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取平台名称
|
||||
/// </summary>
|
||||
public static string GetPlatformName
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_ANDROID
|
||||
return $"Android";
|
||||
#elif UNITY_STANDALONE_OSX
|
||||
return $"MacOs";
|
||||
#elif UNITY_IOS || UNITY_IPHONE
|
||||
return $"iOS";
|
||||
#elif UNITY_WEBGL
|
||||
return $"WebGL";
|
||||
#elif UNITY_STANDALONE_WIN
|
||||
return $"Windows";
|
||||
#else
|
||||
return string.Empty;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 规范化路径
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
public static string NormalizePath(string path)
|
||||
{
|
||||
return path.Replace('\\', '/').Replace("\\", "/");
|
||||
}
|
||||
|
||||
static readonly StringBuilder CombineStringBuilder = new StringBuilder();
|
||||
|
||||
/// <summary>
|
||||
/// 拼接路径
|
||||
/// </summary>
|
||||
/// <param name="paths"></param>
|
||||
/// <returns></returns>
|
||||
public static string Combine(params string[] paths)
|
||||
{
|
||||
CombineStringBuilder.Clear();
|
||||
const string separatorA = "/";
|
||||
const string separatorB = "\\";
|
||||
for (var index = 0; index < paths.Length - 1; index++)
|
||||
{
|
||||
var path = paths[index];
|
||||
CombineStringBuilder.Append(path);
|
||||
if (path.EndsWithFast(separatorA) || path.EndsWithFast(separatorB))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (path.StartsWithFast(separatorA) || path.StartsWithFast(separatorB))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CombineStringBuilder.Append(separatorA);
|
||||
}
|
||||
|
||||
CombineStringBuilder.Append(paths[paths.Length - 1]);
|
||||
return CombineStringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: abf5957e17cb46339da8f67cd4074ffd
|
||||
timeCreated: 1671505311
|
||||
@ -1,63 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace AlicizaX
|
||||
{
|
||||
/// <summary>
|
||||
/// 随机数帮助类
|
||||
/// </summary>
|
||||
public static class RandomHelper
|
||||
{
|
||||
private static Random _random = new Random((int) DateTime.UtcNow.Ticks);
|
||||
|
||||
/// <summary>
|
||||
/// 设置随机种子
|
||||
/// </summary>
|
||||
/// <param name="seed"></param>
|
||||
public static void SetSeed(int seed)
|
||||
{
|
||||
_random = new Random(seed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取UInt64范围内的随机数
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static ulong NextUInt64()
|
||||
{
|
||||
var bytes = new byte[8];
|
||||
_random.NextBytes(bytes);
|
||||
return BitConverter.ToUInt64(bytes, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取Int64范围内的随机数
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static long NextInt64()
|
||||
{
|
||||
var bytes = new byte[8];
|
||||
_random.NextBytes(bytes);
|
||||
return BitConverter.ToInt64(bytes, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取lower与Upper之间的随机数
|
||||
/// </summary>
|
||||
/// <param name="lower"></param>
|
||||
/// <param name="upper"></param>
|
||||
/// <returns></returns>
|
||||
public static int Next(int lower, int upper)
|
||||
{
|
||||
return _random.Next(lower, upper);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取0与1之间的随机数
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static float Next()
|
||||
{
|
||||
return _random.Next(0, 100_000) / 100_000f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace AlicizaX
|
||||
{
|
||||
@ -30,5 +32,32 @@ namespace AlicizaX
|
||||
Plane[] planes = GeometryUtility.CalculateFrustumPlanes(camera);
|
||||
return GeometryUtility.TestPlanesAABB(planes, renderer.bounds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取相机快照
|
||||
/// </summary>
|
||||
/// <param name="main">相机</param>
|
||||
/// <param name="scale">缩放比</param>
|
||||
public static Texture2D GetCaptureScreenshot(Camera main, float scale = 0.5f)
|
||||
{
|
||||
Rect rect = new Rect(0, 0, Screen.width * scale, Screen.height * scale);
|
||||
string name = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss");
|
||||
RenderTexture renderTexture = RenderTexture.GetTemporary((int)rect.width, (int)rect.height, 0);
|
||||
renderTexture.name = SceneManager.GetActiveScene().name + "_" + renderTexture.width + "_" + renderTexture.height + "_" + name;
|
||||
main.targetTexture = renderTexture;
|
||||
main.Render();
|
||||
|
||||
RenderTexture.active = renderTexture;
|
||||
Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false)
|
||||
{
|
||||
name = renderTexture.name
|
||||
};
|
||||
screenShot.ReadPixels(rect, 0, 0);
|
||||
screenShot.Apply();
|
||||
main.targetTexture = null;
|
||||
RenderTexture.active = null;
|
||||
RenderTexture.ReleaseTemporary(renderTexture);
|
||||
return screenShot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
16
Runtime/ABase/Structs/Pair.cs
Normal file
16
Runtime/ABase/Structs/Pair.cs
Normal file
@ -0,0 +1,16 @@
|
||||
namespace AlicizaX
|
||||
{
|
||||
public struct Pair<T1, T2>
|
||||
{
|
||||
public T1 Key { get; set; }
|
||||
public T2 Value { get; set; }
|
||||
|
||||
public bool IsAssigned => Key != null && Value != null;
|
||||
|
||||
public Pair(T1 key, T2 value)
|
||||
{
|
||||
Key = key;
|
||||
Value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/ABase/Structs/Pair.cs.meta
Normal file
11
Runtime/ABase/Structs/Pair.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b0278c1fdfc27bd4c9419d984d7d0ac1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -32,7 +32,7 @@ namespace AlicizaX
|
||||
/// </summary>
|
||||
public void Generate()
|
||||
{
|
||||
Id = GameHelper.GetGuid();
|
||||
Id = Utility.IdGenerator.GetGuid();
|
||||
}
|
||||
|
||||
public static implicit operator string(UniqueID uniqueID)
|
||||
|
||||
@ -1,4 +1,10 @@
|
||||
namespace AlicizaX
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX
|
||||
{
|
||||
public static partial class Utility
|
||||
{
|
||||
@ -7,7 +13,7 @@
|
||||
/// </summary>
|
||||
public static class File
|
||||
{
|
||||
private static readonly string[] UnitList = new[] {"B", "KB", "MB", "GB", "TB", "PB"};
|
||||
private static readonly string[] UnitList = new[] { "B", "KB", "MB", "GB", "TB", "PB" };
|
||||
|
||||
/// <summary>
|
||||
/// 获取字节大小
|
||||
@ -42,6 +48,311 @@
|
||||
return length < 1024 * 1024 * 1024 ? $"{(length / 1024f / 1024f):F2} MB" : $"{(length / 1024f / 1024f / 1024f):F2} GB";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取目录下的所有文件
|
||||
/// </summary>
|
||||
/// <param name="files">文件存放路径列表对象</param>
|
||||
/// <param name="dir">目标目录</param>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void GetAllFiles(List<string> files, string dir)
|
||||
{
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string[] strings = Directory.GetFiles(dir);
|
||||
foreach (string item in strings)
|
||||
{
|
||||
files.Add(item);
|
||||
}
|
||||
|
||||
string[] subDirs = Directory.GetDirectories(dir);
|
||||
foreach (string subDir in subDirs)
|
||||
{
|
||||
GetAllFiles(files, subDir);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理目录
|
||||
/// </summary>
|
||||
/// <param name="dir">目标路径</param>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void CleanDirectory(string dir)
|
||||
{
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string subDir in Directory.GetDirectories(dir))
|
||||
{
|
||||
Directory.Delete(subDir, true);
|
||||
}
|
||||
|
||||
foreach (string subFile in Directory.GetFiles(dir))
|
||||
{
|
||||
File.Delete(subFile);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 目录复制
|
||||
/// </summary>
|
||||
/// <param name="srcDir">源路径</param>
|
||||
/// <param name="targetDir">目标路径</param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void CopyDirectory(string srcDir, string targetDir)
|
||||
{
|
||||
DirectoryInfo source = new DirectoryInfo(srcDir);
|
||||
DirectoryInfo target = new DirectoryInfo(targetDir);
|
||||
|
||||
if (target.FullName.StartsWith(source.FullName, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
throw new Exception("父目录不能拷贝到子目录!");
|
||||
}
|
||||
|
||||
if (!source.Exists)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!target.Exists)
|
||||
{
|
||||
target.Create();
|
||||
}
|
||||
|
||||
FileInfo[] files = source.GetFiles();
|
||||
|
||||
for (int i = 0; i < files.Length; i++)
|
||||
{
|
||||
File.Copy(files[i].FullName, Path.Combine(target.FullName, files[i].Name), true);
|
||||
}
|
||||
|
||||
DirectoryInfo[] dirs = source.GetDirectories();
|
||||
|
||||
for (int j = 0; j < dirs.Length; j++)
|
||||
{
|
||||
CopyDirectory(dirs[j].FullName, Path.Combine(target.FullName, dirs[j].Name));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 复制文件到目标目录
|
||||
/// </summary>
|
||||
/// <param name="sourceFileName">源路径</param>
|
||||
/// <param name="destFileName">目标路径</param>
|
||||
/// <param name="overwrite">是否覆盖</param>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void Copy(string sourceFileName, string destFileName, bool overwrite = false)
|
||||
{
|
||||
if (!System.IO.File.Exists(sourceFileName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
File.Copy(sourceFileName, destFileName, overwrite);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除文件
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void Delete(string path)
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断文件是否存在
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static bool IsExists(string path)
|
||||
{
|
||||
#if ENABLE_GAME_FRAME_X_READ_ASSETS
|
||||
if (IsAndroidReadOnlyPath(path, out var readPath))
|
||||
{
|
||||
return BlankReadAssets.BlankReadAssets.IsFileExists(readPath);
|
||||
}
|
||||
#endif
|
||||
return System.IO.File.Exists(path);
|
||||
}
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
private static bool IsAndroidReadOnlyPath(string path, out string readPath)
|
||||
{
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (Utility.Path.NormalizePath(path).Contains(Utility.Path.AppResPath))
|
||||
{
|
||||
readPath = path.Substring(Utility.Path.AppResPath.Length);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
readPath = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移动文件到目标目录
|
||||
/// </summary>
|
||||
/// <param name="sourceFileName">文件源路径</param>
|
||||
/// <param name="destFileName">目标路径</param>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void Move(string sourceFileName, string destFileName)
|
||||
{
|
||||
if (!System.IO.File.Exists(sourceFileName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Copy(sourceFileName, destFileName, true);
|
||||
Delete(sourceFileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static byte[] ReadAllBytes(string path)
|
||||
{
|
||||
#if ENABLE_GAME_FRAME_X_READ_ASSETS
|
||||
if (IsAndroidReadOnlyPath((path), out var readPath))
|
||||
{
|
||||
return BlankReadAssets.BlankReadAssets.Read(readPath);
|
||||
}
|
||||
#endif
|
||||
|
||||
return File.ReadAllBytes(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="encoding">编码</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static string ReadAllText(string path, Encoding encoding)
|
||||
{
|
||||
return File.ReadAllText(path, encoding);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static string ReadAllText(string path)
|
||||
{
|
||||
return File.ReadAllText(path, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="encoding">编码</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static string[] ReadAllLines(string path, Encoding encoding)
|
||||
{
|
||||
return File.ReadAllLines(path, encoding);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static string[] ReadAllLines(string path)
|
||||
{
|
||||
return File.ReadAllLines(path, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="buffer">写入内容</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void ReadAllLines(string path, byte[] buffer)
|
||||
{
|
||||
File.WriteAllBytes(path, buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="lines">写入的内容</param>
|
||||
/// <param name="encoding">编码</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void WriteAllLines(string path, string[] lines, Encoding encoding)
|
||||
{
|
||||
File.WriteAllLines(path, lines, encoding);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="lines">写入的内容</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void WriteAllLines(string path, string[] lines)
|
||||
{
|
||||
File.WriteAllLines(path, lines, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="content">写入的内容</param>
|
||||
/// <param name="encoding">编码</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void WriteAllText(string path, string content, Encoding encoding)
|
||||
{
|
||||
File.WriteAllText(path, content, encoding);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入指定路径的文件内容,UTF-8
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="content">写入的内容</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void WriteAllText(string path, string content)
|
||||
{
|
||||
File.WriteAllText(path, content, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入指定路径的文件内容
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="buffer">写入的内容</param>
|
||||
/// <returns></returns>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public static void WriteAllBytes(string path, byte[] buffer)
|
||||
{
|
||||
File.WriteAllBytes(path, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
108
Runtime/ABase/Utility/Utility.Gizmo.cs
Normal file
108
Runtime/ABase/Utility/Utility.Gizmo.cs
Normal file
@ -0,0 +1,108 @@
|
||||
using UnityEngine;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace AlicizaX
|
||||
{
|
||||
public static partial class Utility
|
||||
{
|
||||
/// <summary>
|
||||
/// Gizmos 绘制辅助。
|
||||
/// </summary>
|
||||
public static class Gizmo
|
||||
{
|
||||
public static void DrawArrow(Vector3 position, Vector3 direction, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20f)
|
||||
{
|
||||
Gizmos.DrawRay(position, direction);
|
||||
Vector3 right = Quaternion.LookRotation(direction) * Quaternion.Euler(0, 180 + arrowHeadAngle, 0) * new Vector3(0, 0, 1);
|
||||
Vector3 left = Quaternion.LookRotation(direction) * Quaternion.Euler(0, 180 - arrowHeadAngle, 0) * new Vector3(0, 0, 1);
|
||||
Gizmos.DrawRay(position + direction, right * arrowHeadLength);
|
||||
Gizmos.DrawRay(position + direction, left * arrowHeadLength);
|
||||
}
|
||||
|
||||
public static void DrawWireCapsule(Vector3 p1, Vector3 p2, float radius)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (p1 == p2)
|
||||
{
|
||||
Gizmos.DrawWireSphere(p1, radius);
|
||||
return;
|
||||
}
|
||||
|
||||
using (new Handles.DrawingScope(Gizmos.color, Gizmos.matrix))
|
||||
{
|
||||
Quaternion p1Rotation = Quaternion.LookRotation(p1 - p2);
|
||||
Quaternion p2Rotation = Quaternion.LookRotation(p2 - p1);
|
||||
float c = Vector3.Dot((p1 - p2).normalized, Vector3.up);
|
||||
if (c == 1f || c == -1f)
|
||||
{
|
||||
p2Rotation = Quaternion.Euler(p2Rotation.eulerAngles.x, p2Rotation.eulerAngles.y + 180f, p2Rotation.eulerAngles.z);
|
||||
}
|
||||
|
||||
Handles.DrawWireArc(p1, p1Rotation * Vector3.left, p1Rotation * Vector3.down, 180f, radius);
|
||||
Handles.DrawWireArc(p1, p1Rotation * Vector3.up, p1Rotation * Vector3.left, 180f, radius);
|
||||
Handles.DrawWireDisc(p1, (p2 - p1).normalized, radius);
|
||||
Handles.DrawWireArc(p2, p2Rotation * Vector3.left, p2Rotation * Vector3.down, 180f, radius);
|
||||
Handles.DrawWireArc(p2, p2Rotation * Vector3.up, p2Rotation * Vector3.left, 180f, radius);
|
||||
Handles.DrawWireDisc(p2, (p1 - p2).normalized, radius);
|
||||
Handles.DrawLine(p1 + p1Rotation * Vector3.down * radius, p2 + p2Rotation * Vector3.down * radius);
|
||||
Handles.DrawLine(p1 + p1Rotation * Vector3.left * radius, p2 + p2Rotation * Vector3.right * radius);
|
||||
Handles.DrawLine(p1 + p1Rotation * Vector3.up * radius, p2 + p2Rotation * Vector3.up * radius);
|
||||
Handles.DrawLine(p1 + p1Rotation * Vector3.right * radius, p2 + p2Rotation * Vector3.left * radius);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void DrawWireCapsule(Vector3 position, Quaternion rotation, float radius, float height)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
Matrix4x4 angleMatrix = Matrix4x4.TRS(position, rotation, Handles.matrix.lossyScale);
|
||||
using (new Handles.DrawingScope(angleMatrix))
|
||||
{
|
||||
float pointOffset = (height - (radius * 2)) / 2;
|
||||
Handles.DrawWireArc(Vector3.up * pointOffset, Vector3.left, Vector3.back, -180, radius);
|
||||
Handles.DrawLine(new Vector3(0, pointOffset, -radius), new Vector3(0, -pointOffset, -radius));
|
||||
Handles.DrawLine(new Vector3(0, pointOffset, radius), new Vector3(0, -pointOffset, radius));
|
||||
Handles.DrawWireArc(Vector3.down * pointOffset, Vector3.left, Vector3.back, 180, radius);
|
||||
Handles.DrawWireArc(Vector3.up * pointOffset, Vector3.back, Vector3.left, 180, radius);
|
||||
Handles.DrawLine(new Vector3(-radius, pointOffset, 0), new Vector3(-radius, -pointOffset, 0));
|
||||
Handles.DrawLine(new Vector3(radius, pointOffset, 0), new Vector3(radius, -pointOffset, 0));
|
||||
Handles.DrawWireArc(Vector3.down * pointOffset, Vector3.back, Vector3.left, -180, radius);
|
||||
Handles.DrawWireDisc(Vector3.up * pointOffset, Vector3.up, radius);
|
||||
Handles.DrawWireDisc(Vector3.down * pointOffset, Vector3.up, radius);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void DrawCenteredLabel(Vector3 position, string labelText, GUIStyle style = null)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (style == null)
|
||||
{
|
||||
style = new GUIStyle(GUI.skin.label);
|
||||
}
|
||||
|
||||
GUIContent content = new GUIContent(labelText);
|
||||
Vector2 labelSize = style.CalcSize(content);
|
||||
Vector3 screenPosition = HandleUtility.WorldToGUIPoint(position);
|
||||
screenPosition.x -= labelSize.x / 2;
|
||||
screenPosition.y -= labelSize.y / 2;
|
||||
Vector3 worldPosition = HandleUtility.GUIPointToWorldRay(screenPosition).origin;
|
||||
Handles.Label(worldPosition, labelText, style);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void DrawDisc(Vector3 position, float radius, Color outerColor, Color innerColor)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
Handles.color = innerColor;
|
||||
Handles.DrawSolidDisc(position, Vector3.up, radius);
|
||||
Handles.color = outerColor;
|
||||
Handles.DrawWireDisc(position, Vector3.up, radius);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/ABase/Utility/Utility.Gizmo.cs.meta
Normal file
11
Runtime/ABase/Utility/Utility.Gizmo.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1795d7c750b9aaa4abd939fa483d3a66
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -31,6 +31,14 @@ namespace AlicizaX
|
||||
{
|
||||
return Interlocked.Increment(ref _intCounter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成新的 Guid 字符串。
|
||||
/// </summary>
|
||||
public static string GetGuid()
|
||||
{
|
||||
return Guid.NewGuid().ToString("N");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
302
Runtime/ABase/Utility/Utility.Math.cs
Normal file
302
Runtime/ABase/Utility/Utility.Math.cs
Normal file
@ -0,0 +1,302 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX
|
||||
{
|
||||
public static partial class Utility
|
||||
{
|
||||
/// <summary>
|
||||
/// 数学和插值相关工具。
|
||||
/// </summary>
|
||||
public static class Math
|
||||
{
|
||||
public static bool IsApproximate(float valueA, float valueB, float tolerance)
|
||||
{
|
||||
return Mathf.Abs(valueA - valueB) < tolerance;
|
||||
}
|
||||
|
||||
public static float PingPong(float min, float max, float speed = 1f)
|
||||
{
|
||||
return Mathf.PingPong(Time.time * speed, max - min) + min;
|
||||
}
|
||||
|
||||
public static int Wrap(int value, int min, int max)
|
||||
{
|
||||
int newValue = value % max;
|
||||
if (newValue < min)
|
||||
{
|
||||
newValue = max - 1;
|
||||
}
|
||||
|
||||
return newValue;
|
||||
}
|
||||
|
||||
public static float InverseLerp3(float min, float mid, float max, float t)
|
||||
{
|
||||
if (t <= min)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
if (t >= max)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
return t <= mid ? Mathf.InverseLerp(min, mid, t) : 1f - Mathf.InverseLerp(mid, max, t);
|
||||
}
|
||||
|
||||
public static float Remap(float minA, float maxA, float minB, float maxB, float t)
|
||||
{
|
||||
return minB + (t - minA) * (maxB - minB) / (maxA - minA);
|
||||
}
|
||||
|
||||
public static float EaseOut(float start, float end, float t)
|
||||
{
|
||||
t = Mathf.Clamp01(t);
|
||||
t = Mathf.Sin(t * Mathf.PI * 0.5f);
|
||||
return Mathf.Lerp(start, end, t);
|
||||
}
|
||||
|
||||
public static float EaseIn(float start, float end, float t)
|
||||
{
|
||||
t = Mathf.Clamp01(t);
|
||||
t = 1f - Mathf.Cos(t * Mathf.PI * 0.5f);
|
||||
return Mathf.Lerp(start, end, t);
|
||||
}
|
||||
|
||||
public static float SmootherStep(float start, float end, float t)
|
||||
{
|
||||
t = Mathf.Clamp01(t);
|
||||
t = t * t * t * (t * (6f * t - 15f) + 10f);
|
||||
return Mathf.Lerp(start, end, t);
|
||||
}
|
||||
|
||||
public static float InverseLerp(Vector3 a, Vector3 b, Vector3 value)
|
||||
{
|
||||
if (a != b)
|
||||
{
|
||||
Vector3 ab = b - a;
|
||||
Vector3 av = value - a;
|
||||
float t = Vector3.Dot(av, ab) / Vector3.Dot(ab, ab);
|
||||
return Mathf.Clamp01(t);
|
||||
}
|
||||
|
||||
return 0f;
|
||||
}
|
||||
|
||||
public static Vector3 QuadraticBezier(Vector3 p1, Vector3 p2, Vector3 cp, float t)
|
||||
{
|
||||
t = Mathf.Clamp01(t);
|
||||
Vector3 m1 = Vector3.LerpUnclamped(p1, cp, t);
|
||||
Vector3 m2 = Vector3.LerpUnclamped(cp, p2, t);
|
||||
return Vector3.LerpUnclamped(m1, m2, t);
|
||||
}
|
||||
|
||||
public static Vector3 BezierCurve(float t, params Vector3[] points)
|
||||
{
|
||||
if (points.Length < 1)
|
||||
{
|
||||
return Vector3.zero;
|
||||
}
|
||||
|
||||
if (points.Length == 1)
|
||||
{
|
||||
return points[0];
|
||||
}
|
||||
|
||||
t = Mathf.Clamp01(t);
|
||||
Vector3[] cp = points;
|
||||
int n = points.Length - 1;
|
||||
while (n > 1)
|
||||
{
|
||||
Vector3[] rp = new Vector3[n];
|
||||
for (int i = 0; i < rp.Length; i++)
|
||||
{
|
||||
rp[i] = Vector3.LerpUnclamped(cp[i], cp[i + 1], t);
|
||||
}
|
||||
|
||||
cp = rp;
|
||||
n--;
|
||||
}
|
||||
|
||||
return Vector3.LerpUnclamped(cp[0], cp[1], t);
|
||||
}
|
||||
|
||||
public static Vector3 Lerp3(Vector3 a, Vector3 b, Vector3 c, float t)
|
||||
{
|
||||
t = Mathf.Clamp01(t);
|
||||
if (t <= 0.5f)
|
||||
{
|
||||
return Vector3.LerpUnclamped(a, b, t * 2f);
|
||||
}
|
||||
|
||||
return Vector3.LerpUnclamped(b, c, (t * 2f) - 1f);
|
||||
}
|
||||
|
||||
public static Vector3 RangeLerp(float t, params Vector3[] points)
|
||||
{
|
||||
if (points.Length < 1)
|
||||
{
|
||||
return Vector3.zero;
|
||||
}
|
||||
|
||||
if (points.Length == 1)
|
||||
{
|
||||
return points[0];
|
||||
}
|
||||
|
||||
t = Mathf.Clamp01(t);
|
||||
int pointsCount = points.Length - 1;
|
||||
float scale = 1f / pointsCount;
|
||||
float remap = Remap(0f, 1f, 0f, pointsCount, t);
|
||||
int index = Mathf.Clamp(Mathf.FloorToInt(remap), 0, pointsCount - 1);
|
||||
float indexT = Mathf.InverseLerp(index * scale, (index + 1) * scale, t);
|
||||
return Vector3.LerpUnclamped(points[index], points[index + 1], indexT);
|
||||
}
|
||||
|
||||
public static Vector3 Lerp(float t, Vector3[] points)
|
||||
{
|
||||
if (points.Length > 3)
|
||||
{
|
||||
return RangeLerp(t, points);
|
||||
}
|
||||
|
||||
if (points.Length == 3)
|
||||
{
|
||||
return Lerp3(points[0], points[1], points[2], t);
|
||||
}
|
||||
|
||||
if (points.Length == 2)
|
||||
{
|
||||
return Vector3.Lerp(points[0], points[1], t);
|
||||
}
|
||||
|
||||
if (points.Length == 1)
|
||||
{
|
||||
return points[0];
|
||||
}
|
||||
|
||||
return Vector3.zero;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查两个矩形是否相交
|
||||
/// </summary>
|
||||
/// <param name="src"></param>
|
||||
/// <param name="target"></param>
|
||||
/// <returns></returns>
|
||||
public static bool CheckIntersect(RectInt src, RectInt target)
|
||||
{
|
||||
int minX = System.Math.Max(src.x, target.x);
|
||||
int minY = System.Math.Max(src.y, target.y);
|
||||
int maxX = System.Math.Min(src.x + src.width, target.x + target.width);
|
||||
int maxY = System.Math.Min(src.y + src.height, target.y + target.height);
|
||||
if (minX >= maxX || minY >= maxY)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查两个矩形是否相交
|
||||
/// </summary>
|
||||
/// <param name="x1"></param>
|
||||
/// <param name="y1"></param>
|
||||
/// <param name="w1"></param>
|
||||
/// <param name="h1"></param>
|
||||
/// <param name="x2"></param>
|
||||
/// <param name="y2"></param>
|
||||
/// <param name="w2"></param>
|
||||
/// <param name="h2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool CheckIntersect(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)
|
||||
{
|
||||
int minX = System.Math.Max(x1, x2);
|
||||
int minY = System.Math.Max(y1, y2);
|
||||
int maxX = System.Math.Min(x1 + w1, x2 + w2);
|
||||
int maxY = System.Math.Min(y1 + h1, y2 + h2);
|
||||
if (minX >= maxX || minY >= maxY)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查两个矩形是否相交,并返回相交的区域
|
||||
/// </summary>
|
||||
/// <param name="x1"></param>
|
||||
/// <param name="y1"></param>
|
||||
/// <param name="w1"></param>
|
||||
/// <param name="h1"></param>
|
||||
/// <param name="x2"></param>
|
||||
/// <param name="y2"></param>
|
||||
/// <param name="w2"></param>
|
||||
/// <param name="h2"></param>
|
||||
/// <param name="rect"></param>
|
||||
/// <returns></returns>
|
||||
private static bool CheckIntersect(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2, out RectInt rect)
|
||||
{
|
||||
rect = default;
|
||||
int minX = System.Math.Max(x1, x2);
|
||||
int minY = System.Math.Max(y1, y2);
|
||||
int maxX = System.Math.Min(x1 + w1, x2 + w2);
|
||||
int maxY = System.Math.Min(y1 + h1, y2 + h2);
|
||||
if (minX >= maxX || minY >= maxY)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
rect.x = minX;
|
||||
rect.y = minY;
|
||||
rect.width = System.Math.Abs(maxX - minX);
|
||||
rect.height = System.Math.Abs(maxY - minY);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查两个矩形相交的点
|
||||
/// </summary>
|
||||
/// <param name="x1">A 坐标X</param>
|
||||
/// <param name="y1">A 坐标Y</param>
|
||||
/// <param name="w1">A 宽度</param>
|
||||
/// <param name="h1">A 高度</param>
|
||||
/// <param name="x2">B 坐标X</param>
|
||||
/// <param name="y2">B 坐标Y</param>
|
||||
/// <param name="w2">B 宽度</param>
|
||||
/// <param name="h2">B 高度</param>
|
||||
/// <param name="intersectPoints">交叉点列表</param>
|
||||
/// <returns>返回是否相交</returns>
|
||||
public static bool CheckIntersectPoints(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2, int[] intersectPoints)
|
||||
{
|
||||
Vector2Int dPt = new Vector2Int();
|
||||
|
||||
if (false == CheckIntersect(x1, y1, w1, h1, x2, y2, w2, h2, out var rectInt))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < w1; i++)
|
||||
{
|
||||
for (var n = 0; n < h1; n++)
|
||||
{
|
||||
if (intersectPoints[i * h1 + n] == 1)
|
||||
{
|
||||
dPt.x = x1 + i;
|
||||
dPt.y = y1 + n;
|
||||
if (rectInt.Contains(dPt))
|
||||
{
|
||||
intersectPoints[i * h1 + n] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/ABase/Utility/Utility.Math.cs.meta
Normal file
11
Runtime/ABase/Utility/Utility.Math.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb2b3056e5c86d94697f60d958e1012e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX
|
||||
{
|
||||
@ -13,6 +14,45 @@ namespace AlicizaX
|
||||
/// </summary>
|
||||
public static class Net
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取本地 IP 列表。
|
||||
/// </summary>
|
||||
public static string[] GetAddressIPs()
|
||||
{
|
||||
var list = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
|
||||
string[] addressIPs = new string[list.Length];
|
||||
for (int index = 0; index < list.Length; index++)
|
||||
{
|
||||
IPAddress address = list[index];
|
||||
addressIPs[index] = address.ToString();
|
||||
}
|
||||
|
||||
return addressIPs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否有网络连接。
|
||||
/// </summary>
|
||||
public static bool IsReachable()
|
||||
{
|
||||
return Application.internetReachability != NetworkReachability.NotReachable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为局域网或 WiFi 网络。
|
||||
/// </summary>
|
||||
public static bool IsWifi()
|
||||
{
|
||||
return Application.internetReachability == NetworkReachability.ReachableViaLocalAreaNetwork;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为移动网络。
|
||||
/// </summary>
|
||||
public static bool IsViaCarrierData()
|
||||
{
|
||||
return Application.internetReachability == NetworkReachability.ReachableViaCarrierDataNetwork;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取第一个可用的端口号
|
||||
/// </summary>
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
namespace AlicizaX
|
||||
{
|
||||
public static partial class Utility
|
||||
{
|
||||
/// <summary>
|
||||
/// Object 对象工具类
|
||||
/// </summary>
|
||||
public static class Object
|
||||
{
|
||||
/// <summary>
|
||||
/// 交换对象
|
||||
/// </summary>
|
||||
/// <param name="t1"></param>
|
||||
/// <param name="t2"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void Swap<T>(ref T t1, ref T t2)
|
||||
{
|
||||
(t1, t2) = (t2, t1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0264830b4fe54557b5b0f6a6123ffbb1
|
||||
timeCreated: 1666234520
|
||||
@ -1,5 +1,8 @@
|
||||
using System.IO;
|
||||
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX
|
||||
{
|
||||
public static partial class Utility
|
||||
@ -9,6 +12,62 @@ namespace AlicizaX
|
||||
/// </summary>
|
||||
public static class Path
|
||||
{
|
||||
private static readonly StringBuilder CombineStringBuilder = new StringBuilder();
|
||||
|
||||
/// <summary>
|
||||
/// 应用程序外部资源路径存放路径(热更新资源路径)。
|
||||
/// </summary>
|
||||
public static string AppHotfixResPath
|
||||
{
|
||||
get
|
||||
{
|
||||
string game = Application.productName;
|
||||
return $"{Application.persistentDataPath}/{game}/";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 应用程序内部资源路径存放路径。
|
||||
/// </summary>
|
||||
public static string AppResPath => GetRegularPath(Application.streamingAssetsPath);
|
||||
|
||||
/// <summary>
|
||||
/// 应用程序内部资源路径存放路径(www/webrequest专用)。
|
||||
/// </summary>
|
||||
public static string AppResPath4Web
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_IOS || UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN || UNITY_EDITOR
|
||||
return $"file://{Application.streamingAssetsPath}";
|
||||
#else
|
||||
return GetRegularPath(Application.streamingAssetsPath);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取平台名称。
|
||||
/// </summary>
|
||||
public static string PlatformName
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_ANDROID
|
||||
return "Android";
|
||||
#elif UNITY_STANDALONE_OSX
|
||||
return "MacOs";
|
||||
#elif UNITY_IOS || UNITY_IPHONE
|
||||
return "iOS";
|
||||
#elif UNITY_WEBGL
|
||||
return "WebGL";
|
||||
#elif UNITY_STANDALONE_WIN
|
||||
return "Windows";
|
||||
#else
|
||||
return string.Empty;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取规范的路径。
|
||||
/// </summary>
|
||||
@ -24,6 +83,16 @@ namespace AlicizaX
|
||||
return path.Replace('\\', '/');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取规范的路径。
|
||||
/// </summary>
|
||||
/// <param name="path">要规范的路径。</param>
|
||||
/// <returns>规范的路径。</returns>
|
||||
public static string NormalizePath(string path)
|
||||
{
|
||||
return GetRegularPath(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取远程格式的路径(带有file:// 或 http:// 前缀)。
|
||||
/// </summary>
|
||||
@ -40,6 +109,37 @@ namespace AlicizaX
|
||||
return regularPath.Contains("://") ? regularPath : ("file:///" + regularPath).Replace("file:////", "file:///");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 拼接路径。
|
||||
/// </summary>
|
||||
public static string Combine(params string[] paths)
|
||||
{
|
||||
if (paths == null || paths.Length == 0)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
CombineStringBuilder.Clear();
|
||||
for (int index = 0; index < paths.Length - 1; index++)
|
||||
{
|
||||
string path = paths[index];
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CombineStringBuilder.Append(path);
|
||||
char lastChar = path[path.Length - 1];
|
||||
if (lastChar != '/' && lastChar != '\\')
|
||||
{
|
||||
CombineStringBuilder.Append('/');
|
||||
}
|
||||
}
|
||||
|
||||
CombineStringBuilder.Append(paths[paths.Length - 1]);
|
||||
return CombineStringBuilder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除空文件夹。
|
||||
/// </summary>
|
||||
|
||||
111
Runtime/ABase/Utility/Utility.Platform.cs
Normal file
111
Runtime/ABase/Utility/Utility.Platform.cs
Normal file
@ -0,0 +1,111 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX
|
||||
{
|
||||
public static partial class Utility
|
||||
{
|
||||
/// <summary>
|
||||
/// 应用和平台相关的实用函数。
|
||||
/// </summary>
|
||||
public static class Platform
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否是编辑器。
|
||||
/// </summary>
|
||||
public static bool IsEditor
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否是安卓。
|
||||
/// </summary>
|
||||
public static bool IsAndroid
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_ANDROID
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否是 WebGL 平台。
|
||||
/// </summary>
|
||||
public static bool IsWebGL => Application.platform == RuntimePlatform.WebGLPlayer;
|
||||
|
||||
/// <summary>
|
||||
/// 是否是 Windows 平台。
|
||||
/// </summary>
|
||||
public static bool IsWindows => Application.platform == RuntimePlatform.WindowsPlayer;
|
||||
|
||||
/// <summary>
|
||||
/// 是否是 Linux 平台。
|
||||
/// </summary>
|
||||
public static bool IsLinux => Application.platform == RuntimePlatform.LinuxPlayer;
|
||||
|
||||
/// <summary>
|
||||
/// 是否是 Mac 平台。
|
||||
/// </summary>
|
||||
public static bool IsMacOsx => Application.platform == RuntimePlatform.OSXPlayer;
|
||||
|
||||
/// <summary>
|
||||
/// 是否是 iOS 平台。
|
||||
/// </summary>
|
||||
public static bool IsIOS
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_IOS
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 退出应用。
|
||||
/// </summary>
|
||||
public static void Quit()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.EditorApplication.isPlaying = false;
|
||||
return;
|
||||
#endif
|
||||
Application.Quit();
|
||||
}
|
||||
|
||||
#if UNITY_IOS
|
||||
[System.Runtime.InteropServices.DllImport("__Internal")]
|
||||
private static extern void open_url(string url);
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// 打开 URL。
|
||||
/// </summary>
|
||||
public static void OpenURL(string url)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
Application.OpenURL(url);
|
||||
return;
|
||||
#endif
|
||||
#if UNITY_IOS
|
||||
open_url(url);
|
||||
#else
|
||||
Application.OpenURL(url);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/ABase/Utility/Utility.Platform.cs.meta
Normal file
11
Runtime/ABase/Utility/Utility.Platform.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b2027d750c54878b78b6e304ed4ad7d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -59,6 +59,35 @@ namespace AlicizaX
|
||||
return s_Random.NextDouble();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回一个介于 0.0 和 1.0 之间的随机数。
|
||||
/// </summary>
|
||||
/// <returns>大于等于 0.0 并且小于 1.0 的单精度浮点数。</returns>
|
||||
public static float GetRandomSingle()
|
||||
{
|
||||
return (float)s_Random.NextDouble();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回一个随机的 Int64。
|
||||
/// </summary>
|
||||
public static long GetRandomInt64()
|
||||
{
|
||||
byte[] bytes = new byte[8];
|
||||
s_Random.NextBytes(bytes);
|
||||
return BitConverter.ToInt64(bytes, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回一个随机的 UInt64。
|
||||
/// </summary>
|
||||
public static ulong GetRandomUInt64()
|
||||
{
|
||||
byte[] bytes = new byte[8];
|
||||
s_Random.NextBytes(bytes);
|
||||
return BitConverter.ToUInt64(bytes, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用随机数填充指定字节数组的元素。
|
||||
/// </summary>
|
||||
@ -67,6 +96,87 @@ namespace AlicizaX
|
||||
{
|
||||
s_Random.NextBytes(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个与上次值不同的随机数。
|
||||
/// </summary>
|
||||
public static int RandomUnique(int min, int max, int last)
|
||||
{
|
||||
if (min + 1 >= max)
|
||||
{
|
||||
return min;
|
||||
}
|
||||
|
||||
int result = last;
|
||||
while (result == last)
|
||||
{
|
||||
result = UnityEngine.Random.Range(min, max);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个排除指定值集合的随机数。
|
||||
/// </summary>
|
||||
public static int RandomExclude(int min, int max, int[] excludedValues, int maxIterations = 1000)
|
||||
{
|
||||
int result;
|
||||
int iterations = 0;
|
||||
do
|
||||
{
|
||||
if (iterations > maxIterations)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = UnityEngine.Random.Range(min, max);
|
||||
iterations++;
|
||||
}
|
||||
while (Contains(excludedValues, result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个排除现有集合和已选集合的随机数。
|
||||
/// </summary>
|
||||
public static int RandomExcludeUnique(int min, int max, int[] excludedValues, int[] currentValues, int maxIterations = 1000)
|
||||
{
|
||||
int result;
|
||||
int iterations = 0;
|
||||
do
|
||||
{
|
||||
if (iterations > maxIterations)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = UnityEngine.Random.Range(min, max);
|
||||
iterations++;
|
||||
}
|
||||
while (Contains(excludedValues, result) || Contains(currentValues, result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool Contains(int[] values, int target)
|
||||
{
|
||||
if (values == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < values.Length; i++)
|
||||
{
|
||||
if (values[i] == target)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
110
Runtime/ABase/Utility/Utility.Unity.Gameplay.cs
Normal file
110
Runtime/ABase/Utility/Utility.Unity.Gameplay.cs
Normal file
@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace AlicizaX
|
||||
{
|
||||
public static partial class Utility
|
||||
{
|
||||
public static partial class Unity
|
||||
{
|
||||
public static void ShowCursor(bool locked, bool visible)
|
||||
{
|
||||
Cursor.lockState = locked ? CursorLockMode.Locked : CursorLockMode.None;
|
||||
Cursor.visible = visible;
|
||||
}
|
||||
|
||||
public static bool Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance, int cullLayers, Layer interactLayer)
|
||||
{
|
||||
if (Physics.Raycast(ray, out RaycastHit hit, maxDistance, cullLayers))
|
||||
{
|
||||
if (interactLayer.CompareLayer(hit.collider.gameObject))
|
||||
{
|
||||
hitInfo = hit;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
hitInfo = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static AudioSource PlayOneShot2D(Vector3 position, AudioClip clip, float volume = 1f, string name = "OneShotAudio")
|
||||
{
|
||||
if (clip == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
GameObject gameObject = new GameObject(name);
|
||||
gameObject.transform.position = position;
|
||||
AudioSource source = gameObject.AddComponent<AudioSource>();
|
||||
source.spatialBlend = 0f;
|
||||
source.clip = clip;
|
||||
source.volume = volume;
|
||||
source.Play();
|
||||
Object.Destroy(gameObject, clip.length * ((Time.timeScale < 0.01f) ? 0.01f : Time.timeScale));
|
||||
return source;
|
||||
}
|
||||
|
||||
public static AudioSource PlayOneShot2D(Vector3 position, SoundClip clip, string name = "OneShotAudio")
|
||||
{
|
||||
if (clip == null || clip.audioClip == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return PlayOneShot2D(position, clip.audioClip, clip.volume, name);
|
||||
}
|
||||
|
||||
public static AudioSource PlayOneShot3D(Vector3 position, AudioClip clip, float volume = 1f, string name = "OneShotAudio")
|
||||
{
|
||||
if (clip == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
GameObject gameObject = new GameObject(name);
|
||||
gameObject.transform.position = position;
|
||||
AudioSource source = gameObject.AddComponent<AudioSource>();
|
||||
source.spatialBlend = 1f;
|
||||
source.clip = clip;
|
||||
source.volume = volume;
|
||||
source.Play();
|
||||
Object.Destroy(gameObject, clip.length * ((Time.timeScale < 0.01f) ? 0.01f : Time.timeScale));
|
||||
return source;
|
||||
}
|
||||
|
||||
public static AudioSource PlayOneShot3D(Vector3 position, AudioClip clip, float maxDistance, float volume = 1f, string name = "OneShotAudio")
|
||||
{
|
||||
if (clip == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
GameObject gameObject = new GameObject(name);
|
||||
gameObject.transform.position = position;
|
||||
AudioSource source = gameObject.AddComponent<AudioSource>();
|
||||
source.spatialBlend = 1f;
|
||||
source.clip = clip;
|
||||
source.volume = volume;
|
||||
source.maxDistance = maxDistance;
|
||||
source.Play();
|
||||
Object.Destroy(gameObject, clip.length * ((Time.timeScale < 0.01f) ? 0.01f : Time.timeScale));
|
||||
return source;
|
||||
}
|
||||
|
||||
public static AudioSource PlayOneShot3D(Vector3 position, SoundClip clip, string name = "OneShotAudio")
|
||||
{
|
||||
if (clip == null || clip.audioClip == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return PlayOneShot3D(position, clip.audioClip, clip.volume, name);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/ABase/Utility/Utility.Unity.Gameplay.cs.meta
Normal file
11
Runtime/ABase/Utility/Utility.Unity.Gameplay.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b214adecc8c0fab41b3fcd306d4ebb10
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
Reference in New Issue
Block a user