Help with Instantiation and Sprite changing lag
Hello!
I've been working on a farming game that has you spread a certain amount of seeds and then instantiates the plants where the seeds landed, which is based on a random range. However, this was prone to lag since there were too many plants being instantiated at the same time (1500), so I split them up into 15 lists that are instantiated with 10 second delays. But now, I've run into the issue that, when the plants grow, I apply a new sprite to them to represent that. This is causing huge lag (up to 20 seconds to frame update) and has even led to Unity crashing on me. This happens especially when the instantiation and the sprite change happen in the same frame. The sprites are crunched and I've tried to reduce their quality to no avail. Is there any way I can reduce the performance impact to the point at which it is playable on low-end laptops (since those are my project requirements), and not only my gaming PC? Here's the script applied to the plants:
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
using System.Collections.Generic;
public enum GrowthState
{
State1,
State2,
State3,
State4
}
public class Plant : MonoBehaviour {
private GrowthState currentGrowthState;
public int amount = 10;
//private int start = 0;
private Ertrag ertrag;
private Inventory player;
private PlantManager plantManager;
//private Rigidbody rigidbody;
private GameObject plants;
public SpriteRenderer sprite1Renderer;
public SpriteRenderer sprite2Renderer;
public SpriteRenderer sprite3Renderer;
public Transform sprite1;
public Transform sprite2;
public Transform sprite3;
public float positionGrowthState1;
public float positionGrowthState2;
public float positionGrowthState3;
public float positionGrowthState4;
public Sprite Stage1;
public Sprite Stage2;
public Sprite Stage3;
public Sprite Stage4;
private List<SpriteRenderer> sprites = new List<SpriteRenderer>();
private List<Transform> spriteTransforms = new List<Transform>();
void Start()
{
plants = GameObject.Find("Plants");
string debug = string.Format("The GameObject is: {0}", plants);
Debug.Log(debug);
plantManager = plants.GetComponent<PlantManager>();
debug = string.Format("The PlantManager is: {0}", plantManager);
Debug.Log(debug);
AddToList();
GrowthPhase1();
//rigidbody = GetComponent <Rigidbody> ();
//start = Random.Range(0, 10);
}
/*void Update()
{
if (Input.GetKeyDown (KeyCode.O))
{
if(start <= 5)
{
rigidbody.AddForce (0,amount,0,ForceMode.Impulse);
} else if (start >= 5)
{
rigidbody.AddForce (0,start,0,ForceMode.Impulse);
}
}
start = Random.Range (0, 10);
}*/
void AddToList()
{
sprites.Add(sprite1Renderer);
sprites.Add(sprite2Renderer);
sprites.Add(sprite3Renderer);
spriteTransforms.Add(sprite1);
spriteTransforms.Add(sprite2);
spriteTransforms.Add(sprite3);
}
void GrowthPhase1()
{
currentGrowthState = GrowthState.State1;
foreach(SpriteRenderer sprite in sprites)
{
sprite.sprite = Stage1;
} foreach(Transform sprite in spriteTransforms)
{
Vector3 spritePosition = new Vector3(sprite.position.x, positionGrowthState1, sprite.position.z);
sprite.position = spritePosition;
}
StartCoroutine(Growing1(plantManager.growthPhase1Length));
}
void GrowthPhase2()
{
currentGrowthState = GrowthState.State2;
foreach (SpriteRenderer sprite in sprites)
{
sprite.sprite = Stage2;
}foreach(Transform sprite in spriteTransforms)
{
Vector3 spritePosition = new Vector3(sprite.position.x, positionGrowthState2, sprite.position.z);
sprite.position = spritePosition;
}
StartCoroutine(Growing2(plantManager.growthPhase2Length));
}
void GrowthPhase3()
{
currentGrowthState = GrowthState.State3;
foreach (SpriteRenderer sprite in sprites)
{
sprite.sprite = Stage3;
}foreach(Transform sprite in spriteTransforms)
{
Vector3 spritePosition = new Vector3(sprite.position.x, positionGrowthState3, sprite.position.z);
sprite.position = spritePosition;
}
StartCoroutine(Growing3(plantManager.growthPhase3Length));
}
void GrowthPhase4()
{
currentGrowthState = GrowthState.State4;
foreach (SpriteRenderer sprite in sprites)
{
sprite.sprite = Stage4;
}foreach(Transform sprite in spriteTransforms)
{
Vector3 spritePosition = new Vector3(sprite.position.x, positionGrowthState4, sprite.position.z);
sprite.position = spritePosition;
}
}
void OnTriggerEnter (Collider other)
{
if (currentGrowthState == GrowthState.State4)
{
if (other.CompareTag("Sense"))
{
ertrag = other.GetComponent<Ertrag>();
if (ertrag.senseSchwingt == true)
{
player = ertrag.player;
player.menge = player.menge + amount;
Destroy(this.gameObject);
}
}
}
}
IEnumerator Growing1(float waitTime)
{
yield return new WaitForSeconds(waitTime);
GrowthPhase2();
}
IEnumerator Growing2(float waitTime)
{
yield return new WaitForSeconds(waitTime);
GrowthPhase3();
}
IEnumerator Growing3(float waitTime)
{
yield return new WaitForSeconds(waitTime);
GrowthPhase4();
}
}
And here's the one for the Plant Manager:
using UnityEngine;
using System.Collections;
public class PlantSpawner : MonoBehaviour {
public GameObject plantPrefab;
public int plantAmount = 0;
private byte currentListTransfer = 0;
public float waitBetweenSpawns;
public Transform plantParent;
private GameObject currentPlant;
public Transform seedingManagerTransform;
public SeedingManager seedingManager;
private bool spawning = false;
void Update()
{
if(spawning == true)
{
switch (currentListTransfer)
{
case 2:
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
break;
case 3:
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
break;
case 4:
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
break;
case 5:
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
break;
case 6:
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
break;
case 7:
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
break;
case 8:
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
break;
case 9:
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
break;
case 10:
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
break;
case 11:
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
break;
case 12:
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
break;
case 13:
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
break;
case 14:
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
break;
case 15:
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
break;
case 16:
currentListTransfer = 0;
break;
}
}
}
public void PlantSpawning()
{
Spawn(1);
}
void Spawn(int currentList)
{
switch (currentList)
{
case 1:
foreach (Vector3 seed in seedingManager.Positions1)
{
plantAmount++;
currentPlant = (GameObject)Instantiate(plantPrefab, seed, transform.rotation);
currentPlant.transform.parent = plantParent;
currentPlant.name = string.Format("Plant {0}", plantAmount);
spawning = true;
currentListTransfer = 1;
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
}
break;
case 2:
foreach (Vector3 seed in seedingManager.Positions2)
{
plantAmount++;
currentPlant = (GameObject)Instantiate(plantPrefab, seed, transform.rotation);
currentPlant.transform.parent = plantParent;
currentPlant.name = string.Format("Plant {0}", plantAmount);
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
}
break;
case 3:
foreach (Vector3 seed in seedingManager.Positions3)
{
plantAmount++;
currentPlant = (GameObject)Instantiate(plantPrefab, seed, transform.rotation);
currentPlant.transform.parent = plantParent;
currentPlant.name = string.Format("Plant {0}", plantAmount);
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
}
break;
case 4:
foreach (Vector3 seed in seedingManager.Positions4)
{
plantAmount++;
currentPlant = (GameObject)Instantiate(plantPrefab, seed, transform.rotation);
currentPlant.transform.parent = plantParent;
currentPlant.name = string.Format("Plant {0}", plantAmount);
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
}
break;
case 5:
foreach (Vector3 seed in seedingManager.Positions5)
{
plantAmount++;
currentPlant = (GameObject)Instantiate(plantPrefab, seed, transform.rotation);
currentPlant.transform.parent = plantParent;
currentPlant.name = string.Format("Plant {0}", plantAmount);
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
}
break;
case 6:
foreach (Vector3 seed in seedingManager.Positions6)
{
plantAmount++;
currentPlant = (GameObject)Instantiate(plantPrefab, seed, transform.rotation);
currentPlant.transform.parent = plantParent;
currentPlant.name = string.Format("Plant {0}", plantAmount);
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
}
break;
case 7:
foreach (Vector3 seed in seedingManager.Positions7)
{
plantAmount++;
currentPlant = (GameObject)Instantiate(plantPrefab, seed, transform.rotation);
currentPlant.transform.parent = plantParent;
currentPlant.name = string.Format("Plant {0}", plantAmount);
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
}
break;
case 8:
foreach (Vector3 seed in seedingManager.Positions8)
{
plantAmount++;
currentPlant = (GameObject)Instantiate(plantPrefab, seed, transform.rotation);
currentPlant.transform.parent = plantParent;
currentPlant.name = string.Format("Plant {0}", plantAmount);
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
}
break;
case 9:
foreach (Vector3 seed in seedingManager.Positions9)
{
plantAmount++;
currentPlant = (GameObject)Instantiate(plantPrefab, seed, transform.rotation);
currentPlant.transform.parent = plantParent;
currentPlant.name = string.Format("Plant {0}", plantAmount);
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
}
break;
case 10:
foreach (Vector3 seed in seedingManager.Positions10)
{
plantAmount++;
currentPlant = (GameObject)Instantiate(plantPrefab, seed, transform.rotation);
currentPlant.transform.parent = plantParent;
currentPlant.name = string.Format("Plant {0}", plantAmount);
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
}
break;
case 11:
foreach (Vector3 seed in seedingManager.Positions11)
{
plantAmount++;
currentPlant = (GameObject)Instantiate(plantPrefab, seed, transform.rotation);
currentPlant.transform.parent = plantParent;
currentPlant.name = string.Format("Plant {0}", plantAmount);
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
}
break;
case 12:
foreach (Vector3 seed in seedingManager.Positions12)
{
plantAmount++;
currentPlant = (GameObject)Instantiate(plantPrefab, seed, transform.rotation);
currentPlant.transform.parent = plantParent;
currentPlant.name = string.Format("Plant {0}", plantAmount);
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
}
break;
case 13:
foreach (Vector3 seed in seedingManager.Positions13)
{
plantAmount++;
currentPlant = (GameObject)Instantiate(plantPrefab, seed, transform.rotation);
currentPlant.transform.parent = plantParent;
currentPlant.name = string.Format("Plant {0}", plantAmount);
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
}
break;
case 14:
foreach (Vector3 seed in seedingManager.Positions14)
{
plantAmount++;
currentPlant = (GameObject)Instantiate(plantPrefab, seed, transform.rotation);
currentPlant.transform.parent = plantParent;
currentPlant.name = string.Format("Plant {0}", plantAmount);
StartCoroutine(WaitForSpawn(waitBetweenSpawns));
}
break;
case 15:
foreach (Vector3 seed in seedingManager.Positions15)
{
plantAmount++;
currentPlant = (GameObject)Instantiate(plantPrefab, seed, transform.rotation);
currentPlant.transform.parent = plantParent;
currentPlant.name = string.Format("Plant {0}", plantAmount);
}
plantAmount = 0;
spawning = false;
break;
}
}
IEnumerator WaitForSpawn(float waitTime)
{
yield return new WaitForSeconds(waitTime);
currentListTransfer++;
Spawn(currentListTransfer);
}
}
If you require any more code or screenshots, please ask.
I would like to thank you for any help whatsoever in advance:
Thank You!