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.
  2. Dismiss Notice

working with Unity?

Discussion in 'Scripting' started by cantemir, Jul 2, 2014.

  1. cantemir

    cantemir

    Joined:
    Jul 1, 2014
    Posts:
    9
    Hello.
    I'm very new to Unity (total beginner) but I'm currently following the "Stealth" tutorial and I've read through the manual. All for like 3 days. I find working with Unity a little difficult and at the same time pleasant as it has some upsides and downsides from my personal point of view. I'm asking experienced members to explain to me a few things to set me going with Unity on the right track. My way of thinking in Unity will depend largely on you, based on your explanations so please, make time to give me a hand here.

    At the first glance here are the upsides:

    + Unity provides much of the ingredient needed in any project developing: visual awareness.
    It's ready to hand you what you need without rummage. Apart from WYSIWYG editor here's what seemed neat: script public fields displayed in the inspector. Plus they're tweakable from there. Plus they're displayed and tweakable at runtime, as well.

    + The simplicity of editing a prefab into a new unique object and at the same time saving changes to the prefab itself: the difference in the power of "Apply" that only saves the lastly edited value.

    As for the downsides, they all are related to resembling OOP such as "class-subclass", "class-object" and aggregation paradigms. I just don't know how to think in Unity since all developing I have done so far relies on these fundamental paradigms, none of which I can figure out in Unity:

    - Class-object:
    As I see it, in Unity you instantiate an object instead of a class, due to serialization. Then how do i get from this to a class-object approach? How can I make classes as I'm used to, and how do I instantiate them?
    Possible solution:
    create a "prototype" object right after defining the class; create an empty GameObject; assign the prototype reference to this GameObject. Is there a better way, maybe a straight-forward use of real C# class-object?

    - Class-subclass:
    This is related to previous matter. For instance how does one implement an enemy soldier? I guess make a GameObject and add the appropriate components. Now how does one implements an enemy that inherits from the former (but overloads methods and has own fields etc.)?
    Possible solution:
    Make a script with the enemy class that has the nitty-gritty (the "logical subject") of the concept to be modeled and attach it to a GameObject container ("formal subject"), along with other components. Make the desired subclass a different script (of course having a class that inherits from the former class) and possibly attach it to a different GameObject for clarity sake.

    - Aggregation:
    One GameObject can have only 1 component of a certain type. This kind of knocked me out. I needed a gameController GameObject to control 2 light components but I had to create a child GameObject to contain the other light. And this may have continued for every extra light. Conceptually, all the lights are on the same level; even practically, positions are different from one another (if they're in the same position, one has for instance (12, 4, 6) -- world coords whereas the other has (0, 0, 0) ).
    Possible solution:
    Implement all in code. Treat components as GameObject's. As I saw that components may have a reference variable just like a GameObject, I wonder whether we can have free components. If not, assign each component to its own GameObject and make these objects children of the "main" object.
    In general OOP allows objects to contain other objects as fields, of undefined number and even of the type of the container. I don't know how to translate this into Unity architecture.
     
  2. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    You are confusing the terminology. Every object is an instance of a certain class. You can create objects as usual. Though there is an exception in Unity if you are using a class that inherits MonoBehaviour or ScriptableObject. You should not use new for classes that inherit MonoBehaviour, but instead use someGameObject.AddComponent <YourClassInheritingMonoBehaviour> (). Like that you are getting an instance of that class.
    Components that are already part of game objects are just usual objects as you know them from OOP. They are automatically created in Unity, that's all.

    Lets assume you have a class called EnemySoldier which has a subclass called SpecializedEnemySoldier which overrides methods, adds fields, ... . Now the situation is very simple, don't use EnemySoldier if you want to have a SpecializedEnemySoldier. Don't add an EnemySolider, but directly add a SpecializedEnemySoldier. That's it.

    Just do it... Maybe you could provide an example. This would make it easier to help. But again, there is no actual difference.
     
  3. _met44

    _met44

    Joined:
    Jun 1, 2013
    Posts:
    633
    If I may try myself at untangeling your vision of unity.

    Try to consider the GameObjects as super objects (not in the java way, rather the superman way). You'll find parallels with the paradygms that make you feel confortable.

    Then components would be variables and the prefab would be the "super" class of the "super" object.

    In any case, you have access to everything available in C# including interop if you fancy C/C++ but it isn't suggested to abuse it due to interop cost. So as @Dantus pointed out you can create classes and objects as usual and should, to power up your components.

    For inheritance, I saw a tool once that allowed you to nest prefabs without breaking the link with the root. Dunno how it performs though but comments seemed good.

    Other ways may involve using an abstract monobehaviour sub class that you specialize to your need and plugs well onto your prefab.

    For the aggregation part, it depends on the component. Make you own script and see you'll be able to dump as many as you want on a given object.

    Hope I could help a little.

    Good luck and have fun learning :)
     
  4. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,716
    o_O

    Class; a blueprint to create an object.

    Object; a instance in memory created from a class definition.

    Unity works the same way any C# application works. The "new" keyword works just fine, except when you encounter a factory pattern like the GameObject, where you have to pass by its own pipeline to create an instance. There's a "new" hidden somewhere, you just don't access it.
     
  5. cantemir

    cantemir

    Joined:
    Jul 1, 2014
    Posts:
    9
    Thank you all very much for the help.
    To be concrete, I want to make a FPS shooter and I imagined this tree:

    I have a Soldier that may have 3 specializations: GI, Grenadier, Sniper.
    A particular soldier may be Enemy, Neutral or Friendly.
    As friendlies, some are members of player's squad that can be issued orders directly (SquadMember).
    We also have Civilian humans. Soldiers along with civilians (hostages) inherit from Human, that encompasses the common human behaviour i.e.
    maxSpeed, maxHealth, takingDamage(), bone structure, path-finding etc.
    These are common for all subclasses both in variable names and values. More common variables but differing in values: health, inventory[], camera, audio sources[] (footstep, talk[], handleItems, firing etc.).
    Next a subclass has own variables:
    (for Enemy) targetLastPosition, (for Sniper) accuracy etc.

    From what I learned from you guys, I may take one of two ways and I'm asking which one is best (or even correct)?

    1. The mentioned classes made as C# classes (prefered):
    I make a controller GameObject and a script component. In the script I add the whole inheritance tree with all classes and interfaces, all at the root level (not nested).
    Now here come 2 issues, A and B:
    A. How do I instantiate a subclass of Human i.e. spawn 3 G.I.'s in my squad, 4 enemy grenadiers across the map and 10 civilians? Should I use
    Code (CSharp):
    1. GameObject gren;
    2. gren.addComponent<Grenadier>();
    ?
    But how do I add 50 grenadiers? Can I add 50 components of the same type to one GameObject?
    B. How do I assign to each Human multiple audio sources?

    2. The mentioned classes made as prefabs:
    I make a Human prefab and duplicate it and add functionality to make it into a "subclass".
    A. Instantiate(prefab) should work just fine.
    B. The issue remains.
    A new issue "C" would arise: how can I tell the conceptual inheritance tree in the Hierarchy? (How can I know which prefabs were made by editing others and what is specific to "this" prefab?

    If I untangle this, I'm almost across :)
     
  6. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Take care not to over design what you have in mind. I would suggest you to try it out and think of the ways in which those objects are going to be used. Don't use inheritance because it kind of make sense. If you are using inheritance, there should be an actual reason.
    You may try to create a small prototype project. You don't need soldiers, cubes would be sufficient. Create actual scenarios that will matter in your game. If you struggle with something think about solutions, maybe a refactoring is needed, maybe the addition of some methods or properties. Like that you will find actual reasons why you pick a certain design over another one.

    The way you are trying to take right now is certainly possible, but only if you knew Unity a lot better than you actually do. With that lack of experience, you can create a terrific design, but as you are implementing it, you will find a lot of cases you didn't consider and you'll need to redesign and refactor your code. For someone who just started to use Unity, I would strongly recommend to start small and build on it.
     
  7. cantemir

    cantemir

    Joined:
    Jul 1, 2014
    Posts:
    9
    Thank you, Dantus. But come on, don't hold back :) I need to know what and how I can do before I plan what and how I want it done.
    A big hulk of Unity is learned once I know the patterns for the example above, how somebody else would approach it. That's the scenario, not more not less.
    I'm not that inexperienced with game developing, it's just Unity is a little... uniquely structured.
     
  8. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Designing something without having use cases in mind or understanding the basics is always the wrong approach.
    We can not take away the learning curve for you. There are basic things in Unity you don't seem to understand. In my opinion, you are trying to be three steps ahead of what you are capable of doing. You need to understand the basics, because your design choices will depend on it.
    Metaphorically speaking, you are trying to create the plan for a house, but you don't know the environment where the house will finally be and most of the materials and machines that are available are unknown to you. Even if you know what a house is, you don't know yet what the purpose of the house is going to be.
     
  9. cantemir

    cantemir

    Joined:
    Jul 1, 2014
    Posts:
    9
    I presented the exact scenario. I don't know what to do more. Do I have to plan the game further? I just want a handful of specialized characters roaming around and shooting. But for the start just spawn in the game.
    What do you advise me to do? What should I dwell on?
     
  10. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Create a prefab for each specialized character. Make a spawning script that has a reference to each of those prefabs, such that you can instantiate them. The reference to the prefab may already have the correct class type, such as Sniper or Grenadier.
     
  11. cantemir

    cantemir

    Joined:
    Jul 1, 2014
    Posts:
    9
    Thank you. I deeply appreciate this particular reply.