Should I pool a non-monobehaviour class?
I have an infinite generated level. The level is made up of "tiles". The tiles are a non-mono class which holds a reference to a GameObject. Should I pool this class?
Tile Class
using UnityEngine;
public class Tile { // Meta public GameObject parent; // Parent Object public GameObject obj; // Actual tileObject public GameObject text; // Perfect text effect
 // Must be reset on pool
 public Tile prevTile;
 public Tile nextTile;
 // Input & direction
 // Must be reset to false if pooled
 public Inputs input;
 public D direction;
 public Rigidbody rb;
 public Renderer rend;
 public MeshRenderer flashRenderer;
 public SpriteRenderer inputRenderer;
 public Transform inputTransform;
 public ParticleSystem inputEffect;
 public ParticleSystem perfectEffect;
 // Must be reset on pool
 public Sprite inputSprite;
 public BoxCollider collider;
 // Flags 
 // Must all be reset to false if pooled
 public bool dead = false;
 public bool current = false;
 public bool change = false;
 public bool jump = false;
 public bool bounce = false;
 public bool corner = false;
 public bool isFinish = false;
 public bool shaking = false;
 public bool rippling = false;
 public bool flashing = false;
 // Animation
 // Must be reset on pool
 public int inputSpriteIndex;
 public float time = 0f;
 public Vector3 startShakePos;
 public int shakeRot = 1;
 public float currentShake;
 public float textScaleTime = 0.5f;
 public Tile (GameObject p)
 {
     parent = p;
     collider = p.GetComponent<BoxCollider> ();
     collider.isTrigger = false;
     obj = p.transform.GetChild (0).gameObject;
     text = p.transform.GetChild (4).gameObject;
     text.SetActive (false);
     rb = parent.GetComponent<Rigidbody> ();
     rend = obj.GetComponent <Renderer> ();
     inputTransform = parent.transform.GetChild (1);
     inputRenderer = parent.transform.GetChild (1).GetComponent<SpriteRenderer> ();
     inputEffect = parent.transform.GetChild (2).gameObject.GetComponent<ParticleSystem> ();
     perfectEffect = parent.transform.GetChild (3).gameObject.GetComponent <ParticleSystem> ();
     inputTransform.localScale = new Vector3 (0.3f , 0.3f , 0.3f);
 }
}
Initialization
 public Tile GetProceduralTile ()
 {
     // Get prev tile and save its pos and rotation
     prevTile = m.tiles [m.tiles.Count - 1].parent.transform;
     position = prevTile.position;
     rotation = prevTile.eulerAngles;
     // For shake tiles so they always shake horizontally
     if (rotation != lastRotation)
         tileShakeRot *= -1;
     lastRotation = rotation;
     // Plan the tile
     planner.PlanTile ();
     // Get the tile object from pool
     tileObj = Object.Instantiate (refs.tilePrefabs [(int) planner.tileType]);
     // Instantiate a new Tile class
     tile = new Tile (tileObj); // TODO (maybe) pool the Tile class too
     tile.rb.isKinematic = true;
     tile.collider.isTrigger = false;
     // Set the pos , rot , scale of the parent
     tileObj.transform.position = position;
     tileObj.transform.eulerAngles = rotation;
     tileObj.transform.localScale = new Vector3 (tileSizeXZ , tileSizeY , tileSizeXZ);
     // Offset and rotate the parent
     tileObj.transform.Translate (offsets [planner.offset]);
     tileObj.transform.Rotate (rotations [(int) planner.tileType] , Space.World);
     // Add the Tile class to the parent object's hitboxcomponent
     tileObj.GetComponent<TileHitBox> ().tile = tile;
     // Set the parent tag
     tileObj.tag = normalTag;
     // Set tile flags
     tile.jump = planner.jump;
     tile.change = planner.change;
     tile.bounce = planner.bounce;
     tile.corner = planner.corner;
     // Set tile direction and input and sprite
     tile.input = planner.input;
     tile.shakeRot = tileShakeRot;
     // Return the Tile
     return tile;
 }
Depends. Can you provide some more info on the conditions where you'd create/delete an object?
 
Also does it only contain a gameobject reference or do you also instantiate it?
I updated my question with my code.
I often pool non-monobehaviour objects, mostly collections that have a temporary use
But in my case, I have to reset alot of the variables if I pool them. I am wondering if this is more costly than just instantiating a new class with all the data already set to default?
I don't think that setting a couple of variables will have a great impact. Garbage collector in Unity is getting better, but until now, the GC hiccups were a major issue, so I was avoiding any unnecessary allocation. You will have to benchmark it yourself I guess. But as you said, even when the class is instantiated, it's default constructor set every variable to default.
If every new level creates a list of 300 of these things, you may as well create the list once and re-use it for each level. That's pretty much all pooling is. If you create and destroy a dozen each frame, you may as well put old ones on the UnusedTile list and grab new ones from it.
Object pooling was invented for normal classes, long before Unity. It's not like you can only pool gameObjects, or it only saves time for them.
I only instantiate one every 0.5-1 second.
Answer by Captain_Pineapple · Sep 09, 2019 at 09:51 AM
Looking at your code there is basically just one line that is bothersome: tileObj = Object.Instantiate (refs.tilePrefabs [(int) planner.tileType]);
 
all the rest can be done a few hundered times every frame without any further notice in performance. But instantiation is costly. So your question should be: if you pool, can you get around the instantiation part? if yes -> use pooling. If no -> not sure if there will be any positive effect besides perhaps the GC benefits resulting from pooling. But since you also have to search for inactive pooled objects each time you want to activate one you have to add some performance cost right there. So in that case you'd simply have to try and test it.
Your answer
 
 
              koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                