Search Unity

Stuck on Respawn Script

Discussion in 'Scripting' started by DP00707, Jan 31, 2015.

  1. DP00707

    DP00707

    Joined:
    Aug 13, 2014
    Posts:
    29
    I'm having a bit of trouble with this script. It gathers everything I need to consider while respawning, then goes through some tests and respawns.

    Now I'm trying to get the spawning to slow between pieces. Before I've had success using
    Code (CSharp):
    1. yield return new WaitForSeconds(x);
    Unfortunately that only seems to work in a CoRoutine. I've also given Invoke and InvokeRepeating a try. I can't seem to get either to work.

    Here is the current state of my code. It dumps a ton of new game pieces all at once.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class Respawner : MonoBehaviour {
    6.  
    7.     //Each Spawn Point Game Object Linked to these for testing purposes
    8.     public int intS1 = 0;
    9.  
    10.     //variables to load from SpawnPieces
    11.     public GameObject Spawner;
    12.     public float fSpawnDelay;
    13.     public int maxPieces;
    14.     public List<GameObject> MasterSpawn = new List<GameObject>();
    15.  
    16.     //variables to load from GamePlay
    17.     public List<GameObject> selectedObj = new List<GameObject>(); //holds game objects
    18.     public List<GameObject> SpawnList = new List<GameObject>(); //Tracks the spawn points selected
    19.     public GameObject track; //gets the value of current object
    20.     public bool click = false;  //used to track whether the mouse was clicked
    21.     public bool click2 = true; //used to track second click
    22.     private bool RisSelected; //tracks respawn
    23.  
    24.  
    25.  
    26.  
    27.     #region GetComponents - Loads all the pieces necessary from other scripts (Loads on Awake)
    28.     void GetComponents() {
    29.         //Get Needed Components from SpawnPieces
    30.         SpawnPieces spawnLoad = GetComponent<SpawnPieces>();
    31.         //Spawner = spawnLoad.Spawner;
    32.         fSpawnDelay = spawnLoad.fSpawnDelay;
    33.         maxPieces = spawnLoad.maxPieces;
    34.         MasterSpawn = spawnLoad.MasterSpawn;
    35.         //Get Needed Components from GamePlay
    36.         GamePlay gamePlay = FindObjectOfType<GamePlay>();
    37.         selectedObj = gamePlay.selectedObj;
    38.  
    39.     }
    40.     #endregion
    41.  
    42.     #region ReSpawner Gather - Tests for Respawn
    43.     void ReSpawnerGather() {
    44.         foreach(GameObject x in selectedObj) {
    45.             //Load values from Piecscore.cs
    46.             PieceScore select = x.GetComponent<PieceScore>();
    47.             //Get value of current selected piece
    48.             RisSelected = select.RisSelected;
    49.             //Load Values from Spawn Tracker
    50.             var t = x.GetComponent<SpawnTracker>();
    51.             //Get Spawn ID
    52.             track = t.spawnID;
    53.             if(RisSelected == false) {
    54.                 //increment value of how many pieces are needed.
    55.                 intS1 ++;
    56.                 //add tracker to the list
    57.                 SpawnList.Add(track);
    58.                 //turn on the selector so it is selected only once
    59.                 select.RisSelected = true;
    60.             }
    61.         }
    62.     }
    63.     #endregion
    64.  
    65.     void ReSpawn() {
    66.         foreach(GameObject x in SpawnList) {
    67.             if(x == Spawner) {
    68.                 for(int i=0; i<intS1; i++) {
    69.                     int randomSpwn = Random.Range(0, MasterSpawn.Count);
    70.                     Instantiate(MasterSpawn[randomSpwn], Spawner.transform.position, Quaternion.identity);
    71.                 }
    72.             }
    73.             else {
    74.                 PieceScore selectcl = x.GetComponent<PieceScore>();
    75.                 selectcl.RisSelected = false;
    76.                
    77.             }
    78.         }
    79.     }
    80.  
    81.     #region SpawnPieces - Spawns pieces
    82.     IEnumerator SpawnPieces() {
    83.         ReSpawnerGather();
    84.         ReSpawn();
    85.         yield return new WaitForSeconds(fSpawnDelay);
    86.         EmptyValues();
    87.     }
    88.     #endregion
    89.  
    90.  
    91.     #region ClickEvent - Mouse Controls for the respawn (Made to mimic GamePlay Class);
    92.     void ClickEvent() {
    93.         if (Input.GetMouseButtonDown(0)) {
    94.             //Debug.Log ("Clicked");
    95.             click = !click;
    96.             click2 = !click2;
    97.  
    98.         }
    99.         if (click == true) {
    100.  
    101.  
    102.         }
    103.         else if (click2 == true) {
    104.             //ReSpawnerGather();
    105.             StartCoroutine(SpawnPieces());
    106.         }
    107.         else {
    108.            
    109.         }
    110.     }
    111.     #endregion
    112.  
    113.     #region Empty Values - Resets variables for retesting
    114.     void EmptyValues() {
    115.         //Empty all values to set up for another test
    116.         intS1 = 0;
    117.         SpawnList.Clear();
    118.        
    119.     }
    120.     #endregion
    121.  
    122.  
    123.     void Awake() {
    124.         GetComponents();
    125.     }
    126.  
    127.     // Use this for initialization
    128.     void Start () {
    129.  
    130.     }
    131.    
    132.     // Update is called once per frame
    133.     void Update () {
    134.         ClickEvent();
    135.  
    136.     }
    137.  
    138. }
    139.  
    I do suspect that it has something to do with being on Update. I try to increment a value "intS1 ++" which does collect the correct number of pieces that I need to respawn. I just can't figure out how to make only that amount spawn.
     
  2. DP00707

    DP00707

    Joined:
    Aug 13, 2014
    Posts:
    29
    Ok new approach. Yet again the Update function is my enemy.

    So I now have removed most of the code and basically started all over. And it still just won't work.

    So the idea is to grab the entire game object list from another class and on click I'm taking each piece from that list, accessing a component (which contains the game object that piece was spawned from) into another list called Spawnlist.

    That works. The next thing I needed to do was take the list of those game objects and see how many times a specific object is contained within that list. Naturally I thought something like:

    Code (CSharp):
    1.     int checkSpawnList() {
    2.         foreach(GameObject x in SpawnList) {
    3.             PieceScore select = x.GetComponent<PieceScore>();
    4.             //Get value of current selected piece
    5.             SisSelected = select.SisSelected;
    6.             if(x == Spawner && SisSelected == false) {
    7.                 if(SisSelected == false) {
    8.                     Debug.Log ("The Update Function hates me");
    9.                     intS1 ++;
    10.                     SisSelected = true;
    11.                 }
    12.             }
    13.         }
    14.         return intS1;
    15.     }
    Well the problem is that intS1 will not increment. No matter what I do. I need this to increment so I have a base for how many pieces need to be respawned. Well, one victory at a time. Here is my current full code:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class Respawner : MonoBehaviour {
    6.  
    7.     //Each Spawn Point Game Object Linked to these for testing purposes
    8.     public int intS1 = 0;
    9.  
    10.     //variables to load from SpawnPieces
    11.     public GameObject Spawner;
    12.     public float fSpawnDelay;
    13.     public int maxPieces;
    14.     public List<GameObject> MasterSpawn = new List<GameObject>();
    15.  
    16.     //variables to load from GamePlay
    17.     public List<GameObject> selectedObj = new List<GameObject>(); //holds game objects
    18.     public List<GameObject> SpawnList = new List<GameObject>(); //Tracks the spawn points selected
    19.     public GameObject track; //gets the value of current object
    20.     public bool click = false;  //used to track whether the mouse was clicked
    21.     public bool click2 = true; //used to track second click
    22.     private bool RisSelected; //tracks respawn
    23.     private bool SisSelected; //tracks respawn
    24.  
    25.  
    26.  
    27.  
    28.     #region GetComponents - Loads all the pieces necessary from other scripts (Loads on Awake)
    29.     void GetComponents() {
    30.         //Get Needed Components from SpawnPieces
    31.         SpawnPieces spawnLoad = GetComponent<SpawnPieces>();
    32.         //Spawner = spawnLoad.Spawner;
    33.         fSpawnDelay = spawnLoad.fSpawnDelay;
    34.         maxPieces = spawnLoad.maxPieces;
    35.         MasterSpawn = spawnLoad.MasterSpawn;
    36.         //Get Needed Components from GamePlay
    37.         GamePlay gamePlay = FindObjectOfType<GamePlay>();
    38.         selectedObj = gamePlay.selectedObj;
    39.  
    40.     }
    41.     #endregion
    42.  
    43.  
    44.     #region ReSpawner Gather - Tests for Respawn and Builds SpawnList
    45.     void ReSpawnerGather() {
    46.         foreach(GameObject x in selectedObj) {
    47.             //Load values from Piecscore.cs
    48.             PieceScore select = x.GetComponent<PieceScore>();
    49.             //Get value of current selected piece
    50.             RisSelected = select.RisSelected;
    51.             //Load Values from Spawn Tracker
    52.             var t = x.GetComponent<SpawnTracker>();
    53.             //Get Spawn ID
    54.             track = t.spawnID;
    55.             if(RisSelected == false) {
    56.                 //add tracker to the list
    57.                 SpawnList.Add(track);
    58.                 //change selected to true
    59.                 RisSelected = true;
    60.             }
    61.         }
    62.     }
    63.     #endregion
    64.  
    65.     int checkSpawnList() {
    66.         foreach(GameObject x in SpawnList) {
    67.             PieceScore select = x.GetComponent<PieceScore>();
    68.             //Get value of current selected piece
    69.             SisSelected = select.SisSelected;
    70.             if(x == Spawner) {
    71.                 if(SisSelected == false) {
    72.                     Debug.Log ("The Update Function hates me");
    73.                     intS1 ++;
    74.                     SisSelected = true;
    75.                 }
    76.             }
    77.         }
    78.         return intS1;
    79.     }
    80.    
    81.  
    82.  
    83.  
    84.     #region ClickEvent - Mouse Controls for the respawn (Made to mimic GamePlay Class);
    85.     void ClickEvent() {
    86.         if (Input.GetMouseButtonDown(0)) {
    87.             //Debug.Log ("Clicked");
    88.             click = !click;
    89.             click2 = !click2;
    90.  
    91.         }
    92.         if (click == true) {
    93.  
    94.  
    95.         }
    96.         else if (click2 == true) {
    97.             ReSpawnerGather();
    98.             checkSpawnList();
    99.  
    100.         }
    101.     }
    102.     #endregion
    103.  
    104.  
    105.  
    106.     void Awake() {
    107.         GetComponents();
    108.     }
    109.  
    110.  
    111.     // Use this for initialization
    112.     void Start () {
    113.  
    114.     }
    115.    
    116.     // Update is called once per frame
    117.     void Update () {
    118.         ClickEvent();
    119.  
    120.  
    121.     }
    122.  
    123. }
    124.  
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,697
    Since disabled scripts and/or non-active game objects so not get their update or other co routines run, you may want to consider a different pattern/approach.

    One nice universal clean respawn pattern I like is to make a new game object with a generic respawn script on it, and a public GameObject field to who you want to reenable, or instantiate.

    Then when it fires, it activates the target to respawn, then it destroys itself. When you want another respawn, lather rinse repeat, making a fresh respawner.
     
  4. DP00707

    DP00707

    Joined:
    Aug 13, 2014
    Posts:
    29
    Hmm that could work. I'm going to have to try that later tonight. Since each GameObject already contains the value for the spawner it came from, maybe something as simple as having it spawn from that same point if the game object is destroyed.

    I'll keep at it. I'm going to get this to work.
     
  5. brainbender

    brainbender

    Joined:
    Feb 1, 2015
    Posts:
    3
    I have a question on spawning. Is it possible to make the spawn point absolutely random on any point of the floor ? I would like to make a random number of enemies appear on any random point of the entire floor.
     
  6. DP00707

    DP00707

    Joined:
    Aug 13, 2014
    Posts:
    29
    Yeah it should be. You would need to put a Random.Range on the Vector3 position part of the Instantiate line.

    If you look at this part of my initial script:
    Code (CSharp):
    1.  
    2. int randomSpwn = Random.Range(0, MasterSpawn.Count);
    3. Instantiate(MasterSpawn[randomSpwn], Spawner.transform.position, Quaternion.identity);
    4.  
    I'm using a Random.Range to generate a random piece to spawn (from a list called MasterSpawn). Next to that is Spawner.transform.position. This is where it would actually spawn from. One note, Spawner is a variable I already preset to be a GameObject. It is grabbing the position information of that game object. If you set up a Random there, you would be able to make them instantiate on a random location.

    One thing you would have to mitigate is the actual range it would be able to spawn from. You probably don't want enemies falling from the sky or being created below your terrain. I'd setup a list of possible spawn points (just a lot of them to appear very random within your world) and then Randomly instantiate to that location from that list.

    Hope that helps.
     
    Last edited: Feb 3, 2015
  7. DP00707

    DP00707

    Joined:
    Aug 13, 2014
    Posts:
    29
    Well I figured out what I was doing wrong on the script. I was actually losing the list of game objects that I needed to test. I think I should have it worked out in a day or two.