浏览代码

Merge branch 'davejrodriguez/object-pool' into main

/main
Ciro Continisio 4 年前
当前提交
0174edd5
共有 16 个文件被更改,包括 45 次插入1162 次删除
  1. 7
      UOP1_Project/Assets/Scripts/Factory/FactorySO.cs
  2. 9
      UOP1_Project/Assets/Scripts/Pool/ComponentPoolSO.cs
  3. 2
      UOP1_Project/Assets/Scripts/Pool/Example/Assets/Example.unity
  4. 24
      UOP1_Project/Assets/Scripts/Pool/Example/LocalPoolTester.cs
  5. 16
      UOP1_Project/Assets/Scripts/Pool/Example/ParticleFactorySO.cs
  6. 4
      UOP1_Project/Assets/Scripts/Pool/Example/ParticlePoolSO.cs
  7. 21
      UOP1_Project/Assets/Scripts/Pool/Example/PoolTester.cs
  8. 11
      UOP1_Project/Assets/Scripts/Pool/PoolSO.cs
  9. 11
      UOP1_Project/Assets/Scripts/Factory/ComponentFactorySO.cs.meta
  10. 22
      UOP1_Project/Assets/Scripts/Factory/ComponentFactorySO.cs
  11. 1001
      UOP1_Project/Assets/Scripts/Pool/Example/Assets/Particles.prefab
  12. 7
      UOP1_Project/Assets/Scripts/Pool/Example/Assets/Particles.prefab.meta
  13. 37
      UOP1_Project/Assets/Scripts/Pool/Example/PoolableParticle.cs
  14. 11
      UOP1_Project/Assets/Scripts/Pool/Example/PoolableParticle.cs.meta
  15. 13
      UOP1_Project/Assets/Scripts/Pool/IPoolable.cs
  16. 11
      UOP1_Project/Assets/Scripts/Pool/IPoolable.cs.meta

7
UOP1_Project/Assets/Scripts/Factory/FactorySO.cs


/// Implements the IFactory interface for non-abstract types.
/// </summary>
/// <typeparam name="T">Specifies the non-abstract type to create.</typeparam>
public abstract class FactorySO<T> : ScriptableObject, IFactory<T> where T : new()
public abstract class FactorySO<T> : ScriptableObject, IFactory<T>
public virtual T Create()
{
return new T();
}
public abstract T Create();
}
}

9
UOP1_Project/Assets/Scripts/Pool/ComponentPoolSO.cs


/// Implements a Pool for Component types.
/// </summary>
/// <typeparam name="T">Specifies the component to pool.</typeparam>
public abstract class ComponentPoolSO<T> : PoolSO<T> where T : Component, IPoolable
public abstract class ComponentPoolSO<T> : PoolSO<T> where T : Component
{
public abstract int InitialPoolSize { get; set; }
private GameObject _poolRootObject;

{
InitializePool();
}
return base.Request();
T member = base.Request();
member.gameObject.SetActive(true);
return member;
}
public override void Return(T member)

InitializePool();
}
member.transform.SetParent(_poolRootObject.transform);
member.gameObject.SetActive(false);
base.Return(member);
}

newMember.transform.SetParent(_poolRootObject.transform);
newMember.gameObject.SetActive(false);
return newMember;
}

2
UOP1_Project/Assets/Scripts/Pool/Example/Assets/Example.unity


m_Script: {fileID: 11500000, guid: ff0fb790d778a05429eca3a001ab6be1, type: 3}
m_Name:
m_EditorClassIdentifier:
_prefab: {fileID: -6757246126632128155, guid: 13e8a2294914b7744a0b9fe47b807ead,
type: 3}
_initialPoolSize: 5
--- !u!4 &648587143
Transform:

24
UOP1_Project/Assets/Scripts/Pool/Example/LocalPoolTester.cs


public class LocalPoolTester : MonoBehaviour
{
[SerializeField]
private PoolableParticle _prefab = default;
[SerializeField]
private IEnumerator Start()
private void Start()
_factory.Prefab = _prefab;
List<PoolableParticle> particles = _pool.Request(10) as List<PoolableParticle>;
foreach (PoolableParticle particle in particles)
List<ParticleSystem> particles = _pool.Request(10) as List<ParticleSystem>;
foreach (ParticleSystem particle in particles)
particle.transform.position = Random.insideUnitSphere * 5f;
particle.Play();
StartCoroutine(DoParticleBehaviour(particle));
yield return new WaitForSecondsRealtime(5f);
_pool.Return(particles);
}
private IEnumerator DoParticleBehaviour(ParticleSystem particle)
{
particle.transform.position = Random.insideUnitSphere * 5f;
particle.Play();
yield return new WaitForSeconds(particle.main.duration);
particle.Stop(true, ParticleSystemStopBehavior.StopEmitting);
yield return new WaitUntil(()=>particle.particleCount==0);
_pool.Return(particle);
}
}

16
UOP1_Project/Assets/Scripts/Pool/Example/ParticleFactorySO.cs


using UOP1.Factory;
[CreateAssetMenu(fileName = "NewParticleFactory", menuName = "Factory/Particle Factory")]
public class ParticleFactorySO : ComponentFactorySO<PoolableParticle>
public class ParticleFactorySO : FactorySO<ParticleSystem>
[SerializeField]
private PoolableParticle _prefab = default;
public override PoolableParticle Prefab
public override ParticleSystem Create()
get
{
return _prefab;
}
set
{
_prefab = value;
}
return new GameObject("ParticleSystem").AddComponent<ParticleSystem>();
}
}

4
UOP1_Project/Assets/Scripts/Pool/Example/ParticlePoolSO.cs


using UOP1.Factory;
[CreateAssetMenu(fileName = "NewParticlePool", menuName = "Pool/Particle Pool")]
public class ParticlePoolSO : ComponentPoolSO<PoolableParticle>
public class ParticlePoolSO : ComponentPoolSO<ParticleSystem>
{
[SerializeField]
private ParticleFactorySO _factory;

public override IFactory<PoolableParticle> Factory
public override IFactory<ParticleSystem> Factory
{
get
{

21
UOP1_Project/Assets/Scripts/Pool/Example/PoolTester.cs


[SerializeField]
private ParticlePoolSO _pool = default;
private IEnumerator Start()
private void Start()
List<PoolableParticle> particles = _pool.Request(10) as List<PoolableParticle>;
foreach (PoolableParticle particle in particles)
List<ParticleSystem> particles = _pool.Request(10) as List<ParticleSystem>;
foreach (ParticleSystem particle in particles)
particle.transform.position = Random.insideUnitSphere * 5f;
particle.Play();
StartCoroutine(DoParticleBehaviour(particle));
yield return new WaitForSeconds(5f);
_pool.Return(particles);
}
private IEnumerator DoParticleBehaviour(ParticleSystem particle)
{
particle.transform.position = Random.insideUnitSphere * 5f;
particle.Play();
yield return new WaitForSeconds(particle.main.duration);
particle.Stop(true, ParticleSystemStopBehavior.StopEmitting);
yield return new WaitUntil(() => particle.particleCount == 0);
_pool.Return(particle);
}
}

11
UOP1_Project/Assets/Scripts/Pool/PoolSO.cs


/// A generic pool that generates members of type T on-demand via a factory.
/// </summary>
/// <typeparam name="T">Specifies the type of elements to pool.</typeparam>
public abstract class PoolSO<T> : ScriptableObject, IPool<T> where T : IPoolable
public abstract class PoolSO<T> : ScriptableObject, IPool<T>
{
protected readonly Stack<T> _available = new Stack<T>();
public abstract IFactory<T> Factory { get; set; }

public virtual T Request()
{
T member = _available.Count > 0 ? _available.Pop() : Create();
member.OnRequest();
return member;
return _available.Count > 0 ? _available.Pop() : Create();
}
public virtual IEnumerable<T> Request(int num = 1)

public virtual void Return(T member)
{
member.OnReturn(() =>
{
_available.Push(member);
});
_available.Push(member);
}
public virtual void Return(IEnumerable<T> members)

11
UOP1_Project/Assets/Scripts/Factory/ComponentFactorySO.cs.meta


fileFormatVersion: 2
guid: 1d5f471b49fdf1c43a84a8deeedc5183
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

22
UOP1_Project/Assets/Scripts/Factory/ComponentFactorySO.cs


using UnityEngine;
namespace UOP1.Factory
{
/// <summary>
/// Implements the IFactory interface for Component types.
/// </summary>
/// <typeparam name="T">Specifies the component to create.</typeparam>
public abstract class ComponentFactorySO<T> : ScriptableObject, IFactory<T> where T : Component
{
public abstract T Prefab
{
get;
set;
}
public virtual T Create()
{
return Instantiate(Prefab);
}
}
}

1001
UOP1_Project/Assets/Scripts/Pool/Example/Assets/Particles.prefab
文件差异内容过多而无法显示
查看文件

7
UOP1_Project/Assets/Scripts/Pool/Example/Assets/Particles.prefab.meta


fileFormatVersion: 2
guid: 13e8a2294914b7744a0b9fe47b807ead
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

37
UOP1_Project/Assets/Scripts/Pool/Example/PoolableParticle.cs


using UOP1.Pool;
using System;
using System.Collections;
using UnityEngine;
public class PoolableParticle : MonoBehaviour, IPoolable
{
[SerializeField]
private ParticleSystem _particleSystem = default;
public void OnRequest()
{
gameObject.SetActive(true);
}
public void Play()
{
_particleSystem.Play();
}
public void OnReturn(Action onReturned)
{
StartCoroutine(DoReturn(onReturned));
}
IEnumerator DoReturn(Action onReturned)
{
if (_particleSystem.isPlaying)
{
yield return new WaitForSeconds(_particleSystem.main.duration - (_particleSystem.time % _particleSystem.main.duration));
_particleSystem.Stop();
}
yield return new WaitUntil(() => _particleSystem.particleCount == 0);
onReturned.Invoke();
gameObject.SetActive(false);
}
}

11
UOP1_Project/Assets/Scripts/Pool/Example/PoolableParticle.cs.meta


fileFormatVersion: 2
guid: 91146385b82059840915ac17bbf904ae
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

13
UOP1_Project/Assets/Scripts/Pool/IPoolable.cs


using System;
namespace UOP1.Pool
{
/// <summary>
/// Represents an object that can be pooled.
/// </summary>
public interface IPoolable
{
void OnRequest();
void OnReturn(Action onReturned);
}
}

11
UOP1_Project/Assets/Scripts/Pool/IPoolable.cs.meta


fileFormatVersion: 2
guid: 936084c4c3e4d6848bfa61084af46c1c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存