Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Transferring design patterns from XNA to Unity

Discussion in 'Editor & General Support' started by zuhane, Aug 13, 2019 at 3:03 PM.

  1. zuhane

    zuhane

    Joined:
    Mar 29, 2019
    Posts:
    3
    Hello all!

    So I've been an XNA developer for quite a long time, but recently decided to make the switch to Unity, mainly because everybody sings its praises and because of the vast amount of tutorials and support available.

    In terms of actually creating stuff in Unity, I'm starting to understand how it works and find it fairly easy to prototype little things together. However, I'm still struggling with building anything that has any complexity to it, such as a multitude of weapons or enemies that share behaviours. In XNA, I would either used inheritance or split things into components that use inheritance, but I'm not sure how to do this in Unity.

    My current and most specific problem is with a Doom clone I've been working on. I've got various elements working, such as a solid movement system, props, enemies and a few weapons, but I'd now like to expand the player's arsenal to carry more weapons. I'd like each weapon to have exactly 3 firing modes, but I'd like the firing modes to differ massively. The only thing that each weapon has in common is the fact it has a graphic, communicates with the HUD, and contains 3 firing modes.

    At first, I figured this would be quite easy. Each weapon used ray-tracing and has similar properties, so I could simply duplicate the prefabs, rename them, change a few graphics and then modify the component appropriately. However, as I've developed my ideas a little bit, I'd like each firing mode to just be its own self-contained thing that I can have full control over, not inheriting or sharing any behaviours.

    For example, I might want a sword that has a slash attack, charge attack and uppercut attack. I also wanted a weapon which sucks enemies in and stores them in a barrel, then fires them back out. I'd also like weapons that release physical objects, such as living creatures, bombs, etc, rather than just casting a ray and checking for damage. As for creating these types of objects and behaviours, I am totally able to do so! It's more a matter of the design pattern and high-level approach that I am interested in.

    I'd essentially like to create a weapon prefab which contains information for the weapons graphics, HUD integration, animation, etc, that also contains 3 firing modes. I'd like to somehow have it so each weapon requires 3 firing modes, maybe by containing 3 required interfaces, or 3 prefabs which inherit a common behaviour, but I'm unsure what data type to use. I could possibly have a component that is required to inherit an interface, but how can I inherit an interface and MonoBehaviour at the same time? Would the weapon itself be a prefab with a script component that requires 3 prefabs? If someone could shed some light on the situation, I'd greatly appreciate it!

    Thanks,
    Tom

    fddfhgfghg.png
     
    Last edited: Aug 13, 2019 at 3:25 PM
  2. El_Sombrerero

    El_Sombrerero

    Joined:
    Oct 15, 2017
    Posts:
    3
    hi, you can make a base class (that inherits from MonoBehavior) that implement some common code for the weapons and then make specific classes the inherits form your base class

    (MonoBehavior )
    |
    ( Base Weapon Class)
    | |
    (Sword Clasee) (Gun Class)

    Try to sperate the behaviors of the components in differentes scripts. Maybe you will have Base Weapon Class, a Base Fire Mode Class, etc.

    In c# you just can inherite from 1 class but implement many interfaces

    In unity you can have a prefab variant , it's like a prefab that inherits from other prefab
     
  3. bart_the_13th

    bart_the_13th

    Joined:
    Jan 16, 2012
    Posts:
    437
    This. Unity happens to be component based
     
  4. DonkeyPotato

    DonkeyPotato

    Joined:
    Mar 23, 2018
    Posts:
    9
    Saw your post on the Indie Game Dev FB group. Much easier to follow up here though...

    It seems like you're kind of mixing code and data inheritance together in your question. Unless the model of the weapon changes based on the firing mode, I don't think you'd want a prefab for each of the firing modes. Prefab variants are useful when you want an identical set of components, with changes only to the data driving them.

    Based on what you're describing, I would setup a single prefab per weapon, with the firing modes represented as different components on that prefab/gameobject, or possibly as ScriptableObjects if you needed to share identical firing modes between different weapons.

    On the code side I'd have something like this:
    Weapon : MonoBehaviour - Maintains a list of firing modes, and manages switching between them.
    IFiringMode - Interface for a firing mode that Weapon would use. This may be as simple as a single function to turn the mode on or off.
    BaseFiringMode : MonoBehaviour - Abstract base class that implements the functionality that's shared between modes.
    FiringMode1...n : BaseFiringMode - Your concrete firing mode classes that does most of the work of firing the weapon. They'd have serialized fields for all the VFX, sounds, etc. specific to that mode.

    Then each weapon prefab would have a Weapon component on it and a series of concrete firing mode components. The weapon component can grab all the firing modes in Awake() with a call to GetComponents<IFiringMode>().

    The prefab/gameobject hierarchy would look something like this:
    GravityWeaponPrefab
    ModelPrefab (GameObject)
    MeshRendererComponent
    AnimatorComponent​
    WeaponComponent
    GravityPushComponent (Firing mode)
    GravityPullComponent (Firing mode)​
    Note - It's important to have a parent GameObject that contains all your components, and then your model as a child gameobject. If you attach your components directly to the model game object, they get nuked if you reimport the model. Or if you want to change to a different model, it becomes a big pain. Setting up the hierarchy in the way I showed above avoids a lot of headaches.

    If you go the ScriptableObject route, things change quite a bit. Weapon would need a serialized list referencing the ScriptableObject assets, which means you can't use an interface, and you'd have to manually drive updates and such from Weapon. So 'IFiringMode' goes away. And BaseFiringMode would inherit from ScriptableObject. Each firing mode would be a stand-alone asset on disk. Unless you need to share completely identical firing modes (same data and code!) between weapons, I wouldn't go this route.

    Hope that all makes sense, and is helpful.
     
  5. zuhane

    zuhane

    Joined:
    Mar 29, 2019
    Posts:
    3
    Thank you all for the awesome posts and help. Also a huge shout out to DonkeyPotato. Your method has cleared up and awful lot of mystery surrounding the problem at hand. I'm going to try directly using your approach and see if I get any joy with designing the weapons in this new manner. I think I should be focusing on breaking everything down into the smallest possible pieces I can. I'll re-sharping a couple of my existing weapons into this new format and see if it helps. I'll let you know how this works out and share some example for any future readers. Thanks again for the help.

    EDIT: I'd just like to include this. I made a little diagram of an example structure of how I think I should design my weapons. It's obviously not fully future-proof, but does this look like a decent way to create my weapons? Feedback would be immensely helpful!

    safgafafafafafaff.png
     
    Last edited: Aug 15, 2019 at 9:12 PM
    DonkeyPotato likes this.
  6. DonkeyPotato

    DonkeyPotato

    Joined:
    Mar 23, 2018
    Posts:
    9
    Glad I could help! Good luck with it.