How to get the equipped weapon reference from the template variable

Hi guys,

I’m having some trouble with my project, and I’m still pretty new so I apologize if I can’t adequately articulate what I’m trying to do.

So, the projectile is supposed to read the character’s equipped weapon and pull the appropriate values for muzzle velocity, damage, and weapon spread to plug into the forumla. That way, the projectile always behaves in the manner dictated by the held weapon and it’s ammunition type.

All the weapons are made from a master template (BP_FiringWeaponBase), and I’ve found through some trial and error that a parent variable type is forward compatible with the children, but a child variable type is not BACKWARD compatible with the parent. IE: If the reference is of BP_FiringWeaponBase, it will accept a BP_AssaultRifle, but a BP_AssaultRifle variable is not compatible with a BP_FiringWeaponBase reference, as below.

I need the character to be able to accept all types of weapons, however the projectile blueprint does not read the overridden values of the damage, muzzle velocity, and current spread variables: it only sees the template values from BP_FiringWeaponBase. Can someone help?

Thanks!

Kind of confused by what you wrote BUT I think I understand what you are trying to do. You have a character and it can carry multiple weapons. Each weapon has its specific “stats” (velocity, damage, spread etc). You want to automatically update the fired projectile’s stats based on the weapon the player is holding and thus set a “generic” projectile to the stats of the “held weapon”? If I got that correct then this is what I suggest. “Parent” blueprints should carry all data common to your weapons, this would be the weapon specific stats (velocity, damage, spread). Place these into a custom struct variable for easy access and use. Create a custom projectile BP with the same variables placed in a struct. So you have 2 blueprints, and 1 struct. A WeaponBlueprintBase, this holds all data related to the weapon and the projectile it fires…COMMON data, to ALL weapons. Create as many child weapon blueprints as you want from this parent. When the player picks up a weapon, cast to this parent class. You can then take the output pin of the parent class cast node and pull the struct out, this will have the SPECIFIC data held by that child blueprint NOT parent default values. You can then “spawn actor from class” and select your custom projectile BP. Expose its weapon data “struct” on spawn. This will allow you to directly set the projectile struct values. All you need to do now is set the struct of the projectile to the struct values from the output of the cast node earlier.

Hi there,

The problem you have encountered is a fundamental part of the design of object oriented programming.

Classes hold in themselves properties (variables) and methods (functions, events).

You see, a child class inherits ALL of the variables and functions of the parent class. You can see the inherited variables by clicking on the “eye” icon above your varable list’s search box.

This means that if you call a method or try to get a property of the parent class from a child class it is GUARANTEED to have it. This is why child class references can be saved in parent type variables.

Yes, the child can change (override) methods or modify properties defined in the parent class but they will still have all of them and can even have additional properties and methods of their own.

On the other hand if you call a method or try to get a property specific for the child class from a parent it will not have it. This is why parent class references can NOT be saved in child type variables.

Suppose you have a child reference in a parent type variable. If you try to access the child specific variables and methods you will not be able to because you treat it as a parent. This is where downcasting (CastTo nodes) comes in. You can downcast the variable to the child type you want. The returned variable will be of that child type and you will be able to access all its methods and properties. However, casting may fail if you have saved different child reference than the one you try to cast to.

In terms of game architecture, the character usually only holds a parent class weapon.

This parent class holds all the variables like Range, Damage, Mesh, ClipSize and methods Attack(), AlternativeAttack(), Reload().

The child classes all have different values for Range, Damage and Mesh ClipSize.

They would also have different implementation (blueprint graph) on Attack(): the knife will stab, the shotgun will fire.

And would also have different implementation (blueprint graph) on AlternativeAttack(): the rifle will fire a grenade, the sniper will aim down sight.

Additionally can also have properties and methods that are unique to them: like muzzle velocity for the rifle, spread for the shotgun, zoom for the sniper, delay for the grenades.

This way your character will not care which gun is currently equipped. He/she will just call Attack() on a parent type variable and the child reference will execute whatever its specific Attack() does.

