Search Unity

Instantiate prefab with individual control script???

Discussion in 'Scripting' started by Ryeath, Apr 27, 2017.

  1. Ryeath

    Ryeath

    Joined:
    Dec 4, 2016
    Posts:
    265
    Hi everyone.

    I don't think I am using instantiate in the correct way and could use a nudge in the right direction.

    Working on my level where the player needs to cross a grid in a specific, randomly generated path. I have the path generation script working (thanks to those who reviewed my code). I now took it into the game (was testing by graphing with paper). I made a prefab cube with a script and a trigger on it. I added to the script a spawn loop that instantiates a cube, assigns the mapCode to it, puts that object in an array and moves to the next one. That is working fine, I can move my player across the grid, if the order is correct the cube turns green, if not the player is sent back to start.

    The problem is when I try to reset the cube colors, the reset only works on the last cube instantiated. The array of cube objects (called tiles in the script) says it has 80 elements, which it should, but the loop only resets the last element.

    Here is the relevant code.

    Code (CSharp):
    1.     private GridTriggerControl tc;      //trigger control object
    2.     public GameObject FloorTile;        //floor trigger object (prefab)
    3.     private GameObject TempTile;
    4.     public Vector3 firstTile = new Vector3(-4.5f, 0.005f, -3.5f);   //start location of grid layout
    5.     private Vector3 SpawnLocation;
    6.     public GameObject[] tiles;
    Code (CSharp):
    1.  public void SetTiles()
    2.     {
    3.         SpawnLocation = firstTile;  //start spot for first quad
    4.         bool startQuad = false;     //flag to set starting quad
    5.         int tilesCount = 0;         //position of prefab in tiles array
    6.  
    7.         for (int i = 0; i < gridRows; i++)
    8.         {
    9.             for (int j = 0; j < gridColumns; j++)
    10.             {
    11.                 TempTile = Instantiate(FloorTile, SpawnLocation, Quaternion.identity);
    12.                 tc = TempTile.GetComponent<GridTriggerControl>();
    13.  
    14.                 if (grid[i, j] == 1)        //match to map code 1 for starting square
    15.                 {
    16.                     startQuad = true;
    17.                 }
    18.                 else startQuad = false;
    19.  
    20.                 tc.CodeAssignment(grid[i, j], startQuad, tilesCount);       //pass map code to floor tile object
    21.                 tiles[tilesCount] = TempTile;
    22.                 tilesCount = tilesCount + 1;
    23.                 SpawnLocation = SpawnLocation + new Vector3(1.0f, 0.0f, 0.0f);
    24.             }
    25.             SpawnLocation.x = firstTile.x;     //reset to first column
    26.             SpawnLocation = SpawnLocation + new Vector3(0.0f, 0.0f, 1.0f); //move to next row
    27.         }
    28.     }
    29.  
    30.     public void ResetTiles()
    31.     {
    32.         for (int i = 0; i < tiles.Length; i++)
    33.         {
    34.             Debug.Log("Tiles Array Length " + tiles.Length);
    35.             tc.Reset();
    36.         }
    37.     }
    38. }
    Code (CSharp):
    1. public class GridTriggerControl : MonoBehaviour
    2. {
    3.     static public int stageCode = 1;
    4.  
    5.     public int gridCode;                //match up with map code on controller
    6.     public int triggerCode;             //element in tiles array
    7.     public PathGenerator PG;            //pathgenerator object
    8.     private PlayerController PC;        //player controller object
    9.     private GameController GC;          //game controller object
    10.  
    11.     private enum quadStatus {clear, set, damage};     //damage state
    12.     private quadStatus status;   //used to determine if damage awarded
    13.     private bool quadActive;
    14.  
    15.     private Renderer rend;
    16.  
    17.     void Awake()
    18.     {
    19.         GameObject PathGenObject = GameObject.FindWithTag("PathGenerator"); //create object instance
    20.         if (PathGenObject != null)
    21.         {
    22.             PG = PathGenObject.GetComponent<PathGenerator>();       //get script reference
    23.         }
    24.         else Debug.Log("Can not find path generator");
    25.  
    26.         GameObject GameControllerObject = GameObject.FindWithTag("GameController"); //create object instance
    27.         if (GameControllerObject != null)
    28.         {
    29.             GC = GameControllerObject.GetComponent<GameController>();       //get script reference
    30.         }
    31.         else Debug.Log("Can not find game controller");
    32.  
    33.  
    34.         GameObject PlayerControllerObject = GameObject.FindWithTag("Player");
    35.         if (PlayerControllerObject != null)
    36.         {
    37.             PC = PlayerControllerObject.GetComponent<PlayerController>();
    38.         }
    39.         else Debug.Log("Can not find player");
    40.  
    41.  
    42.         status = quadStatus.clear;
    43.         quadActive = true;
    44.         rend = GetComponent<Renderer>();
    45.     }
    46.  
    47.     void Start ()
    48.     {
    49.         GC.DisplayUpdate(PC.health.ToString(), "");
    50.     }
    51.  
    52.     public void CodeAssignment(int code, bool startQuad, int tiles)
    53.     {
    54.         triggerCode = tiles;
    55.         gridCode = code;        //mapCode passed from grid array
    56.         if (startQuad)
    57.         {
    58.             rend.material.color = Color.green;
    59.         }
    60.         else rend.material.color = Color.yellow;
    61.  
    62.     }
    63.  
    64.     private void OnTriggerEnter(Collider other)
    65.     {
    66.         GC.DisplayUpdate(PC.health.ToString(), "");
    67.  
    68.         if (!quadActive) return;    //avoid multiple trigger events
    69.  
    70.         if (stageCode == gridCode)  //successful move
    71.         {
    72.             rend.material.color = Color.green;
    73.             status = quadStatus.clear;
    74.             stageCode = stageCode + 1;
    75.             quadActive = false;
    76.         }
    77.         else WrongChoice();
    78.     }
    79.  
    80.     private void WrongChoice()
    81.     {
    82.         if (status == quadStatus.set)
    83.         {
    84.             status = quadStatus.damage;
    85.         }
    86.         else status = quadStatus.set;
    87.  
    88.         if (status == quadStatus.damage)
    89.         {
    90.             PC.health = PC.health - 10;
    91.             GC.DisplayUpdate(PC.health.ToString(), "10 Damage Received");
    92.         }
    93.  
    94.         PC.GridCrossingReset();     //put player back at start
    95.         stageCode = 1;
    96.         PG.ResetTiles();
    97.     }
    98.  
    99.     public void Reset()
    100.     {
    101.         Debug.Log(gridCode);
    102.         Debug.Log(triggerCode);
    103.         rend.material.color = Color.blue;
    104.         quadActive = true;
    105.     }
    106.  
    107. }
    Any help pointing me in the right direction would be much appreciated.

    Edit: The GridTriggerControl script in on the cube. The other code is on the path generator, with some irrelevant code omitted for space.
     
    Last edited: Apr 27, 2017
  2. steego

    steego

    Joined:
    Jul 15, 2010
    Posts:
    969
    Code (csharp):
    1.  
    2.     public void ResetTiles()
    3.     {
    4.         for (int i = 0; i < tiles.Length; i++)
    5.         {
    6.             Debug.Log("Tiles Array Length " + tiles.Length);
    7.             tc.Reset();
    8.         }
    9.     }
    10.  
    You are not using the indexer (i) anywhere, you are only resetting the tc tile multiple times.

    You should probably be doing tiles[ i ].Reset()
     
  3. Ryeath

    Ryeath

    Joined:
    Dec 4, 2016
    Posts:
    265
    Thanks steego.

    I guess I was focusing to hard on my weak area (objects and such), assuming I was doing something wrong there, and overlooked the basics.

    I will try it when I get home tonight.
     
  4. Ryeath

    Ryeath

    Joined:
    Dec 4, 2016
    Posts:
    265
    So, apparently indexer is not the same as index. I have my array set up as just a plain array, but that doesn't appear to work, so I started looking up indexers.

    From what I have read so far an indexer is a property that allows members of a class to be treated like an array. So if I want an array of Objects would I need to make a base class and then use the indexer on a derived class. For example,

    public class BaseTriggerClass
    indexer
    public class Triggers : BasetriggerClass
    TriggerControlScript

    So that way Triggers would be a member of BaseTriggerClass and could be indexed? or am I way off on this?
     
  5. steego

    steego

    Joined:
    Jul 15, 2010
    Posts:
    969
    Indexers are neat, but I don't think you should need them here. Just looping over an array and using the index should be fine, what problem are you having with it?
     
  6. Ryeath

    Ryeath

    Joined:
    Dec 4, 2016
    Posts:
    265
    I only had a little bit of time to mess with it last night, but when I tried using the array index I couldn't get the GridTriggerControl script to reference. Once it didn't work I started reading up on indexers but couldn't quite figure out how they worked.

    If regular array should work, then I just need to do some more experimenting tonight and figure it out.

    Thanks for your help steego.
     
  7. steego

    steego

    Joined:
    Jul 15, 2010
    Posts:
    969
    You might need something like tiles[ i ].GetComponent<GridTriggerControl>().Reset();
     
  8. Ryeath

    Ryeath

    Joined:
    Dec 4, 2016
    Posts:
    265
    I got it working using a list, although I think the array would work also.

    I ended up using two statements, something like

    tc = list
    tc.reset()

    I can post the actual code when I get home later. (is it sad that I have more time to play around when I'm at work than when I am at home?)
    Once I got that working I discovered a minor flaw in my testing logic, but that should be easy enough to resolve.

    Thanks again.
     
    steego likes this.