From 1a9a59ab075febaa9f617db84c3f0342c8647f0c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=99=88=E6=80=9D=E6=B5=B7?= <1464576565@qq.com>
Date: Mon, 23 Mar 2026 19:10:57 +0800
Subject: [PATCH] =?UTF-8?q?=E5=B7=A5=E5=85=B7=E7=B1=BB=E9=87=8D=E6=96=B0?=
=?UTF-8?q?=E6=95=B4=E5=90=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Extension/Extension/ArrayExtensions.cs | 56 ++++++
.../Extension/ArrayExtensions.cs.meta} | 5 +-
.../Extension/CollectionExtensions.cs | 2 +-
.../Extension/EnumerableExtensions.cs} | 22 +--
.../Extension/EnumerableExtensions.cs.meta | 11 ++
.../Extension/Extension/StringExtensions.cs | 107 +++++++++-
.../ABase/Extension/UnityEngine.Common.meta | 8 +
.../UnityEngine.CommonExtensions.cs | 148 ++++++++++++++
.../UnityEngine.CommonExtensions.cs.meta | 11 ++
...bject.meta => UnityEngine.GameObject.meta} | 0
.../ComponentExtensions.cs | 0
.../ComponentExtensions.cs.meta | 0
.../GameObjectExtensions.cs} | 28 ++-
.../GameObjectExtensions.cs.meta} | 0
.../RectTransformExtensions.cs | 63 ++++++
...s.meta => RectTransformExtensions.cs.meta} | 0
...ormExtension.cs => TransformExtensions.cs} | 4 +-
...on.cs.meta => TransformExtensions.cs.meta} | 0
.../UnityEngine.UIExtension.cs | 27 ---
.../UnityEngine.Vector2Extension.cs | 26 ---
.../UnityEngine.Vector2/Vector2Extensions.cs | 55 ++++++
...sion.cs.meta => Vector2Extensions.cs.meta} | 0
.../UnityEngine.Vector3/AxisExtensions.cs | 86 ++++++++
.../AxisExtensions.cs.meta | 11 ++
...ctor3Extension.cs => Vector3Extensions.cs} | 13 +-
...sion.cs.meta => Vector3Extensions.cs.meta} | 0
Runtime/ABase/Helper/ApplicationHelper.cs | 128 ------------
.../ABase/Helper/ApplicationHelper.cs.meta | 3 -
Runtime/ABase/Helper/DistinctHelper.cs.meta | 3 -
Runtime/ABase/Helper/FileHelper.cs | 4 +-
Runtime/ABase/Helper/NetworkHelper.cs | 58 ------
Runtime/ABase/Helper/NetworkHelper.cs.meta | 3 -
Runtime/ABase/Helper/ObjectHelper.cs | 12 --
Runtime/ABase/Helper/ObjectHelper.cs.meta | 3 -
Runtime/ABase/Helper/PathHelper.cs | 112 -----------
Runtime/ABase/Helper/PathHelper.cs.meta | 3 -
Runtime/ABase/Helper/RandomHelper.cs | 63 ------
Runtime/ABase/Structs/Pair.cs | 16 ++
Runtime/ABase/Structs/Pair.cs.meta | 11 ++
Runtime/ABase/Structs/UniqueID.cs | 2 +-
Runtime/ABase/Utility/Utility.Gizmo.cs | 108 +++++++++++
Runtime/ABase/Utility/Utility.Gizmo.cs.meta | 11 ++
Runtime/ABase/Utility/Utility.IdGenerator.cs | 8 +
Runtime/ABase/Utility/Utility.Math.cs | 183 ++++++++++++++++++
Runtime/ABase/Utility/Utility.Math.cs.meta | 11 ++
Runtime/ABase/Utility/Utility.Net.cs | 40 ++++
Runtime/ABase/Utility/Utility.Object.cs | 22 ---
Runtime/ABase/Utility/Utility.Object.cs.meta | 3 -
Runtime/ABase/Utility/Utility.Path.cs | 100 ++++++++++
Runtime/ABase/Utility/Utility.Platform.cs | 111 +++++++++++
.../ABase/Utility/Utility.Platform.cs.meta | 11 ++
Runtime/ABase/Utility/Utility.Random.cs | 110 +++++++++++
.../ABase/Utility/Utility.Unity.Gameplay.cs | 106 ++++++++++
.../Utility/Utility.Unity.Gameplay.cs.meta | 11 ++
54 files changed, 1449 insertions(+), 490 deletions(-)
create mode 100644 Runtime/ABase/Extension/Extension/ArrayExtensions.cs
rename Runtime/ABase/{Helper/RandomHelper.cs.meta => Extension/Extension/ArrayExtensions.cs.meta} (69%)
rename Runtime/ABase/{Helper/DistinctHelper.cs => Extension/Extension/EnumerableExtensions.cs} (61%)
create mode 100644 Runtime/ABase/Extension/Extension/EnumerableExtensions.cs.meta
create mode 100644 Runtime/ABase/Extension/UnityEngine.Common.meta
create mode 100644 Runtime/ABase/Extension/UnityEngine.Common/UnityEngine.CommonExtensions.cs
create mode 100644 Runtime/ABase/Extension/UnityEngine.Common/UnityEngine.CommonExtensions.cs.meta
rename Runtime/ABase/Extension/{UnityEngage.GameObject.meta => UnityEngine.GameObject.meta} (100%)
rename Runtime/ABase/Extension/{UnityEngage.GameObject => UnityEngine.GameObject}/ComponentExtensions.cs (100%)
rename Runtime/ABase/Extension/{UnityEngage.GameObject => UnityEngine.GameObject}/ComponentExtensions.cs.meta (100%)
rename Runtime/ABase/Extension/{UnityEngage.GameObject/UnityEngage.GameObjectExtension.cs => UnityEngine.GameObject/GameObjectExtensions.cs} (76%)
rename Runtime/ABase/Extension/{UnityEngage.GameObject/UnityEngage.GameObjectExtension.cs.meta => UnityEngine.GameObject/GameObjectExtensions.cs.meta} (100%)
create mode 100644 Runtime/ABase/Extension/UnityEngine.Transform/RectTransformExtensions.cs
rename Runtime/ABase/Extension/UnityEngine.Transform/{UnityEngine.UIExtension.cs.meta => RectTransformExtensions.cs.meta} (100%)
rename Runtime/ABase/Extension/UnityEngine.Transform/{UnityEngine.TransformExtension.cs => TransformExtensions.cs} (99%)
rename Runtime/ABase/Extension/UnityEngine.Transform/{UnityEngine.TransformExtension.cs.meta => TransformExtensions.cs.meta} (100%)
delete mode 100644 Runtime/ABase/Extension/UnityEngine.Transform/UnityEngine.UIExtension.cs
delete mode 100644 Runtime/ABase/Extension/UnityEngine.Vector2/UnityEngine.Vector2Extension.cs
create mode 100644 Runtime/ABase/Extension/UnityEngine.Vector2/Vector2Extensions.cs
rename Runtime/ABase/Extension/UnityEngine.Vector2/{UnityEngine.Vector2Extension.cs.meta => Vector2Extensions.cs.meta} (100%)
create mode 100644 Runtime/ABase/Extension/UnityEngine.Vector3/AxisExtensions.cs
create mode 100644 Runtime/ABase/Extension/UnityEngine.Vector3/AxisExtensions.cs.meta
rename Runtime/ABase/Extension/UnityEngine.Vector3/{UnityEngine.Vector3Extension.cs => Vector3Extensions.cs} (78%)
rename Runtime/ABase/Extension/UnityEngine.Vector3/{UnityEngine.Vector3Extension.cs.meta => Vector3Extensions.cs.meta} (100%)
delete mode 100644 Runtime/ABase/Helper/ApplicationHelper.cs
delete mode 100644 Runtime/ABase/Helper/ApplicationHelper.cs.meta
delete mode 100644 Runtime/ABase/Helper/DistinctHelper.cs.meta
delete mode 100644 Runtime/ABase/Helper/NetworkHelper.cs
delete mode 100644 Runtime/ABase/Helper/NetworkHelper.cs.meta
delete mode 100644 Runtime/ABase/Helper/ObjectHelper.cs
delete mode 100644 Runtime/ABase/Helper/ObjectHelper.cs.meta
delete mode 100644 Runtime/ABase/Helper/PathHelper.cs
delete mode 100644 Runtime/ABase/Helper/PathHelper.cs.meta
delete mode 100644 Runtime/ABase/Helper/RandomHelper.cs
create mode 100644 Runtime/ABase/Structs/Pair.cs
create mode 100644 Runtime/ABase/Structs/Pair.cs.meta
create mode 100644 Runtime/ABase/Utility/Utility.Gizmo.cs
create mode 100644 Runtime/ABase/Utility/Utility.Gizmo.cs.meta
create mode 100644 Runtime/ABase/Utility/Utility.Math.cs
create mode 100644 Runtime/ABase/Utility/Utility.Math.cs.meta
delete mode 100644 Runtime/ABase/Utility/Utility.Object.cs
delete mode 100644 Runtime/ABase/Utility/Utility.Object.cs.meta
create mode 100644 Runtime/ABase/Utility/Utility.Platform.cs
create mode 100644 Runtime/ABase/Utility/Utility.Platform.cs.meta
create mode 100644 Runtime/ABase/Utility/Utility.Unity.Gameplay.cs
create mode 100644 Runtime/ABase/Utility/Utility.Unity.Gameplay.cs.meta
diff --git a/Runtime/ABase/Extension/Extension/ArrayExtensions.cs b/Runtime/ABase/Extension/Extension/ArrayExtensions.cs
new file mode 100644
index 0000000..7a02a4a
--- /dev/null
+++ b/Runtime/ABase/Extension/Extension/ArrayExtensions.cs
@@ -0,0 +1,56 @@
+using UnityEngine;
+
+[UnityEngine.Scripting.Preserve]
+public static class ArrayExtensions
+{
+ ///
+ /// 从数组中随机取一个元素。
+ ///
+ public static T Random(this T[] items)
+ {
+ System.Random rnd = new System.Random();
+ if (items.Length > 0)
+ {
+ return items[rnd.Next(0, items.Length)];
+ }
+
+ return default;
+ }
+
+ ///
+ /// 获取与目标值最接近的元素索引。
+ ///
+ 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);
+ }
+ }
+}
diff --git a/Runtime/ABase/Helper/RandomHelper.cs.meta b/Runtime/ABase/Extension/Extension/ArrayExtensions.cs.meta
similarity index 69%
rename from Runtime/ABase/Helper/RandomHelper.cs.meta
rename to Runtime/ABase/Extension/Extension/ArrayExtensions.cs.meta
index 488ca5d..3d8ee3d 100644
--- a/Runtime/ABase/Helper/RandomHelper.cs.meta
+++ b/Runtime/ABase/Extension/Extension/ArrayExtensions.cs.meta
@@ -1,8 +1,7 @@
fileFormatVersion: 2
-guid: c7bd0b921d0715a4caa7a59d261e8803
-timeCreated: 1474942922
-licenseType: Pro
+guid: ae1b3849ddfb58045a96ac9927218a73
MonoImporter:
+ externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
diff --git a/Runtime/ABase/Extension/Extension/CollectionExtensions.cs b/Runtime/ABase/Extension/Extension/CollectionExtensions.cs
index 1a48199..153c24e 100644
--- a/Runtime/ABase/Extension/Extension/CollectionExtensions.cs
+++ b/Runtime/ABase/Extension/Extension/CollectionExtensions.cs
@@ -145,4 +145,4 @@ namespace System.Collections.Generic
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Runtime/ABase/Helper/DistinctHelper.cs b/Runtime/ABase/Extension/Extension/EnumerableExtensions.cs
similarity index 61%
rename from Runtime/ABase/Helper/DistinctHelper.cs
rename to Runtime/ABase/Extension/Extension/EnumerableExtensions.cs
index 741c831..ab8b77f 100644
--- a/Runtime/ABase/Helper/DistinctHelper.cs
+++ b/Runtime/ABase/Extension/Extension/EnumerableExtensions.cs
@@ -1,27 +1,19 @@
using System;
using System.Collections.Generic;
+using System.Linq;
namespace AlicizaX
{
- ///
- /// 去重。帮助类
- ///
[UnityEngine.Scripting.Preserve]
- public static class DistinctHelper
+ public static class EnumerableExtensions
{
///
- /// 根据条件去重
+ /// 根据指定键进行去重。
///
- ///
- ///
- ///
- ///
- ///
[UnityEngine.Scripting.Preserve]
public static IEnumerable DistinctBy(this IEnumerable source, Func keySelector)
{
var identifiedKeys = new HashSet();
-
foreach (var item in source)
{
if (identifiedKeys.Add(keySelector(item)))
@@ -30,5 +22,13 @@ namespace AlicizaX
}
}
}
+
+ ///
+ /// 判断集合是否包含另一个集合中的所有元素。
+ ///
+ public static bool ContainsAll(this IEnumerable source, IEnumerable values)
+ {
+ return !source.Except(values).Any();
+ }
}
}
diff --git a/Runtime/ABase/Extension/Extension/EnumerableExtensions.cs.meta b/Runtime/ABase/Extension/Extension/EnumerableExtensions.cs.meta
new file mode 100644
index 0000000..40f725b
--- /dev/null
+++ b/Runtime/ABase/Extension/Extension/EnumerableExtensions.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c6d80b4ea1444e5ab93a9ae1dbaa6946
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Runtime/ABase/Extension/Extension/StringExtensions.cs b/Runtime/ABase/Extension/Extension/StringExtensions.cs
index 3aefd4d..468f051 100644
--- a/Runtime/ABase/Extension/Extension/StringExtensions.cs
+++ b/Runtime/ABase/Extension/Extension/StringExtensions.cs
@@ -198,6 +198,30 @@ public static class StringExtension
return string.Format(text, args);
}
+ ///
+ /// 转换为标题格式。
+ ///
+ public static string ToTitleCase(this string str)
+ {
+ return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
+ }
+
+ ///
+ /// 判断字符串是否为空。
+ ///
+ public static bool IsEmpty(this string str)
+ {
+ return string.IsNullOrEmpty(str);
+ }
+
+ ///
+ /// 返回当前字符串,若为空则返回备用值。
+ ///
+ public static string Or(this string str, string otherwise)
+ {
+ return !string.IsNullOrEmpty(str) ? str : otherwise;
+ }
+
///
/// 将[\n、\t、\r、空格]替换为空,并返回
///
@@ -226,6 +250,87 @@ public static class StringExtension
return self;
}
+ ///
+ /// 替换起止字符之间的片段。
+ ///
+ 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);
+ }
+
+ ///
+ /// 替换指定包裹标记中的内容。
+ ///
+ 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;
+ }
+
+ ///
+ /// 读取起止字符之间的内容。
+ ///
+ 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;
+ }
+
+ ///
+ /// 读取所有起止字符之间的内容。
+ ///
+ 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();
+ foreach (Match match in matches)
+ {
+ matchList.Add(match.Groups[1].Value);
+ }
+
+ results = matchList.ToArray();
+ return true;
+ }
+
+ results = Array.Empty();
+ return false;
+ }
+
+ ///
+ /// 以单词为边界替换内容。
+ ///
+ 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;
}
-}
\ No newline at end of file
+}
diff --git a/Runtime/ABase/Extension/UnityEngine.Common.meta b/Runtime/ABase/Extension/UnityEngine.Common.meta
new file mode 100644
index 0000000..406bd64
--- /dev/null
+++ b/Runtime/ABase/Extension/UnityEngine.Common.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: a4c9cbd4e6d1ba84fb42b601118e51a1
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Runtime/ABase/Extension/UnityEngine.Common/UnityEngine.CommonExtensions.cs b/Runtime/ABase/Extension/UnityEngine.Common/UnityEngine.CommonExtensions.cs
new file mode 100644
index 0000000..9e841be
--- /dev/null
+++ b/Runtime/ABase/Extension/UnityEngine.Common/UnityEngine.CommonExtensions.cs
@@ -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;
+ }
+ }
+}
diff --git a/Runtime/ABase/Extension/UnityEngine.Common/UnityEngine.CommonExtensions.cs.meta b/Runtime/ABase/Extension/UnityEngine.Common/UnityEngine.CommonExtensions.cs.meta
new file mode 100644
index 0000000..47f1c99
--- /dev/null
+++ b/Runtime/ABase/Extension/UnityEngine.Common/UnityEngine.CommonExtensions.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fdcd89fb0474b6949b197c7da1cb81fa
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Runtime/ABase/Extension/UnityEngage.GameObject.meta b/Runtime/ABase/Extension/UnityEngine.GameObject.meta
similarity index 100%
rename from Runtime/ABase/Extension/UnityEngage.GameObject.meta
rename to Runtime/ABase/Extension/UnityEngine.GameObject.meta
diff --git a/Runtime/ABase/Extension/UnityEngage.GameObject/ComponentExtensions.cs b/Runtime/ABase/Extension/UnityEngine.GameObject/ComponentExtensions.cs
similarity index 100%
rename from Runtime/ABase/Extension/UnityEngage.GameObject/ComponentExtensions.cs
rename to Runtime/ABase/Extension/UnityEngine.GameObject/ComponentExtensions.cs
diff --git a/Runtime/ABase/Extension/UnityEngage.GameObject/ComponentExtensions.cs.meta b/Runtime/ABase/Extension/UnityEngine.GameObject/ComponentExtensions.cs.meta
similarity index 100%
rename from Runtime/ABase/Extension/UnityEngage.GameObject/ComponentExtensions.cs.meta
rename to Runtime/ABase/Extension/UnityEngine.GameObject/ComponentExtensions.cs.meta
diff --git a/Runtime/ABase/Extension/UnityEngage.GameObject/UnityEngage.GameObjectExtension.cs b/Runtime/ABase/Extension/UnityEngine.GameObject/GameObjectExtensions.cs
similarity index 76%
rename from Runtime/ABase/Extension/UnityEngage.GameObject/UnityEngage.GameObjectExtension.cs
rename to Runtime/ABase/Extension/UnityEngine.GameObject/GameObjectExtensions.cs
index 1655000..597af4b 100644
--- a/Runtime/ABase/Extension/UnityEngage.GameObject/UnityEngage.GameObjectExtension.cs
+++ b/Runtime/ABase/Extension/UnityEngine.GameObject/GameObjectExtensions.cs
@@ -3,7 +3,7 @@ using System.Collections.Generic;
namespace UnityEngine
{
- public static class UnityEngageGameObjectExtension
+ public static class GameObjectExtensions
{
public static void SafeDestroySelf(
this Object obj)
@@ -81,5 +81,31 @@ namespace UnityEngine
return gameObject.scene.name != null;
}
+
+ ///
+ /// 设置对象下所有 MeshRenderer 的 rendering layer。
+ ///
+ 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())
+ {
+ if (set)
+ {
+ renderer.renderingLayerMask |= layerMask;
+ }
+ else
+ {
+ renderer.renderingLayerMask &= ~layerMask;
+ }
+ }
+ }
+
}
}
diff --git a/Runtime/ABase/Extension/UnityEngage.GameObject/UnityEngage.GameObjectExtension.cs.meta b/Runtime/ABase/Extension/UnityEngine.GameObject/GameObjectExtensions.cs.meta
similarity index 100%
rename from Runtime/ABase/Extension/UnityEngage.GameObject/UnityEngage.GameObjectExtension.cs.meta
rename to Runtime/ABase/Extension/UnityEngine.GameObject/GameObjectExtensions.cs.meta
diff --git a/Runtime/ABase/Extension/UnityEngine.Transform/RectTransformExtensions.cs b/Runtime/ABase/Extension/UnityEngine.Transform/RectTransformExtensions.cs
new file mode 100644
index 0000000..05d1440
--- /dev/null
+++ b/Runtime/ABase/Extension/UnityEngine.Transform/RectTransformExtensions.cs
@@ -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 GetChildTransforms(this RectTransform rectTransform)
+ {
+ foreach (var item in rectTransform)
+ {
+ yield return item as RectTransform;
+ }
+ }
+ }
+}
diff --git a/Runtime/ABase/Extension/UnityEngine.Transform/UnityEngine.UIExtension.cs.meta b/Runtime/ABase/Extension/UnityEngine.Transform/RectTransformExtensions.cs.meta
similarity index 100%
rename from Runtime/ABase/Extension/UnityEngine.Transform/UnityEngine.UIExtension.cs.meta
rename to Runtime/ABase/Extension/UnityEngine.Transform/RectTransformExtensions.cs.meta
diff --git a/Runtime/ABase/Extension/UnityEngine.Transform/UnityEngine.TransformExtension.cs b/Runtime/ABase/Extension/UnityEngine.Transform/TransformExtensions.cs
similarity index 99%
rename from Runtime/ABase/Extension/UnityEngine.Transform/UnityEngine.TransformExtension.cs
rename to Runtime/ABase/Extension/UnityEngine.Transform/TransformExtensions.cs
index 34aea17..882cea7 100644
--- a/Runtime/ABase/Extension/UnityEngine.Transform/UnityEngine.TransformExtension.cs
+++ b/Runtime/ABase/Extension/UnityEngine.Transform/TransformExtensions.cs
@@ -3,7 +3,7 @@ using UnityEngine;
namespace UnityEngine
{
[UnityEngine.Scripting.Preserve]
- public static class UnityEngineTransformExtension
+ public static class TransformExtensions
{
///
/// 查找子节点的名称符合的 。
@@ -271,4 +271,4 @@ namespace UnityEngine
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Runtime/ABase/Extension/UnityEngine.Transform/UnityEngine.TransformExtension.cs.meta b/Runtime/ABase/Extension/UnityEngine.Transform/TransformExtensions.cs.meta
similarity index 100%
rename from Runtime/ABase/Extension/UnityEngine.Transform/UnityEngine.TransformExtension.cs.meta
rename to Runtime/ABase/Extension/UnityEngine.Transform/TransformExtensions.cs.meta
diff --git a/Runtime/ABase/Extension/UnityEngine.Transform/UnityEngine.UIExtension.cs b/Runtime/ABase/Extension/UnityEngine.Transform/UnityEngine.UIExtension.cs
deleted file mode 100644
index 19b12e1..0000000
--- a/Runtime/ABase/Extension/UnityEngine.Transform/UnityEngine.UIExtension.cs
+++ /dev/null
@@ -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;
- }
- }
-}
diff --git a/Runtime/ABase/Extension/UnityEngine.Vector2/UnityEngine.Vector2Extension.cs b/Runtime/ABase/Extension/UnityEngine.Vector2/UnityEngine.Vector2Extension.cs
deleted file mode 100644
index 4d7548a..0000000
--- a/Runtime/ABase/Extension/UnityEngine.Vector2/UnityEngine.Vector2Extension.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-namespace UnityEngine
-{
- public static class UnityEngineVector2Extension
- {
- ///
- /// 取 的 (x, y) 转换为 的 (x, 0, y)。
- ///
- /// 要转换的 Vector2。
- /// 转换后的 Vector3。
- public static Vector3 ToVector3(this Vector2 vector2)
- {
- return new Vector3(vector2.x, 0f, vector2.y);
- }
-
- ///
- /// 取 的 (x, y) 和给定参数 y 转换为 的 (x, 参数 y, y)。
- ///
- /// 要转换的 Vector2。
- /// Vector3 的 y 值。
- /// 转换后的 Vector3。
- public static Vector3 ToVector3(this Vector2 vector2, float y)
- {
- return new Vector3(vector2.x, y, vector2.y);
- }
- }
-}
\ No newline at end of file
diff --git a/Runtime/ABase/Extension/UnityEngine.Vector2/Vector2Extensions.cs b/Runtime/ABase/Extension/UnityEngine.Vector2/Vector2Extensions.cs
new file mode 100644
index 0000000..9f8da2c
--- /dev/null
+++ b/Runtime/ABase/Extension/UnityEngine.Vector2/Vector2Extensions.cs
@@ -0,0 +1,55 @@
+namespace UnityEngine
+{
+ public static class Vector2Extensions
+ {
+ ///
+ /// 取 的 (x, y) 转换为 的 (x, 0, y)。
+ ///
+ /// 要转换的 Vector2。
+ /// 转换后的 Vector3。
+ public static Vector3 ToVector3(this Vector2 vector2)
+ {
+ return new Vector3(vector2.x, 0f, vector2.y);
+ }
+
+ ///
+ /// 取 的 (x, y) 和给定参数 y 转换为 的 (x, 参数 y, y)。
+ ///
+ /// 要转换的 Vector2。
+ /// Vector3 的 y 值。
+ /// 转换后的 Vector3。
+ public static Vector3 ToVector3(this Vector2 vector2, float y)
+ {
+ return new Vector3(vector2.x, y, vector2.y);
+ }
+
+ ///
+ /// 判断值是否在向量区间内。
+ ///
+ 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;
+ }
+
+ ///
+ /// 判断角度是否在向量表示的角度区间内。
+ ///
+ 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;
+ }
+
+ ///
+ /// 从区间内取随机值。
+ ///
+ public static float Random(this Vector2 vector)
+ {
+ return UnityEngine.Random.Range(vector.x, vector.y);
+ }
+ }
+}
diff --git a/Runtime/ABase/Extension/UnityEngine.Vector2/UnityEngine.Vector2Extension.cs.meta b/Runtime/ABase/Extension/UnityEngine.Vector2/Vector2Extensions.cs.meta
similarity index 100%
rename from Runtime/ABase/Extension/UnityEngine.Vector2/UnityEngine.Vector2Extension.cs.meta
rename to Runtime/ABase/Extension/UnityEngine.Vector2/Vector2Extensions.cs.meta
diff --git a/Runtime/ABase/Extension/UnityEngine.Vector3/AxisExtensions.cs b/Runtime/ABase/Extension/UnityEngine.Vector3/AxisExtensions.cs
new file mode 100644
index 0000000..3d1f05e
--- /dev/null
+++ b/Runtime/ABase/Extension/UnityEngine.Vector3/AxisExtensions.cs
@@ -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;
+ }
+ }
+}
diff --git a/Runtime/ABase/Extension/UnityEngine.Vector3/AxisExtensions.cs.meta b/Runtime/ABase/Extension/UnityEngine.Vector3/AxisExtensions.cs.meta
new file mode 100644
index 0000000..93aec24
--- /dev/null
+++ b/Runtime/ABase/Extension/UnityEngine.Vector3/AxisExtensions.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b282fd247f4930142a14784638083a56
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Runtime/ABase/Extension/UnityEngine.Vector3/UnityEngine.Vector3Extension.cs b/Runtime/ABase/Extension/UnityEngine.Vector3/Vector3Extensions.cs
similarity index 78%
rename from Runtime/ABase/Extension/UnityEngine.Vector3/UnityEngine.Vector3Extension.cs
rename to Runtime/ABase/Extension/UnityEngine.Vector3/Vector3Extensions.cs
index d58d65f..02cebc0 100644
--- a/Runtime/ABase/Extension/UnityEngine.Vector3/UnityEngine.Vector3Extension.cs
+++ b/Runtime/ABase/Extension/UnityEngine.Vector3/Vector3Extensions.cs
@@ -3,7 +3,7 @@
///
/// 对 Unity 的扩展方法。
///
- public static class UnityEngineVector3Extension
+ public static class Vector3Extensions
{
///
/// 取 的 (x, y, z) 转换为 的 (x, z)。
@@ -25,5 +25,14 @@
{
return new Vector3(vector3.x, vector3.y, vector3.z);
}
+
+ ///
+ /// 按分量相乘。
+ ///
+ public static Vector3 Multiply(this Vector3 lhs, Vector3 rhs)
+ {
+ lhs.Scale(rhs);
+ return lhs;
+ }
}
-}
\ No newline at end of file
+}
diff --git a/Runtime/ABase/Extension/UnityEngine.Vector3/UnityEngine.Vector3Extension.cs.meta b/Runtime/ABase/Extension/UnityEngine.Vector3/Vector3Extensions.cs.meta
similarity index 100%
rename from Runtime/ABase/Extension/UnityEngine.Vector3/UnityEngine.Vector3Extension.cs.meta
rename to Runtime/ABase/Extension/UnityEngine.Vector3/Vector3Extensions.cs.meta
diff --git a/Runtime/ABase/Helper/ApplicationHelper.cs b/Runtime/ABase/Helper/ApplicationHelper.cs
deleted file mode 100644
index 76612fc..0000000
--- a/Runtime/ABase/Helper/ApplicationHelper.cs
+++ /dev/null
@@ -1,128 +0,0 @@
-using UnityEngine;
-
-namespace AlicizaX
-{
- ///
- /// 应用帮助类
- ///
- [UnityEngine.Scripting.Preserve]
- public static class ApplicationHelper
- {
- ///
- /// 是否是编辑器
- ///
- [UnityEngine.Scripting.Preserve]
- public static bool IsEditor
- {
- get
- {
-#if UNITY_EDITOR
- return true;
-#else
- return false;
-#endif
- }
- }
-
- ///
- /// 是否是安卓
- ///
- [UnityEngine.Scripting.Preserve]
- public static bool IsAndroid
- {
- get
- {
-#if UNITY_ANDROID
- return true;
-#else
- return false;
-#endif
- }
- }
-
- ///
- /// 是否是WebGL平台
- ///
- [UnityEngine.Scripting.Preserve]
- public static bool IsWebGL
- {
- get { return Application.platform == RuntimePlatform.WebGLPlayer; }
- }
-
- ///
- /// 是否是Windows平台
- ///
- [UnityEngine.Scripting.Preserve]
- public static bool IsWindows
- {
- get { return Application.platform == RuntimePlatform.WindowsPlayer; }
- }
-
- ///
- /// 是否是Linux平台
- ///
- [UnityEngine.Scripting.Preserve]
- public static bool IsLinux
- {
- get { return Application.platform == RuntimePlatform.LinuxPlayer; }
- }
-
-
- ///
- /// 是否是Mac平台
- ///
- [UnityEngine.Scripting.Preserve]
- public static bool IsMacOsx
- {
- get { return Application.platform == RuntimePlatform.OSXPlayer; }
- }
-
- ///
- /// 是否是iOS 移动平台
- ///
- [UnityEngine.Scripting.Preserve]
- public static bool IsIOS
- {
- get
- {
-#if UNITY_IOS
- return true;
-#else
- return false;
-#endif
- }
- }
-
- ///
- /// 退出
- ///
- 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
- ///
- /// 打开URL
- ///
- /// url地址
- 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
- }
- }
-}
diff --git a/Runtime/ABase/Helper/ApplicationHelper.cs.meta b/Runtime/ABase/Helper/ApplicationHelper.cs.meta
deleted file mode 100644
index be5aafc..0000000
--- a/Runtime/ABase/Helper/ApplicationHelper.cs.meta
+++ /dev/null
@@ -1,3 +0,0 @@
-fileFormatVersion: 2
-guid: 4bb21c08b2dd4b15af73858c5daf4a99
-timeCreated: 1676885563
\ No newline at end of file
diff --git a/Runtime/ABase/Helper/DistinctHelper.cs.meta b/Runtime/ABase/Helper/DistinctHelper.cs.meta
deleted file mode 100644
index 120b38d..0000000
--- a/Runtime/ABase/Helper/DistinctHelper.cs.meta
+++ /dev/null
@@ -1,3 +0,0 @@
-fileFormatVersion: 2
-guid: 777c1056a4804d90960109d21275c56e
-timeCreated: 1670814641
\ No newline at end of file
diff --git a/Runtime/ABase/Helper/FileHelper.cs b/Runtime/ABase/Helper/FileHelper.cs
index 016e544..53b1bea 100644
--- a/Runtime/ABase/Helper/FileHelper.cs
+++ b/Runtime/ABase/Helper/FileHelper.cs
@@ -152,9 +152,9 @@ namespace AlicizaX
{
if (Application.platform == RuntimePlatform.Android)
{
- if (PathHelper.NormalizePath(path).Contains(PathHelper.AppResPath))
+ if (Utility.Path.NormalizePath(path).Contains(Utility.Path.AppResPath))
{
- readPath = path.Substring(PathHelper.AppResPath.Length);
+ readPath = path.Substring(Utility.Path.AppResPath.Length);
return true;
}
}
diff --git a/Runtime/ABase/Helper/NetworkHelper.cs b/Runtime/ABase/Helper/NetworkHelper.cs
deleted file mode 100644
index 999ff0b..0000000
--- a/Runtime/ABase/Helper/NetworkHelper.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-using System.Collections.Generic;
-using System.Net;
-using UnityEngine;
-
-namespace AlicizaX
-{
- ///
- /// 网络帮助类
- ///
- public static class NetworkHelper
- {
- ///
- /// 获取本地的IP列表
- ///
- ///
- 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;
- }
-
- ///
- /// 是否有网络
- ///
- ///
- public static bool IsReachable()
- {
- return Application.internetReachability != NetworkReachability.NotReachable;
- }
-
- ///
- /// 是否是WIFI
- ///
- ///
- public static bool IsWifi()
- {
- return Application.internetReachability == NetworkReachability.ReachableViaLocalAreaNetwork;
- }
-
- ///
- /// 是否是移动网络
- ///
- ///
- public static bool IsViaCarrierData()
- {
- //当用户使用移动网络时
- return Application.internetReachability == NetworkReachability.ReachableViaCarrierDataNetwork;
- }
- }
-}
diff --git a/Runtime/ABase/Helper/NetworkHelper.cs.meta b/Runtime/ABase/Helper/NetworkHelper.cs.meta
deleted file mode 100644
index 83204e2..0000000
--- a/Runtime/ABase/Helper/NetworkHelper.cs.meta
+++ /dev/null
@@ -1,3 +0,0 @@
-fileFormatVersion: 2
-guid: debb4ec407ad464e9aa0cbee452683e1
-timeCreated: 1666448562
\ No newline at end of file
diff --git a/Runtime/ABase/Helper/ObjectHelper.cs b/Runtime/ABase/Helper/ObjectHelper.cs
deleted file mode 100644
index 610fe39..0000000
--- a/Runtime/ABase/Helper/ObjectHelper.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace AlicizaX
-{
- [UnityEngine.Scripting.Preserve]
- public static class ObjectHelper
- {
- [UnityEngine.Scripting.Preserve]
- public static void Swap(ref T t1, ref T t2)
- {
- (t1, t2) = (t2, t1);
- }
- }
-}
diff --git a/Runtime/ABase/Helper/ObjectHelper.cs.meta b/Runtime/ABase/Helper/ObjectHelper.cs.meta
deleted file mode 100644
index d826c1f..0000000
--- a/Runtime/ABase/Helper/ObjectHelper.cs.meta
+++ /dev/null
@@ -1,3 +0,0 @@
-fileFormatVersion: 2
-guid: 41b9276a283a4b6a9afcdde1b884ff70
-timeCreated: 1667393013
\ No newline at end of file
diff --git a/Runtime/ABase/Helper/PathHelper.cs b/Runtime/ABase/Helper/PathHelper.cs
deleted file mode 100644
index 07b6fd1..0000000
--- a/Runtime/ABase/Helper/PathHelper.cs
+++ /dev/null
@@ -1,112 +0,0 @@
-using System.Text;
-using UnityEngine;
-
-namespace AlicizaX
-{
- public static class PathHelper
- {
- ///
- ///应用程序外部资源路径存放路径(热更新资源路径)
- ///
- [UnityEngine.Scripting.Preserve]
- public static string AppHotfixResPath
- {
- get
- {
- string game = Application.productName;
- string path = $"{Application.persistentDataPath}/{game}/";
- return path;
- }
- }
-
- ///
- /// 应用程序内部资源路径存放路径
- ///
- public static string AppResPath
- {
- get { return NormalizePath(Application.streamingAssetsPath); }
- }
-
- ///
- /// 应用程序内部资源路径存放路径(www/webrequest专用)
- ///
- [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
- }
- }
-
- ///
- /// 获取平台名称
- ///
- 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
- }
- }
-
- ///
- /// 规范化路径
- ///
- ///
- ///
- public static string NormalizePath(string path)
- {
- return path.Replace('\\', '/').Replace("\\", "/");
- }
-
- static readonly StringBuilder CombineStringBuilder = new StringBuilder();
-
- ///
- /// 拼接路径
- ///
- ///
- ///
- 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();
- }
- }
-}
diff --git a/Runtime/ABase/Helper/PathHelper.cs.meta b/Runtime/ABase/Helper/PathHelper.cs.meta
deleted file mode 100644
index 22bd71d..0000000
--- a/Runtime/ABase/Helper/PathHelper.cs.meta
+++ /dev/null
@@ -1,3 +0,0 @@
-fileFormatVersion: 2
-guid: abf5957e17cb46339da8f67cd4074ffd
-timeCreated: 1671505311
\ No newline at end of file
diff --git a/Runtime/ABase/Helper/RandomHelper.cs b/Runtime/ABase/Helper/RandomHelper.cs
deleted file mode 100644
index c471b06..0000000
--- a/Runtime/ABase/Helper/RandomHelper.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using System;
-
-namespace AlicizaX
-{
- ///
- /// 随机数帮助类
- ///
- public static class RandomHelper
- {
- private static Random _random = new Random((int) DateTime.UtcNow.Ticks);
-
- ///
- /// 设置随机种子
- ///
- ///
- public static void SetSeed(int seed)
- {
- _random = new Random(seed);
- }
-
- ///
- /// 获取UInt64范围内的随机数
- ///
- ///
- public static ulong NextUInt64()
- {
- var bytes = new byte[8];
- _random.NextBytes(bytes);
- return BitConverter.ToUInt64(bytes, 0);
- }
-
- ///
- /// 获取Int64范围内的随机数
- ///
- ///
- public static long NextInt64()
- {
- var bytes = new byte[8];
- _random.NextBytes(bytes);
- return BitConverter.ToInt64(bytes, 0);
- }
-
- ///
- /// 获取lower与Upper之间的随机数
- ///
- ///
- ///
- ///
- public static int Next(int lower, int upper)
- {
- return _random.Next(lower, upper);
- }
-
- ///
- /// 获取0与1之间的随机数
- ///
- ///
- public static float Next()
- {
- return _random.Next(0, 100_000) / 100_000f;
- }
- }
-}
diff --git a/Runtime/ABase/Structs/Pair.cs b/Runtime/ABase/Structs/Pair.cs
new file mode 100644
index 0000000..e239f23
--- /dev/null
+++ b/Runtime/ABase/Structs/Pair.cs
@@ -0,0 +1,16 @@
+namespace AlicizaX
+{
+ public struct Pair
+ {
+ 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;
+ }
+ }
+}
diff --git a/Runtime/ABase/Structs/Pair.cs.meta b/Runtime/ABase/Structs/Pair.cs.meta
new file mode 100644
index 0000000..3175181
--- /dev/null
+++ b/Runtime/ABase/Structs/Pair.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b0278c1fdfc27bd4c9419d984d7d0ac1
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Runtime/ABase/Structs/UniqueID.cs b/Runtime/ABase/Structs/UniqueID.cs
index 3c0a036..3a10314 100644
--- a/Runtime/ABase/Structs/UniqueID.cs
+++ b/Runtime/ABase/Structs/UniqueID.cs
@@ -32,7 +32,7 @@ namespace AlicizaX
///
public void Generate()
{
- Id = GameHelper.GetGuid();
+ Id = Utility.IdGenerator.GetGuid();
}
public static implicit operator string(UniqueID uniqueID)
diff --git a/Runtime/ABase/Utility/Utility.Gizmo.cs b/Runtime/ABase/Utility/Utility.Gizmo.cs
new file mode 100644
index 0000000..477f9da
--- /dev/null
+++ b/Runtime/ABase/Utility/Utility.Gizmo.cs
@@ -0,0 +1,108 @@
+using UnityEngine;
+
+#if UNITY_EDITOR
+using UnityEditor;
+#endif
+
+namespace AlicizaX
+{
+ public static partial class Utility
+ {
+ ///
+ /// Gizmos 绘制辅助。
+ ///
+ 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
+ }
+ }
+ }
+}
diff --git a/Runtime/ABase/Utility/Utility.Gizmo.cs.meta b/Runtime/ABase/Utility/Utility.Gizmo.cs.meta
new file mode 100644
index 0000000..d16272e
--- /dev/null
+++ b/Runtime/ABase/Utility/Utility.Gizmo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1795d7c750b9aaa4abd939fa483d3a66
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Runtime/ABase/Utility/Utility.IdGenerator.cs b/Runtime/ABase/Utility/Utility.IdGenerator.cs
index 292af51..ff6dcec 100644
--- a/Runtime/ABase/Utility/Utility.IdGenerator.cs
+++ b/Runtime/ABase/Utility/Utility.IdGenerator.cs
@@ -31,6 +31,14 @@ namespace AlicizaX
{
return Interlocked.Increment(ref _intCounter);
}
+
+ ///
+ /// 生成新的 Guid 字符串。
+ ///
+ public static string GetGuid()
+ {
+ return Guid.NewGuid().ToString("N");
+ }
}
}
}
diff --git a/Runtime/ABase/Utility/Utility.Math.cs b/Runtime/ABase/Utility/Utility.Math.cs
new file mode 100644
index 0000000..ae6b296
--- /dev/null
+++ b/Runtime/ABase/Utility/Utility.Math.cs
@@ -0,0 +1,183 @@
+using UnityEngine;
+
+namespace AlicizaX
+{
+ public static partial class Utility
+ {
+ ///
+ /// 数学和插值相关工具。
+ ///
+ 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;
+ }
+ }
+ }
+}
diff --git a/Runtime/ABase/Utility/Utility.Math.cs.meta b/Runtime/ABase/Utility/Utility.Math.cs.meta
new file mode 100644
index 0000000..6d14d94
--- /dev/null
+++ b/Runtime/ABase/Utility/Utility.Math.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: eb2b3056e5c86d94697f60d958e1012e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Runtime/ABase/Utility/Utility.Net.cs b/Runtime/ABase/Utility/Utility.Net.cs
index 4ef9926..a7503b7 100644
--- a/Runtime/ABase/Utility/Utility.Net.cs
+++ b/Runtime/ABase/Utility/Utility.Net.cs
@@ -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
///
public static class Net
{
+ ///
+ /// 获取本地 IP 列表。
+ ///
+ 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;
+ }
+
+ ///
+ /// 是否有网络连接。
+ ///
+ public static bool IsReachable()
+ {
+ return Application.internetReachability != NetworkReachability.NotReachable;
+ }
+
+ ///
+ /// 是否为局域网或 WiFi 网络。
+ ///
+ public static bool IsWifi()
+ {
+ return Application.internetReachability == NetworkReachability.ReachableViaLocalAreaNetwork;
+ }
+
+ ///
+ /// 是否为移动网络。
+ ///
+ public static bool IsViaCarrierData()
+ {
+ return Application.internetReachability == NetworkReachability.ReachableViaCarrierDataNetwork;
+ }
///
/// 获取第一个可用的端口号
///
diff --git a/Runtime/ABase/Utility/Utility.Object.cs b/Runtime/ABase/Utility/Utility.Object.cs
deleted file mode 100644
index 5f2d17c..0000000
--- a/Runtime/ABase/Utility/Utility.Object.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-namespace AlicizaX
-{
- public static partial class Utility
- {
- ///
- /// Object 对象工具类
- ///
- public static class Object
- {
- ///
- /// 交换对象
- ///
- ///
- ///
- ///
- public static void Swap(ref T t1, ref T t2)
- {
- (t1, t2) = (t2, t1);
- }
- }
- }
-}
diff --git a/Runtime/ABase/Utility/Utility.Object.cs.meta b/Runtime/ABase/Utility/Utility.Object.cs.meta
deleted file mode 100644
index 9249cd1..0000000
--- a/Runtime/ABase/Utility/Utility.Object.cs.meta
+++ /dev/null
@@ -1,3 +0,0 @@
-fileFormatVersion: 2
-guid: 0264830b4fe54557b5b0f6a6123ffbb1
-timeCreated: 1666234520
\ No newline at end of file
diff --git a/Runtime/ABase/Utility/Utility.Path.cs b/Runtime/ABase/Utility/Utility.Path.cs
index c1056a8..d4264af 100644
--- a/Runtime/ABase/Utility/Utility.Path.cs
+++ b/Runtime/ABase/Utility/Utility.Path.cs
@@ -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
///
public static class Path
{
+ private static readonly StringBuilder CombineStringBuilder = new StringBuilder();
+
+ ///
+ /// 应用程序外部资源路径存放路径(热更新资源路径)。
+ ///
+ public static string AppHotfixResPath
+ {
+ get
+ {
+ string game = Application.productName;
+ return $"{Application.persistentDataPath}/{game}/";
+ }
+ }
+
+ ///
+ /// 应用程序内部资源路径存放路径。
+ ///
+ public static string AppResPath => GetRegularPath(Application.streamingAssetsPath);
+
+ ///
+ /// 应用程序内部资源路径存放路径(www/webrequest专用)。
+ ///
+ 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
+ }
+ }
+
+ ///
+ /// 获取平台名称。
+ ///
+ 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
+ }
+ }
///
/// 获取规范的路径。
///
@@ -24,6 +83,16 @@ namespace AlicizaX
return path.Replace('\\', '/');
}
+ ///
+ /// 获取规范的路径。
+ ///
+ /// 要规范的路径。
+ /// 规范的路径。
+ public static string NormalizePath(string path)
+ {
+ return GetRegularPath(path);
+ }
+
///
/// 获取远程格式的路径(带有file:// 或 http:// 前缀)。
///
@@ -40,6 +109,37 @@ namespace AlicizaX
return regularPath.Contains("://") ? regularPath : ("file:///" + regularPath).Replace("file:////", "file:///");
}
+ ///
+ /// 拼接路径。
+ ///
+ 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();
+ }
+
///
/// 移除空文件夹。
///
diff --git a/Runtime/ABase/Utility/Utility.Platform.cs b/Runtime/ABase/Utility/Utility.Platform.cs
new file mode 100644
index 0000000..bba8649
--- /dev/null
+++ b/Runtime/ABase/Utility/Utility.Platform.cs
@@ -0,0 +1,111 @@
+using UnityEngine;
+
+namespace AlicizaX
+{
+ public static partial class Utility
+ {
+ ///
+ /// 应用和平台相关的实用函数。
+ ///
+ public static class Platform
+ {
+ ///
+ /// 是否是编辑器。
+ ///
+ public static bool IsEditor
+ {
+ get
+ {
+#if UNITY_EDITOR
+ return true;
+#else
+ return false;
+#endif
+ }
+ }
+
+ ///
+ /// 是否是安卓。
+ ///
+ public static bool IsAndroid
+ {
+ get
+ {
+#if UNITY_ANDROID
+ return true;
+#else
+ return false;
+#endif
+ }
+ }
+
+ ///
+ /// 是否是 WebGL 平台。
+ ///
+ public static bool IsWebGL => Application.platform == RuntimePlatform.WebGLPlayer;
+
+ ///
+ /// 是否是 Windows 平台。
+ ///
+ public static bool IsWindows => Application.platform == RuntimePlatform.WindowsPlayer;
+
+ ///
+ /// 是否是 Linux 平台。
+ ///
+ public static bool IsLinux => Application.platform == RuntimePlatform.LinuxPlayer;
+
+ ///
+ /// 是否是 Mac 平台。
+ ///
+ public static bool IsMacOsx => Application.platform == RuntimePlatform.OSXPlayer;
+
+ ///
+ /// 是否是 iOS 平台。
+ ///
+ public static bool IsIOS
+ {
+ get
+ {
+#if UNITY_IOS
+ return true;
+#else
+ return false;
+#endif
+ }
+ }
+
+ ///
+ /// 退出应用。
+ ///
+ 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
+
+ ///
+ /// 打开 URL。
+ ///
+ 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
+ }
+ }
+ }
+}
diff --git a/Runtime/ABase/Utility/Utility.Platform.cs.meta b/Runtime/ABase/Utility/Utility.Platform.cs.meta
new file mode 100644
index 0000000..f4e8c79
--- /dev/null
+++ b/Runtime/ABase/Utility/Utility.Platform.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3b2027d750c54878b78b6e304ed4ad7d
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Runtime/ABase/Utility/Utility.Random.cs b/Runtime/ABase/Utility/Utility.Random.cs
index 52cb02e..8b4c1ec 100644
--- a/Runtime/ABase/Utility/Utility.Random.cs
+++ b/Runtime/ABase/Utility/Utility.Random.cs
@@ -59,6 +59,35 @@ namespace AlicizaX
return s_Random.NextDouble();
}
+ ///
+ /// 返回一个介于 0.0 和 1.0 之间的随机数。
+ ///
+ /// 大于等于 0.0 并且小于 1.0 的单精度浮点数。
+ public static float GetRandomSingle()
+ {
+ return (float)s_Random.NextDouble();
+ }
+
+ ///
+ /// 返回一个随机的 Int64。
+ ///
+ public static long GetRandomInt64()
+ {
+ byte[] bytes = new byte[8];
+ s_Random.NextBytes(bytes);
+ return BitConverter.ToInt64(bytes, 0);
+ }
+
+ ///
+ /// 返回一个随机的 UInt64。
+ ///
+ public static ulong GetRandomUInt64()
+ {
+ byte[] bytes = new byte[8];
+ s_Random.NextBytes(bytes);
+ return BitConverter.ToUInt64(bytes, 0);
+ }
+
///
/// 用随机数填充指定字节数组的元素。
///
@@ -67,6 +96,87 @@ namespace AlicizaX
{
s_Random.NextBytes(buffer);
}
+
+ ///
+ /// 获取一个与上次值不同的随机数。
+ ///
+ 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;
+ }
+
+ ///
+ /// 获取一个排除指定值集合的随机数。
+ ///
+ 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;
+ }
+
+ ///
+ /// 获取一个排除现有集合和已选集合的随机数。
+ ///
+ 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;
+ }
}
}
}
diff --git a/Runtime/ABase/Utility/Utility.Unity.Gameplay.cs b/Runtime/ABase/Utility/Utility.Unity.Gameplay.cs
new file mode 100644
index 0000000..0c7ae86
--- /dev/null
+++ b/Runtime/ABase/Utility/Utility.Unity.Gameplay.cs
@@ -0,0 +1,106 @@
+using UnityEngine;
+
+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();
+ 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();
+ 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();
+ 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);
+ }
+ }
+ }
+}
diff --git a/Runtime/ABase/Utility/Utility.Unity.Gameplay.cs.meta b/Runtime/ABase/Utility/Utility.Unity.Gameplay.cs.meta
new file mode 100644
index 0000000..5c4c476
--- /dev/null
+++ b/Runtime/ABase/Utility/Utility.Unity.Gameplay.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b214adecc8c0fab41b3fcd306d4ebb10
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: