Giter VIP home page Giter VIP logo

unitygenericpool's Introduction

UnityGenericPool

A pooling solution for Unity3D that can store "almost" anything; ranging from Unity objects (e.g. Component, GameObject, Texture) to plain C# objects. It can't store structs but since they are pass-by-value, that would be pointless.

This pool comes with a helper class (SimplePoolHelper) that provides global access to pools that can optionally be named. It is no longer necessary to keep references to pools in your scripts (however, if you wish, you can ignore SimplePoolHelper and manage your pools manually). Note that SimplePoolHelper pools are stored statically and are persistent between scenes.

Method Signatures

SimplePool<T>:

bool Populate( int count )
bool Populate( T blueprint, int count )
T Pop()
T[] Pop( int count )
void Push( T obj )
void Push( IEnumerable<T> objects )
void Clear( bool destroyObjects = true )

SimplePoolHelper:

static SimplePool<T> GetPool<T>( string poolName = null )
static void Push<T>( T obj, string poolName = null )
static T Pop<T>( string poolName = null )
static void Pool<T>( this T obj, string poolName = null )

Example Code

using UnityEngine;

public class PlayerWeapons : MonoBehaviour 
{
	public Transform bulletPrefab;
	public Transform grenadePrefab;

	// Called when the scene starts
	void Awake()
	{
		// Get a Transform pool called Bullets
		SimplePool<Transform> bulletsPool = SimplePoolHelper.GetPool<Transform>( "Bullets" );

		// Get another Transform pool called Grenades
		SimplePool<Transform> grenadesPool = SimplePoolHelper.GetPool<Transform>( "Grenades" );

		// When a bullet is pooled, deactivate it
		bulletsPool.OnPush = ( item ) => item.gameObject.SetActive( false );

		// When a bullet is fetched from the pool, activate it and set its position
		bulletsPool.OnPop = ( item ) =>
		{
			item.gameObject.SetActive( true );
			item.position = transform.position;
			item.rotation = transform.rotation;
		};
		
		// When pool tries to create a new bullet (when empty), create an instance of bulletPrefab and keep it alive between scenes
		bulletsPool.CreateFunction = ( template ) => 
		{
			Transform newBullet = Instantiate( bulletPrefab );
			DontDestroyOnLoad( newBullet );
			return newBullet;
		};

		// When a grenade is pooled, deactivate it
		grenadesPool.OnPush = ( item ) => item.gameObject.SetActive( false );
		// When a grenade is fetched from the pool, activate it (you can also set its position here, it is entirely up to you)
		grenadesPool.OnPop = ( item ) => item.gameObject.SetActive( true );
		// When pool tries to create a new grenade, simply create an instance of grenadePrefab
		grenadesPool.CreateFunction = ( template ) => Instantiate( grenadePrefab );

		// Populate the pool with 10 bullet instances (optional)
		bulletsPool.Populate( 10 );

		// Populate the pool with 4 grenade instances (optional)
		grenadesPool.Populate( 4 );

		// Yet another pool that will store some WaitForSeconds instances for reuse in Grenade class
		// This pool is different from the previous pools in two ways:
		// 1) it stores a plain object: WaitForSeconds, which is not a Component nor a GameObject
		// 2) it has no name since there is only one pool of type WaitForSeconds; note that
		//    it is faster and more efficient to access an unnamed pool in SimplePoolHelper
		// CreateFunction: simply create a new WaitForSeconds instance that waits for 6 seconds
		// There is no need to do any special operations on OnPush or OnPop, so they are not altered
		SimplePoolHelper.GetPool<WaitForSeconds>().CreateFunction = ( template ) => new WaitForSeconds( 6f );
	}

	// Called when the object is destroyed
	void OnDestroy()
	{
		// This transform is about to be destroyed, bullets fetched from pool can no longer use it
		// So fetched bullets are simply activated, without changing their position
		SimplePoolHelper.GetPool<Transform>( "Bullets" ).OnPop = ( item ) => item.gameObject.SetActive( true );

		// Grenades in the pool are not persistent between scenes (unlike bullets), and will become null references
		// So clear all grenade instances in the Grenades pool
		SimplePoolHelper.GetPool<Transform>( "Grenades" ).Clear();
	}

	void Update()
	{
		// Left mouse button clicked: fire a bullet
		if( Input.GetMouseButtonDown( 0 ) )
		{
			// Add forward force to the bullet
			SimplePoolHelper.Pop<Transform>( "Bullets" ).GetComponent<Rigidbody>().velocity = transform.forward * 100f;
		}

		// Right mouse button clicked: throw a grenade
		if( Input.GetMouseButtonDown( 1 ) )
		{
			Transform grenade = SimplePoolHelper.Pop<Transform>( "Grenades" );

			// Set the position of the grenade (unlike bullets, it is not automatically set in Pop)
			grenade.position = transform.position;

			// Add forward force to the grenade (also some upwards force as well)
			grenade.GetComponent<Rigidbody>().velocity = transform.forward * 30f + transform.up * 15f;
		}
	}
}
using UnityEngine;

public class Bullet : MonoBehaviour 
{
	// Pool the bullet if it doesn't hit anything in 5 seconds
	void OnEnable()
	{
		Invoke( "PoolBullet", 5f );
	}

	// Bullet is deactivated (probably hit something and got pooled), cancel the PoolBullet invoke just in case
	void OnDisable()
	{
		CancelInvoke( "PoolBullet" );
	}
	
	void OnCollisionEnter( Collision other )
	{
		// Apply damage to the collided entity
		Health entityHealth = other.transform.GetComponent<Health>();
		if( entityHealth != null )
			entityHealth.ApplyDamage( 10 );

		// Pool the bullet instead of destroying it 
		// As bullets are kept in a Transform pool, the Pool extension function is used on the transform of the pool
		transform.Pool( "Bullets" );

		// Alternative pool method (does exactly the same thing as Pool function)
		// SimplePoolHelper.Push( transform, "Bullets" );
	}

	private void PoolBullet()
	{
		transform.Pool( "Bullets" );
	}
}
using UnityEngine;
using System.Collections;

public class Grenade : MonoBehaviour 
{
	// Explode after 6 seconds
	// Notice how we use OnEnable instead of Start as Start is only called once during the lifetime of the object
	void OnEnable()
	{
		StartCoroutine( Explode() );
	}

	IEnumerator Explode()
	{
		// Fetch an instance of WaitForSeconds from the pool
		WaitForSeconds waitForSeconds = SimplePoolHelper.Pop<WaitForSeconds>();

		// Wait for 6 seconds (set in PlayerWeapons class)
		yield return waitForSeconds;

		// Pool the WaitForSeconds instance for reuse
		waitForSeconds.Pool();

		// Play some fancy particles
		GetComponent<ParticleSystem>().Emit( 50 );

		// Pool the grenade for reuse
		transform.Pool( "Grenades" );
	}
}

unitygenericpool's People

Contributors

yasirkula avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.