mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
Merge pull request #28 from ALEXTANGXIAO/TEngine_v_3.0.0
TEngine v 3.0.0
This commit is contained in:
3
Assets/GameScripts/HotFix/GameBase/GameTickWatcher.meta
Normal file
3
Assets/GameScripts/HotFix/GameBase/GameTickWatcher.meta
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b062b3e32edd4536a4308a3d180842e0
|
||||||
|
timeCreated: 1681989133
|
@@ -0,0 +1,40 @@
|
|||||||
|
using TEngine;
|
||||||
|
|
||||||
|
namespace GameBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 用来在多线程下检测耗时。
|
||||||
|
/// </summary>
|
||||||
|
public struct GameTickWatcher
|
||||||
|
{
|
||||||
|
private long _startTick;
|
||||||
|
|
||||||
|
public GameTickWatcher()
|
||||||
|
{
|
||||||
|
_startTick = System.DateTime.Now.Ticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Refresh()
|
||||||
|
{
|
||||||
|
_startTick = System.DateTime.Now.Ticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取用时。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public float ElapseTime()
|
||||||
|
{
|
||||||
|
long endTick = System.DateTime.Now.Ticks;
|
||||||
|
return (float)((endTick - _startTick) / 10000) / 1000.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 输出用时。
|
||||||
|
/// </summary>
|
||||||
|
public void LogUsedTime()
|
||||||
|
{
|
||||||
|
Log.Info($"Used Time: {this.ElapseTime()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7320165f7aa147a998a30fe2f7a5a5c2
|
||||||
|
timeCreated: 1681989139
|
8
Assets/GameScripts/HotFix/GameBase/Loom.meta
Normal file
8
Assets/GameScripts/HotFix/GameBase/Loom.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dab5f3e08b4367d41b801af29d381ca8
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
190
Assets/GameScripts/HotFix/GameBase/Loom/Loom.cs
Normal file
190
Assets/GameScripts/HotFix/GameBase/Loom/Loom.cs
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
//开启一个Loom进程
|
||||||
|
Loom.RunAsync(() =>
|
||||||
|
{
|
||||||
|
aucThread = new Thread(ReceiveMsg);
|
||||||
|
aucThread.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
//进程调用主线程方法
|
||||||
|
MainPack pack = (MainPack)MainPack.Descriptor.Parser.ParseFrom(buffer, 0, len);
|
||||||
|
Loom.QueueOnMainThread((param) =>
|
||||||
|
{
|
||||||
|
UdpHandleResponse(pack);
|
||||||
|
}, null);
|
||||||
|
|
||||||
|
*******************************************************************************/
|
||||||
|
namespace GameBase
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loom多线程通信。
|
||||||
|
/// <remarks></remarks>
|
||||||
|
/// </summary>
|
||||||
|
public class Loom : MonoBehaviour
|
||||||
|
{
|
||||||
|
public Dictionary<string, CancellationTokenSource> TokenSourcesDictionary = new Dictionary<string, CancellationTokenSource>();
|
||||||
|
private static readonly int MaxThreads = 8;
|
||||||
|
private static int _numThreads;
|
||||||
|
private static Loom _current;
|
||||||
|
|
||||||
|
public static Loom Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
return _current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Awake()
|
||||||
|
{
|
||||||
|
_current = this;
|
||||||
|
_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnDestroy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool _initialized;
|
||||||
|
|
||||||
|
private static void Initialize()
|
||||||
|
{
|
||||||
|
if (!_initialized)
|
||||||
|
{
|
||||||
|
if (!Application.isPlaying)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_initialized = true;
|
||||||
|
|
||||||
|
var obj = new GameObject("[Loom]");
|
||||||
|
|
||||||
|
_current = obj.AddComponent<Loom>();
|
||||||
|
|
||||||
|
DontDestroyOnLoad(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct NoDelayedQueueItem
|
||||||
|
{
|
||||||
|
public Action<object> Action;
|
||||||
|
public object Param;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly List<NoDelayedQueueItem> _actions = new List<NoDelayedQueueItem>();
|
||||||
|
|
||||||
|
public struct DelayedQueueItem
|
||||||
|
{
|
||||||
|
public float Time;
|
||||||
|
public Action<object> Action;
|
||||||
|
public object Param;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly List<DelayedQueueItem> _delayed = new List<DelayedQueueItem>();
|
||||||
|
|
||||||
|
private readonly List<DelayedQueueItem> _currentDelayed = new List<DelayedQueueItem>();
|
||||||
|
|
||||||
|
public static void QueueOnMainThread(Action<object> taction, object param, float time = 0f)
|
||||||
|
{
|
||||||
|
if (time != 0f)
|
||||||
|
{
|
||||||
|
lock (Current._delayed)
|
||||||
|
{
|
||||||
|
Current._delayed.Add(new DelayedQueueItem { Time = Time.time + time, Action = taction, Param = param });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lock (Current._actions)
|
||||||
|
{
|
||||||
|
Current._actions.Add(new NoDelayedQueueItem { Action = taction, Param = param });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Thread RunAsync(Action action)
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
while (_numThreads >= MaxThreads)
|
||||||
|
{
|
||||||
|
Thread.Sleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
Interlocked.Increment(ref _numThreads);
|
||||||
|
ThreadPool.QueueUserWorkItem(RunAction, action);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RunAction(object action)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
((Action)action)();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Interlocked.Decrement(ref _numThreads);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OnDisable()
|
||||||
|
{
|
||||||
|
if (_current == this)
|
||||||
|
{
|
||||||
|
_current = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly List<NoDelayedQueueItem> _currentActions = new List<NoDelayedQueueItem>();
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
if (_actions.Count > 0)
|
||||||
|
{
|
||||||
|
lock (_actions)
|
||||||
|
{
|
||||||
|
_currentActions.Clear();
|
||||||
|
_currentActions.AddRange(_actions);
|
||||||
|
_actions.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < _currentActions.Count; i++)
|
||||||
|
{
|
||||||
|
_currentActions[i].Action(_currentActions[i].Param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_delayed.Count > 0)
|
||||||
|
{
|
||||||
|
lock (_delayed)
|
||||||
|
{
|
||||||
|
_currentDelayed.Clear();
|
||||||
|
_currentDelayed.AddRange(_delayed.Where(d => d.Time <= Time.time));
|
||||||
|
for (int i = 0; i < _currentDelayed.Count; i++)
|
||||||
|
{
|
||||||
|
_delayed.Remove(_currentDelayed[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < _currentDelayed.Count; i++)
|
||||||
|
{
|
||||||
|
_currentDelayed[i].Action(_currentDelayed[i].Param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/GameScripts/HotFix/GameBase/Loom/Loom.cs.meta
Normal file
11
Assets/GameScripts/HotFix/GameBase/Loom/Loom.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: eea4adc555e37f842abf5dd24c191d93
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
3
Assets/GameScripts/HotFix/GameBase/Singleton.meta
Normal file
3
Assets/GameScripts/HotFix/GameBase/Singleton.meta
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 00565f0d362f4c36836804455e19c3df
|
||||||
|
timeCreated: 1681990210
|
@@ -2,9 +2,14 @@
|
|||||||
|
|
||||||
namespace GameBase
|
namespace GameBase
|
||||||
{
|
{
|
||||||
public class Singleton<T> where T:new()
|
/// <summary>
|
||||||
|
/// 通用单例。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">泛型T。</typeparam>
|
||||||
|
public class Singleton<T> where T : new()
|
||||||
{
|
{
|
||||||
private static T _instance;
|
private static T _instance;
|
||||||
|
|
||||||
public static T Instance
|
public static T Instance
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -19,4 +24,4 @@ namespace GameBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
214
Assets/GameScripts/HotFix/GameBase/Singleton/TSingleton.cs
Normal file
214
Assets/GameScripts/HotFix/GameBase/Singleton/TSingleton.cs
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using TEngine;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.SceneManagement;
|
||||||
|
|
||||||
|
namespace GameBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 单例接口。
|
||||||
|
/// </summary>
|
||||||
|
public interface ISingleton
|
||||||
|
{
|
||||||
|
void Active();
|
||||||
|
|
||||||
|
void Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 单例管理器(统一化持久和释放)。
|
||||||
|
/// </summary>
|
||||||
|
public static class SingletonMgr
|
||||||
|
{
|
||||||
|
private static List<ISingleton> _singletonList;
|
||||||
|
private static Dictionary<string, GameObject> _gameObjects;
|
||||||
|
private static GameObject _root;
|
||||||
|
|
||||||
|
public static GameObject Root
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_root == null)
|
||||||
|
{
|
||||||
|
_root = GameObject.Find("[SingletonMgr]");
|
||||||
|
|
||||||
|
if (_root == null)
|
||||||
|
{
|
||||||
|
_root = new GameObject("[SingletonMgr]")
|
||||||
|
{
|
||||||
|
transform =
|
||||||
|
{
|
||||||
|
position = Vector3.zero
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
UnityEngine.Object.DontDestroyOnLoad(_root);
|
||||||
|
}
|
||||||
|
return _root;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Retain(ISingleton go)
|
||||||
|
{
|
||||||
|
if (_singletonList == null)
|
||||||
|
{
|
||||||
|
_singletonList = new List<ISingleton>();
|
||||||
|
}
|
||||||
|
|
||||||
|
_singletonList.Add(go);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Retain(GameObject go)
|
||||||
|
{
|
||||||
|
if (_gameObjects == null)
|
||||||
|
{
|
||||||
|
_gameObjects = new Dictionary<string, GameObject>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_gameObjects.ContainsKey(go.name))
|
||||||
|
{
|
||||||
|
_gameObjects.Add(go.name, go);
|
||||||
|
if (Application.isPlaying)
|
||||||
|
{
|
||||||
|
UnityEngine.Object.DontDestroyOnLoad(go);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Release(GameObject go)
|
||||||
|
{
|
||||||
|
if (_gameObjects != null && _gameObjects.ContainsKey(go.name))
|
||||||
|
{
|
||||||
|
_gameObjects.Remove(go.name);
|
||||||
|
UnityEngine.Object.Destroy(go);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Release(ISingleton go)
|
||||||
|
{
|
||||||
|
if (_singletonList != null && _singletonList.Contains(go))
|
||||||
|
{
|
||||||
|
_singletonList.Remove(go);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Release()
|
||||||
|
{
|
||||||
|
if (_gameObjects != null)
|
||||||
|
{
|
||||||
|
foreach (var item in _gameObjects)
|
||||||
|
{
|
||||||
|
UnityEngine.Object.Destroy(item.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
_gameObjects.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_singletonList != null)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _singletonList.Count; ++i)
|
||||||
|
{
|
||||||
|
_singletonList[i].Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
_singletonList.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
Resources.UnloadUnusedAssets();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GameObject GetGameObject(string name)
|
||||||
|
{
|
||||||
|
GameObject go = null;
|
||||||
|
if (_gameObjects != null)
|
||||||
|
{
|
||||||
|
_gameObjects.TryGetValue(name, out go);
|
||||||
|
}
|
||||||
|
|
||||||
|
return go;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static bool ContainsKey(string name)
|
||||||
|
{
|
||||||
|
if (_gameObjects != null)
|
||||||
|
{
|
||||||
|
return _gameObjects.ContainsKey(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static ISingleton GetSingleton(string name)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _singletonList.Count; ++i)
|
||||||
|
{
|
||||||
|
if (_singletonList[i].ToString() == name)
|
||||||
|
{
|
||||||
|
return _singletonList[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 释放所有单例。
|
||||||
|
/// </summary>
|
||||||
|
public static void ReStart()
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
|
||||||
|
SceneManager.LoadScene(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 全局单例对象(非线程安全)。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">泛型T。</typeparam>
|
||||||
|
public abstract class TSingleton<T> : ISingleton where T : TSingleton<T>, new()
|
||||||
|
{
|
||||||
|
private static T _instance;
|
||||||
|
|
||||||
|
public static T Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (null == _instance)
|
||||||
|
{
|
||||||
|
_instance = new T();
|
||||||
|
_instance.Init();
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
Log.Info($"TSingleton Instance:{typeof(T).Name}");
|
||||||
|
#endif
|
||||||
|
SingletonMgr.Retain(_instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsValid => _instance != null;
|
||||||
|
|
||||||
|
protected TSingleton()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Init()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Active()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Release()
|
||||||
|
{
|
||||||
|
if (_instance != null)
|
||||||
|
{
|
||||||
|
SingletonMgr.Release(_instance);
|
||||||
|
_instance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: aa2cb5bb622045d7a6f2a4c4faea3ca6
|
||||||
|
timeCreated: 1681989590
|
111
Assets/GameScripts/HotFix/GameBase/Singleton/UnitySingleton.cs
Normal file
111
Assets/GameScripts/HotFix/GameBase/Singleton/UnitySingleton.cs
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
using TEngine;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace GameBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 具备Unity完整生命周期的单例。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
public abstract class UnitySingleton<T> : MonoBehaviour where T : MonoBehaviour
|
||||||
|
{
|
||||||
|
private static T _instance;
|
||||||
|
|
||||||
|
public static T Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_instance == null)
|
||||||
|
{
|
||||||
|
var ins = UnityEngine.Object.FindObjectOfType<T>();
|
||||||
|
if (ins != null)
|
||||||
|
{
|
||||||
|
var obj = ins.gameObject;
|
||||||
|
obj.name = typeof(T).Name;
|
||||||
|
_instance = ins;
|
||||||
|
SingletonMgr.Retain(obj);
|
||||||
|
return Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.Type thisType = typeof(T);
|
||||||
|
string instName = thisType.Name;
|
||||||
|
GameObject go = SingletonMgr.GetGameObject(instName);
|
||||||
|
if (go == null)
|
||||||
|
{
|
||||||
|
go = GameObject.Find($"{instName}");
|
||||||
|
if (go == null)
|
||||||
|
{
|
||||||
|
go = new GameObject(instName);
|
||||||
|
go.transform.position = Vector3.zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_instance = go.GetComponent<T>();
|
||||||
|
if (_instance == null)
|
||||||
|
{
|
||||||
|
_instance = go.AddComponent<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_instance == null)
|
||||||
|
{
|
||||||
|
Log.Error($"Can't create UnitySingleton<{typeof(T)}>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T Active()
|
||||||
|
{
|
||||||
|
return Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsValid => _instance != null;
|
||||||
|
|
||||||
|
private bool CheckInstance()
|
||||||
|
{
|
||||||
|
if (this == Instance)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameObject.Destroy(gameObject);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnLoad()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Awake()
|
||||||
|
{
|
||||||
|
if (CheckInstance())
|
||||||
|
{
|
||||||
|
OnLoad();
|
||||||
|
}
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
Log.Debug($"UnitySingleton Instance:{typeof(T).Name}");
|
||||||
|
#endif
|
||||||
|
GameObject tEngine = SingletonMgr.Root;
|
||||||
|
if (tEngine != null)
|
||||||
|
{
|
||||||
|
this.gameObject.transform.SetParent(tEngine.transform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnDestroy()
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Release()
|
||||||
|
{
|
||||||
|
if (_instance != null)
|
||||||
|
{
|
||||||
|
SingletonMgr.Release(_instance.gameObject);
|
||||||
|
_instance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 25c99243aa534df5870e36fdf9d36afd
|
||||||
|
timeCreated: 1681990223
|
@@ -0,0 +1,175 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public static partial class Utility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 硬件设备性能适配工具相关的实用函数。
|
||||||
|
/// </summary>
|
||||||
|
public static class DevicePerformance
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取设备性能评级。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>性能评级</returns>
|
||||||
|
public static DevicePerformanceLevel GetDevicePerformanceLevel()
|
||||||
|
{
|
||||||
|
if (SystemInfo.graphicsDeviceVendorID == 32902)
|
||||||
|
{
|
||||||
|
//集显
|
||||||
|
return DevicePerformanceLevel.Low;
|
||||||
|
}
|
||||||
|
else //NVIDIA 系列显卡(N卡)和AMD系列显卡。
|
||||||
|
{
|
||||||
|
//根据目前硬件配置三个平台设置了不一样的评判标准(仅个人意见)。
|
||||||
|
//CPU核心数。
|
||||||
|
#if UNITY_EDITOR || UNITY_STANDALONE_WIN
|
||||||
|
if (SystemInfo.processorCount <= 2)
|
||||||
|
#elif UNITY_STANDALONE_OSX || UNITY_IPHONE
|
||||||
|
if (SystemInfo.processorCount < 2)
|
||||||
|
#elif UNITY_ANDROID
|
||||||
|
if (SystemInfo.processorCount <= 4)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
//CPU核心数<=2判定为低端。
|
||||||
|
return DevicePerformanceLevel.Low;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//显存。
|
||||||
|
int graphicsMemorySize = SystemInfo.graphicsMemorySize;
|
||||||
|
//内存。
|
||||||
|
int systemMemorySize = SystemInfo.systemMemorySize;
|
||||||
|
#if UNITY_EDITOR || UNITY_STANDALONE_WIN
|
||||||
|
if (graphicsMemorySize >= 4000 && systemMemorySize >= 8000)
|
||||||
|
return DevicePerformanceLevel.High;
|
||||||
|
else if (graphicsMemorySize >= 2000 && systemMemorySize >= 4000)
|
||||||
|
return DevicePerformanceLevel.Mid;
|
||||||
|
else
|
||||||
|
return DevicePerformanceLevel.Low;
|
||||||
|
#elif UNITY_STANDALONE_OSX || UNITY_IPHONE
|
||||||
|
if (graphicsMemorySize >= 4000 && systemMemorySize >= 8000)
|
||||||
|
return DevicePerformanceLevel.High;
|
||||||
|
else if (graphicsMemorySize >= 2000 && systemMemorySize >= 4000)
|
||||||
|
return DevicePerformanceLevel.Mid;
|
||||||
|
else
|
||||||
|
return DevicePerformanceLevel.Low;
|
||||||
|
#elif UNITY_ANDROID
|
||||||
|
if (graphicsMemorySize >= 6000 && systemMemorySize >= 8000)
|
||||||
|
return DevicePerformanceLevel.High;
|
||||||
|
else if (graphicsMemorySize >= 2000 && systemMemorySize >= 4000)
|
||||||
|
return DevicePerformanceLevel.Mid;
|
||||||
|
else
|
||||||
|
return DevicePerformanceLevel.Low;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据手机性能修改项目设置。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lowQuality">QualitySettings中对应Low的等级。</param>
|
||||||
|
/// <param name="midQuality">QualitySettings中对应Mid的等级。</param>
|
||||||
|
/// <param name="highQuality">QualitySettings中对应High的等级。</param>
|
||||||
|
public static void ModifySettingsBasedOnPerformance(int lowQuality, int midQuality, int highQuality)
|
||||||
|
{
|
||||||
|
DevicePerformanceLevel level = GetDevicePerformanceLevel();
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case DevicePerformanceLevel.Low:
|
||||||
|
QualitySettings.SetQualityLevel(lowQuality, true);
|
||||||
|
break;
|
||||||
|
case DevicePerformanceLevel.Mid:
|
||||||
|
QualitySettings.SetQualityLevel(midQuality, true);
|
||||||
|
break;
|
||||||
|
case DevicePerformanceLevel.High:
|
||||||
|
QualitySettings.SetQualityLevel(highQuality, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据机型配置自动设置质量。
|
||||||
|
/// </summary>
|
||||||
|
public static void ModifySettingsBasedOnPerformance()
|
||||||
|
{
|
||||||
|
DevicePerformanceLevel level = GetDevicePerformanceLevel();
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case DevicePerformanceLevel.Low:
|
||||||
|
SetQualitySettings(QualityLevel.Low);
|
||||||
|
break;
|
||||||
|
case DevicePerformanceLevel.Mid:
|
||||||
|
SetQualitySettings(QualityLevel.Mid);
|
||||||
|
break;
|
||||||
|
case DevicePerformanceLevel.High:
|
||||||
|
SetQualitySettings(QualityLevel.High);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据自身需要调整各级别需要修改的设置,可根据需求修改低中高三种方案某一项具体设置。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="qualityLevel">质量等级。</param>
|
||||||
|
public static void SetQualitySettings(QualityLevel qualityLevel)
|
||||||
|
{
|
||||||
|
switch (qualityLevel)
|
||||||
|
{
|
||||||
|
case QualityLevel.Low:
|
||||||
|
//前向渲染使用的像素灯的最大数量,建议最少为1。
|
||||||
|
QualitySettings.pixelLightCount = 2;
|
||||||
|
//你可以设置使用最大分辨率的纹理或者部分纹理(低分辨率纹理的处理开销低)。选项有 0_完整分辨率,1_1/2分辨率,2_1/4分辨率,3_1/8分辨率。
|
||||||
|
QualitySettings.masterTextureLimit = 1;
|
||||||
|
//设置抗锯齿级别。选项有 0_不开启抗锯齿,2_2倍,4_4倍和8_8倍采样。
|
||||||
|
QualitySettings.antiAliasing = 0;
|
||||||
|
//是否使用粒子软融合
|
||||||
|
QualitySettings.softParticles = false;
|
||||||
|
//启用实时反射探针,此设置需要用的时候再打开。
|
||||||
|
QualitySettings.realtimeReflectionProbes = false;
|
||||||
|
//如果启用,公告牌将面向摄像机位置而不是摄像机方向。似乎与地形系统有关,此处没啥必要打开。
|
||||||
|
QualitySettings.billboardsFaceCameraPosition = false;
|
||||||
|
//设置软硬阴影是否打开
|
||||||
|
QualitySettings.shadows = ShadowQuality.Disable;
|
||||||
|
//设置垂直同步方案,VSyncs数值需要在每帧之间传递,使用0为不等待垂直同步。值必须是0,1或2。
|
||||||
|
QualitySettings.vSyncCount = 0;
|
||||||
|
break;
|
||||||
|
case QualityLevel.Mid:
|
||||||
|
QualitySettings.pixelLightCount = 4;
|
||||||
|
QualitySettings.antiAliasing = 2;
|
||||||
|
QualitySettings.softParticles = false;
|
||||||
|
QualitySettings.realtimeReflectionProbes = true;
|
||||||
|
QualitySettings.billboardsFaceCameraPosition = true;
|
||||||
|
QualitySettings.shadows = ShadowQuality.HardOnly;
|
||||||
|
QualitySettings.vSyncCount = 2;
|
||||||
|
break;
|
||||||
|
case QualityLevel.High:
|
||||||
|
QualitySettings.pixelLightCount = 4;
|
||||||
|
QualitySettings.antiAliasing = 8;
|
||||||
|
QualitySettings.softParticles = true;
|
||||||
|
QualitySettings.realtimeReflectionProbes = true;
|
||||||
|
QualitySettings.billboardsFaceCameraPosition = true;
|
||||||
|
QualitySettings.shadows = ShadowQuality.All;
|
||||||
|
QualitySettings.vSyncCount = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum DevicePerformanceLevel
|
||||||
|
{
|
||||||
|
Low,
|
||||||
|
Mid,
|
||||||
|
High
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum QualityLevel
|
||||||
|
{
|
||||||
|
Low,
|
||||||
|
Mid,
|
||||||
|
High
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 464e226f0422412e89e9cd4012b6291c
|
||||||
|
timeCreated: 1681990596
|
Reference in New Issue
Block a user