Using scriptableobjects: Weirdly spawning duplicate prefabs

Hi there!

So, I decided to learn using SO for my next project:

You control a player that can move onto a platform that can be captured by standing on it; The platform loads data from a SO which contains the following three sets of data:
patformPrefab: The building model that will be activated once the platform is captured
figtherPrefab: The units that are spawned every 2 seconds after the platform was captured
Time until captured: The time it takes to capture the building.

The spawning of the units is managed on the platform script that also loads the SO data (probably could be improved, but I am beginner, so I don’t really care about optimizing this at the moment).

Now the weird thing:
Most of the time, the platform acts correctly: After being captured, the building prefab is activated, and the units are spawned perfeclty. However, when I have multiple platforms copy pasted, occasionally (and I cannot really point out when exactly) more than 1 unit is spawned, instead two are spawned at the same time?!

It seems that even if only one platform is in the scene, that occasionally units are spawned twice simultaneoulsy. I just don’t get why. The code never says to spawn two units, so I don’t know where my error is…

This is the code handling the spawning, please help :slight_smile:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlatformBaseLoadSO : MonoBehaviour

{
    public PlatformScriptableObject platformSO;

    private GameObject platformPrefab;
    private GameObject fighterPrefabs;
    private float timeUntilCaptured;

    private float counter;
    private bool _startCounter = false;

    private void Awake()
    {
        LoadSOData();
    }


    private void Update()
    {
        CalculateCaptureTimer();
    }


    private void LoadSOData()
    {
        timeUntilCaptured = platformSO.timeUntilCaptured;
        platformPrefab = Instantiate(platformSO.platformPrefab, transform.position, Quaternion.identity); //fix offset: GO is not flat on the ground;
        platformPrefab.SetActive(false);
        fighterPrefabs = platformSO.fighterPrefabs;
    }

    private void CalculateCaptureTimer()
    {
        if (_startCounter == true)
        {
            counter += Time.deltaTime;
            Debug.Log(counter);
            if (counter >= timeUntilCaptured)
            {
                counter = platformSO.timeUntilCaptured;
                _startCounter = false;
                CapturedPlatform();
            }
        }
        else
        {
            _startCounter = false;
            counter = 0f;
        }
    }

    private void SpawnFigtherUnits()
    {
        StartCoroutine(WaitBeforeSpawningMoreFigthersRoutine());
    }

    IEnumerator WaitBeforeSpawningMoreFigthersRoutine()
    {
        yield return new WaitForSeconds(2f);
        Instantiate(fighterPrefabs, platformPrefab.transform.position + new Vector3(2, 0, 0), Quaternion.identity);
        //set them to a parent obj later;
        SpawnFigtherUnits();
    }

    public void CapturedPlatform()
    {
        platformPrefab.SetActive(true);
        SpawnFigtherUnits();
    }

    private void OnTriggerStay(Collider other)
    {
        if (other.gameObject.tag == "Player")
        {
            _startCounter = true;
            Debug.Log("Player collided with Trigger of platform");
        }

    }

    private void OnTriggerExit(Collider other)
    {
        if (other.gameObject.tag == "Player")
        {
            _startCounter = false;
        }
    }
}

Solved it! In case anyone was wondering: The onTriggerStay started the timer again when the player continued to stand on it. So I added a bool _isCaptured to only start the counter when player stands on the platform AND isCaptured is false. The PlatformCaptured function then sets the isCaptured bool to true, so that the timer cannot run again.

1 Like