Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by BerRGP · Mar 06, 2020 at 12:20 AM · unity 2dlists

Need help with an issue regarding lists (I think).

Hello. I apologize in advance if this is not the correct place to post this question. I recently started learning how to use Unity, and I ran into a problem I can't seem to solve.

For a bit of context, I'm trying to create a Tetris-style game. Rather than randomly generate all pieces, I decided to do what the actual games do and give pieces in sets of 7, just in a random order. I created an empty spawner to hold 2 scripts: one to "hold" the default pieces and a list of the upcoming pieces in the game, and one to actually spawn them. While I was doing this second one, I ran into this problem.


The "UpcomingPiecesManager" script:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class UpcomingPiecesManager : MonoBehaviour
 {
     // An array with the pieces that will be generated by default
     public GameObject[] standardPieces;
 
     // A list of the upcoming pieces, which are decided in advance
     private List<GameObject> upcomingPieces = new List<GameObject>();
 
     // Start is called before the first frame update
     void Start()
     {
         // Start with at least 16 pieces
         while (upcomingPieces.Count < 16)
         {
             AddSetOfPieces();
         }
     }
 
     // Update is called once per frame
     void Update()
     {
         // Keep at least 16 pieces generated at a time
         if (upcomingPieces.Count < 16)
         {
             AddSetOfPieces();
         }
     }
 
     // Randomize the order of a given set of pieces
     public GameObject[] RandomizePieceOrder(GameObject[] pieces)
     {
         for (int currentPiece = 0; currentPiece < pieces.Length; currentPiece++)
         {
             int randomIndex = Random.Range(0, pieces.Length);
             GameObject temp = pieces[randomIndex];
             pieces[randomIndex] = pieces[currentPiece];
             pieces[currentPiece] = temp;
         }
         return pieces;
     }
 
     // Add a set of the default pieces in a randomized order
     public void AddSetOfPieces()
     {
         GameObject[] upcomingPiecesAddition = RandomizePieceOrder(standardPieces);
             foreach (var piece in upcomingPiecesAddition)
             {
                 upcomingPieces.Add(piece);
             }
     }
 
     public GameObject GetNextPiece(int index = 0)
     {
         return upcomingPieces[index];
     }
 
     public void DiscardNextPiece()
     {
         upcomingPieces.RemoveAt(0);
     }
 
     public void AddUpcomingPiece(GameObject piece)
     {
         upcomingPieces.Add(piece);
     }
 }



The "PieceSpawner" script:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class PieceSpawner : MonoBehaviour
 {
     // Start is called before the first frame update
     void Start()
     {
         SpawnNextPiece();
     }
 
     // Update is called once per frame
     void Update()
     {
         
     }
 
     // Spawns the next piece in the list and removes it from it
     public void SpawnNextPiece()
     {
         GameObject pieceToSpawn = gameObject.GetComponent<UpcomingPiecesManager>().GetNextPiece();
         gameObject.GetComponent<UpcomingPiecesManager>().DiscardNextPiece();
         Instantiate(pieceToSpawn, transform.position, Quaternion.identity);
     }
 }



When playing the game, I run into this issue:

 ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.


Since the index is 0, it seems to imply the list doesn't contain anything yet. I tried changing "AddSetOfPieces" to show a message whenever a piece is added, and it confirms they are added, so that is working, but the message saying they were added only happens after the error message. That seems to imply to me that the scripts are trying to access the list before the pieces are added. How can I solve this?


I apologize if this is a bit hard to read. As I said, I only just started, but I kind of want to solve this.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by Namey5 · Mar 06, 2020 at 01:18 AM

Logically, there isn't actually anything wrong with your scripts; they function exactly as they should. The error itself however would come from script order. The order in which scripts are executed in Unity isn't always obvious, and in this case chances are your Start function in the second script is being called before the Start function in the first script, therefore the array hasn't been initialised by the time it's being used.

Whilst you can force scripts to execute in a certain order, that's more of a hack and doesn't actually 'fix' the problem. You could also initialise the list in a method that is called earlier, such as OnEnable or Awake, and that would work fine too. Aside from Unity specific hacks though, I would have suggested initialising the array and spawning the first piece in the same place so that you can control the order, but instead I will pose a question; is there a reason these need to be separate scripts in the first place? If the piece spawner script relies entirely on variables from the manager script, would it not be easier to just have the spawning process be a part of the manager script? That way, you could force the calls to be in order, it would centralise the whole process and it shouldn't make things any less readable as the processes in the manager script would still fall under piece management.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image BerRGP · Mar 06, 2020 at 11:30 AM 0
Share

Thank you for your answer! I'm honestly not entirely sure why I decided to separate the scripts... I guess it seemed like a good idea at the time? That's what I get for doing this while tired, I guess.

I'll join the scripts, then. But I'm glad the issue wasn't entirely my fault and was more of a quirk in how Unity works. I'll keep that in $$anonymous$$d in the future. Thanks once again!

avatar image Namey5 BerRGP · Mar 06, 2020 at 01:08 PM 0
Share

Honestly, your scripts are actually very well written (especially when compared to a lot of the samples we get on this website), and I can see why most people like to separate functionality. I just personally prefer to have all relevant code in the same place because it gives me the ability to keep track of everything better, and in cases like this it means that things should just work. At the end of the day, it's all personal preference really - so long as it works the way it was intended and is performant & readable it really doesn't matter.

avatar image BerRGP Namey5 · Mar 06, 2020 at 04:49 PM 0
Share

Yeah, it's just better to join them. And thanks, I was already a bit familiar with program$$anonymous$$g, so I wasn't totally lost. I sometimes fear my code is excessively verbose, but I like to make it as readable as possible.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

129 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Lists are empty when they aren't supposed to be 2 Answers

C# How to display all list items in Unity,C# How to show all items in a list in Unity, one item per line 0 Answers

How do I moveTowards all the items in a list one at a time? 1 Answer

Unity 2D (4.3) Controlling Sprite Playback Code 0 Answers

Perform an action after Animator is finished 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges