Search Unity

Resolved List<T> objects and Update function

Discussion in 'Scripting' started by yosefstudios, May 7, 2020.

  1. yosefstudios

    yosefstudios

    Joined:
    May 8, 2015
    Posts:
    129
    Well, let's get straight to the point...

    I'm coding a little script that works as a "manager" to control some of the objects of my scene. It consist of differents objects that show to me a message once I interact with them. It should work like this:

    1. First, on inspector, I set the DialogBox (a gameobject) and the TextBox (a text). They are what I consider as GENERAL SCRIPT PROPERTIES. All of the objects use them.
    2. Next, I create with help of List<T>, a list of Objects with shared properties (as a txtMessage, a name). They all have the same variables, but with different settings (a different name and message to display). They all send the txtMessage to TextBox, which means that all different objects share the same TextBox, but they show a different message through it. Note: all object properties are defined in another class, a nested class. I consider them as GENERAL OBJECT PROPERTIES.
    3. Now, all objects need to be...let's say, "accesed", by the Player. So I thought that maybe, having a SphereCollider set to trigger for every object could be an...easy way to work with. SOOOooo... on the same class that I previously defined the properties of the objects, I created the OnTriggerEnter method, so that way every different object has its own method. Well...seems logical to me at least.
    4. After that, my logic says it should work like this: every object has its own trigger, with their own properties. When the player collides with an specific object, a specific message will show up. Every different object will show up a different message through the TextBox.
    Now...there's the problem. First, this is the script that I made:
    Code (CSharp):
    1. public GameObject dialogBox;
    2.     public Text txtBox;
    3.     public static bool isOnTrigger=false;
    4.  
    5.     public List<Objeto> ListaObjetos = new List<Objeto>();
    6.  
    7.     void Update(){
    8.         //How???
    9.     }
    10.  
    11.     //La estrucutura general de objectos
    12.     [System.Serializable]
    13.     public class Objeto{
    14.        
    15.         public GameObject obj;
    16.  
    17.         public static string objName;
    18.         public string msg;
    19.  
    20.         void OnTriggerEnter(Collider other){
    21.             isOnTrigger = true;
    22.         }
    23.         void OnTriggerExit(Collider other){
    24.             isOnTrigger = true;
    25.         }
    26.  
    27.         public void ActionOnObject(Text txtToReplace){
    28.             if(Input.GetKeyDown(KeyCode.F)){
    29.                 if(isOnTrigger==true){
    30.                     txtToReplace.text = msg;
    31.                 }
    32.             }
    33.         }
    34.     }
    As you notice, the object properties are defined in another class INSIDE the main class. In that way, I created a List of the type Object, so on the inspector I'm able to create different objects and set different properties.

    And...now I have a problem. I honestly don't have any idea of how to "run" the methods from Object on the Update method.
    I notice that at runtime, those methods never appear. So basically the script doesn't work.

    My logic says that, if I put the OnTrigger methods OUTSIDE the class...wouldn't they be considered as GENERAL SCRIPT PROPERTIES? I mean...If I collide with an Object... every Object will be detected as the same, isn't it?

    I'm stuck here...and I don't know what to do. I tried with a foreach but...I didn't knew how to...apply it, to my code.

    Any ideas? I'm sorry if this seems dumb to you, I have a long time without coding...and my logic is having a hard time reconstructing itself.

    By the way...I'm sorry if my english is bad. I tried really hard hahaha
     
  2. Antony-Blackett

    Antony-Blackett

    Joined:
    Feb 15, 2011
    Posts:
    1,778
    class Objeto needs to be a MonoBehaviour to have unity events like OnTriggerEnter work.... but because it's a sub class i'm not sure that'll work either.

    Just put OnTriggerEnter(Collider other) in the same place you'd put Awake or Start or Update.

    Code (CSharp):
    1.  
    2.   void OnTriggerEnter(Collider other)
    3.   {
    4.     Debug.Log( "OnTriggerEnter", gameObject );
    5.   }
    6.  
    Use Debug.Log to help you understand where your code is failing or if it's even running at all.


    Good luck.
     
  3. yosefstudios

    yosefstudios

    Joined:
    May 8, 2015
    Posts:
    129
    Well, thanks for your reply. I tried that and it also didn't work. I also tried directly creating objects in the script, like this:
     public Objeto obj1 = new Objeto();


    Buuut...It still doesn't do what I want to do. I'm starting to think that is actually impossible to achieve what I'm trying...
    If I move the Trigger events outside the nested class, of course, they become part of the gameObject itself (I mean, those events become part of the empty object where I have put the script manager, not the Objects).

    Debug.Log just told me that the script wasn't working, basically.

    Don't know why but I'm somehow convinced that there's a way to do it...
    I'll keep searching and testing.
     
  4. Antony-Blackett

    Antony-Blackett

    Joined:
    Feb 15, 2011
    Posts:
    1,778
    I don't think I really understand your setup in that case.

    What I would do is this:

    Each gameObject attach a collider so you get trigger events when the player enters the collider.

    and a script like this:

    Code (CSharp):
    1. class MessageTrigger : MonoBehaviour
    2. {
    3.   public string displayName;
    4.   public string message;
    5.  
    6.   void OnTriggerEnter(Collider other)
    7.   {
    8.     Debug.Log( "displayName: " + displayName, gameObject );
    9.     Debug.Log( "message: " + message, gameObject );
    10.   }
    11. }
    After you do that, check that the trigger debug message is firing in the console so that you know it is working as expected.

    Now all you need to do is decide how to get a reference to your DialogBox and TextBox.

    Personally, I'd keep it simple and just add another two public variables to your script and connect them in the inspector. like so:

    Code (CSharp):
    1.  
    2. class MessageTrigger : MonoBehaviour
    3. {
    4.   public string displayName;
    5.   public string message;
    6.   public GameObject dialogBox;
    7.   public Text textBox; // (or whatever text class you are using)
    8.  
    9.   void OnTriggerEnter(Collider other)
    10.   {
    11.     Debug.Log( "displayName: " + displayName, gameObject );
    12.     Debug.Log( "message: " + message, gameObject );
    13.  
    14.     // I don't know what you intend to do with these so I'll take a guess.
    15.     dialogBox.SetActive(true);
    16.     textBox.text = message + displayName;
    17.   }
    18. }
    19.  
    If you only what a message to show on player input then you can do it like you did, setting a bool flag and then checking input in Update, or you could just do it in OnTriggerStay



    Code (CSharp):
    1.  
    2. class MessageTrigger : MonoBehaviour
    3. {
    4.   public string displayName;
    5.   public string message;
    6.   public GameObject dialogBox;
    7.   public Text textBox; // (or whatever text class you are using)
    8.  
    9.   void OnTriggerStay(Collider other)
    10.   {
    11.     Debug.Log( "displayName: " + displayName, gameObject );
    12.     Debug.Log( "message: " + message, gameObject );
    13.  
    14.     if( Input.GetKeyDown( KeyCode.F ) )
    15.     {
    16.       // I don't know what you intend to do with these so I'll take a guess.
    17.       dialogBox.SetActive(true);
    18.       textBox.text = message + displayName;
    19.     }
    20.   }
    21. }
    22.  
     
    Last edited: May 8, 2020
  5. yosefstudios

    yosefstudios

    Joined:
    May 8, 2015
    Posts:
    129
    Hmmmmm...that's actually what I wanted to do at the beginning, but I honestly thought It would be easier just to code a "manager" for all objects in just one script. But it seems it's just a headache soooo I guess I'll just do the original idea: a script for every object.

    Anyway, many thanks for your help! I guess you saved me from making a completely mess...
     
  6. Antony-Blackett

    Antony-Blackett

    Joined:
    Feb 15, 2011
    Posts:
    1,778
    Yeah, usually early on it's easier to do it this way. I sometimes have to refactor things into managers but only if there's a conflict, like if there are two objects that are both in the same location and one takes priority, then you'll need some way to resolve that conflict and a manager is one way to do that.

    But for now, if this works and it's easier, do it this way.