So I have a base class for a Gun. I have the basic info that each gun will have contained in this class. However, I want to know the best way to shoot these guns. Since some are going to be automatic and since some will be semi-automatic etc. I don’t want to have to do a check every frame to see what type of firing the gun needs to. On my player game object, I have a spot for the current gun which is an instance of the gun class therefore I can put any inheriting class in it. So what would be the most efficient way to call a shooting method for different types of guns?
That’s going to be a single integer compare, or a string compare if you insist. Trust me, just preparing to decide to call each one of your Update() functions each frame takes more grinding than that!!
Do NOT optimize until a) you have a problem, and b) you attached a profiler to measure the problem.
As for how to do it, handle it all within scripts on each GameObject, then turn off all the guns you’re not using, turn the one on that you are… that’s always going to be the cleanest setup.
Hey ConnorBaltich,
This sounds like a great use of the state pattern: State · Design Patterns Revisited · Game Programming Patterns.
- On the player script send your input to the Gun
- Each gun has multiple states (idle / firing / reloading )
- Have each gun implements it’s own HandleUpdate which is called from the player’s update method
- If the input contains the fire command on a gun state which should fire, that gun will proxy the call to it’s own Fire method
For example, AK47’s firing state would handle the fire button being continuously pressed down by staying in the fire state / firing more bullets… wheras a glock would ignore that input, cycle directly back into idle.
Cheers =)
In case anyone is interested here is what I did. I created an interface called IShooting, next I had the semi auto and auto classes use the interface. the interface has a handleUpdate method which is called from the playerController. I will definitely be implementing the states suggested by Kirby later in development.
Heres some examples of how I did things
This is an automatic gun class
public class AutoGun : Gun, IShooting
{
public void HandleUpdate()
{
if (Input.GetButton("Fire1"))
{
Debug.Log("AUTO FIRE");
}
}
}
Heres the interface
public interface IShooting
{
void HandleUpdate();
}
Finally here’s how it is called from the playerController
((IShooting)currentGun).HandleUpdate();
The currentGun variable is just a slot for the Gun class which semiAuto and Auto extend
This works well for me and thanks for everyone’s help =)
Also this is my Gun class in case there is any confusion
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static PlayerController;
public class Gun : MonoBehaviour
{
[Header("Info")]
public new string name;
public float reloadTime = .5f;
public Transform barrelPosition;
[Header("Magazine")]
public float fireRate = .3f;
public int clipSize = 30;
[Header("Damage")]
public float baseDamage = 100;
[HideInInspector]
public float lastShot = 0;
[HideInInspector]
public int leftInClip = 1;
[HideInInspector]
public Rigidbody rb;
private void Start()
{
rb = GetComponent<Rigidbody>();
}
}
I appreciate the response, but the question wasn’t so much about optimization, it was more that I knew there was a cleaner way to do it than a bunch of if-else statements. But I will keep your advice on optimization in mind. Much thanks!
Checking this every frame is extremely trivial processing wise.
I would likely have just done a switch statement and moved on to the next thing in the project. Efficiency in development isn’t just about efficiency of your code, but also efficiency in your time spent on the code. The more time you dwell on trivial issues, the less game you are producing, effectively lost opportunity to either make more games or make this game objectively better in the same amount of time. My 2 cents
I know. like I said it wasn’t so much about optimization. I just figured there was a better and easier way to be able to quickly create more gun types. I know a few extra if statements are going to have basically no impact on the performance. I just wanted to take the time to see if there was a system out there. But I really do need to work on approaching problems more like you said lol.
I have a single Boolean member of my weapon interface. It represents whether or not the player is pulling the trigger. All behavior regarding what to do is in the gun itself. No if statements, just polymorphism.
Thats actually what I have right now. Since the post a lot progress has been made and I have a Shoot() method in the gun class, so in each other class like Auto, Semi-Auto, and Burst, they handle the input and just call the method from Gun because they inherit from it.
Glad you made some good progress on this! Let us know if you run into any blockers or want to share some code =)
Thanks! I have a nice system for attachments now too. I just need a good way to render the gun and hands with a separate fov and make it so they don’t clip.
Using the hdrp. I dislike the fps sample’s method I really just want a replacement for what the old renderer had.