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

Question How best to create different types of weapons?

Discussion in 'Scripting' started by HansSchmulge, Aug 30, 2023.

  1. HansSchmulge

    HansSchmulge

    Joined:
    Nov 29, 2022
    Posts:
    7
    Hello.
    I created two types of weapons - machine guns (shoot with raycast) and mortars (shoot with projectiles).
    1.png 2.png
    For them I have two scripts:
    -GunBehavior Script (depends on weapon type - it can be CannonGunBeh.cs or MachineGunBeh.cs)
    -TurretRotation Script

    Now I have these guns as prefabs, and I'm going to create a shotgun (shoots 3 raycasts at once) and a LaserGun (shoots a plasma projectile).

    For the laser, I can use an existing cannon script by changing only the projectile model and sound in the editor.
    For a shotgun, in theory, I can use the script for a machine gun only by adding the ability to shoot 3 raycasts at once with a certain spread (that is, change the filling of the main script by adding the "number of bullets per shot" field in the editor).

    However, I don’t know if this is a good idea at all and if it’s worth storing it all in Prefabs at all? I've heard of Scriptable Objects, but I don't know if they fit this case.

    I would like to hear advice on how best to implement such things in Unity.

    Thanks in advance :3
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    Looks like you're already well down the track with those two broad categories of weapons.

    Also, when you write this;

    You are already thinking correctly about the problem.

    The next step will be to think about what each of these things can do: be selected, fire, report how much ammo they have, etc.

    And here's some programming tools to help extract this commonality!

    Using Interfaces in Unity3D:

    https://forum.unity.com/threads/how...rereceiver-error-message.920801/#post-6028457

    https://forum.unity.com/threads/manager-classes.965609/#post-6286820

    Check Youtube for other tutorials about interfaces and working in Unity3D. It's a pretty powerful combination.

    Prefabs could represent broad categories of weapons. You use them when your script needs to interoperate with Gameobjects.

    ScriptableObjects could represent configuration mechanisms for on particular category of weapon.

    So a "gun" prefab might accept different scriptableObjects that configure how it works.

    Same might go for a mortar weapon.

    The key to success will look very much like your current approach: iterate a little, stop and understand, experiment, refactor, see what you need next, iterate a little more, etc.

    Here's more about ScriptableObjects:

    https://forum.unity.com/threads/scr...tiple-units-in-your-team.925409/#post-6055289

    https://forum.unity.com/threads/cre...ssigned-in-the-inspector.946240/#post-6174205

    Usage as a shared common data container:

     
    Chubzdoomer, Yoreki and HansSchmulge like this.
  3. HansSchmulge

    HansSchmulge

    Joined:
    Nov 29, 2022
    Posts:
    7
    Thanks.
    Sorry, but could you please answer this question:
    - I have now one script called WeaponCore.cs (manages shooting, reloading, stores muzzle transforms etc), WeaponCharacteristicsScriptableObjecs.cs (stores basic characteristics such as range, maxAmmo per clip, how many bullets will you fire from one muzzle (important for shotguns)
    etc), AudioConfigScriptableObject.sc (stores everything related to weapon sounds).
    - And I just don't know, whether is a good idea or not to store all the possible functions in WeaponCore.cs, like Shoot() for Raycast shooting and Shoot() for shell shooting, Reload() (reloads ammo in clip, when there is no ammo in a clip or the player presses "R") and AutoReload() (adds some ammo to your clip if the player hasn't fired in a while).
    Because I think it's easier to keep all these functions in one script (as it is in one YouTube tutorial I found) and it will be possible to easily change, for example, a machine gun to a cannon just by editing some boolean variables and adding a shell prefab, but it's probably more efficient and not as messy to create different scripts with interfaces like:
    -MachineGun Script : IShootable, IReloadable, IRayShootable, IEquipable
    -Shotgun Script: IShootable, IAutoReloadable, IRayShootable, IEquipable
    -Cannon: IShootable, IAutoReloadable, ILaunchable, IEquipable
    -Laser: IShootable, IReloadable, ILaunchable, IEquipable
    etc.
    I hope I explained my question clearly, which I'm not sure about :/
     
    Last edited: Sep 5, 2023
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    What you're describing is a bit of a subclass sandbox type pattern, which can have it's pros and cons. I'm not a fan as huge classes with tons and tons of code isn't my style. My preference is to break things up manageable, easily understandable objects, but other folks would say otherwise.

    One option you have more in line with the latter option is to encapsulate common functionality into plain C# objects that express these interfaces (or express properties that the interfaces expect). For example, you could have
    ReloadStandard
    ,
    ReloadAuto
    etc C# objects that you reuse as necessary in different weapons.

    You could also compose all the necessary facets of a weapon with components, taking advantage of Unity's component architecture.

    Don't be too scared to make lots of scripts. It's a pretty normal part of coding.
     
    HansSchmulge and SisusCo like this.