Upgraded pools, Cleaned-up unused code

This commit is contained in:
VladimirPirozhenko 2022-08-20 08:00:04 +03:00
parent f494fea030
commit 89ad14949b
20 changed files with 5990 additions and 317 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,6 @@
fileFormatVersion: 2
guid: 2c1414029cb91084cba78a71f08c5906
folderAsset: yes
DefaultImporter:
guid: 23b83b303fe60d84dae6e35495f84cb8
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:

View File

@ -0,0 +1,45 @@
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Reflection;
using System.IO;
public class PoolCodeGenerator
{
private CodeCompileUnit targetUnit;
private string targetClassName;
private string poolNameSpaceName;
private CodeTypeDeclaration targetClass;
private string outputFilePath;
public PoolCodeGenerator(string outputFilePath, string targetClassName, string poolNameSpaceName, string pooledObjectClassName)
{
this.targetClassName = targetClassName;
this.poolNameSpaceName = poolNameSpaceName;
this.outputFilePath = outputFilePath;
targetUnit = new CodeCompileUnit();
//TODO: MAKE NAMESPACE OPTIONAL
CodeNamespace poolNamespace = new CodeNamespace(poolNameSpaceName);
targetClass = new CodeTypeDeclaration();
targetClass.IsClass = true;
targetClass.Name = this.targetClassName;
targetClass.TypeAttributes =
TypeAttributes.Public| TypeAttributes.Sealed;
poolNamespace.Types.Add(targetClass);
targetUnit.Namespaces.Add(poolNamespace);
targetClass.BaseTypes.Add(new CodeTypeReference("BasePool",new CodeTypeReference(pooledObjectClassName)));//Add("BasePool");
}
public void GenerateCSharpCode()
{
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.BracingStyle = "C";
using (StreamWriter sourceWriter = new StreamWriter(outputFilePath,false))
{
provider.GenerateCodeFromCompileUnit(
targetUnit, sourceWriter, options);
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 939d99470209e0c4e9dabc90e83785cf
guid: 22399ee0b51264e48a25e9f74125859d
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -1,106 +1,58 @@
using System;
using System.Collections;
using System.IO;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Reflection;
using System;
using System.IO;
public class PoolCodeGenerator
{
private CodeCompileUnit targetUnit;
private string targetClassName;
private string poolNameSpaceName;
private CodeTypeDeclaration targetClass;
private string outputFilePath;
public PoolCodeGenerator(string outputFilePath, string targetClassName, string poolNameSpaceName, string pooledObjectClassName)
{
this.targetClassName = targetClassName;
this.poolNameSpaceName = poolNameSpaceName;
this.outputFilePath = outputFilePath;
targetUnit = new CodeCompileUnit();
//TODO: MAKE NAMESPACE OPTIONAL
CodeNamespace poolNamespace = new CodeNamespace(poolNameSpaceName);
targetClass = new CodeTypeDeclaration();
targetClass.IsClass = true;
targetClass.Name = this.targetClassName;
targetClass.TypeAttributes =
TypeAttributes.Public| TypeAttributes.Sealed;
poolNamespace.Types.Add(targetClass);
targetUnit.Namespaces.Add(poolNamespace);
targetClass.BaseTypes.Add(new CodeTypeReference("BasePool",new CodeTypeReference(pooledObjectClassName)));//Add("BasePool");
}
public void GenerateCSharpCode()
{
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.BracingStyle = "C";
using (StreamWriter sourceWriter = new StreamWriter(outputFilePath,false))
{
provider.GenerateCodeFromCompileUnit(
targetUnit, sourceWriter, options);
}
}
}
[CustomEditor(typeof(PoolingObject<>),true)]
public class PoolCreator : Editor
public class PoolCreator
{
private string targetClassName;
private string poolNamespaceName;
private bool pendingToGeneration = false;
private int poolCapacity = 10;
private void OnEnable()
private GameObject poolingObject;
//private void OnEnable()
//{
// AssemblyReloadEvents.afterAssemblyReload += GeneratePoolPrefab;
//}
//private void OnDisable()
//{
// AssemblyReloadEvents.afterAssemblyReload -= GeneratePoolPrefab;
//}
public PoolCreator(GameObject poolingObject,int poolCapacity, string poolNamespaceName)
{
AssemblyReloadEvents.afterAssemblyReload += GeneratePoolPrefab;
this.poolingObject = poolingObject;
this.poolCapacity = poolCapacity;
this.poolNamespaceName = poolNamespaceName;
GeneratePoolScript();
}
private void OnDisable()
public void GeneratePoolScript()
{
AssemblyReloadEvents.afterAssemblyReload -= GeneratePoolPrefab;
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
EditorGUILayout.IntField("Pool Capacity: ",poolCapacity);
if (GUILayout.Button("Create Pool From This Object"))
{
string poolObjectName = target.GetType().Name;
string targetClassName = poolObjectName + "Pool";
string poolNamespaceName = "Pools";
this.targetClassName = targetClassName;
this.poolNamespaceName = poolNamespaceName;
PoolCodeGenerator generator = new PoolCodeGenerator($"{Application.dataPath}/Scripts/Road/Pools/{targetClassName}.cs", targetClassName, poolNamespaceName, poolObjectName); //$"{targetClassName}.cs"
var relativePath = $"Assets/Scripts/Road/Pools/{targetClassName}.cs";
generator.GenerateCSharpCode();
AssetDatabase.ImportAsset(relativePath);
AssetDatabase.Refresh();
EditorUtility.RequestScriptReload();
AssetDatabase.SaveAssets();
pendingToGeneration = true;
}
string poolObjectName = poolingObject.GetType().Name;
string targetClassName = poolObjectName + "Pool";
this.targetClassName = targetClassName;
PoolCodeGenerator generator = new PoolCodeGenerator($"{Application.dataPath}/Scripts/Road/Pools/{targetClassName}.cs", targetClassName, poolNamespaceName, poolObjectName); //$"{targetClassName}.cs"
var relativePath = $"Assets/Scripts/Road/Pools/{targetClassName}.cs";
generator.GenerateCSharpCode();
AssetDatabase.ImportAsset(relativePath);
AssetDatabase.Refresh();
EditorUtility.RequestScriptReload();
AssetDatabase.SaveAssets();
// pendingToGeneration = true;
}
public void GeneratePoolPrefab()
{
if (!pendingToGeneration)
return;
GameObject poolingObject = new GameObject(targetClassName);
Type poolingObjectType = target.GetType();
GameObject poolObject = new GameObject(targetClassName);
Type poolingObjectType = poolingObject.GetType();
Assembly assem = poolingObjectType.Assembly;
string poolName = $"{target.name}Pool";
string poolName = $"{poolingObject.name}Pool";
Type poolType = assem.GetType($"{poolNamespaceName}.{targetClassName}");
//Type genericClass = typeof(BasePool<>);
//Type constructedClass = genericClass.MakeGenericType(poolingObjectType);
poolingObject.AddComponent(poolType);
poolingObject.name = poolName;
poolObject.AddComponent(poolType);
poolObject.name = poolName;
Type typeOfField = poolType;
FieldInfo fieldInfo = null;
@ -111,8 +63,8 @@ public class PoolCreator : Editor
}
if (fieldInfo == null) throw new ArgumentOutOfRangeException("Prefab", string.Format("Field {0} was not found in Type {1}", "prefab", typeOfField.FullName));
var poolingObjectComponent = poolingObject.GetComponent(poolType);
fieldInfo.SetValue(poolingObjectComponent, target);
var poolingObjectComponent = poolObject.GetComponent(poolType);
fieldInfo.SetValue(poolingObjectComponent, poolingObject);
Type capacityType = poolType;
//if (capacityType.GetProperty("Capacity", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) == null)
// throw new ArgumentOutOfRangeException("Capacity", string.Format("Property {0} was not found in Type {1}", "Capacity", obj.GetType().FullName));
@ -129,7 +81,7 @@ public class PoolCreator : Editor
localPath = AssetDatabase.GenerateUniqueAssetPath(localPath);
bool prefabSuccess;
PrefabUtility.SaveAsPrefabAssetAndConnect(poolingObject, localPath, InteractionMode.UserAction, out prefabSuccess);
PrefabUtility.SaveAsPrefabAssetAndConnect(poolObject, localPath, InteractionMode.UserAction, out prefabSuccess);
if (prefabSuccess == true)
Debug.Log("Prefab was saved successfully");
@ -137,4 +89,5 @@ public class PoolCreator : Editor
Debug.Log("Prefab failed to save" + prefabSuccess);
Debug.Log("Done");
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 9ca19bcf0c7b9e64b94968ce8eeea0de
guid: 5cdbd5dce7522f649bda974218e1e500
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -0,0 +1,99 @@
using UnityEditor;
using UnityEngine;
using System.Reflection;
using System;
using System.IO;
[CustomEditor(typeof(PoolingObject<>),true)]
public class PoolCreatorInspector : Editor
{
private string targetClassName;
private string poolNamespaceName;
private bool pendingToGeneration = false;
private int poolCapacity = 10;
private void OnEnable()
{
// pendingToGeneration = false;
AssemblyReloadEvents.afterAssemblyReload += GeneratePoolPrefab;
}
private void OnDisable()
{
// pendingToGeneration = false;
AssemblyReloadEvents.afterAssemblyReload -= GeneratePoolPrefab;
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
EditorGUILayout.IntField("Pool Capacity: ",poolCapacity);
if (GUILayout.Button("Create Pool From This Object"))
{
string poolObjectName = target.GetType().Name;
string targetClassName = poolObjectName + "Pool";
string poolNamespaceName = "Pools";
this.targetClassName = targetClassName;
this.poolNamespaceName = poolNamespaceName;
PoolCodeGenerator generator = new PoolCodeGenerator($"{Application.dataPath}/Scripts/Road/Pools/{targetClassName}.cs", targetClassName, poolNamespaceName, poolObjectName); //$"{targetClassName}.cs"
var relativePath = $"Assets/Scripts/Road/Pools/{targetClassName}.cs";
generator.GenerateCSharpCode();
AssetDatabase.ImportAsset(relativePath);
AssetDatabase.Refresh();
EditorUtility.RequestScriptReload();
AssetDatabase.SaveAssets();
pendingToGeneration = true;
}
}
public void GeneratePoolPrefab()
{
if (pendingToGeneration == false)
return;
pendingToGeneration = false;
GameObject poolingObject = new GameObject(targetClassName);
Type poolingObjectType = target.GetType();
Assembly assem = poolingObjectType.Assembly;
string poolName = $"{target.name}Pool";
Type poolType = assem.GetType($"{poolNamespaceName}.{targetClassName}");
poolingObject.AddComponent(poolType);
poolingObject.name = poolName;
Type typeOfField = poolType;
FieldInfo fieldInfo = null;
while (fieldInfo == null && typeOfField != null)
{
fieldInfo = typeOfField.GetField("prefab", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
typeOfField = typeOfField.BaseType;
}
if (fieldInfo == null) throw new ArgumentOutOfRangeException("Prefab", string.Format("Field {0} was not found in Type {1}", "prefab", typeOfField.FullName));
var poolingObjectComponent = poolingObject.GetComponent(poolType);
fieldInfo.SetValue(poolingObjectComponent, target);
Type capacityType = poolType;
PropertyInfo propertyInfo = capacityType.BaseType.GetProperty("Capacity", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
propertyInfo.SetValue(poolingObjectComponent, poolCapacity, BindingFlags.NonPublic | BindingFlags.Instance, null, null, null);
if (!Directory.Exists("Assets/Prefabs/Pools"))
AssetDatabase.CreateFolder("Assets/Prefabs", "Pools");
string localPath = "Assets/Prefabs/Pools/" + poolName + ".prefab";
localPath = AssetDatabase.GenerateUniqueAssetPath(localPath);
bool prefabSuccess;
PrefabUtility.SaveAsPrefabAssetAndConnect(poolingObject, localPath, InteractionMode.UserAction, out prefabSuccess);
if (prefabSuccess == true)
Debug.Log("Prefab was saved successfully");
else
Debug.Log("Prefab failed to save" + prefabSuccess);
Debug.Log("Done");
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 737c01cbc791a3748b6d82f8a200e7d1
guid: 9ca19bcf0c7b9e64b94968ce8eeea0de
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -0,0 +1,64 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEngine;
public class PoolCreatorWindow : EditorWindow
{
private int poolCapacity = 10;
private GameObject poolingObject;
private PoolCreator creator;
private void OnEnable()
{
AssemblyReloadEvents.afterAssemblyReload += CreatePoolPrefab;
}
private void OnDisable()
{
AssemblyReloadEvents.afterAssemblyReload -= CreatePoolPrefab;
}
[MenuItem("Pooling/PoolCreatorWindow")]
public static void ShowWindow()
{
EditorWindow.GetWindow(typeof(PoolCreatorWindow));
}
void OnGUI()
{
// The actual window code goes here
EditorGUILayout.IntField("Pool Capacity: ", poolCapacity);
//GameObject pObj = EditorGUI.ObjectField(new Rect(3, 3, position.width - 6, 20),
// "Blablabla",
// obj,
// typeof(GameObject));
//poolingObject = EditorGUILayout.ObjectField(poolingObject, typeof(PoolingObject<>), true) as PoolingObject<>;
//Type type;
// foreach (var component in poolingObject.GetComponents(typeof(PoolingObject<>)))
// {
// type = component.GetType();
//Type poolingObjectType = poolingObject.GetType();
// Assembly assem = poolingObjectType.Assembly;
//string poolName = $"{poolingObject.name}Pool";
// Type poolType = assem.GetType("Turret");
//var poolingObjectComponent = poolingObject.GetComponent(poolingObjectType);
if (GUILayout.Button("Create Pool From This Object"))
{
// creator = new PoolCreator(component, poolCapacity, "Pools");
}
// }
}
private void CreatePoolPrefab()
{
if (creator == null)
return;
creator.GeneratePoolPrefab();
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: c83d0633ae49f864191b0891870b2279
guid: f0bfc4b29502d834fb03d076136c3d34
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -1,22 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//enum EWeaponState {iShooting,CanShoot,CannotShoot,Reloading}
public class WeaponController : MonoBehaviour
{
[SerializeField] List<Weapon> weapons;
[SerializeField] Transform weaponPoint;
private Weapon currentWeapon;
public bool canShoot { get; set;} //player
void Start()
{
currentWeapon = weapons[0];
currentWeapon.Equip(weaponPoint);
canShoot = true;
}
public void PerfomShoot()
{
if (canShoot)
StartCoroutine(currentWeapon.Shoot());
}
}

View File

@ -1,3 +1,4 @@
using Pools;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@ -13,7 +14,7 @@ public class ChunkGenerator : MonoBehaviour
if (ObstaclePools.IsEmpty())
return chunkToFill;
var obstaclePool = ObstaclePools.GetRandomElement();
var obstacle = obstaclePool.GetFromPool();
var obstacle = obstaclePool.Spawn();
chunkToFill.Obstacles.Add(obstacle);
obstacle.transform.SetParent(chunkToFill.transform, true);
obstacle.transform.localPosition = chunkToFill.Grid.GetRandomPosition();

View File

@ -21,8 +21,8 @@ public class ChunkSpawner : MonoBehaviour // TODO: ISpawner
public void SpawnInitialChunks()
{
lastChunk = chunkPool.GetFromPool();
for (int i = 0; i < chunkPool.Capacity / 2; i++)
lastChunk = chunkPool.Spawn();
for (int i = 0; i < chunkPool.InitialCapacity; i++)
{
Spawn();
}
@ -30,7 +30,8 @@ public class ChunkSpawner : MonoBehaviour // TODO: ISpawner
public void Spawn()
{
Chunk newChunk = chunkPool.GetFromPool();
Chunk newChunk = chunkPool.Spawn();
newChunk.gameObject.SetActive(true);
newChunk.ChangeTransformBasedOnPreviousChunk(lastChunk);
chunkGenerator.Generate(newChunk);
lastChunk = newChunk;

View File

@ -1,19 +1,24 @@
using UnityEngine;
public class BasePool<T> : MonoBehaviour where T : PoolingObject<T>
{
[field: SerializeField] public int Capacity { get; private set; }
[SerializeField] private int capacity;
[SerializeField] private bool isActiveByDefault;
[SerializeField] private T prefab;
public int Capacity { get { return pool.Capacity; } private set { capacity = value; } }
public int InitialCapacity { get; private set; }
private ObjectPool<T> pool;
private void Awake()
{
pool = new ObjectPool<T>(CreateAction, GetAction, ReturnAction, Capacity);
pool = new ObjectPool<T>(CreateAction, GetAction, ReturnAction, DestroyAction,capacity,isActiveByDefault);
InitialCapacity = capacity;
}
protected virtual T CreateAction()
{
T instance = Instantiate(prefab);
instance.gameObject.SetActive(false);
instance.transform.SetParent(gameObject.transform, false);
instance.OwningPool = this;
return instance;
@ -28,8 +33,61 @@ public class BasePool<T> : MonoBehaviour where T : PoolingObject<T>
{
instance.gameObject.SetActive(false);
}
protected virtual void DestroyAction(T instance)
{
Destroy(instance.gameObject);
}
public T GetFromPool()
public int GetActiveElementCount()
{
return pool.GetActiveElementsCount();
}
public int GetInactiveElementCount()
{
return pool.GetInactiveElementsCount();
}
public bool ContainsElement(T element)
{
return pool.ContainsElement(element);
}
public bool ContainsElement(T element, bool isActive)
{
return pool.ContainsElement(element, isActive);
}
public bool TryGetFromPos(in Vector3 pos, out T element)
{
if (pool.TryGetFromPos(pos, out element))
{
return true;
}
return false;
}
public void Destroy(T obj)
{
pool.Destroy(obj);
}
public void DestroyAllElements()
{
pool.DestroyAllElements();
}
public void DestroyAllElements(bool isActive)
{
pool.DestroyAllElements(isActive);
}
public void ReturnAllElementsToPool()
{
pool.ReturnAllElementsToPool();
}
public T Spawn()
{
return pool.Get();
}

View File

@ -1,62 +1,78 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
//Ïåðåäàâàòü Action ïî äîáàâëåíèþ è óäàëåíèþ èç ïóëà
public class ObjectPool<T> : IEnumerable<T> where T : MonoBehaviour
{
public int Capacity { get; private set; }
private Func<T> actionOnCreate;
private Action<T> actionOnGet;
private Action<T> actionOnRelease;
private Action<T> actionOnDestroy;
private List<T> pool;
private List<T> activePoolElements;
private Queue<T> inactivePoolElements;
public ObjectPool(Func<T> actionOnCreate, Action<T> actionOnGet, Action<T> actionOnRelease, int initialCapacity)
public ObjectPool(Func<T> actionOnCreate, Action<T> actionOnGet, Action<T> actionOnRelease, Action<T> actionOnDestroy, int initialCapacity,bool isActiveByDefault)
{
Capacity = initialCapacity;
this.actionOnCreate = actionOnCreate;
this.actionOnGet = actionOnGet;
this.actionOnRelease = actionOnRelease;
pool = new List<T>();
this.actionOnDestroy = actionOnDestroy;
activePoolElements = new List<T>();
inactivePoolElements = new Queue<T>();
for (uint i = 0; i < Capacity; i++)
{
var obj = actionOnCreate();
pool.Add(obj);
}
}
public T this[int i]
{
get => pool[i];
set => pool[i] = value;
}
public T TryGetFromPos(in Vector3 pos,bool isActive)
{
foreach (var obj in pool)
{
if (isActive)
// inactivePoolElements.Enqueue(obj);
//obj.gameObject.SetActive(isActiveByDefault);
if (isActiveByDefault)
{
if (obj.gameObject.activeInHierarchy && pos == obj.gameObject.transform.position)
{
actionOnGet.Invoke(obj);
return obj;
}
actionOnGet(obj);
}
else
{
if (!obj.gameObject.activeInHierarchy && pos == obj.gameObject.transform.position)
{
actionOnGet.Invoke(obj);
return obj;
}
actionOnRelease(obj);
}
}
return null;
}
public bool ContainsElement(T element)
{
return ContainsElement(element, true) || ContainsElement(element, false);
}
public bool ContainsElement(T element,bool isActive)
{
if (isActive)
{
return activePoolElements.Contains(element);
}
else
{
return inactivePoolElements.Contains(element);
}
}
public bool TryGetFromPos(in Vector3 pos,out T element)
{
element = null;
foreach (var obj in activePoolElements)
{
if (pos == obj.gameObject.transform.position)
{
actionOnGet.Invoke(obj);
element = obj;
return true;
}
}
return false;
}
public T Get()
{
if (TryGet(out var element))
@ -64,55 +80,102 @@ public class ObjectPool<T> : IEnumerable<T> where T : MonoBehaviour
return element;
}
T instance = ExpandPool();
instance.gameObject.SetActive(true);
return instance;
}
private bool TryGet(out T element)
{
List<T> inactiveObjects = GetInactiveElements();
if (inactiveObjects.Count > 0)
{
var obj = inactiveObjects[UnityEngine.Random.Range(0, inactiveObjects.Count)];
element = obj;
actionOnGet.Invoke(element);
return true;
}
element = null;
return false;
}
public List<T> GetInactiveElements()
{
return pool.FindAll(obj => !obj.gameObject.activeInHierarchy);
}
public List<T> GetActiveElements()
{
return pool.FindAll(obj => obj.gameObject.activeInHierarchy);
}
public T ExpandPool()
private T ExpandPool()
{
var obj = actionOnCreate();
Capacity++;
pool.Add(obj);
obj.gameObject.SetActive(true);
activePoolElements.Add(obj);
return obj;
}
private bool TryGet(out T element)
{
element = null;
if (inactivePoolElements.Count > 0)
{
var obj = inactivePoolElements.Dequeue();
if (obj == null)
{
return false;
}
element = obj;
actionOnGet.Invoke(element);
activePoolElements.Add(obj);
return true;
}
return false;
}
public void Destroy(T obj)
{
activePoolElements.Remove(obj);
actionOnDestroy.Invoke(obj);
}
public void DestroyAllElements()
{
DestroyAllElements(true);
DestroyAllElements(false);
}
public void DestroyAllElements(bool isActive)
{
if (isActive)
{
foreach (var obj in activePoolElements)
{
Destroy(obj);
}
activePoolElements.Clear();
}
else
{
foreach (var obj in inactivePoolElements)
{
Destroy(obj);
}
inactivePoolElements.Clear();
}
}
public void ReturnAllElementsToPool()
{
foreach (var obj in activePoolElements)
{
ReturnToPool(obj);
}
activePoolElements.Clear();
}
public int GetInactiveElementsCount()
{
return inactivePoolElements.Count();
}
public int GetActiveElementsCount()
{
return activePoolElements.Count();
}
public void ReturnToPool(T obj)
{
if (obj == null)
{
activePoolElements.RemoveAll(o => o == null);
return;
if (obj.gameObject.activeInHierarchy)
}
if (activePoolElements.Remove(obj))
{
actionOnRelease.Invoke(obj);
inactivePoolElements.Enqueue(obj);
}
return;
}
public IEnumerator<T> GetEnumerator()
{
return pool.GetEnumerator();
return activePoolElements.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()

View File

@ -1,7 +1,18 @@
using System;
using UnityEngine;
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
public class ObstaclePool : BasePool<Obstacle>
namespace Pools
{
public sealed class ObstaclePool : BasePool<Obstacle>
{
}
}

View File

@ -1,34 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BulletProjectile : MonoBehaviour, IResettable
{
[SerializeField] private float projectileSpeed;
[SerializeField] private float projectileLifetime;
private Rigidbody bulletRigidBody;
public WaitForSeconds ProjectileLifetimeWait { get; private set; }
public event Action<BulletProjectile> OnBulletHit;
void Awake()
{
bulletRigidBody = GetComponent<Rigidbody>();
ProjectileLifetimeWait = new WaitForSeconds(projectileLifetime);
}
public void Launch(Vector3 direction)
{
bulletRigidBody.velocity = direction * projectileSpeed;
}
private void OnTriggerEnter(Collider other)
{
if (other.TryGetComponent(out Obstacle obstacle))
{
obstacle.Impact();
OnBulletHit?.Invoke(this);
}
}
public void ResetToDefault()
{
gameObject.SetActive(false);
}
}

View File

@ -1,49 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ProjectileSpawner
{
private BulletProjectile projectilePrefab;
private Transform projectileParent;
private ObjectPool<BulletProjectile> projectilePool;
private int initialPoolCapacity;
public ProjectileSpawner(BulletProjectile projectilePrefab,Transform projectileParent)
{
initialPoolCapacity = 15;
this.projectilePrefab = projectilePrefab;
this.projectileParent = projectileParent;
projectilePool = new ObjectPool<BulletProjectile>(CreateProjectile, GetProjectile, HideProjectile, initialPoolCapacity);
}
private BulletProjectile CreateProjectile()
{
BulletProjectile projectile = GameObject.Instantiate(projectilePrefab, new Vector3(), new Quaternion());
projectile.gameObject.SetActive(false);
projectile.transform.SetParent(projectileParent);
return projectile;
}
private void GetProjectile(BulletProjectile projectile)
{
projectile.gameObject.SetActive(true);
projectile.OnBulletHit += ReturnToPool;
}
private void HideProjectile(BulletProjectile projectile)
{
projectile.ResetToDefault();
projectile.OnBulletHit -= ReturnToPool;
}
public void ReturnToPool(BulletProjectile projectile)
{
if (projectile == null)
return;
projectilePool.ReturnToPool(projectile);
}
public BulletProjectile Spawn(Vector3 spawnPos)
{
BulletProjectile projectile = projectilePool.Get();
projectile.transform.position = spawnPos;
return projectile;
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: ab42421ab93861f429f78f4fd3b1608c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,32 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class Weapon : MonoBehaviour
{
[SerializeField] Transform projectileParent;
[SerializeField] BulletProjectile projectilePrefab;
[SerializeField] Transform muzzlePoint;
ProjectileSpawner projectileSpawner;
private void Awake()
{
projectileSpawner = new ProjectileSpawner(projectilePrefab, projectileParent);
}
public void Equip(Transform weaponPoint)
{
transform.gameObject.SetActive(true);
transform.SetParent(weaponPoint, false);
transform.localPosition = Vector3.zero;
transform.localRotation = Quaternion.identity;
transform.localScale = Vector3.one;
}
public IEnumerator Shoot()
{
Vector3 spawnPosition = muzzlePoint.transform.position;
BulletProjectile projectile = projectileSpawner.Spawn(spawnPosition);
projectile.Launch(Vector3.forward);
yield return projectile.ProjectileLifetimeWait;
projectileSpawner.ReturnToPool(projectile);
}
}