I hope I managed to explain it but be sure to read somewhere about the basics of the Object Oriented Programming (OOP). This topic is so fundamental that you will be able to find hundreds of results if you search in Google or YouTube.

Your explanation makes a lot of sense, and that is how I’ve been trying to archetype everything.

Sounds like I just had it backwards: It should be spawning BP_FiringWeaponBase, and then Casting To: BP_AssaultRifle if I understand correctly, but changing the CurrentWeapon variable type basically breaks the entire weapon system.

Swapping to the Secondary Weapon also sets CurrentWeapon, and Aiming, Reloading, and Ammo replenishment all depend on it.

What I really need is for the CurrentWeapon variable type to not be set in stone: meaning, it needs to be the same type as whatever weapon the character is actively holding, assuming the character can hold MANY different weapons.

Does that make sense?

This is an incredibly good idea. Right now I just have the individual variables stored in the master template BP itself. It’s gonna be some work to convert all that into a struct and then re-work all the weapon code around that.

Based on dZh0’s response it sounds like I may have accidentally coded myself into a corner though. Maybe this needs to be done regardless lol.

Thank you for the suggestion, I appreciate it.

Good explanation! Also if you look at what I posted this answers your current question. “Current weapon” must be the PARENT class. And then pull from the PARENT cast the class default variables which will be set to the specific values of the child object type you fed into the parent class cast.

cast to the child class to access it variables

OK! it was some work, but I got all the weapon variables converted to a struct. Everything works again: shooting, aiming, reloading, replenishing ammo, and all elements of the HUD… but I have a problem.

Ammunition type variables are still not being carried over to the projectile, and it’s because ammunition values are not handled by the weapon, but by a separate blueprint. The idea was to make ammunition modular so that the character could find ammo upgrades in the field. Like finding dragon’s breath rounds for the shotgun, or replacing the standard FMJ rounds with hollow points as a couple examples. Also it’s the AMMUNITION that does damage to things, the gun is just the delivery mechanism .

Ammunition was originally handled by an actor component, but that was the whole issue that started this line of questioning: the actor component accessed by the CurrentWeapon variable was always loaded with the default values because CurrentWeapon was a Default template variable type. I didn’t think adding a component reference through a struct would work, so I changed it to an invisible scene component actor bp that could be loaded with variables and script for bullet behavior.

However, the value is grayed out, and it says “editing this value in a class default object is not allowed” when I hover over it in the weapon template bp.

250115-capture.png

I also tried setting the struct member in the begin play of the specific weapon, and it’s still reading none when it tries to access the CurrentAmmoType variable of the struct (because it’s set to “none” as default and can’t be edited.)

I’ve tried everything I can think of, but getting this to work seems to be above my ken. Do you have a suggestion? lol.

Here you go. I tested this out and it works just fine for me. You create 2 custom structs, one for the weapon data one for the ammo data. The weapon data struct will contain an “ammo data” struct as one of its members allowing these values to be changed without changing the weapon class. All weapons inherit from a common parent, all ammo inherits from a common parent. The player has one variable that is a reference to the PARENT class weapon and thus can hold any child weapon. The child weapons by containing a struct of type “ammo data” can then have that modified by ammo pick ups in the world. The ammo pick up will just relay its info to the weapon and the weapon updates its “ammo data” struct within itself. The player therefore can access any and all data through one reference to a parent class weapon. Hope this helps. (I didn’t show the ammo struct specifically FYI but you still need to create that, so in total 2 parent BPs, one for the weapon, one for the ammo, 2 custom structs one for ammo data one for weapon data which ALSO has an ammo data struct within it) Then create as many child weapon and ammo BPs as you like. On overlap of a weapon, SET the current weapon variable on the player, on overlap of an ammo box SET the ammo data struct within the current weapon and the weapon will now fire the new ammo.

OMG brilliant! I didn’t realize a struct could hold another struct as a variable.

Thank you for going through so much trouble!

No problem, although not gonna lie I feel like we’ve over complicated something relatively simple…but it works so there is that haha