Initial commit: Client Doc docs Server Tools
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -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$"+初始登录name(SystemInfo.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$"+初始登录name(SystemInfo.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$"+初始登录name(SystemInfo.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:
|
||||
@@ -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:
|
||||
Reference in New Issue
Block a user