添加对象池并更新KeySettingManager的README

This commit is contained in:
2024-07-10 16:39:46 +08:00
parent 68665845ab
commit 15c2849090
5 changed files with 187 additions and 10 deletions

View File

@@ -20,7 +20,7 @@ namespace AnnoyingUtils.KeyboardInput
if (_instance) return _instance;
_instance = FindObjectOfType<KeySettingManager>();
if (_instance) return _instance;
var go = new GameObject("KeySettingManager");
var go = new GameObject(nameof(KeySettingManager));
_instance = go.AddComponent<KeySettingManager>();
return _instance;

View File

@@ -2,17 +2,20 @@
```csharp
public class KeyMapping
{
public string actionName;
public KeyCode keyCode;
{
public string actionName;
public KeyCode keyCode;
public KeyMapping(string actionName, KeyCode keyCode)
{
this.actionName = actionName;
this.keyCode = keyCode;
}
public KeyMapping(string actionName, KeyCode keyCode)
{
this.actionName = actionName;
this.keyCode = keyCode;
}
}
```
<code>KeySettingManager</code>为单例类
//todo
在<code>LoadKeySettings()</code>中填写自己需要的键位对即可。
调用<code>GetKey(string actionName)</code>获取行为对应的KeyCode
调用<code>SetKey(string actionName, KeyCode newKeyCode)</code>设置行为对应KeyCode

View File

@@ -0,0 +1,29 @@
using UnityEditor;
using UnityEngine;
namespace AnnoyingUtils.Pool.Editor
{
[InitializeOnLoad]
public static class SingletonObjectPoolInitializer
{
static SingletonObjectPoolInitializer()
{
CreateSingletonInstances();
}
private static void CreateSingletonInstances()
{
var types = typeof(SingletonObjectPool<>).Assembly.GetTypes();
foreach (var type in types)
{
if (!type.IsSubclassOf(typeof(MonoBehaviour)) || !type.BaseType.IsGenericType ||
type.BaseType.GetGenericTypeDefinition() != typeof(SingletonObjectPool<>)) continue;
var existingInstances = UnityEngine.Object.FindObjectsOfType(type);
if (existingInstances.Length != 0) continue;
var obj = new GameObject(type.Name);
obj.AddComponent(type);
Debug.Log(type.Name + " 单例实力已创建");
}
}
}
}

42
Pool/README.md Normal file
View File

@@ -0,0 +1,42 @@
新建一个对象池类继承SingletonObjectPool后在UnityEditor中会自动创建以类名为名称的单例实例。
```csharp
public class EnemyPool : SingletonObjectPool<Enemy>
{
}
```
用法示例如下方刷怪圈
```csharp
public class EnemySpawner : MonoBehaviour
{
public GameObject enemyPrefab;
public int initialPoolSize = 5;
public int maxPoolSize = 10;
public float spawnInterval = 3f;
public int spawnCount = 1;
public float spawnRadius = 5f;
private void Start()
{
SingletonObjectPool<Enemy>.Instance.Init(enemyPrefab.GetComponent<Enemy>(), initialPoolSize, maxPoolSize);
StartCoroutine(SpawnEnemiesCoroutine());
}
private IEnumerator SpawnEnemiesCoroutine()
{
while (true)
{
yield return new WaitForSeconds(spawnInterval);
SpawnEnemies();
}
}
private void SpawnEnemies()
{
for (var i = 0; i < spawnCount; i++)
{
var spawnPosition = transform.position + (Vector3)Random.insideUnitCircle * spawnRadius;
SingletonObjectPool<Enemy>.Instance.Spawn(transform).transform.position = spawnPosition;
}
}
}
```

View File

@@ -0,0 +1,103 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Pool;
namespace AnnoyingUtils.Pool
{
public class SingletonObjectPool<T> : MonoBehaviour where T : MonoBehaviour
{
#region
private static SingletonObjectPool<T> _instance;
public static SingletonObjectPool<T> Instance
{
get
{
if (_instance) return _instance;
_instance = FindObjectOfType<SingletonObjectPool<T>>();
if (_instance) return _instance;
var obj = new GameObject(typeof(SingletonObjectPool<T>).Name);
_instance = obj.AddComponent<SingletonObjectPool<T>>();
return _instance;
}
}
#endregion
private ObjectPool<T> _pool;
private T _prefab;
private Queue<T> _activeObjects;
private int _maxActiveObjects;
public void Init(T prefab, int defaultCapacity = 1, int maxSize = 10)
{
if (prefab is null)
{
Debug.LogError("预制体为空");
return;
}
_prefab = prefab;
_maxActiveObjects = maxSize;
_pool = new ObjectPool<T>(CreateFunc, ActionOnGet, ActionOnRelease, ActionOnDestroy, true, defaultCapacity,
maxSize);
_activeObjects = new Queue<T>();
}
private T CreateFunc()
{
return Instantiate(_prefab);
}
private void ActionOnGet(T obj)
{
obj.gameObject.SetActive(true);
_activeObjects.Enqueue(obj);
}
private void ActionOnRelease(T obj)
{
obj.gameObject.SetActive(false);
}
private void ActionOnDestroy(T obj)
{
Destroy(obj.gameObject);
}
//供滴人死亡、子弹命中等调用
public void Release(T obj)
{
if (_pool is null)
{
Debug.LogWarning(typeof(T).Name + " 对象池未实例化");
return;
}
_activeObjects.Dequeue();
_pool.Release(obj);
}
public T Spawn(Transform parent)
{
if (_pool is null)
{
Debug.LogWarning(typeof(T).Name + " 对象池未实例化");
return null;
}
//检查是否超出容量
if (_activeObjects.Count >= _maxActiveObjects)
{
var oldestObject = _activeObjects.Peek();
Release(oldestObject);
}
var temp = _pool.Get();
temp.transform.position = parent.position;
return temp;
}
}
}