Search Unity

Question I can't seem to "attach" an instance of a scriptable object to another scriptable object

Discussion in 'Scripting' started by samdaman93, Apr 6, 2021.

  1. samdaman93

    samdaman93

    Joined:
    Oct 3, 2015
    Posts:
    37
    Hello,

    I'm writing a text adventure at the moment and I'm coding the method that takes an array of strings and turns them into scriptable objects. I did this so I can create the objects at runtime and I'm not worried about changing any of their values permanently. I've got two issues:

    - Is there a way to view the scriptable objects instances I create? I think this would help in debugging my problem
    - I seem to have to created the right objects, my code just gets stuck at line 89 in the code below because of the error below. Note I've only copied the method that creates the scriptable objects and line 258 is line 89.

    NullReferenceException: Object reference not set to an instance of an object
    GameController.createRooms (System.String[] textArray) (at Assets/Scripts/GameController.cs:258)
    GameController.Awake () (at Assets/Scripts/GameController.cs:32)

    Code (CSharp):
    1.     public void createRooms(string[] textArray)
    2.     {
    3.         List<Room> Rooms = new List<Room>();
    4.         List<int> roomTextPositions = new List<int>();
    5.         Dictionary<string, Room> RoomNames = new Dictionary<string, Room>();
    6.  
    7.         //create room objects
    8.         int counter = 0;
    9.         foreach (string line in textArray)
    10.         {
    11.             counter += 1;
    12.             if (line.Contains("[R]"))
    13.             {
    14.                 roomTextPositions.Add(counter);
    15.                 int textline = counter;
    16.                 string lineHolder = line.Replace("[R]", "");
    17.                 Room Room = ScriptableObject.CreateInstance("Room") as Room;
    18.                 Room.description = textArray[counter].Replace("[D1]","");
    19.                 Room.returnToRoomDescription = textArray[counter+1].Replace("[D2]", "");
    20.                 Rooms.Add(Room);
    21.                 RoomNames.Add(lineHolder, Room);
    22.                
    23.             }
    24.            
    25.         }
    26.  
    27.         for (int i = 0; i < Rooms.Count; i++)
    28.         {
    29.             //checks if the next room in text file has been found, if so will break while loop and return exits.
    30.             bool bootfromscript = false;
    31.  
    32.             int Linecounter;
    33.  
    34.             //make exit array per room
    35.             for (int j = 0; j < Rooms.Count; j++)
    36.             {
    37.                 int roomExits = 0;
    38.                 Linecounter = roomTextPositions[j];
    39.                 bootfromscript = false;
    40.  
    41.                 while (bootfromscript != true)
    42.                 {
    43.                     if (textArray[Linecounter].Contains("[R]")||Linecounter==textArray.Length-1)
    44.                     {
    45.                         bootfromscript = true;
    46.                     }
    47.  
    48.                     if (textArray[Linecounter].Contains("[E]"))
    49.                     {
    50.                         roomExits++;
    51.                         Rooms[i].exits = new Exit[roomExits];
    52.                     }
    53.  
    54.                     Linecounter++;
    55.                 }
    56.  
    57.             }
    58.  
    59.             //Setup exits and attach to rooms
    60.             for (int j = 0; j < Rooms[i].exits.Length; j++)
    61.             {
    62.                 int Exitcounter = 0;
    63.                 Linecounter = roomTextPositions[i];
    64.                 bootfromscript = false;
    65.  
    66.                 while (bootfromscript != true)
    67.                 {
    68.                     if (textArray[Linecounter].Contains("[R]") || Linecounter == textArray.Length - 1)
    69.                     {
    70.                         bootfromscript = true;
    71.                     }
    72.  
    73.                     if (textArray[Linecounter].Contains("[E]"))
    74.                     {
    75.                         Exit exit = new Exit();
    76.                         exit.exitDescription = textArray[Linecounter + 1].Replace("[ED]", "");
    77.                         exit.valueRoom = RoomNames[textArray[Linecounter].Replace("[E]", "")];
    78.                         Rooms[i].exits[Exitcounter] = exit;
    79.                         Exitcounter++;
    80.                     }
    81.  
    82.                     Linecounter++;
    83.                 }
    84.  
    85.             }
    86.  
    87.         }
    88.  
    89.         roomNavigation.currentRoom = Rooms[0];
    90.     }
    Any ideas? I'm stuck :(
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    as a matter of fact...

    The answer is always the same... ALWAYS. It is the single most common error ever.

    Don't waste your life spinning around and round on this error. Instead, learn how to fix it fast... it's EASY!!

    Some notes on how to fix a NullReferenceException error in Unity3D
    - also known as: Unassigned Reference Exception
    - also known as: Missing Reference Exception
    - also known as: Object reference not set to an instance of an object

    http://plbm.com/?p=221

    The basic steps outlined above are:
    - Identify what is null
    - Identify why it is null
    - Fix that.

    Expect to see this error a LOT. It's easily the most common thing to do when working. Learn how to fix it rapidly. It's easy. See the above link for more tips.

    This is the kind of mindset and thinking process you need to bring to this problem:

    https://forum.unity.com/threads/why-do-my-music-ignore-the-sliders.993849/#post-6453695

    Step by step, break it down, find the problem.
     
  3. samdaman93

    samdaman93

    Joined:
    Oct 3, 2015
    Posts:
    37
    Ok thanks, I'm doing my best here, but I don't think I'm attaching the Room object to the room navigation script properly. Any advice on that? I'm not sure how to do it. Usually I'd drag the first room onto the script in the inspector, but since its an instance I don't know how to do this via code
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    Excellent!

    You're adding it to a list... in your mind does that constitute "attached?" It is a reasonably-done reference.

    But you HAVE TO FIX THE NULLREF first.

    I would change the above to be:

    Code (csharp):
    1. Room Room = ScriptableObject.CreateInstance<Room>();
    but the form you had probably works, it is just subject to typos.

    But again, you HAVE TO FIX THE NULLREF first.
     
  5. samdaman93

    samdaman93

    Joined:
    Oct 3, 2015
    Posts:
    37
    I added it to the list as a way to keep track of all the rooms and then cycle through them in my for loops changing the required variables in the scriptable object. The part I'm struggling with is getting the Current Room to be the instantiated object. If I take out line 89 in the quoted code. I don't receive the null reference exception.

    I also made your recommended change above. Should I be using something like getcomponent somehow to "attach" my instances for both the exit arrays and the rooms to the navigation script?

    Navigation Script


    At runtime the game controller is attached via code, but I can't get the room to be set as an instance created above
     
  6. samdaman93

    samdaman93

    Joined:
    Oct 3, 2015
    Posts:
    37
    Anyone else have some advice? really struggling to solve this error. Cheers