-
Notifications
You must be signed in to change notification settings - Fork 1
Tutorial Pool
Added Pool System feature to CodeOptPro. For now any Node or child of Node can be used as a pooling object. This feature will help a lot in performance for objects that will share common objects. For example if two gun objects have similar bullet type then they can both use a pool of those bullets. That way it will give an illusion that there are a lot of bullets but in reality they are sharing the same bullets. I have also given the option to create your own custom pool system. To use the pool system you will first need to create a new PoolManagerHelper from the Managers tab in the Variable Creator or you can use the already created pool manager resource called default_pool. For any examples below we will be using the default pool manager, default_pool. First lets look into the COP_Pool.
- void add_requests( Node object ) - This is the method for requesting a pool object and MUST be called by the pool object receiver scripts. From the pool manager this is the ONLY method that needs to be called to get a pool object.
To make an object into a pool object receiver you MUST add certain methods to it or just simply use the script template called COP_pool_receiver_object_template.gd which is under Node. Let me explain the properties and methods for the pool object receiver.
- COP_PoolHelper pool_manager - This is the pool manager reference that will be used to request for pool objects. Below is an example on how to requset for a pool object.
func some_func() -> void:
pool_manager.get_manager().add_request(self) # Requesting a pool object
- void _receive_pool_object ( Node object ) - This method receives the pool object from the pool manager. It is advised to change the parameter type to the ones you are expecting to receive. That way it may help with performance a little bit more. Below is an example of when a pool object has been received.
extends Node
var _received_object: Node3D
func _receive_pool_object(object: Node3D) -> void:
_received_object = object # Storing the received object
print("Object Received: ", _received_object.name) # Printing the name of the received object
- bool _is_pool_receiver () - This method just checks if the script is a pool object receiver through duck typing. This method will not effect your code but may later be needed for automation check.
Lets use the pool_local for this example. Firstly create a new Node and name it Update_Manager_Local and add the script process_manager_local.gd. Secondly create a new Node in a scene and name it Pool. Then attach the script called pool_local.gd. Now let me explain all the properties for the pool_local.gd script.
- Update Manager - The reference to the update manager. For local pool manager it should be local update manager and for global pool manager it should be global update manager which is the update manager helper resource.
- Helper - This is the manager helper resource for the pool manager. This manager will be set by the pool manager ONLY and will be called by the pool object receiver. By default there is already a pool manager created called default_pool. You can use that for your game or use a new one by creating it from the Variable Creator under the Manager tab called PoolManagerHelper.
- Is Enable At Start - This flag will decide if the pool manager will be enabled when the game starts. If true then the pooling manager will work from the start. If false then the pooling manager will NOT work from the start. You can also enable/disable the pooling manager through script by calling it's method called set_active(). You will get access to this method either through the COP_PoolHelper reference or by COP_Pool reference. It is recommended to use the COP_PoolHelper reference. Below is an example for the set_active() method.
@export var pool_manager: COP_PoolHelper
func some_func() -> void:
pool_manager.get_manager().set_active(true) # Enabling the pooling system
- P Objects - This array contains all the pool objects, NOTE: The prefix _p means the variable is protected. You do NOT need to populate the array as it will be done automatically when running the auto setup process. The pool manager will add all the children from Pool Object Holder during the auto setup process.
- Pool Object Holder - This is the Node that will contain all pool objects from which the pool objects will be added to the pool manager automatically during the auto setup process. If NO holder is provided to this field then by default the script's Node will be considered as the object holder.
Alright now lets fill up the fields for the pool_local.gd. For the Helper field select the default_pool, NOTE: default_pool resource can be found in res://addons/kamran_wali/code_opt_pro/variables/default_pool.tres. For the Is Enable At Start select the true variable resource, NOTE: true resource can be found in res://addons/kamran_wali/code_opt_pro/variables/true.tres. Keep the other two fields as is because they are going to be auto populated by the auto setup process.
Now add 10 Node3D objects as children for the Pool Node. Name all of them as Obj1, Obj2, Obj3... Obj10 etc. Now run the auto setup process manually, for how to run auto setup process manually please check out the link Auto Setup. You will notice that the P Objects array will be populated with Node3D children from the Pool Object Holder. Also you will notice that the Pool Object Holder will be set as the Pool Node because by default if a Pool Object Holder is NOT provided then the Node that the script is attached to will be stored as the Pool Object Holder.
Ok, now we need to create the pool object receiver script. It is very simple. The best way to create a new pool object receiver script is to create a new script and then using COP_pool_receiver_object_template template, under the Node, to create a new pool object receiver. If you haven't already then you should copy the script_templates folder to the root folder to get the script templates from the CodeOptPro. Another way to make an existing script into a pool object receiver is to add an export variable called var pool_manager: COP_PoolHelper and two more methods to the script called void _receive_pool_object(object) and bool _is_pool_receiver() and then finally making the script a @tool script. Below is an example of a pool object receiver script.
@tool
extends Node
## The pool manager for requesting pool objects.
@export var pool_manager: COP_PoolHelper
var _pool_object: Node3D
func _process(delta) -> void:
if Input.is_action_just_pressed("ui_left"):
pool_manager.get_manager().add_request(self)
## This method receives a pool object
func _receive_pool_object(object) -> void:
_pool_object = object
print("Pool Object: ", _pool_object.name)
## This method always sends true as the script is a pool receiver.
## This method is needed for duck typing check and SHOULD NOT BE
## OVERRIDDEN OR CHANGED!
func _is_pool_receiver() -> bool:
return true
Now go back to the editor and create a new Node and name it Pool Receiver Object and attach the pool receiver object script to it. Select the Pool Receiver Object and give it the default_pool resource in the Pool Manager field. Finally just run the game.
After running the game keep pressing the left arrow key button. You will notice that the Output window is printing all the pool objects' name 1 by 1 and then it cycles back to the first pool object. This is how the pool system works in CodeOptPro.
You can also create your own custom pooling managers. All you have to do is to create a new script using either the COP_pool_manager_local_template.gd or the COP_pool_manager_global_template.gd. I have given notes in the template as well to further help to understand how to create a new custom pooling manager. Let me explain the methods in both the templates.
- void update ( float delta ) - This is the frame update method of the pooling system. It is recommended to call the parent's update method here as well so that the request processes can happen. Also any type of frame dependent logic should be put here.
- void _p_setup_object_pool () - This method is responsible for populating the pool object array during the auto setup process. It is recommended to keep it as is but if you want to make some changes here then you can.
- bool _p_is_pool_object ( Node object ) - During auto setup process this method checks if the added object is a pool object. The default way is the fastest way to check if the object is a pool object. It does so by sending the value true all the time. But if you want to check for a pool object, lets say if the object has a certain method by calling the method has_method(String), then you should do it here.
- bool _p_is_pool_object_available ( Node object ) - This method checks if a pool object is available to send to a request object for example if a flag of a certain object is false only then send it.
- Tutorial Bar
- Tutorial Debug
- Tutorial Instantiate Object
- Tutorial Pool
- Tutorial Timer
- Tutorial Update Manager
- Tutorial Variable Creator
- Bars
- Debugs
- Maths
- Pools
- Resources
- Fixed Vars
- Managers
- Observers
- Vars
- Script Templates
- Timers
- Updates