Initial commit: Client Doc docs Server Tools

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
ud18010
2026-07-10 10:24:29 +08:00
co-authored by Cursor
commit 7e35d8da31
3374 changed files with 680813 additions and 0 deletions
@@ -0,0 +1,602 @@
using UnityEngine;
using System.Runtime.InteropServices;
#if !UNITY_WEBGL
using System.Net;
using System.Net.Sockets;
#endif
//using GYGame;
using System;
using System.Text;
using System.Collections.Generic;
using System.Threading;
using XLua;
namespace XGame
{
public class ConsoleWindow : MonoBehaviour
{
#if UNITY_STANDALONE_OSX //|| UNITY_EDITOR_OSX
const string ConsoleWindowsDLL = "ConsoleWindow";
[DllImport(ConsoleWindowsDLL, CallingConvention = CallingConvention.Cdecl)]
public static extern int ShowConsoleWin();
[DllImport(ConsoleWindowsDLL, CallingConvention = CallingConvention.Cdecl)]
public static extern void ShowErrorMsg(string msg);
[DllImport(ConsoleWindowsDLL, CallingConvention = CallingConvention.Cdecl)]
public static extern void ShowWarningMsg(string msg);
[DllImport(ConsoleWindowsDLL, CallingConvention = CallingConvention.Cdecl)]
public static extern void ShowLogMsg(string msg);
void ShowConsole()
{
ShowConsoleWin();
}
void HandleLog(string message, string stackTrace, LogType type)
{
message = message + "\n";
if (type == LogType.Log)
{
ShowLogMsg(message);
}
else if (type == LogType.Warning)
{
ShowWarningMsg(message);
}
else
{
ShowErrorMsg(message + stackTrace);
}
}
#elif UNITY_STANDALONE_WIN
void ShowConsole()
{
//XConsoleHelper.ClearConsole();
}
void HandleLog(string message, string stackTrace, LogType type)
{
message = message + "\n";
//XConsoleHelper.Write(type, message);
//可以根据Type加前缀
message = message + "\n";
//发送到服务器转外置console
//可以根据Type加前缀
switch (type)
{
case LogType.Error:
message = "Error: " + AppendLuaStackTrace(message);
break;
case LogType.Exception:
message = "Exception: " + AppendLuaStackTrace(message);
break;
case LogType.Warning:
message = "Warning: " + message;
break;
default:
break;
}
Send(message);//*/
}
#else
void ShowConsole()
{
}
void HandleLog(string message, string stackTrace, LogType type)
{
//可以根据Type加前缀
message = message + "\n";
//发送到服务器转外置console
//可以根据Type加前缀
switch (type)
{
case LogType.Error:
message = "Error: " + AppendLuaStackTrace(message);
break;
case LogType.Exception:
message = "Exception: " + AppendLuaStackTrace(message);
break;
case LogType.Warning:
message = "Warning: " + message;
break;
default:
break;
}
Send(message);
}
#endif
//ud 20220106 增加远程信息调试功能
#if !UNITY_WEBGL
static private Socket LogSocket;
static private bool LogSocketConnecting;
static private readonly object LogSocketLock = new object();
const string RemoteConsoleHost = "119.91.115.142";
const int RemoteConsolePort = 15098;
const int RemoteConsoleConnectTimeoutMs = 1500;
#else
static XWebSocket WebSocket;// = new GYWebSocket();
#endif
private const int BuffSize = 10240;
static private string LuaScript = null;
static byte[] MsgBuffer = new byte[64000];
static int BufferPos = 0;
public void Init()
{
bool bConsole = true;//起始不加载false
#if UNITY_EDITOR
bConsole = false;
#endif
//外网包就跳过
//。。。
//#if !UNITY_STANDALONE
if(bConsole)
{
ConnectConsoleServer(SystemInfo.graphicsDeviceName);
}
//#endif
}
[CSharpCallLua]
static public void ConnectConsoleServer(string name)
{
#if UNITY_EDITOR || UNITY_WEBGL //编辑器和WebGL不开
#if UNITY_WEBGL
if (WebSocket == null)
{
string url = $"192.168.51.100:15098";//$"ws://182.61.4.164:15098";//$"ws://119.91.115.142:15098";//
lsocket.connect(url, 0, (ws, err) =>
{
WebSocket = ws;
if (ws != null)
{
//Debug.LogError($"Console Connect OK!");
string msg = "$set~^client$" + name + ",x\r\n";
Send(msg);
}
else
{
Debug.LogError($"Console Connect Err: {err}");
}
});
}
else
{//重设名字
//发送客户端登录(改换idname),"$set~^client$"+初始登录nameSystemInfo.deviceUniqueIdentifier+"|"+账号id
string msg = "$set~^client$" + name + ",x\r\n";
Send(msg);
}
#endif
return;
#else
ConnectConsoleServerAsync(name);
return;
#if false
if (LogSocket == null || !LogSocket.Connected)
{
try
{
//初始化网络,连接服务器,接收或发送给服务器
if (LogSocket == null)
LogSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//LogSocket.Connect("192.168.8.60", 13782);//服务器所在
LogSocket.Connect("119.91.115.142", 15098);//外网调试服
//LogSocket.Connect("192.168.10.166", 8861);
//发送客户端登录(改换idname),"$set~^client$"+初始登录nameSystemInfo.deviceUniqueIdentifier+"|"+账号id
string msg = "$set~^client$" + name + ",x\r\n";
Send(msg);
ReceiveAsync();
if (LogSocket != null && !LogSocket.Connected)
{
LogSocket.Close();
LogSocket = null;
Debug.LogWarning("ConnectConsoleServer Failed!");
}
else
{
Debug.Log("ConnectConsoleServer OK!");
}
}
catch (Exception e)
{
Debug.LogWarning("ConnectConsoleServer Failed : " + e.Message);
}
}
else
{
//发送客户端登录(改换idname),"$set~^client$"+初始登录nameSystemInfo.deviceUniqueIdentifier+"|"+账号id
string msg = "$set~^client$" + name + ",x\r\n";
Send(msg);
}
#endif
#endif
}
#if !UNITY_WEBGL && !UNITY_EDITOR
class ConsoleConnectState
{
public Socket Socket;
public string Name;
public volatile bool TimedOut;
public ConsoleConnectState(Socket socket, string name)
{
Socket = socket;
Name = name;
}
}
static private void ConnectConsoleServerAsync(string name)
{
if (LogSocket != null && LogSocket.Connected)
{
string msg = "$set~^client$" + name + ",x\r\n";
Send(msg);
return;
}
lock (LogSocketLock)
{
if (LogSocketConnecting)
return;
LogSocketConnecting = true;
}
Socket socket = null;
IAsyncResult connectResult = null;
ConsoleConnectState state = null;
try
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.NoDelay = true;
state = new ConsoleConnectState(socket, name);
LogSocket = socket;
connectResult = socket.BeginConnect(RemoteConsoleHost, RemoteConsolePort, OnConsoleConnected, state);
ThreadPool.QueueUserWorkItem(_ =>
{
try
{
if (connectResult != null && !connectResult.AsyncWaitHandle.WaitOne(RemoteConsoleConnectTimeoutMs))
{
state.TimedOut = true;
SafeClose(socket);
lock (LogSocketLock)
{
if (LogSocket == socket)
LogSocket = null;
LogSocketConnecting = false;
}
Debug.LogWarning("ConnectConsoleServer timeout.");
}
}
finally
{
try
{
if (connectResult != null)
connectResult.AsyncWaitHandle.Close();
}
catch { }
}
});
}
catch (Exception e)
{
SafeClose(socket);
lock (LogSocketLock)
{
if (LogSocket == socket)
LogSocket = null;
LogSocketConnecting = false;
}
Debug.LogWarning("ConnectConsoleServer Failed : " + e.Message);
}
}
static private void OnConsoleConnected(IAsyncResult result)
{
ConsoleConnectState state = result.AsyncState as ConsoleConnectState;
Socket socket = state != null ? state.Socket : null;
try
{
if (socket == null)
return;
socket.EndConnect(result);
if (socket.Connected)
{
LogSocket = socket;
string msg = "$set~^client$" + state.Name + ",x\r\n";
Send(msg);
ReceiveAsync();
Debug.Log("ConnectConsoleServer OK!");
}
}
catch (Exception e)
{
SafeClose(socket);
lock (LogSocketLock)
{
if (LogSocket == socket)
LogSocket = null;
}
if (state == null || !state.TimedOut)
Debug.LogWarning("ConnectConsoleServer Failed : " + e.Message);
}
finally
{
lock (LogSocketLock)
{
if (LogSocket == socket || LogSocket == null)
LogSocketConnecting = false;
}
}
}
static private void SafeClose(Socket socket)
{
try { socket?.Close(); } catch { }
}
#endif
void Update()
{
if (LuaScript != null)
{//在主线程执行代码
string sLua = LuaScript;
LuaScript = null;
//Debug.Log($"Run Lua : {sLua}");
try
{
LuaManager.m_Instance.DoString(sLua);
}
catch (Exception e)
{
Debug.LogWarning("Do Lua Failed : " + e.Message);
}
}
#if UNITY_WEBGL
//WebSocket 每帧要获得是否有信息
if (WebSocket != null)
{
int recLength = WebSocket.GetRecvSize();
if (recLength > 0)
{
string strError = "";
byte[] data = WebSocket.recv(ref strError);
//拆粘包处理
SetData(data, recLength);
}
}
#endif
}
static private void ReceiveAsync()
{
#if !UNITY_WEBGL
if (LogSocket == null || !LogSocket.Connected) return;
var Buff = new byte[BuffSize];
LogSocket.BeginReceive(Buff, 0, BuffSize, SocketFlags.None, OnReceived, Buff);
#endif
}
static public void OnReceived(IAsyncResult result)
{
#if !UNITY_WEBGL
if (LogSocket == null || !LogSocket.Connected)
{
Debug.LogError("Remote Console DisConnected: ");
return;
}
byte[] data = (byte[])result.AsyncState;
int recLength = LogSocket.EndReceive(result, out SocketError error);
if (recLength <= 0)
{
Debug.LogError($"Remote Console Error: {error}");
return;
}
ReceiveAsync();
//拆粘包处理
SetData(data, recLength);
#endif
}
public static void SetData(byte[] data, int recLength)
{
//拆粘包处理
data.CopyTo(MsgBuffer, BufferPos);
recLength = recLength + BufferPos;
int pos = 0;
for (int j = 0; j < 100; ++j)
{
//前两个字节是长度
short len = BitConverter.ToInt16(MsgBuffer, pos);
if (recLength - pos - 2 < len)
{//长度不足
if (pos == 0)
{
BufferPos = recLength;
}
else
{
data.CopyTo(MsgBuffer, BufferPos);
Buffer.BlockCopy(MsgBuffer, pos, MsgBuffer, 0, recLength - pos);
BufferPos = recLength - pos;
}
break;
}
//处理
System.Text.Encoding encoding = System.Text.Encoding.Default;
//这里是接收线程,不能直接执行代码,可能会出错
int luasize = len;
if (MsgBuffer[pos + 2 + len - 1] == '\0')
luasize = len - 1;
if (LuaScript == null)
{//memcpy(msg.sData, p_tsock->buffer + pos + sizeof(unsigned short), len);
LuaScript = encoding.GetString(MsgBuffer, pos + 2, luasize);
}
else
{
LuaScript = LuaScript + encoding.GetString(MsgBuffer, pos + 2, luasize);
}
pos += len + 2;
if (pos == recLength + BufferPos)
{
BufferPos = 0;
break;
}
}
}
public static void Log(LogType logType, string log)
{
#if !UNITY_WEBGL
if (LogSocket == null || !LogSocket.Connected) return;
#else
if (WebSocket == null) return;
#endif
string fLog = "";
switch (logType)
{
case LogType.Error:
fLog = "Error: " + AppendLuaStackTrace(log);
break;
case LogType.Exception:
fLog = "Exception: " + AppendLuaStackTrace(log);
break;
case LogType.Warning:
fLog = "Warning: " + log;
break;
default:
fLog = log;
break;
}
Send(fLog);
}
private static string AppendLuaStackTrace(string message)
{
string luaStackTrace = GetLuaStackTrace();
if (string.IsNullOrEmpty(luaStackTrace))
{
return message;
}
Debug.Log("\nLua Stack:\n" + luaStackTrace);
return message + "\nLua Stack:\n" + luaStackTrace;
}
private static string GetLuaStackTrace()
{
LuaEnv luaEnv = LuaManager.m_LuaEnv;
if (luaEnv == null)
{
return null;
}
try
{
object[] results = luaEnv.DoString("return debug.traceback('', 2)", "ConsoleWindow.GetLuaStackTrace");
if (results != null && results.Length > 0)
{
return results[0] as string;
}
}
catch
{
// Keep logging robust even if the Lua VM is not in a callable state.
}
return null;
}
private static void Send(string msg)
{
#if !UNITY_WEBGL
if (LogSocket != null && LogSocket.Connected)
{
byte[] content = Encoding.Default.GetBytes(msg);
ushort size = (ushort)content.Length;
byte[] bytes = BitConverter.GetBytes(size);
byte[] buff = new byte[bytes.Length + content.Length];
bytes.CopyTo(buff, 0);
content.CopyTo(buff, bytes.Length);
int nSend = LogSocket.Send(buff);
//nSend = size;
}
#else
if (WebSocket != null)
{
byte[] content = Encoding.Default.GetBytes(msg);
ushort size = (ushort)content.Length;
byte[] bytes = BitConverter.GetBytes(size);
byte[] buff = new byte[bytes.Length + content.Length];
bytes.CopyTo(buff, 0);
content.CopyTo(buff, bytes.Length);
string errorMsg = null;
WebSocket.send(buff, null, ref errorMsg);
}
#endif
}
private static void SendBytes(byte[] buff)
{
#if !UNITY_WEBGL
if (LogSocket != null && LogSocket.Connected)
{
ushort size = (ushort)buff.Length;
byte[] bytes = BitConverter.GetBytes(size);
byte[] sendbuf = new byte[bytes.Length + buff.Length];
bytes.CopyTo(sendbuf, 0);
buff.CopyTo(sendbuf, bytes.Length);
LogSocket.Send(sendbuf);
}
#else
if (WebSocket != null)
{
ushort size = (ushort)buff.Length;
byte[] bytes = BitConverter.GetBytes(size);
byte[] sendbuf = new byte[bytes.Length + buff.Length];
bytes.CopyTo(sendbuf, 0);
buff.CopyTo(sendbuf, bytes.Length);
string errorMsg = null;
WebSocket.send(sendbuf, null, ref errorMsg);
}
#endif
}
#if !UNITY_EDITOR
void Awake()
{
Init();
Application.logMessageReceived += HandleLog;
}
void OnDestroy()
{
Application.logMessageReceived -= HandleLog;
//if (LogSocket != null && LogSocket.Connected)
//{
// LogSocket.Disconnect(false);
//}
}
#else
void Awake()
{
Init();
Application.logMessageReceived += HandleLog;
}
#endif
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0ca08f2ff7cc23d4187a29a38ccadce7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,235 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
#if UNITY_WEBGL
using WeChatWASM;
#endif
using ZXing;
using ZXing.QrCode;
/// <summary>
/// 扫描图片
/// </summary>
public class ScanQRCode : MonoBehaviour
{
bool isOpen = true; //true当前开启扫描状态 false 当前是关闭扫描状态
Animator ani; //扫描动画
private WebCamTexture m_webCameraTexture;//摄像头实时显示的画面
private BarcodeReader m_barcodeRender; //申请一个读取二维码的变量
//存放二维码的纹理图片
Texture2D encoded;
[Header("显示摄像头画面的RawImage")]
public RawImage m_cameraTexture;
[Header("扫描间隔")]
public float m_delayTime = 3f;
[Header("开启扫描按钮")]
public Button openScanBtn;
[Header("扫描按钮")]
public Button ScanBtn;
void Start()
{
Debug.Log("ScanQRCode.Start()");
/*初始化纹理图片
* 注意:宽高度大小必须是256,
* 否则出现索引超出数组边界错误
*/
encoded = new Texture2D(256, 256);
CreatQr("http://192.168.1.88/T");
ScanBtn.onClick.AddListener(()=>{
StartScanQRCode((rs) =>
{
CreatQr(rs);
});
});
return;
try
{
//摄像机权限
#if UNITY_WEBGL
if (LoadDll.m_bInWX)
{
AppAuthorizeSetting au = WX.GetAppAuthorizeSetting();
if (au.cameraAuthorized != "authorized")
{//未授权
AuthorizeOption opt = new AuthorizeOption();
opt.complete = (rs) => { Debug.Log($"Cam Authorze complete {rs.errMsg}"); };
opt.success = (rs) => { Debug.Log($"Cam Authorze success {rs.errMsg}"); };
opt.fail = (rs) => { Debug.Log($"Cam Authorze fail {rs.errMsg}"); };
WX.Authorize(opt);
return;
}
}
else
#endif
{
Application.RequestUserAuthorization(UserAuthorization.WebCam);
}
InitQRScan();
}
catch(System.Exception e)
{
Debug.Log($"{e.Message}");
}
}
void InitQRScan()
{
WebCamDevice[] tDevices = WebCamTexture.devices; //获取所有摄像头
if (tDevices.Length > 0)
{
string tDeviceName = tDevices[0].name; //获取第一个摄像头,用第一个摄像头的画面生成图片信息
m_webCameraTexture = new WebCamTexture(tDeviceName, 400, 300);//名字,宽,高
m_cameraTexture.texture = m_webCameraTexture; //赋值图片信息
m_webCameraTexture.Play(); //开始实时显示
m_barcodeRender = new BarcodeReader();
}
else
{
Debug.Log("No Camera!");
return;
}
ani = GetComponent<Animator>();
OpenScanQRCode(); //默认不扫描
//按钮监听
openScanBtn.onClick.AddListener(OpenScanQRCode);
}
#region
/// <summary>
/// 创建二维码
/// </summary>
public void CreatQr(string QrCodeStr)
{
if (QrCodeStr != string.Empty)
{
//二维码写入图片
var color32 = Encode(QrCodeStr, encoded.width, encoded.height);
encoded.SetPixels32(color32); //更改纹理的像素颜色
encoded.Apply();
//生成的二维码图片附给RawImage
m_cameraTexture.texture = encoded;
}
else
Debug.Log("没有生成信息");
}
/// <summary>
/// 生成二维码
/// </summary>
/// <param name="textForEncoding">需要生产二维码的字符串</param>
/// <param name="width">宽</param>
/// <param name="height">高</param>
/// <returns></returns>
private static Color32[] Encode(string formatStr, int width, int height)
{
//绘制二维码前进行一些设置
QrCodeEncodingOptions options = new QrCodeEncodingOptions();
//设置字符串转换格式,确保字符串信息保持正确
options.CharacterSet = "UTF-8";
//设置绘制区域的宽度和高度的像素值
options.Width = width;
options.Height = height;
//设置二维码边缘留白宽度(值越大留白宽度大,二维码就减小)
options.Margin = 1;
/*实例化字符串绘制二维码工具
* BarcodeFormat:条形码格式
* Options: 编码格式(支持的编码格式)
*/
var barcodeWriter = new BarcodeWriter { Format = BarcodeFormat.QR_CODE, Options = options };
//进行二维码绘制并进行返回图片的颜色数组信息
return barcodeWriter.Write(formatStr);
}
#endregion
#region
void StartScanQRCode(Action<string> callback)
{
#if UNITY_WEBGL
if (LoadDll.m_bInWX)
{
ScanCodeOption sco = new ScanCodeOption();
sco.success = (rs) => { Debug.Log($"Cam Scan success {rs.result}\n {rs.path}\n {rs.rawData}"); callback(rs.rawData); };
sco.fail = (rs) => { Debug.Log($"Cam Scan fail {rs.errMsg}"); callback(""); };
WX.ScanCode(sco);
Debug.Log("WX Scan ScanCode");
}
else
{
Debug.Log("WebGL Scan Not Ready");
}
#endif
}
//开启关闭扫描二维码
void OpenScanQRCode()
{
if (isOpen)
{
//开启状态,需要关闭扫描
ani.Play("CloseScan", 0, 0);
//CancelInvoke("CheckQRCode");
Debug.Log("CloseScan ");
}
else
{
//关闭状态,需要开启扫描
//开始扫描
ani.Play("OpenScan", 0, 0);
//以秒为单位调用方法
//InvokeRepeating("CheckQRCode", 0, m_delayTime);
Debug.Log("OpenScan ");
}
isOpen = !isOpen;
}
#endregion
#region
/// <summary>
/// 检索二维码方法
/// </summary>
public void CheckQRCode()
{
//存储摄像头画面信息贴图转换的颜色数组
Color32[] m_colorData = m_webCameraTexture.GetPixels32();
//将画面中的二维码信息检索出来
var tResult = m_barcodeRender.Decode(m_colorData, m_webCameraTexture.width, m_webCameraTexture.height);
if (tResult != null)
{
//Application.OpenURL(tResult.Text);
Debug.Log(tResult.Text);
}
else
{
Debug.Log("CheckQRCode Error");
}
}
#endregion
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2cb2f34d7a8b866419efaa2e0b6b30cc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using UnityEngine;
namespace XGame
{
/// <summary>
/// ALgorithm相关的实用函数。
/// </summary>
public static partial class Utility
{
public static void Swap<T>(ref T x, ref T y)
{
T t = x;
x = y;
y = t;
}
/// <summary>
/// 递归求组合(从n个不同元素中取出m个元素组合)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list">结果列表</param>
/// <param name="arr">所求数组</param>
/// <param name="n">辅助变量</param>
/// <param name="m">辅助变量</param>
/// <param name="pos">辅助下标存储数组</param>
/// <param name="M">辅助变量</param>
public static void GetCombination<T>(ref List<T[]> list, T[] arr, int n, int m, int[] pos, int M)
{
for (int i = n; i >= m; i--)
{
pos[m - 1] = i - 1;
if (m > 1)
{
GetCombination(ref list, arr, i - 1, m - 1, pos, M);
}
else
{
T[] temp = new T[M];
for (int j = 0; j < M; j++)
{
temp[j] = arr[pos[j]];
}
if (list == null)
{
list = new List<T[]>();
}
list.Add(temp);
}
}
}
/// <summary>
/// 数组中n个元素的组合
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="arr">所求数组</param>
/// <param name="n">元素个数</param>
/// <returns>组合结果列表</returns>
public static List<T[]> GetCombination<T>(T[] arr, int n)
{
if (arr.Length < n)
{
return null;
}
List<T[]> list = new List<T[]>();
GetCombination(ref list, arr, arr.Length, n, new int[n], n);
return list;
}
/// <summary>
/// 递归求排列(从n个不同元素中取出m个元素排列)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="result">结果列表</param>
/// <param name="list">所求数组</param>
/// <param name="start">起始标号</param>
/// <param name="end">结束标号</param>
public static void GetPermutation<T>(ref List<T[]> list, T[] arr, int start, int end)
{
if (start == end)
{
T[] temp = new T[arr.Length];
arr.CopyTo(temp, 0);
if (list == null)
{
list = new List<T[]>();
}
list.Add(temp);
}
for (int i = start; i <= end; i++)
{
Swap(ref arr[i], ref arr[start]);
GetPermutation(ref list, arr, start + 1, end);
Swap(ref arr[i], ref arr[start]);
}
}
/// <summary>
/// 数组n个元素的排列
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="arr">所求数组</param>
/// <param name="n">元素个数</param>
/// <returns>排列结果列表</returns>
public static List<T[]> GetPermutation<T>(T[] arr, int n)
{
if (arr.Length < n)
{
return null;
}
List<T[]> list = new List<T[]>();
List<T[]> comList = GetCombination(arr, n);
foreach (var com in comList)
{
List<T[]> perList = new List<T[]>();
GetPermutation(ref perList, com, 0, n - 1);
list.AddRange(perList);
}
return list;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f3e3e37167b4bed44b47cbfee57b40fe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,526 @@
using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;
namespace XGame
{
public class Type_Null
{
public static int Reserve = 0;
}
public static partial class Utility
{
//private static float FLOAT_PRECISION = 1e-5f;
private static Dictionary<string, int> sActorIdDic = new Dictionary<string, int>();
private static Dictionary<string, Type> sTypeDic = new Dictionary<string, Type>();
private static Dictionary<string, Assembly> Asms = new Dictionary<string, Assembly>();
private static Type typeNull = typeof(Type_Null);
public static int GenClientNameId(string actorTypeName)
{
if (sActorIdDic.ContainsKey(actorTypeName) == false)
{
sActorIdDic.Add(actorTypeName, 0);
}
++sActorIdDic[actorTypeName];
return sActorIdDic[actorTypeName];
}
static Type SuperGetType(string sTypeName)
{
Type typeValue;
if (sTypeDic.TryGetValue(sTypeName, out typeValue))
{
if (typeValue == typeNull)
return null;
else
return typeValue;
}
else
{
typeValue = Type.GetType(sTypeName);//底包的类型有就不用下面的麻烦代码
if (typeValue != null)
{
sTypeDic[sTypeName] = typeValue;
//Debug.Log($"SuperGetType sTypeDic 1 : {sTypeName}");
return typeValue;
}
Assembly[] foundAsms = null;
if (Asms.Count == 0)
{
foundAsms = AppDomain.CurrentDomain.GetAssemblies();
foreach (var asm in foundAsms)
{
//只检查GYFramework 和Assembly-CSharp 热更相关的dll
//Debug.Log($"SuperGetType : {sTypeName} ({asm.GetName().Name})");
string asmName = asm.GetName().Name;
if (asmName == "GYFramework" || asmName == "Assembly-CSharp")
{
Asms[asmName] = asm;
}
}
}
foreach (var asm in Asms)
{
typeValue = asm.Value.GetType(sTypeName);
if (typeValue != null)
{
sTypeDic[sTypeName] = typeValue;
//Debug.Log($"SuperGetType sTypeDic 2 : {sTypeName}");
return typeValue;
}
}
//最后全量查找
if (null == foundAsms)
{
foundAsms = AppDomain.CurrentDomain.GetAssemblies();
}
foreach (var asm in foundAsms)
{
string asmName = asm.GetName().Name;
typeValue = asm.GetType(sTypeName);
if (typeValue != null)
{
Asms[asmName] = asm;
sTypeDic[sTypeName] = typeValue;
//Debug.Log($"SuperGetType sTypeDic 3: {sTypeName}");
return typeValue;
}
}
sTypeDic[sTypeName] = typeNull;
//Debug.Log($"SuperGetType Error : {sTypeName} == null");
}
return null;
}
public static Type GetTypeByTypeName(string typeName)
{
System.Type type = SuperGetType(typeName);//Type.GetType(typeName);//
if (null == type)
{
string newTypeName = "XGame" + "." + typeName;
type = SuperGetType(newTypeName); //Type.GetType(newTypeName);//
//if (null == type)
//{
// newTypeName = "XGame" + "." + typeName;
// type = SuperGetType(newTypeName); //Type.GetType(newTypeName);//
//}
}
return type;
}
public static Type GetTypeByTypeName<BaseType>(string typeName) where BaseType : class
{
System.Type type = Type.GetType(typeName);
if (type == null)
{
string newTypeName = "XGame" + "." + typeName;
type = Type.GetType(newTypeName);
//if (type == null)
//{
// newTypeName = "XGame" + "." + typeName;
// type = Type.GetType(newTypeName);
//}
}
if (type == null)
{
Debug.LogError("GetTypeByTypeName typeName:{0} get type return null");
return null;
}
if (!typeof(BaseType).IsAssignableFrom(type))
{
Debug.LogError($"GetTypeByTypeName typeName:{typeName} is not subclass of {typeof(BaseType).FullName}");
return null;
}
return type;
}
/// <summary>
/// 判断指定的类型 <paramref name="type"/> 是否是指定泛型类型的子类型,或实现了指定泛型接口。
/// </summary>
/// <param name="type">需要测试的类型。</param>
/// <param name="generic">泛型接口类型,传入 typeof(IXxx)</param>
/// <returns>如果是泛型接口的子类型,则返回 true,否则返回 false。</returns>
public static bool HasImplementedRawGeneric(this Type type, Type generic)
{
if (type == null) throw new ArgumentNullException(nameof(type));
if (generic == null) throw new ArgumentNullException(nameof(generic));
// 测试接口。
var isTheRawGenericType = type.GetInterfaces().Any(IsTheRawGenericType);
if (isTheRawGenericType) return true;
// 测试类型。
while (type != null && type != typeof(object))
{
isTheRawGenericType = IsTheRawGenericType(type);
if (isTheRawGenericType) return true;
type = type.BaseType;
}
// 没有找到任何匹配的接口或类型。
return false;
// 测试某个类型是否是指定的原始接口。
bool IsTheRawGenericType(Type test)
=> generic == (test.IsGenericType ? test.GetGenericTypeDefinition() : test);
}
public static object GetPropValue(object obj, String name)
{
foreach (String part in name.Split('.'))
{
if (obj == null)
{
return null;
}
Type type = obj.GetType();
PropertyInfo info = type.GetProperty(part);
if (info == null)
{
return null;
}
obj = info.GetValue(obj, null);
}
return obj;
}
public static T GetPropValue<T>(object obj, String name)
{
object retval = GetPropValue(obj, name);
if (retval == null)
{
return default(T);
}
// throws InvalidCastException if types are incompatible
return (T)retval;
}
public static object GetFieldValue(object obj, String name)
{
foreach (String part in name.Split('.'))
{
if (obj == null)
{
return null;
}
Type type = obj.GetType();
FieldInfo info = type.GetField(part);
if (info == null)
{
return null;
}
obj = info.GetValue(obj);
}
return obj;
}
public static T GetFieldValue<T>(object obj, String name)
{
object retval = GetFieldValue(obj, name);
if (retval == null)
{
return default(T);
}
// throws InvalidCastException if types are incompatible
return (T)retval;
}
public static T CreateInstance<T>(string typeName, params object[] args) where T : class
{
if (string.IsNullOrEmpty(typeName) || typeName == "")
{
typeName = typeof(T).FullName;
}
Type type = Type.GetType(typeName);
if (type == null)
{
Debug.LogError($"Get Type from type name:{type} return null");
return null;
}
if (typeof(T).IsAssignableFrom(type) == false)
{
Debug.LogError($"{type} is not assignable from {typeof(T).Name}");
return null;
}
T instance = Activator.CreateInstance(type, args) as T;
return instance;
}
public static object CopyObject(object srcObject)
{
Type type = srcObject.GetType();
object newObject = Activator.CreateInstance(type);
FieldInfo[] fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public
| BindingFlags.Instance | BindingFlags.Static);
for (int i = 0; i < fields.Length; ++i)
{
FieldInfo fi = fields[i];
fi.SetValue(newObject, fi.GetValue(srcObject));
}
PropertyInfo[] props = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Public
| BindingFlags.Instance | BindingFlags.Static);
for (int i = 0; i < props.Length; ++i)
{
PropertyInfo fi = props[i];
fi.SetValue(newObject, fi.GetValue(srcObject));
}
return newObject;
}
public static bool CopyObject(object srcObject, object targetObject)
{
Type srcType = srcObject.GetType();
Type targetType = targetObject.GetType();
if (srcType != targetType)
{
return false;
}
FieldInfo[] fields = srcType.GetFields(BindingFlags.NonPublic | BindingFlags.Public
| BindingFlags.Instance | BindingFlags.Static);
for (int i = 0; i < fields.Length; ++i)
{
FieldInfo fi = fields[i];
fi.SetValue(targetObject, fi.GetValue(srcObject));
}
PropertyInfo[] props = srcType.GetProperties(BindingFlags.NonPublic | BindingFlags.Public
| BindingFlags.Instance | BindingFlags.Static);
for (int i = 0; i < props.Length; ++i)
{
PropertyInfo fi = props[i];
fi.SetValue(targetObject, fi.GetValue(srcObject));
}
return true;
}
public static object CopyFields(object src)
{
Type t = src.GetType();
object res = Activator.CreateInstance(t);
FieldInfo[] list = t.GetFields();
for (int i = 0; i < list.Length; ++i)
{
FieldInfo fi = list[i];
fi.SetValue(res, fi.GetValue(src));
}
return res;
}
public static T ParseEnum<T>(string value, T defaultValue) where T : struct
{
T v;
return Enum.TryParse<T>(value, true, out v) ? v : defaultValue;
}
public static void ThrowError(string fmt, params object[] args)
{
string msg = String.Format(fmt, args);
throw new Exception(msg);
}
/// <summary>
/// 计算字符串的MD5值
/// </summary>
public static string GetStringMd5(string source)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] data = System.Text.Encoding.UTF8.GetBytes(source);
byte[] md5Data = md5.ComputeHash(data, 0, data.Length);
md5.Clear();
string destString = "";
for (int i = 0; i < md5Data.Length; i++)
{
destString += System.Convert.ToString(md5Data[i], 16).PadLeft(2, '0');
}
destString = destString.PadLeft(32, '0');
return destString.ToUpper();
}
/// <summary>
/// 计算文件的MD5值
/// </summary>
public static string GetFileMd5(string file)
{
try
{
FileStream fs = new FileStream(file, FileMode.Open);
System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(fs);
fs.Close();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
catch (Exception ex)
{
throw new Exception("md5file() fail, error:" + ex.Message);
}
}
public static string GetBytesMd5(byte[] bytes)
{
System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(bytes);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
public static long GetTimeTick()
{
var ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalMilliseconds);
}
public static double XWorldGetTime()
{
return Time.realtimeSinceStartupAsDouble;
}
public static bool IsPossibleSimulator()
{
if (Application.isEditor)
{
return false;
}
bool isSimulator = false;
isSimulator = isSimulator || SystemInfo.graphicsDeviceName == "Netease";
isSimulator = isSimulator || SystemInfo.deviceModel == "Netease MuMu";
string processorType = SystemInfo.processorType.ToLower();
isSimulator = isSimulator || processorType.Contains("intel") || processorType.Contains("amd");
return isSimulator;
}
// 格式化文件大小
private static string[] sSuffix = { "B", "KB", "MB", "GB", "TB" };
public static string FormatBytesStr(long bytes)
{
float size = Convert.ToSingle(bytes);
int sufIdx = 0;
for(sufIdx = 0; sufIdx < sSuffix.Length; sufIdx++)
{
if(size >= 1024)
{
size = Mathf.Ceil(size / 1024);
continue;
}
else
{
break;
}
}
string format = size + sSuffix[sufIdx];
return format;
}
public static bool Contains<T>(T[] array, T value) where T : class
{
for (int i = 0; i < array.Length; ++i)
{
if (array[i] == value)
{
return true;
}
}
return false;
}
public static bool Contains(string[] array, string value)
{
for (int i = 0; i < array.Length; ++i)
{
if (array[i].CompareTo(value) == 0)
{
return true;
}
}
return false;
}
public static int RandomRangeToInt(int min,int max)
{
return UnityEngine.Random.Range(min,max);
}
public static void CreateMulDirectory(string path)
{
if (Directory.Exists(path))
return;
int n = path.LastIndexOf('/');
if(n == -1)
n = path.LastIndexOf('\\');
if (n == -1)
{
Directory.CreateDirectory(path);
return;
}
string subpath = path.Substring(0, n);
if (Directory.Exists(subpath))
{
Directory.CreateDirectory(path);
}
else
{
CreateMulDirectory(subpath);
Directory.CreateDirectory(path);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 13fe870d13c1c494980ac1fb9062d173
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,740 @@
using System;
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using DG.Tweening;
using XLua;
namespace XGame
{
[LuaCallCSharp]
public static partial class Utility
{
private static readonly List<Transform> mTempList = new List<Transform>();
public static void DestroyUnityObject(UnityEngine.Object unityObject)
{
if (unityObject != null)
{
UnityEngine.Object.Destroy(unityObject);
}
}
public static void DestroyUnityObjectImmediate(UnityEngine.Object unityObject)
{
if (unityObject != null)
{
UnityEngine.Object.DestroyImmediate(unityObject);
}
}
public static GameObject CreateGameObject(GameObject parent, string name)
{
GameObject go = new GameObject(name);
if (parent != null)
{
go.transform.parent = parent.transform;
}
NormalizeTransform(go.transform);
return go;
}
public static GameObject NewGameObeject(string name)
{
return new GameObject(name);
}
//gameobject ops
//create a child gameobject under the parent ,then normilize its transform
public static GameObject CreateChildGameObject(GameObject parent, string name)
{
GameObject go = new GameObject(name);
if (parent != null)
{
go.transform.parent = parent.transform;
}
NormalizeTransform(go.transform);
return go;
}
public static bool DestroyChildren(Transform transform)
{
if (transform == null || transform.childCount == 0)
{
return false;
}
List<Transform> childTransformList = new List<Transform>();
foreach (Transform child in transform)
{
childTransformList.Add(child);
}
for (int i = 0; i < childTransformList.Count; i++)
{
childTransformList[i].parent = null;
DestroyUnityObject(childTransformList[i].gameObject);
}
childTransformList.Clear();
return true;
}
//normalize an transform
public static void NormalizeTransform(Transform transform)
{
transform.localPosition = Vector3.zero;
transform.localRotation = Quaternion.identity;
transform.localScale = Vector3.one;
}
public static T FindObjectInScene<T>() where T : UnityEngine.Object
{
T component = UnityEngine.Object.FindObjectOfType<T>() as T;
return component;
}
public static bool IsActive(this GameObject gameObject)
{
if (gameObject == null)
{
return false;
}
if (gameObject.activeSelf)
{
return gameObject.transform.localScale == Vector3.one;
}
return false;
}
public static void SetActiveByScale(this Component component, bool active)
{
if (null == component) { return; }
component.transform.localScale = active ? Vector3.one : Vector3.zero;
}
public static void SetActiveByScale(this GameObject component, bool active)
{
if (null == component) { return; }
component.transform.localScale = active ? Vector3.one : Vector3.zero;
}
public static void SetActiveEx(this Transform t, bool active)
{
if (null == t) { return; }
t.gameObject.SetActiveEx(active);
}
public static void SetActiveEx(this Component component, bool active)
{
if (null == component) { return; }
if (component.gameObject.activeSelf != active)
{
component.gameObject.SetActive(active);
}
}
public static bool SetActiveEx(this GameObject gameObject, bool active)
{
if (gameObject == null)
{
return false;
}
if (gameObject.activeSelf != active)
{
gameObject.SetActive(active);
}
return true;
}
/// <summary>
/// 通过缩放大小 隐藏
/// </summary>
/// <param name="gameObject"></param>
/// <param name="active"></param>
/// <returns></returns>
public static bool SetActiveExTwo(this GameObject gameObject, bool active)
{
if (gameObject == null)
{
return false;
}
//强制active
if (gameObject.activeSelf == false)
{
gameObject.SetActive(true);
}
if (active)
{
gameObject.transform.localScale = Vector3.one;
}
else
{
gameObject.transform.localScale = Vector3.zero;
}
return true;
}
public static bool SetActiveExTwo(this Component comp, bool active)
{
if (comp == null)
{
return false;
}
SetActiveExTwo(comp.gameObject, active);
return true;
}
public static bool SetActive3(this Transform t, bool active)
{
return SetActive3(t.gameObject, active);
}
/// <summary>
/// 通过把位置挪出屏幕外 隐藏
/// </summary>
/// <param name="gameObject"></param>
/// <param name="active"></param>
/// <returns></returns>
public static bool SetActive3(this GameObject gameObject, bool active)
{
if (gameObject == null)
{
return false;
}
//gameObject.SetActiveEx(active);
//CanvasGroup g = gameObject.GetComponent<CanvasGroup>();
//if (g == null)
//{
// g = gameObject.AddComponent<CanvasGroup>();
//}
//g.alpha = active ? 1 : 0;
//g.interactable = active;
//g.blocksRaycasts = active;
//Canvas[] canvases = gameObject.GetComponentsInChildren<Canvas>();
//int toLayer = LayerMask.NameToLayer(active ? "UI" : "InVisible");
//for (int i = 0; i < canvases.Length; i++)
//{
// canvases[i].gameObject.layer = toLayer;
//}
//MeshRenderer[] mrs = gameObject.GetComponentsInChildren<MeshRenderer>();
//for (int i = 0; i < mrs.Length; i++)
//{
// mrs[i].enabled = active;
//}
//UiEffect[] effects = gameObject.GetComponentsInChildren<UiEffect>();
//for (int i = 0; i < effects.Length; i++)
//{
// effects[i].gameObject.layer = toLayer;
//}
//gameObject.SetActiveEx(active);
Vector3 pos = gameObject.transform.localPosition;
gameObject.transform.localPosition = new Vector3(pos.x, pos.y, active ? 0 : 99999);
return true;
}
/// <summary>
/// 是否隐藏了
/// </summary>
/// <param name="gameObject"></param>
/// <returns></returns>
public static bool IsHide(this GameObject gameObject)
{
return !gameObject.activeSelf || gameObject.transform.localScale == Vector3.zero || gameObject.transform.localPosition.z >= 99999;
}
public static bool IsHide(this Transform t)
{
return !t.gameObject.activeSelf || t.localScale == Vector3.zero || t.localPosition.z >= 99999;
}
public static GameObject[] GetChildren(this GameObject gameObject)
{
List<GameObject> children = new List<GameObject>();
foreach (Transform child in gameObject.transform)
{
children.Add(child.gameObject);
}
return children.ToArray();
}
public static GameObject FindGameObject(this GameObject go, string name)
{
return !go ? null : go.transform.FindGameObject(name);
}
public static GameObject FindGameObject(this Transform tf, string name)
{
Transform targetTransform = tf.FindTransform(name);
return targetTransform ? targetTransform.gameObject : null;
}
public static Transform FindTransform(this GameObject go, string name)
{
return !go ? null : go.transform.FindTransform(name);
}
public static Transform FindTransform(this Transform tf, string name)
{
if (!tf)
{
return null;
}
if (string.IsNullOrEmpty(name))
{
return null;
}
mTempList.Clear();
mTempList.Add(tf);
int index = 0;
while (mTempList.Count > index)
{
Transform transform = mTempList[index++];
for (int i = 0; i < transform.childCount; ++i)
{
Transform childTransform = transform.GetChild(i);
if (childTransform.name == name)
{
return childTransform;
}
mTempList.Add(childTransform);
}
}
return null;
}
public static T FindComponent<T>(this GameObject go, string name) where T : Component
{
if (go == null)
{
return null;
}
return go.transform.FindComponent<T>(name);
}
public static T FindComponent<T>(this Transform tf, string name) where T : Component
{
if (tf == null)
{
return null;
}
Transform target = tf.FindTransform(name);
if (target == null)
{
return null;
}
return target.GetComponent<T>();
}
public static Component GetOrAddComponent(this GameObject GO, string typeName)
{
if (string.IsNullOrEmpty(typeName))
{
Debug.LogError("GetOrAddComponent typeName is null");
return null;
}
Type componentType = Utility.GetTypeByTypeName(typeName);
if (componentType == null)
{
Debug.LogError($"GetOrAddComponent componentType is null, typeName:{typeName}");
return null;
}
Component result = null;
if (!GO) return result;
result = GO.GetComponent(componentType);
if (!result)
{
result = GO.AddComponent(componentType);
}
return result;
}
public static T GetOrAddComponent<T>(this GameObject GO) where T : UnityEngine.Component
{
T result = null;
if (!GO) return result;
result = GO.GetComponent<T>();
if (!result)
{
result = GO.AddComponent<T>();
}
return result;
}
public static GameObject[] GetAllChildrenGameObjects(this GameObject go)
{
Transform[] allTrans = go.GetComponentsInChildren<Transform>();
List<GameObject> allGOs = new List<GameObject>();
for (int i = 0; i < allTrans.Length; ++i)
{
allGOs.Add(allTrans[i].gameObject);
}
return allGOs.ToArray();
}
public static Transform FindSocketTransform(GameObject go, string socketName)
{
if (string.IsNullOrEmpty(socketName))
{
return null;
}
Transform socketTrans = null;
Transform[] childrenTrans = go.transform.GetComponentsInChildren<Transform>(true);
int count = childrenTrans != null ? childrenTrans.Length : 0;
for (int i = 0; i < count; i++)
{
if (childrenTrans[i] != null && childrenTrans[i].name == socketName)
{
socketTrans = childrenTrans[i];
break;
}
}
return socketTrans;
}
public static void SetPosition(this GameObject go, float x, float y, float z)
{
if (go == null)
{
Debug.LogError("Utility SetPosition go is null");
return;
}
go.transform.position = new Vector3(x, y, z);
}
public static void SetPosition(this Transform trans, float x, float y, float z)
{
if (trans == null)
{
Debug.LogError("Utility SetPosition trans is null");
return;
}
trans.position = new Vector3(x, y, z);
}
public static void SetLocalPosition(this GameObject go, float x, float y, float z)
{
if (go == null)
{
Debug.LogError("Utility SetLocalPosition go is null");
return;
}
go.transform.localPosition = new Vector3(x, y, z);
}
public static void SetLocalPosition(this Transform trans, float x, float y, float z)
{
if (trans == null)
{
Debug.LogError("Utility SetLocalPosition trans is null");
return;
}
trans.localPosition = new Vector3(x, y, z);
}
public static void SetRotation(this GameObject go, float x, float y, float z, float w)
{
if (go == null)
{
Debug.LogError("Utility SetRotation go is null");
return;
}
go.transform.rotation = new Quaternion(x, y, z, w);
}
public static void SetRotation(this Transform trans, float x, float y, float z, float w)
{
if (trans == null)
{
Debug.LogError("Utility SetRotation trans is null");
return;
}
trans.rotation = new Quaternion(x, y, z, w);
}
public static void SetLocalRotation(this GameObject go, float x, float y, float z, float w)
{
if (go == null)
{
Debug.LogError("Utility SetLocalRotation go is null");
return;
}
go.transform.localRotation = new Quaternion(x, y, z, w);
}
public static void SetLocalRotation(this Transform trans, float x, float y, float z, float w)
{
if (trans == null)
{
Debug.LogError("Utility SetLocalRotation trans is null");
return;
}
trans.localRotation = new Quaternion(x, y, z, w);
}
public static void SetLocalEulerAngles(this GameObject go, float x, float y, float z)
{
if (go == null)
{
Debug.LogError("Utility SetLocalEulerAngles go is null");
return;
}
go.transform.localEulerAngles = new Vector3(x, y, z);
}
public static void SetLocalEulerAngles(this Transform trans, float x, float y, float z)
{
if (trans == null)
{
Debug.LogError("Utility SetLocalEulerAngles trans is null");
return;
}
trans.localEulerAngles = new Vector3(x, y, z);
}
public static void SetLocalScale(this GameObject go, float x, float y, float z)
{
if (go == null)
{
Debug.LogError("Utility SetLocalScale go is null");
return;
}
go.transform.localScale = new Vector3(x, y, z);
}
public static void SetLocalScale(this Transform trans, float x, float y, float z)
{
if (trans == null)
{
Debug.LogError("Utility SetLocalScale trans is null");
return;
}
trans.localScale = new Vector3(x, y, z);
}
public static void SetLocalScale(this Transform trans, float scale)
{
if (trans == null)
{
Debug.LogError("Utility SetLocalScale trans is null");
return;
}
trans.localScale = new Vector3(scale, scale, scale);
}
public static DG.Tweening.Core.TweenerCore<Vector3, Vector3, DG.Tweening.Plugins.Options.VectorOptions> DOLocalMove(this Transform trans,float x,float y,float z,float duration,bool snapping = false)
{
return trans.DOLocalMove(new Vector3(x, y, z), duration, snapping);
}
#region
public static float GetPosition(this Transform t, out float y, out float z)
{
Vector3 position = t.position;
y = position.y;
z = position.z;
return t.position.x;
}
public static float GetPosition(this GameObject t, out float y, out float z)
{
return t.transform.GetPosition(out y,out z);
}
public static float GetLocalPosition(this Transform t, out float y, out float z)
{
Vector3 position = t.localPosition;
y = position.y;
z = position.z;
return position.x;
}
public static float GetLocalPosition(this GameObject t, out float y, out float z)
{
return t.transform.GetLocalPosition(out y, out z);
}
public static void GetLocalScale(this Transform t, out float x, out float y, out float z)
{
x = t.localScale.x;
y = t.localScale.y;
z = t.localScale.z;
}
public static void GetLocalScale(this GameObject t, out float x, out float y, out float z)
{
t.transform.GetLocalScale(out x,out y, out z);
}
public static void GetRotation(this Transform t, out float x, out float y, out float z, out float w)
{
x = t.rotation.x;
y = t.rotation.y;
z = t.rotation.z;
w = t.rotation.w;
}
public static void GetRotation(this GameObject o, out float x, out float y, out float z, out float w)
{
o.transform.GetRotation(out x, out y, out z, out w);
}
public static void GetLocalRotation(this Transform t, out float x, out float y, out float z, out float w)
{
x = t.localRotation.x;
y = t.localRotation.y;
z = t.localRotation.z;
w = t.localRotation.w;
}
public static void GetLocalRotation(this GameObject o, out float x, out float y, out float z, out float w)
{
o.transform.GetLocalRotation(out x, out y, out z, out w);
}
public static void GetEulerAngle(this Transform t, out float x, out float y, out float z)
{
x = t.eulerAngles.x;
y = t.eulerAngles.y;
z = t.eulerAngles.z;
}
public static void GetEulerAngle(this GameObject o, out float x, out float y, out float z)
{
o.transform.GetEulerAngle(out x, out y, out z);
}
public static void GetLocalEulerAngle(this Transform t, out float x, out float y, out float z)
{
x = t.localEulerAngles.x;
y = t.localEulerAngles.y;
z = t.localEulerAngles.z;
}
public static void GetLocalEulerAngle(this GameObject o, out float x, out float y, out float z)
{
o.transform.GetLocalEulerAngle(out x, out y, out z);
}
public static void GetAnchoredPosition(this RectTransform t, out float x, out float y)
{
x = t.anchoredPosition.x;
y = t.anchoredPosition.y;
}
public static bool IsActive(this Transform t)
{
return t.gameObject.IsActive();
}
#endregion
public static bool Exist(this UnityEngine.Object obj)
{
return obj;
}
public static bool IsUnityObject(object unityObject)
{
if (unityObject != null)
{
if (unityObject is UnityEngine.Object)
{
return true;
}
}
return false;
}
public static Component GetComponent(this Component component, string asm, string typeName)
{
var gen_ret = component.GetComponent(typeName);
if (gen_ret != null)
return gen_ret;
System.Type componentType = Utility.GetTypeByTypeName(typeName);
if (componentType == null)
{
#if ENV_INTRANET
Debug.LogWarning($"GetType('{typeName}') Failed!! componentName:{component.name}");
#endif
return null;
}
gen_ret = component.GetComponent(componentType);
if (gen_ret == null)
{
#if ENV_INTRANET
Debug.LogWarning($"{component.name}.GetComponent({typeName}) Failed!!");
#endif
}
return gen_ret;
}
public static Component GetComponent(this GameObject gameObject, string asm, string typeName)
{
var gen_ret = gameObject.GetComponent(typeName);
if (gen_ret != null)
return gen_ret;
System.Type componentType = Utility.GetTypeByTypeName(typeName);
if (componentType == null)
{
#if ENV_INTRANET
Debug.LogWarning($"GetType('{typeName}') Failed!! objectName:{gameObject.name}");
#endif
return null;
}
gen_ret = gameObject.GetComponent(componentType);
if (gen_ret == null)
{
#if ENV_INTRANET
Debug.LogWarning($"Go.GetComponent({typeName}) Failed!!");
#endif
}
return gen_ret;
}
//防止代码剪裁
//private static void PreventCodeClipping(GameObject obj)
//{
// Empty4Raycast a = obj.GetComponent<Empty4Raycast>();
//}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 33dfc8d859349a34d850ed113ea7dd81
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,40 @@
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
namespace XWorld
{
//协程等待对话框关闭
public class WaitForDialogClose : CustomYieldInstruction
{
private bool _isClosed;
public override bool keepWaiting => !_isClosed; // 对话框未关闭时持续等待
public void OnDialogClosed() => _isClosed = true;
}
public class WaitDialogController
{
// 关闭事件(网页4的消息管理思想)
public UnityEvent OnClose;
WaitForDialogClose waitObj;
public void CloseDialog()
{
waitObj?.OnDialogClosed();
}
IEnumerator ShowDialogCoroutine(Button CloseButton)
{
CloseButton.onClick.AddListener(() =>
{
CloseDialog();
});
waitObj = new WaitForDialogClose();
yield return waitObj; // 协程在此处暂停,直到对话框关闭
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e75e501321e37b1419f7efa1b3baabe8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+105
View File
@@ -0,0 +1,105 @@
#if UNITY_WEBGL
using WeChatWASM;
#endif
public static class XData
{
//存储
public static void DeleteAll()
{
#if UNITY_WEBGL
if (GlobalData.bWX)
WX.StorageDeleteAllSync();
else
PlayerPrefs.DeleteAll();
#endif
UnityEngine.PlayerPrefs.DeleteAll();
}
public static void DeleteKey(string key)
{
#if UNITY_WEBGL
if (GlobalData.bWX)
WX.StorageDeleteKeySync(key);
else
PlayerPrefs.DeleteKey(key);
#endif
UnityEngine.PlayerPrefs.DeleteKey(key);
}
public static float GetFloat(string key, float defaultValue = 0)
{
#if UNITY_WEBGL
if (GlobalData.bWX)
return WX.StorageGetFloatSync(key, defaultValue);
else
PlayerPrefs.GetFloat(key, defaultValue);
#endif
return UnityEngine.PlayerPrefs.GetFloat(key, defaultValue);
}
public static int GetInt(string key, int defaultValue = 0)
{
#if UNITY_WEBGL
if (GlobalData.bWX)
return WX.StorageGetIntSync(key, defaultValue);
else
return PlayerPrefs.GetInt(key, defaultValue);
#endif
return UnityEngine.PlayerPrefs.GetInt(key, defaultValue);
}
public static string GetString(string key, string defaultValue = "")
{
#if UNITY_WEBGL
if (GlobalData.bWX)
return WX.StorageGetStringSync(key, defaultValue);
else
return PlayerPrefs.GetString(key, defaultValue);
#endif
return UnityEngine.PlayerPrefs.GetString(key, defaultValue);
}
public static bool HasKey(string key)
{
#if UNITY_WEBGL
if (GlobalData.bWX)
return WX.StorageHasKeySync(key);
else
return PlayerPrefs.HasKey(key);
#endif
return UnityEngine.PlayerPrefs.HasKey(key);
}
public static void Save()
{
if (!GlobalData.bWX)
UnityEngine.PlayerPrefs.Save();
//微信不需要
}
public static void SetFloat(string key, float value)
{
#if UNITY_WEBGL
if (GlobalData.bWX)
WX.StorageSetFloatSync(key,value);
else
PlayerPrefs.SetFloat(key, value);
#endif
UnityEngine.PlayerPrefs.SetFloat(key, value);
}
public static void SetInt(string key, int value)
{
#if UNITY_WEBGL
if (GlobalData.bWX)
WX.StorageSetIntSync(key, value);
else
PlayerPrefs.SetInt(key, value);
#endif
UnityEngine.PlayerPrefs.SetInt(key, value);
}
public static void SetString(string key, string value)
{
#if UNITY_WEBGL
if (GlobalData.bWX)
WX.StorageSetStringSync(key, value);
else
PlayerPrefs.SetString(key, value);
#endif
UnityEngine.PlayerPrefs.SetString(key, value);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 769d032f308771040b3665df4e92ee9a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,101 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace XGame
{
public class XProgress
{
Transform m_trLoading = null;
Slider m_Slider;
int m_Aim = 0;
int m_Cur = 0;
float m_fLastTime = 0;
//float m_fTimePerOne;
bool m_bShow = false;
public XProgress()
{
GameObject obj = GameObject.Find("Main");
Transform tr = obj.transform;
for (int i = 0; i < tr.childCount; ++i)
{
Transform child = tr.GetChild(i);
if (child.name == "Loading")
{
m_trLoading = child;
break;
}
}
m_trLoading.gameObject.SetActive(m_bShow);
if (m_trLoading != null)
{
for (int i = 0; i < m_trLoading.childCount; ++i)
{
Transform child = m_trLoading.GetChild(i);
m_Slider = child.GetComponent<Slider>();
if (m_Slider != null)
{
m_Slider.maxValue = 100;
m_Slider.minValue = 0;
break;
}
}
}
}
// Start is called before the first frame update
public void Show(bool bShow)
{
m_bShow = bShow;
}
public void ChangeSlider(Slider slider)
{
m_Slider = slider;
}
//1-100
public void Set(int percent)
{
if (!m_bShow)
return;
if (m_Cur == 0 && percent > 0)
{//µÚÒ»´Î
m_trLoading.gameObject.SetActive(true);
m_fLastTime = Time.realtimeSinceStartup;
//m_fTimePerOne = 0.1f;
m_Cur = 1;
}
else if (percent < m_Cur)
{
m_Cur = percent;
}
m_Aim = percent;
}
// Update is called once per frame
public void Update()
{
if (m_Cur >= 100)
{
m_trLoading.gameObject.SetActive(false);
m_Cur = 0;
m_Aim = 0;
}
else if (m_Aim > 0)
{//½øÐÐÖÐ
if (m_Aim > m_Cur)
{
if (m_Aim - m_Cur > 10)
m_Cur += (m_Aim - m_Cur)/10;
else
m_Cur++;
if (m_Slider != null)
{
m_Slider.value = m_Cur;
}
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5f20c9485a591ab41bf1c2c3359fa9b4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: