silverua / slay-the-spire-map-in-unity

Implementation of the Slay the Spire Map in Unity3d
MIT License
273 stars 65 forks source link

ArgumentOutOfRangeException: Index was out of range #12

Open scobbydoodev opened 3 years ago

scobbydoodev commented 3 years ago

Hello I'm getting this error when i try to regenerate the map:

ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index System.ThrowHelper.ThrowArgumentOutOfRangeException (System.ExceptionArgument argument, System.ExceptionResource resource) (at <437ba245d8404784b9fbab9b439ac908>:0) System.ThrowHelper.ThrowArgumentOutOfRangeException () (at <437ba245d8404784b9fbab9b439ac908>:0) System.Collections.Generic.List1[T].get_Item (System.Int32 index) (at <437ba245d8404784b9fbab9b439ac908>:0) Map.ShufflingExtension.Random[T] (System.Collections.Generic.IList1[T] list) (at Assets/Scripts/ShufflingExtension.cs:29) Map.MapGenerator.PlaceLayer (System.Int32 layerIndex) (at Assets/Scripts/MapGenerator.cs:77) Map.MapGenerator.GetMap (Map.MapConfig conf) (at Assets/Scripts/MapGenerator.cs:33) Map.MapManager.GenerateNewMap () (at Assets/Scripts/MapManager.cs:41) Map.MapManagerInspector.OnInspectorGUI () (at Assets/Scripts/Editor/MapManagerInspector.cs:18) UnityEditor.UIElements.InspectorElement+<>c__DisplayClass55_0.b__0 () (at <78f1ad0f25c84e3ca853e639f50d95f5>:0) UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)

I have added some new types of nodes and added to my MapConfig but I can't solve this problem. Thanks.

silverua commented 3 years ago

Hi. Thanks for posting.

Short answer: node blueprints of some node types are missing in your MapConfig scriptable object that you are using to create your map. The simplest fix - make sure that node blueprints of all the possible types that are defined in the project are featured in the nodeBlueprints list of your MapConfig scriptable object (make new NodeBlueprint objects with NodeTypes that you are missing, plug them into your MapConfig).

Long answer: The line where you are most likely getting this error is this one: var blueprintName = config.nodeBlueprints.Where(b => b.nodeType == nodeType).ToList().Random().name;

You will be getting an error similar to yours if you try to call .Random() on an empty collection. Empty collection in this case means that some node for this layer was either defined in the map config or randomly generated, but there was no such node in the nodeBlueprints of the MapConfig.

nodeType is either defined in the config or randomly selected in this line if random generation is enabled: var nodeType = Random.Range(0f, 1f) < layer.randomizeNodes ? GetRandomNode() : layer.nodeType;

NodeTypes that can be selected randomly are defined in this list: private static readonly List RandomNodes = new List {NodeType.Mystery, NodeType.Store, NodeType.Treasure, NodeType.MinorEnemy, NodeType.RestSite};

To make sure that you are not getting any errors, make sure that your MapConfig object has at least one NodeBlueprint of each of these types added into nodeBlueprints list. Because you can randomly get one of these node types and the corresponding NodeBlueprint must be there. Otherwise, you will get the same error again. If you are noticing that this RandomNodes list contains some of the NodeTypes that you are not going to have in your game or that you are not using, you can just remove entries from this list or replace them with new NodeTypes that you want to use.

scobbydoodev commented 3 years ago

Thank you your answer solved my porblem, now i'm having another issue when i click on the generate button the new map overlaps the old but the old don't dissapear i dont have any error on the console. Why is this happening? Thank you

silverua commented 3 years ago

After you generate, it then calls MapView.ShowMap(), which then calls MapView.ClearMap(). I would compare your code with the original code from the repo: 1) Does the method MapView.ShowMap() have a call ClearMap(); in it? 2) Is the method ClearMap() any different from the one in the original project? 3) Add breakpoints and run with debugger or include logs into these methods to make sure that they are getting called.

paulan94 commented 1 year ago

I also got a similar error from removing one of the already existing nodes in the nodeBlueprints list of the defaultmapconfig scriptable object. The error was because I deleted the "Store" NodeType in the NodeBlueprint class. As a result, it seemingly set the already existing Node scriptableobjects ("Minor Enemy", "Treasure", etc) to random types or null in the case of the "Store" scriptable object. Once I changed those values to non-null values the errors subsided.

Bufferoverflovv commented 1 year ago

@paulan94 are you able to share your fix for this? I was hoping to remove the example nodes and create my own but it's been giving me a lot of errors trying to do this.

For example I remove the rest site node from the Random Nodes list and then remove it from my list of nodes in the mapconfig and the layer. This works fine and the rest site node no longer generates. However when I go to remove the enum entry in NodeBlueprint is when there is an index exception error.

Adding my own nodes works okay until I also sometimes get an index exception error where I think its trying to add a null node.

paulan94 commented 1 year ago

@Bufferoverflovv have you looked at your map config's layers? I'm using the default map config, but edited it to match my needs. You said you removed those nodes from the layer, but it may have caused some errors with the node paths for the other nodes. You have to make sure that the nodes in the "Layers" section of the map config are valid, otherwise it will throw an index exception.

Bufferoverflovv commented 1 year ago

@paulan94 I have no layer in my map config with a rest site node set, it's not set in the mapgenerator class in random nodes, it's been removed from the list of node types and the scriptable object was deleted from the project. Still getting the same error.

ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index System.Collections.Generic.List1[T].get_Item (System.Int32 index) (at <75633565436c42f0a6426b33f0132ade>:0) Map.ShufflingExtension.Random[T] (System.Collections.Generic.IList1[T] list) (at Assets/Scripts/ShufflingExtension.cs:29) Map.MapGenerator.PlaceLayer (System.Int32 layerIndex) (at Assets/Scripts/MapGenerator.cs:76) Map.MapGenerator.GetMap (Map.MapConfig conf) (at Assets/Scripts/MapGenerator.cs:33) Map.MapManager.GenerateNewMap () (at Assets/Scripts/MapManager.cs:41)

I can't really pinpoint why this is still giving me an error.

@silverua Is there any chance you could do a write up or a video about how to create and add your own nodes or remove the example nodes?