Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Help with executing a generic weapon

Discussion in 'Scripting' started by ShrikeDev, Sep 11, 2022.

  1. ShrikeDev

    ShrikeDev

    Joined:
    May 31, 2018
    Posts:
    31
    I'm making a framework for multiple, swappable weapontypes, i want the input manager to execute the perform function of a weapon. the weapons are divided into their own classes inheriting class Weapon which inherits monobehaviour

    So, what I'm trying to do:
    From player input manager, OnInput executes a function in playercontroller monobehaviour, which then runs the "perform" function for an arbitrary weapon class which is a monobehaviour

    The bad way i'm currently doing it, let's say the player has a sword:
    Input happens, in inputmanager ->
    Code (CSharp):
    1.        
    2. private void WeaponMainhandPerform(InputAction.CallbackContext context) {
    3.               GetComponent<IHPlayerController>().mainhandWeapon.GetWeapon();
    4. }
    5.  
    playercontroller runs GetWeapon function from assigned scriptableObject Sword(WeaponConfig), the WeaponConfig SO has an enum with all the weapontypes (Sword,Knife,Etc). Sword(WeaponConfig) has been assigned the value for Sword. So to run the correct weapon perform, GetWeapon uses this ugly switch:
    Code (CSharp):
    1.  
    2. public void GetWeapon() {
    3.             switch (weaponType) {
    4.                 case WeaponTypes.Sword:
    5.                     prefab.GetComponent<Sword>().PerformWeapon();
    6.                     break;
    7.                 case WeaponTypes.Knife:
    8.                     prefab.GetComponent<Knife>().PerformWeapon();
    9.                     break;
    10.             }
    11. }
    12.  
    So currently it flows like this PlayerInput : Monobehaviour -> PlayerController : Monobehaviour -> WeaponSO : ScriptableObject -> (Prefab) Sword : Weapon : Monobehaviour

    What's a better way to do this? Both the sword and knife class inherits from the class Weapon which in turn inherits from monobehaviour. I'm not a very experienced programmer, so not sure what's best to use in this case. Virtual override? Interface? Polymorphism? (haven't used these before just that *maybe* they could be useful here) Any suggestions appreciated. If i could just replace the switch with something that gets the correct weapon class and function it would be perfect, or if i should just refactor in some way.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,514
  3. ShrikeDev

    ShrikeDev

    Joined:
    May 31, 2018
    Posts:
    31
    I actually did look into interfaces but was put off when i read this result when googling about them
    http://hightalestudios.com/2017/03/friends-dont-let-friends-use-interfaces-on-monobehaviour-objects/
    But i'm using a scriptableObject as middleman not monobehaviour, i don't know i'm fresh and impressionable lol. I'll look into trying with an interface.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,514
    From my reading, it sounds like he used interfaces for something that didn't bring him any value and then wrote a long click-baity "Friends don't let friends..." article about it. To his credit he updated it with current interface getter abilities.

    You know what they say about the "internet of lies." :)

    Try his way, try interfaces, try lots of things. It's really the only reasonable way to arrive at an informed decision.
     
  5. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,910
    An interface or inherited base class will reduce the switch to one line, or remove the GetWeapon function completely.

    You could also store the perform functions in a dictionary and call it like so:
    Code (csharp):
    1. Dictionary<WeaponTypes, Action> WeaponFunctions;
    2.  
    3. WeaponFunctions[weaponType]();