Heres my code (the singleton was created later, I used to store those variables inside the script but I was like, maybe if I put it at one place it’s better, I don’t know) :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Sirenix.OdinInspector;
public class FXPoolManager : MonoBehaviour
{
public static FXPoolManager Instance = null;
[SerializeField, Required, TabGroup("Variables")]
WaitForSecondsVariable waitForExplosion = null;
[SerializeField, Required, TabGroup("Pools")]
ParticleSystemPoolVariable explosionFXPool = null;
[SerializeField, Required, TabGroup("Pools")]
ParticleSystemPoolVariable smallExplosionFXPool = null;
[SerializeField, Required, TabGroup("Pools")]
SpriteRendererArrayVariable burnedSprites = null;
[SerializeField, Required, TabGroup("Trees")]
Mesh[] burnedTreeMeshes = null;
[SerializeField, Required, TabGroup("Trees")]
Material burnedTreeMaterial = null;
public WaitForSecondsVariable WaitForExplosion { get { return waitForExplosion; } }
public ParticleSystemPoolVariable ExplosionFXPool { get { return explosionFXPool; } }
public ParticleSystemPoolVariable SmallExplosionFXPool { get { return smallExplosionFXPool; } }
public SpriteRendererArrayVariable BurnedSprites { get { return burnedSprites; } }
public Mesh[] BurnedTreeMeshes { get { return burnedTreeMeshes; } }
public Material BurnedTreeMaterial { get { return burnedTreeMaterial; } }
void Awake ()
{
if (Instance == null)
Instance = this;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using Sirenix.OdinInspector;
public class Building : MonoBehaviour, IDestroyable
{
[SerializeField, Required, TabGroup("Values")]
FloatVariable buildingMaxHealth = null, buildingExplosionSize = null;
public float? Health { get { return health; } }
public float MaxHealth { get { return GetMaxHealth(); } }
public int Value { get { return MaxHealth == 0 ? 1 : (int)buildingMaxHealth.Value; } }
public bool IsDead { get { return false; } }
public Vector3 Position { get { return transform.position; } }
float? health = null;
ParticleSystem explosion = null;
ParticleSystem smallExplosion = null;
Coroutine smallExplosionRoutine = null;
SpriteRenderer burnedSprite = null;
Vector3 spritePosition = Vector3.zero * .2f;
float GetMaxHealth ()
{
return buildingMaxHealth == null ? 0 : buildingMaxHealth.Value;
}
float GetExplosionSize ()
{
return buildingExplosionSize == null ? 2 : buildingExplosionSize.Value;
}
public bool Attack (float _damage, Vector3 _direction)
{
if (!health.HasValue)
health = MaxHealth;
health -= _damage;
if (health <= 0)
{
Kill(_direction);
return true;
}
return false;
}
public void Kill (Vector3 _direction)
{
if (FXPoolManager.Instance.BurnedSprites != null)
{
for (int i = 0; i < FXPoolManager.Instance.BurnedSprites.Items.Length; i++)
{
burnedSprite = Instantiate(FXPoolManager.Instance.BurnedSprites.Items[Random.Range(0, FXPoolManager.Instance.BurnedSprites.Items.Length)]);
spritePosition.x = transform.position.x;
spritePosition.z = transform.position.z;
burnedSprite.transform.position = spritePosition;
}
}
if (FXPoolManager.Instance.ExplosionFXPool != null)
{
explosion = FXPoolManager.Instance.ExplosionFXPool.Pick();
explosion.transform.localScale = Vector3.one * GetExplosionSize();
explosion.transform.position = transform.position + Vector3.up * 2;
explosion.Play();
explosion.gameObject.AddComponent<ParticleDestroyer>().DestroyParticle(FXPoolManager.Instance.ExplosionFXPool, explosion);
}
GetComponent<BoxCollider>().enabled = false;
_direction.Normalize();
Vector3 direction = new Vector3(_direction.x * 10, 10, _direction.z * 10);
transform.DOMove(transform.position + direction, 1.5f).SetEase(Ease.OutQuad).OnComplete(() => Destroy(gameObject));
StartCoroutine(Rotate(_direction));
}
IEnumerator SmallExplosion ()
{
smallExplosion = FXPoolManager.Instance.SmallExplosionFXPool.Pick();
smallExplosion.transform.localScale = Vector3.one;
smallExplosion.transform.position = transform.position + Vector3.up;
smallExplosion.Play();
smallExplosion.gameObject.AddComponent<ParticleDestroyer>().DestroyParticle(FXPoolManager.Instance.SmallExplosionFXPool, smallExplosion);
yield return FXPoolManager.Instance.WaitForExplosion.Wait;
smallExplosionRoutine = null;
}
IEnumerator Rotate (Vector3 _direction)
{
float time = 1.5f;
int randomSpeed = Random.Range(200, 600);
while (time > 0)
{
transform.Rotate(_direction * Time.deltaTime * randomSpeed);
time -= Time.deltaTime;
yield return null;
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using Sirenix.OdinInspector;
public class Tree : MonoBehaviour, IDestroyable
{
public float? Health { get { return health; } }
public float MaxHealth { get { return maxHealth; } }
public int Value { get { return 1; } }
public bool IsDead { get { return false; } }
public Vector3 Position { get { return transform.position; } }
float maxHealth = 0;
float? health = null;
ParticleSystem explosion = null;
ParticleSystem smallExplosion = null;
Coroutine smallExplosionRoutine = null;
SpriteRenderer burnedSprite = null;
Vector3 spritePosition = Vector3.zero * .2f;
public bool Attack (float _damage, Vector3 _direction)
{
if (!health.HasValue)
health = maxHealth;
health -= _damage;
if (health <= 0)
{
Kill(_direction);
return true;
}
if (smallExplosionRoutine == null)
smallExplosionRoutine = StartCoroutine(SmallExplosion());
return false;
}
public void Kill (Vector3 _direction)
{
GetComponent<BoxCollider>().enabled = false;
GetComponent<MeshFilter>().mesh = FXPoolManager.Instance.BurnedTreeMeshes[Random.Range(0, FXPoolManager.Instance.BurnedTreeMeshes.Length)];
GetComponent<MeshRenderer>().material = FXPoolManager.Instance.BurnedTreeMaterial;
if (FXPoolManager.Instance.BurnedSprites != null)
{
for (int i = 0; i < FXPoolManager.Instance.BurnedSprites.Items.Length; i++)
{
burnedSprite = Instantiate(FXPoolManager.Instance.BurnedSprites.Items[Random.Range(0, FXPoolManager.Instance.BurnedSprites.Items.Length)]);
spritePosition.x = transform.position.x;
spritePosition.z = transform.position.z;
burnedSprite.transform.position = spritePosition;
}
}
if (FXPoolManager.Instance.ExplosionFXPool != null)
{
explosion = FXPoolManager.Instance.ExplosionFXPool.Pick();
explosion.transform.localScale = Vector3.one * Random.Range(4, 6);
explosion.transform.position = transform.position + Vector3.up * 3;
explosion.Play();
explosion.gameObject.AddComponent<ParticleDestroyer>().DestroyParticle(FXPoolManager.Instance.ExplosionFXPool, explosion);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using Sirenix.OdinInspector;
public class Fields : MonoBehaviour, IDestroyable
{
[SerializeField, Required]
GameObject[] objectsToDestroy = null;
public float? Health { get { return health; } }
public float MaxHealth { get { return maxHealth; } }
public int Value { get { return 1; } }
public bool IsDead { get { return false; } }
public Vector3 Position { get { return transform.position; } }
float maxHealth = 0;
float? health = null;
SpriteRenderer burnedSprite = null;
Vector3 spritePosition = Vector3.zero * .2f;
ParticleSystem explosion = null;
public bool Attack (float _damage, Vector3 _direction)
{
if (!health.HasValue)
health = maxHealth;
health -= _damage;
if (health <= 0)
{
Kill(_direction);
return true;
}
return false;
}
public void Kill (Vector3 _direction)
{
GetComponent<BoxCollider>().enabled = false;
if (FXPoolManager.Instance.BurnedSprites != null)
{
for (int i = 0; i < FXPoolManager.Instance.BurnedSprites.Items.Length; i++)
{
burnedSprite = Instantiate(FXPoolManager.Instance.BurnedSprites.Items[Random.Range(0, FXPoolManager.Instance.BurnedSprites.Items.Length)]);
spritePosition.x = transform.position.x;
spritePosition.z = transform.position.z;
burnedSprite.transform.position = spritePosition;
}
}
if (FXPoolManager.Instance.ExplosionFXPool != null)
{
explosion = FXPoolManager.Instance.ExplosionFXPool.Pick();
explosion.transform.localScale = Vector3.one * 2;
explosion.transform.position = transform.position + Vector3.up;
explosion.Play();
explosion.gameObject.AddComponent<ParticleDestroyer>().DestroyParticle(FXPoolManager.Instance.ExplosionFXPool, explosion);
}
for (int i = 0; i < objectsToDestroy.Length; i++)
Destroy(objectsToDestroy[i]);
}
}
Building doesnt work for health, they all get destroyed instantly like they have 0 maxHP but only some of them do (set in the inspector).
Tree works fine.
Fields doesn’t destroy objectsToDestroy.
All of them spawns the burnedSprites and the explosionFX.
And this behavior only happens on iOS. Works fine on editor and android.