Use Update to instantiate specific object

Hi, can someone please help me adjust the code.
I’m trying to spawn more than one unit from a building
I have a UI setup where you click on the button (via event trigger)

right now it works but it spawns one random unit from two update functions

I couldn’t figure out how to edit the “ProduceUnits” function to include more than one unit so I duplicated it.
I realize that it’s a backwards way of doing it but I’m new to coding (just started from 0 one month ago) and just trying to stitch stuff together the best I can.

I basically just want to click the button, spawn queue to start the count down and then eventually spawn the unit
This is a script I followed from a course, and I’m just trying to tweak it to suit my project

Sorry if this isn’t the place for this question, point me in the right direction, please!

this is my code for UnitSpawner:

using Mirror;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class UnitSpawner : NetworkBehaviour, IPointerClickHandler
{
    [SerializeField] private Health health = null;
    [SerializeField] private Unit unitPrefab = null, unitPrefabTank2 = null, unitPrefabTank3 = null;
    //[SerializeField] private Unit unitPrefabTank2 = null;
    //[SerializeField] private Unit unitPrefabTank3 = null;
    [SerializeField] private Transform unitSpawnPoint = null;
    [SerializeField] private TMP_Text remainingUnitsText = null;
    [SerializeField] private Image unitProgressImage = null;
    [SerializeField] private int maxUnitQueue = 5;
    [SerializeField] private float spawnMoveRange = 7;
    [SerializeField] private float unitSpawnDuration = 5;
    [SyncVar(hook = nameof(ClientHandleQueuedUnitsUpdated))]
    private int queuedUnits;
    [SyncVar]
    private float unitTimer;
    private float progressImageVelocity;
    private void Update()
    {
        if (isServer)
        {
            ProduceUnits();
            ProduceUnitTank2();
        }
      
        if (isClient)
        {
            UpdateTimerDisplay();
            //unit queue timer displayer
        }
    }
    #region Server
    //what to do when unit dies
    public override void OnStartServer()
    {
        health.ServerOnDie += ServerHandleDie;
    }
    public override void OnStopServer()
    {
        health.ServerOnDie -= ServerHandleDie;
    }
    [Server]
    private void ProduceUnits()
    {//every frame try to produce units
        //queued Units
       
        if(queuedUnits == 0) { return; }
        unitTimer += Time.deltaTime;
        if(unitTimer < unitSpawnDuration) { return; }
        //unitspawn
        GameObject unitInstance = Instantiate(
            unitPrefab.gameObject,
            unitSpawnPoint.position,
            unitSpawnPoint.rotation);
        NetworkServer.Spawn(unitInstance, connectionToClient);//spawn on all clients and give ownership to one player
        //move it near spawn
        Vector3 spawnOffset = Random.insideUnitSphere * spawnMoveRange;
        spawnOffset.y = unitSpawnPoint.position.y;
        UnitMovement unitMovement = unitInstance.GetComponent<UnitMovement>();
        unitMovement.ServerMove(unitSpawnPoint.position + spawnOffset);
        //reset timer
        queuedUnits--;
        unitTimer = 0f;
       
    }
    private void ProduceUnitTank2()
    {//every frame try to produce units
        //queued Units
        if (queuedUnits == 0) { return; }
        unitTimer += Time.deltaTime;
        if (unitTimer < unitSpawnDuration) { return; }
        //unitspawn
        GameObject unitInstance = Instantiate(
            unitPrefabTank2.gameObject,
            unitSpawnPoint.position,
            unitSpawnPoint.rotation);
        NetworkServer.Spawn(unitInstance, connectionToClient);//spawn on all clients and give ownership to one player
        //move it near spawn
        Vector3 spawnOffset = Random.insideUnitSphere * spawnMoveRange;
        spawnOffset.y = unitSpawnPoint.position.y;
        UnitMovement unitMovement = unitInstance.GetComponent<UnitMovement>();
        unitMovement.ServerMove(unitSpawnPoint.position + spawnOffset);
        //reset timer
        queuedUnits--;
        unitTimer = 0f;
    }
    [Server]
    private void ServerHandleDie()
    {
       NetworkServer.Destroy(gameObject);
    }
    [Command]
    private void CmdSpawnUnitTank1()
    {
        if(queuedUnits == maxUnitQueue) { return; }
        RTSPlayer player = connectionToClient.identity.GetComponent<RTSPlayer>();
        if(player.GetResources() < unitPrefab.GetResourceCost()) { return; }
        queuedUnits++;
        player.SetResources(player.GetResources() - unitPrefab.GetResourceCost());
       
    }
    [Command]
    private void CmdSpawnUnitTank2()
    {
        if (queuedUnits == maxUnitQueue) { return; }
        RTSPlayer player = connectionToClient.identity.GetComponent<RTSPlayer>();
        if (player.GetResources() < unitPrefabTank2.GetResourceCost()) { return; }
        queuedUnits++;
        player.SetResources(player.GetResources() - unitPrefabTank2.GetResourceCost());
    }
    [Command]
    private void CmdSpawnUnitTank3()
    {
        if (queuedUnits == maxUnitQueue) { return; }
        RTSPlayer player = connectionToClient.identity.GetComponent<RTSPlayer>();
        if (player.GetResources() < unitPrefabTank3.GetResourceCost()) { return; }
        queuedUnits++;
        player.SetResources(player.GetResources() - unitPrefabTank3.GetResourceCost());
    }
    #endregion
    #region Client
    private void UpdateTimerDisplay()
    {
        float newProgress = unitTimer / unitSpawnDuration;
        //if it's all filled, put it back to beginign
        if(newProgress < unitProgressImage.fillAmount)
        {
            unitProgressImage.fillAmount = newProgress;
        }
        else
        {
            //code to smove the fill increase
            unitProgressImage.fillAmount = Mathf.SmoothDamp
                (unitProgressImage.fillAmount,
                newProgress,
                ref progressImageVelocity,
                0.1f);      
        }
    }
    public void OnPointerClick(PointerEventData eventData)//when click on game object
    {
        if(eventData.button != PointerEventData.InputButton.Left) { return; }//click left mouse
        if (!hasAuthority) { return; }//check if it's your object
        //CmdSpawnUnit();//spawn unit when clicking on building
    }
   
    private void ClientHandleQueuedUnitsUpdated(int oldUnits, int newUnits)
    {
        remainingUnitsText.text = newUnits.ToString();
    }
    public void EventClickOnUISpawnTank1()//Click on UI to spawn Unit
    {
        CmdSpawnUnitTank1();
    }
    public void EventClickOnUISpawnTank2()//Click on UI to spawn Unit2
    {
        CmdSpawnUnitTank2();
    }
    public void EventClickOnUISpawnTank3()//Click on UI to spawn Unit3
    {
        CmdSpawnUnitTank3();
    }
    #endregion
}

The above code is hideously complicated client-server architected stuff… I would recommend going back to some dramatically-simpler tutorials, otherwise you really are not going to benefit from hammering the above into some kind of functionality without actually understanding what you are doing.

If you insist on continuing with highly-advanced code this early in your career, you need to get good at debugging code and understanding what is really happening. To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

Doing this should help you answer these types of questions:

  • is this code even running? which parts are running? how often does it run?
  • what are the values of the variables involved? Are they initialized?

Knowing this information will help you reason about the behavior you are seeing.

1 Like

Thanks for the reply, I was able to solve it by setting up a few lists and having units called out of those lists.

Sorry, I prob should’ve posted specific parts of code I had questions about, posting the whole thing might look confusing at first. Will know for the future :slight_smile: