Best way to create and store a data type that might differ in number of variables with each entry

I’ll begin by saying I have little experience using Unreal/C++ and I come from Unity/C#. Because of that I haven’t grasped many of Unreal’s quirks or C++ in Unreal for that matter.

The Problem:
I want to make a weapon database. Weapons have different weapon types, and each weapon type has some core variables that every gun should have, but also, some added variables on top (Added variables depend on the type so each type has a different set of variables).

I want this data to be stored and be easily accessible.

On BeginPlay, I would like to access that data and instantiate a copy of a weapon (using an ID or name) on the player for him to use.

What I have done:
I have a class “WeaponBase” which extends “AActor” (Which is not a good idea since the mais purpose is to store data) and contains variables that every weapon should have (Name, Damage, Range, …).

Then I have several subclasses which extend “WeaponBase” and add more variables on top of it. They also override the firing methods but that logic can easily be relocated elsewhere so that’s not a problem.

But now I don’t know what to do with these classes, which brings me to another point.

Something that I still haven’t gotten used to, or perhaps, haven’t understood yet, is that constructors in Unreal don’t take parameters because of the UObject system. So I haven’t found a way to create weapons within the code.

Then I thought that If I don’t need methods, I could easily turn this class into a struct. Plus, I read that there’s struct inheritance in C++ which would be great in this case, but unfortunately, UStructs don’t have it.

I also researched the combined use of Structs and DataTables, but then I couldn’t store the different types of weapons on the same table. And if I made a table for each weapon type, I’m not sure if I can create a variable on my character to house any possible weapon, ence the use of the “BaseWeapon”.

If in this post I assumed anything that is incorrect about either Unreal or C++ don’t hesitate to correct me.
If I failed to explain any aspect sufficiently please say so.
Also, sorry for the long read.

Thanks in advance!

Unity Example:
If it helps to better understand what I want to accomplish, here’s an example I actually got working while I was still using Unity. The way I would go about this would be to create “BaseWeapon” as a Scriptable Object Class, create some Scriptable Object Classes that extend “BaseWeapon” (one for each weapon type). Then I would create as many weapons as I wanted in the editor using those subclasses and add them to an “BaseWeapon” Array. Finally I would have a variable of type “BaseWeapon” in the player character to store the weapon the player currently holds.

i am using uml diagram software to process my ideas and it helps me to do these tough tasks you explained in your post.

one thing I can tell you that you should use structs/dataTables to sort all of your variables for all of your logics

1 Like

I don’t know if this is the best way but you might be able to use the “Construct [Class]” node to create an instance of the class, then you can immediately set its members.

1 Like

Yes, classes work pretty much identically in C++ and C#. So, you do the same thing.

1 Like

I’m tried uml in the past but I’m just not a big fan, but I do have everything in notes.
I do like the idea of using structs/data tables. Currently trying something using those.

I don’t know what you mean by “Construct [Class]” node, could you please explain or link me to somewhere I can find out? Sorry for the trouble!

The way I did it in Unity was using Scriptable Objects which are exclusive to Unity, not C#. Because of that I haven’t managed to replicate it in Unreal/C++.

I would use structs with data tables or create components where you can add the component to any actor and access its unique variables and functions.

2 Likes

Hey @HHACarvalho first off, welcome to the forums and Unreal itself! I actually learned Unity/C# before going over to Unreal/C++. As many of the others have noted the difference in how you’d implement this is definitely personal preference. So my personal preference would be the way you went for polymorphism off the bat extending the base classes and overriding what’s needed. That said, you could go with what @Kaidoom15 was saying and extend it as a scene component instead of from AActor unless the objects themselves will need to be extended actors.

1 Like

There is absolutely nothing special whatsoever about Unity’s ScriptableObject, they are just an empty class that does nothing on their own. You can create a blueprint off of UObject, or create a Struct, for the same thing. At least, as far as I’m aware.

2 Likes

I just mean the ‘Construct’ node - if you start typing ‘Construct WeaponBase’ there should be node called that that will just create an instance of WeaponBase, which will live in the current blueprint (or whatever you plug into Target.)

About making a DataTable, couldn’t you give the row struct a WeaponBase, and give each character a WeaponBase variable? Is that the sort of system you’re going for?
Or if the character needs a specific weapon type, you could make character’s variable a specific weapon subclass and when you look up the weapon instance from the DataTable, cast it into the correct weapon type. I guess this would be a bit inelegant though because the WeaponBase entry in the DataTable wouldn’t stop you from putting in the wrong weapon subclass.

1 Like

First of all, thanks to everyone who took their time to help me out!

Here’s what ended up doing:

  • As many of you suggested I created a struct and paired it with a Datatable to store the essential information about the weapons.

  • I made an additional struct that extends the first one and adds a few more variables that don’t need to be saved in the Datatable (Ex: Current ammo inside the magazine).

  • Instead of AActor, WeaponBase now extends UObject since UObject is the base class for all Unreal objects, and therefore, more lightweight. And also because actors are meant to be placed in the scene and that isn’t the case here.

  • I also found a slightly more “elegant” way around the fact that you can’t use constructors with parameters in Unreal by following the solution provided by akaPrometh in this forum post: Passing arguments to constructors in UE4? - #6 by akaPrometh

Brief explanation: You basically create a static method that instantiates the object, takes in the parameters you want and passes them to another non-static method that is going to assign the values to the variables (like a constructor would do).

Thanks again for all the help!

1 Like