Shared stats for player and npc?

Hello all,
Firstly, my apologies if this has been asked before but i haven’t been able to find any info on this specifically.
I’m creating a single player, 3rd person RPG project. I’m starting to layout my player and npc mechanics such as stats, health, abilities etc.

In my mind and through my sketching I envision being able to create a core set of rules that all characters (enemy, npc, player) could pull from and use. I would break this up into sections that would be used or not used depending on the character. Let me explain.

All characters would have health. Player, npc & enemy. So this would be in a base universal set of variables (not sure where it would be stored)
Next would be stats like strength, agility and charisma. These would be held in another pace but useable by npcs and player not needed for enemies.

Then there might be a few variables that are only needed for the pc such as reputation or faction like/dislike.

I would love to set up a check box or select variable (is pc, is npc, is enemy) to derermine what other variables are needed.

So my question is, what would you recommend as the best method to store this info and how would i retrieve it for the different pc,npc, enemies etc.

In a perfect world i see it as being able creating a new npc as a duplicate pawn then edit there variables to what is suitable (warrior had more strength than a wizard etc.)

It would be a great template system to easily create many npcs and enemies that are needed in an rpg. If anyone is familiar with the elderscrolls construction kits you may know what I mean.

If anyone can point me in the right direction I would be very grateful.

Thank you all.

What you’ve described is the very core of OOP.

Start with a base class that has all the shareable functionality, you can extend from that class to create children with unique variables and functions.

Also, look into components, these are modular pieces that add functionality when you need it. Here’s a neat video showing it in action.

Hi Newest,

Thanks for your reply. So I’ve done some research and almost got where I needed to. I’m going to show you some of my workflow and see if I’ve either almost got it or totally stuffed it up, (Hoping the former)

First I created a struct to hold my variables. I have 3 core stats (used by all character BP), NPC stats (added to npc and player BP) and player stats (only added to player BP).

Here is the Core struct

Next I created a core behavior actor component blueprint. This handles my default player behavior such as opening and closing the menu & It’s where I’ll store functions for characters that are universal etc.

I have created a reference to the character and added the struct as a variable.

Then I add that to the player blueprint which allows me to edit the stats from the player blueprint see below.

Now here’s where I fall down. In my UMG I can get the string variable character name just by binding it to the player character variable and I figured out how to get the origin to display (it’s a variable selection from an enum)

How I did this was by setting a variable in my player BP on event begin play

That allowed me to get the data in the UMG bind code

I could do that for the other stats but and I wrote some code to increase the stat (pressing “v” adds +1 to the stat) My concern is that I kind of fluked my way to the stat binding and feel like I’m probably doing it wrong. (Just cause it works doesn’t mean it’s right)

I’ll have to post my code in the next reply.

Can anyone tell me if I need to change my process or if I’m just missing something really simple? Anything will be really appreciated.

It’s important I get this right from the beginning as it is the core of my stats/abilities system in this game and I don’t want to have to massively re-write my code later.

Thanks all.

Ha ha, sorry Everynone. I thought your handle was newest but obviously that’s post related.

The thing with your approach is that variable binding is kind of inefficient and can get messy. First of all, you’ll need to write a function for every variable… and that’s annoying, to put it mildly. In addition, this variable is pulled every frame. For every widget you run a function, every frame. It’s fine if you’re doing something simple but there are better ways.

A more reasonable method is to send a struct (that you are already using in your object) to the widget and have widget elements pull the info from that struct. This is actually made pretty convenient:

215287-structpulling.png

The only thing you need to do is to update the struct that is in your widget and the widget elements will handle the rest. You no longer need to write function bindings for all variables. Unfortunately, not everything works like that because there may be no direct conversion - you cannot bind a vector variable for example.

But there is a much better way. One that requires no binding whatsoever, does not do anything every frame, does not care whether the object is valid and allows you to preformat the data for display. The downside is that you need to write it yourself. :slight_smile: (still better than writing bindings!)

You can flag TextBlocks as variables and update them directly:

215303-updatewidget.png

You do it from outside of the widget and only when it needs updating. When your character’s stats change, call the widget’s CustomEvent (or function) and push the text into the text blocks. Even better, you can write a small function that takes a struct and pushes the preformatted text into text blocks, all at once.

The above method is the most convenient and efficient one I’ve found.

Yup, read my post above. :slight_smile:

Awesome, thanks Everynon. It’s great to get some clarity on this and the method you described using the text block set to a variable is much more preferred. That’s what i had in my head original but was unsure how to accomplish. So to change my process so it works that way i should: keep my stats in the struct, keep my actor component that has the functions like health/damage etc. And keep adding that to the player or NPC where i can st the stats values. Then don’t call these forum the umg but instead create the function to push the values to the textblocks. That’s great (if correct) and won’t require much re-writing. However, when you say the downside is ill have to write it myself do you mean in c++ or can it be fine in blueprints? Is your image all that is needed to simply update the text and if so does that need to go in my actor company or my player BP or does that not matter?

Thanks again for all your help.

However, when you say the downside is
ill have to write it myself do you
mean in c++ or can it be fine in
blueprints? Is your image all that is
needed to simply update the text and
if so does that need to go in my actor
company or my player BP or does that
not matter?

This is 100% blueprints. And the function/custom event can be in the widget, unless you are going to do some really heavy lifting inside or are planning on having 1000s of them.

Then don’t call these forum the umg
but instead create the function to
push the values to the textblocks.

Yes, precisely. In you widget, create a function that takes a struct. When the properties of the actor change, call that widget’s function and provide the updated struct (it can be a bunch of separate vars, too - whatever is easier/more logical).

The aforementioned function breaks the struct apart and sets TextBlock’s text, formatting it as needed. It’s a really neat solution.

Hmmm, I think I’m doing it wrong. As a test I set my Player Name to a variable

Then in my CorePlayer_Behaviour Actor Componant I tried to add the set text node but when I add the playername variable it requires a target. I thought that would be the player character but nothing I put there works.

Is that because I need a function like you put in the UMG? or do you think it is because I’m trying to call it from the actor componant and not the player BP?

Sorry to be a noob, but when you say create a function that takes a struct, I’m not 100% sure what you mean. I know how to create functions but not sure how I’m getting the struct and if I need that function to return anything?

Sorry and thanks again.

ok, that makes more sense. I was trying to do it from my actor component not my player BP (I’m guessing that’s not possible). So in your example what is “ship”? - Is that the player character?

I realize it’s probably hard to give advice when not seeing the whole picture and appreciate it.

See if you can create something similar in the widget and set the text blocks:

And from your player you’d call the player’s widget like so and feed it the struct:

215334-call.png

Imagine the above code is in the Player and the Ship is the widget.

So basically, the player object has a widget and tells the widget to update its elements.

So in your example what is “ship”? -
Is that the player character?

It says it right there under the pic :slight_smile:

I was trying to do it from my actor
component not my player BP (I’m
guessing that’s not possible).

I do not think there is right or wrong here. You can do both. If you keep the data in the actor’s component (something I like more and more these days), you can send it to the widget from that component.

Or, you can access the component’s struct from the actor and send it to the widget. Pick your poison.

Find something that seems the most logical to you and we can iron out the communication logistics between the elements that need to talk to one another.