Search Unity

Resolved Reference constructor inside of itself?

Discussion in 'Getting Started' started by jacob77898, Oct 27, 2022.

  1. jacob77898

    jacob77898

    Joined:
    Oct 7, 2021
    Posts:
    13
    Hi! Is this thing possible?
    Code (CSharp):
    1. public class Room
    2. {
    3.     public Room myRoom;
    4.  
    5.     public Room(Room r)
    6.     {
    7.         this.myRoom = r;
    8.     }
    9. }
    If yes, then it doesn't seem to keep the variables.
    Lets add a string in it:
    Code (CSharp):
    1. public class Room
    2. {
    3.     public Room myRoom;
    4.     public string text;
    5.  
    6.     public Room(Room r, string txt)
    7.     {
    8.         this.myRoom = r;
    9.         this.text = txt;
    10.     }
    11. }
    So, I have another script where i create those objects

    Code (CSharp):
    1. private Room[] _rooms = new Room[5];
    2. public Room[] data = new Room[5]; // Set values in inspector
    3.  
    4. private void CreateRooms()
    5. {
    6.    _rooms[0] = new Room(data[0], "123");
    7.    _rooms[1] = new Room(data[1], "321");
    8.   /...
    9. }
    And then i have a simple method to display the rooms
    Code (CSharp):
    1. public Text someText;
    2.  
    3. private void DisplayRoom()
    4. {
    5.    someText.text = _rooms[0].text;
    6. }
    This works fine BUT if i access the room inside of the constructor and print the text...
    Code (CSharp):
    1. public Text someText;
    2.  
    3. private void DisplayRoom()
    4. {
    5.    someText.text = _rooms[0].myRoom.text[;
    6.    // myRoom.text is data.text that was set in inspector
    7. }
    It prints a blank string. Idk what's wrong, I can't figure it out from the last night.
     
  2. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    I think you may be misunderstanding constructors.

    The purpose of a constructor is to be able to create an instance of an object and initialize it with values set through the parameters (if provided). The constructor gets called automatically when you use the new keyword to assign a reference. Consider this somewhat contrived example:
    Code (CSharp):
    1. public class Room {
    2.     private string name;
    3.     private Vector2 roomDimensions;
    4.     private float floorSquareFootage;
    5.  
    6.     public Room(int width, int length, string name = "Unnamed") {
    7.         roomDimensions = new Vector2(width, length);
    8.         this.name = name;
    9.     }
    10. }
    11.  
    12. public class ConstructorExample: MonoBehavior {
    13.     private void Start() {
    14.         Room livingRoom = new Room(9f, 12f, "Living Room");
    15.         Room extraRoom = new Room(4f, 7f);
    16.     }
    17. }
    The constructor allows me to create a new room and set some properties for that room in one place. It wouldn't make sense for the Room object to have a reference to another Room inside it, especially if that reference is pointing at itself!



    I would say just drop the part out of your Room class that has any reference to Room and go from there.

    Code (CSharp):
    1. public class Room
    2. {
    3.     public string text;
    4.     public Room(string txt)
    5.     {
    6.         this.text = txt;
    7.     }
    8. }
     
    jacob77898 likes this.
  3. jacob77898

    jacob77898

    Joined:
    Oct 7, 2021
    Posts:
    13
    Yeah i think i understand how they work, but its not exactly what im looking for. Im making a simple game where there you choose option one or two and then you go to another room where you make other choices and so on.
    This is the class of the Constructor
    Code (CSharp):
    1. [System.Serializable]
    2. public class Room
    3. {
    4.     public string story; // this is what happend in the room
    5.     public string text1; // this is what you will do
    6.     public string text2;
    7.     public Room option1; // this is the room you will go to
    8.     public Room option2;
    9.  
    10.     public Room(string story, string text1, string text2, Room opt1, Room opt2)
    11.     {
    12.         this.story = story;
    13.         this.text1 = text1;
    14.         this.text2 = text2;
    15.         this.option1 = opt1;
    16.         this.option2 = opt2;
    17.     }
    I thought of creating another Constructor for the Option like this:
    Code (CSharp):
    1. public class Option
    2. {
    3.     public string text;
    4.     public Room room;
    5.  
    6.     public Option(string text, Room room)
    7.     {
    8.         this.text = text;
    9.         this.room = room;
    10.     }
    11. }
    But the problem is that if I want to make for example 20 rooms, I need 20 lines for the rooms and 40 lines for the options. It will be impossible to understand what's going on with the code or the logic.

    I'm a bit embarrassed because im asking you nearly all of the game logic but it would very much appreciated.
    Thanks for your time!
     
    Schneider21 likes this.
  4. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Ah, I gotcha. I think the piece of the puzzle you're missing here is what are collectively referred to as Collections.

    Collections are things like arrays, Lists, Dictionaries, and my personal favorite, Hashsets. When combined with custom data types, they can be extremely powerful.

    Code (CSharp):
    1. public class Room {
    2.     // Room-specific details here
    3.     public string storyText;
    4.     public List<RoomOption> roomOptions;
    5. }
    6.  
    7. public struct RoomOption {
    8.     public Room gotoRoom;
    9.     public string optionText;
    10. }
    11.  
    12. public class RoomMovement: MonoBehavior {
    13.     public Room roomData;
    14.  
    15.     private void Start() {
    16.         // Display the room's storyText to the player
    17.  
    18.         // Loop through room's roomOptions and create buttons for each
    19.         // Set the button's text to each RoomOption's optionText value
    20.  
    21.         // OnClick, execute GoToRoom(gotoRoom) for that option
    22.     }
    23.  
    24.     public void GoToRoom(Room room) {
    25.         // Load room
    26.     }
    27. }
    Please keep in mind this is barely above pseudocode level, and I can't say I'd structure things this way myself, but it should get you moving in the right direction, at least. It's worth looking into ScriptableObjects and using instances of those instead of plain C# classes, as it provides a number of advantages like Inspector reference assignments which might be particularly useful for you.
     
    jacob77898 likes this.
  5. jacob77898

    jacob77898

    Joined:
    Oct 7, 2021
    Posts:
    13
    Big thanks for you man. You really pointed me at the right direction, I haven't look about ScriptableObjects, but i sure will. Thanks!
     
    Schneider21 likes this.