Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

C# syntax help...

Discussion in 'Scripting' started by jeremyace, Feb 4, 2006.

  1. jeremyace

    jeremyace

    Joined:
    Oct 12, 2005
    Posts:
    1,661
    Hey guys, I am trying to learn OOP in C# and unity and I am having a problem and I can't figure out what's wrong.

    I wrote a general AI script, subclassed it in another script to fine-tune the individual characteristics of this agent, BUT when I want to hide the member variables that are defined in my general AI code, I get the warning about hiding. Ok, no problem I understand that, I run the game and my new variable isn't 'taking'. So I add a 'new' keyword and I get the error that the same name is used twice. I will write small code to show what I am doing:

    Code (csharp):
    1.  
    2. //blah blah
    3.  
    4. public class AI_Steering : MonoBehaviour{
    5.   public float maxSpeed = 50F;
    6.   //blah blah
    7. }
    8.  
    9. //--------------------------------------------
    10. // then in my other script when I subclass it:
    11. //--------------------------------------------
    12.  
    13. public class MyBehaviour : AI_Steering {
    14. //I want to override the maxSpeed var set in
    15. //AI_Steering
    16.  
    17. new public float maxSpeed = 500F;
    18.  
    19. }
    20.  
    It doesn't work. If I remove the 'new' then it just gives the warning but doesn't seem to update my new value, but when I add it in, Unity throws an error about same name multiple times.

    I looked around in various C# pages about member hiding but they all say (including the unity warning ;)) to use the new keyword. So I am sorry if this is a simple C# syntax issue but I couldn't find the info elsewhere.

    Thanks guys,
    -Jeremy
     
  2. NCarter

    NCarter

    Joined:
    Sep 3, 2005
    Posts:
    686
    You can't override the definition of a member variable. Instead, you'd need to assign a different value to it, maybe in the Awake or Start events.

    Watch out that while Unity supports OOP and inheritance in C#, when dealing with derivatives of MonoBehaviour you need to make certain allowances for the way Unity works. For example, in C++, I'd assign the different value to the member variable in the constructor. However, in Unity, the constructor doesn't fire when you'd expect it to (it seems to fire in the editor, prior to the game!), so you have to do things which would normally go in the constructor in the Awake or Start events.

    In practice, I found that for MonoBehaviour scripts, it's better to not use too much inheritance. Instead, break the scripts up into smaller modules of functionality and swap in alternative modules to change the behaviour of an object.

    That's just MonoBehaviour derivatives, though... when writing custom classes with no base class, you're free to do anything you want.
     
  3. jeremyace

    jeremyace

    Joined:
    Oct 12, 2005
    Posts:
    1,661
    Thanks a lot for the help NCarter. I did try just changing the value but it didn't seem to take. I shall try it again as it was quite late. ;)

    Thanks for the tips about inheritance as well. Right now I am just creating a base Steering Behaviour script that I want to subclass for each agent so I don't *think* I'll have much trouble. I don't really have to do anything much more complex than this. I just want to add some uniqueness to individual agents without tweaking in the inspector.

    Thanks a lot,
    -Jeremy
     
  4. tsphillips

    tsphillips

    Joined:
    Jan 9, 2006
    Posts:
    359
    Just a comment on the values that appear in the inspector --

    From what I have seen, they do not automatically update when the script changes. Say you have the following in your script:
    Code (csharp):
    1.  
    2. public int lives = 3;
    3.  
    You play around and decide 3 is too few and you want to make it 4. Now you have:
    Code (csharp):
    1.  
    2. public int lives = 4;
    3.  
    If the script had already been attached to an object, the lives value in the inspector will remain at 3. It will not change to 4 when the script is changed. To reload the values from the script, select the "Reset" option from the script component attached to the object. (The script component in the inspector should have an icon on the right side. Click that and select "Reset.")
     
  5. jeremyace

    jeremyace

    Joined:
    Oct 12, 2005
    Posts:
    1,661
    I have noticed that as well. It is annoying when you have several variables that point to gameobjects and everytime you make a small change you have to reset and reconnect all of your connections. Maybe I should put this in the wish list...

    I have also noticed that in some cases resetting doesn't fully update the script. Sometimes the only way I can get a change to 'take' is actually removing the script and re-applying it to my object. Has anyone else seen this? And yes, I am waiting until the script is finished compiling before I hit play. ;)

    -Jeremy
     
  6. NCarter

    NCarter

    Joined:
    Sep 3, 2005
    Posts:
    686
    Well, Unity can't know whether you want it to replace all the default values with the new default or if you meant for them to stay the same. While it's a bit annoying, I think the current behaviour is correct.

    When I'm developing a script and experimenting to find the best default values, I usually make them temporarily non-public. That way they disappear from all objects altogether, and when you make them public again they all get reset to the new defaults.
     
  7. jeremyace

    jeremyace

    Joined:
    Oct 12, 2005
    Posts:
    1,661
    Yeah, I have no problem with that behaviour. It would be nice if Unity read what variables you changed and updated them in the inspector when you save in your script.

    What does bother me though, is that sometimes even resetting wont make your changes work. The only thing (that I have found) that works in these cases is removing the whole script altogether and then reattaching it. That bothers me and I doubt that was intended. Reset should reset. Maybe I am doing something wrong, but I doubt it in this case.

    -Jeremy
     
  8. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    The behaviours should NOT change the variables when you modify the scripts. The values in the scripts are default variables. You may have inserted the behaviour all over the place and tweaked the values to be just right. Even worse, a level designer may have done that. Then you change the script and all their work is gone.

    If you want this functionality, you should make the variables private, removing them from level-designer tweaking. What I've sometimes done is to keep variables public during initial construction, then changed them to be private once I've found a good value for them in the inspector.

    @jeremy:
    Do you have a reproducible case about the inspectors not resetting properly? I've never seen it happen. Is there a particular type of data it doesn't reset?
     
  9. jeremyace

    jeremyace

    Joined:
    Oct 12, 2005
    Posts:
    1,661
    That makes sense. I really never liked the idea of setting variables in the editor that are contrary to the scripts for more than just tweaking. Didn't seem like a good idea to have the final variables defined there as opposed to the code, but that's just my paranoia ;) Something I will have to get used to using.

    Unfortunately not. It *seems* random. I will watch for the next time it happens and see if I can find a pattern.

    What has happened is I changed a block of code (I don't know, moved if/then statements around, etc) and afer I saved and waited for compile, I played the game and my changes didn't 'take'. My changes were actual logic changes and not variables. When I hit reset, reconnected what needed to be and then played again my changes still didn't register. Only when I removed the script component altogether and reattached it did my change show. It could have been something wrong I was doing, but I really don't think so.

    Unfortunately that's all I have right now. When/if it happens again I shall let you know.

    -Jeremy