I’m new; I’m an Artist, not a Coder.
Quick Summary : Anyhow, I’m attempting a Final Fantasy-like combat system. There will be up to 7 BP_Characters on each side (2 sides). For now it’s manual control (for Debugging purpose), so player gets to choose which Action to perform, on whom. But the goal is to later convert that into auto-battle like in [Ogre Battle].
I already got the basic Turn system working. [MY CURRENT PROGRESS]
I also tested basic Health systems. It works. But only when it’s Self-Inflicted (Healing and Damaging.) I need to be able to Cast the Heal/Attack onto the Target (selected by Player, for now.) instead.
I tried Casting to BP_Character → GetPlayerCharacter → Player Index 0, and obviously that didn’t work.
I presume I need to make a list/array of all participating BP_Character ??
What are good ways to implement this system ? I believe I can use this same method for almost all interaction between BP_Characters once I got this down. (AoE might be another story… but that comes after I implement some Formation/Positioning systems)
Ps. Again, I’m very new to this. So your answers/explanations might have to be like ELI5…
Thanks in advance.
First off, no, it’s not that hard. Second, I’m tired and will explain more later, but… What you want to do is use a base class and make child actors. You also probably want to use interfaces.
I’ll be back in about 10 hours, but that should keep you busy. The documentation is really good if you already have somewhat of a grasp on what you’re doing otherwise it’s Arcane writing. What you’re trying to do is kind of advanced but it looks like you’ve already got a pretty good handle on it so if you can figure it out by yourself that’s great if not I’ll give you my Discord handle and I can help you through it.
I am not quite sure I understand this: “I also tested basic Health systems. It works. But only when it’s Self-Inflicted (Healing and Damaging.) I need to be able to Cast the Heal/Attack onto the Target (selected by Player, for now.) instead.”
I assume you are not sure how to cast to the right instance of a BP actor. Generally there are many ways, one of them being using interfaces like rklsImmersion suggested. But casting is better if you know which instance should receive the damage. I would do it like this:
- If it is melee damage (I am not familiar so much with Final Fantasy combat), then you probably have some collision volumes overlapping. In the Character_BP create “Event OnBeginOverlap”, pull off “other actor” and cast it toe CP_Character (or enemy or whichever the right one is).
- If it is ranged damage, you usually make a raycast, a line that must hit the enemy. pull off from there and “break hit result” and then you find “hit actor”. Cast it to the character blueprint and you got it !
Please let me know if I misunderstood your question. I am happy to help you.
I think getting more info on how the player selects the target would be useful.
For now I’m going with ‘Player clicks Attack button, then click on the target to Attack’ route. So I could make sure I got everything right.
But eventually I plan to go with Auto AI combat… So, by then, the targeting will be by “Target with least HP”, or “Target with highest Power”, or “Target with Bleeding/Weakness/Debuff On”, or “Target by Class/Role)”. (Player can decide which Tactics to use as Default, or temporary change during Combat itself). So, eventually I will need to make a list/Array/Struct/something of that, and maybe allow Sorting by HP/Power/etc and use the Index 0 Target, I guess ? No clue yet… Still learning.
@BreakMaker Will Raycast method or BeginOverlap will a problem if Attacking Character moves pass other Character to the specific Character to be attacked ?? There will be a bunch of Characters on the field later.
Self-Healing/Injure command (which is useless in gameplay-wise… though this means I can use this for using Potion on Self, Dealing damage to self and a greater amount to the target.) Just about everything is on BP_Participant, which is the Character.
Hmmm, I see I can slap BPInterface on for something like Changing Damage or maybe even DamageoverTime… Will have to look more into it.
Child BP, I feel like I’m missing something here. My plan is to use the current BP_Participant as the Parent. And other characters (such as BP_Swordsman, BP_Archer, etc) as Child. Though that still doesn’t help me with how to select specific Actor (that Player clicks on) to act upon.
Maybe I could do it in a way that after Player click on ‘Heal’ button, the game Spawns a Healing Effect on where Player clicks, and that Effect comes with BeginOverlap and heals whatever target it overlaps with ??
Are your battles taking place in a separate level or do they take place in the same level where the player would move around in the world? Because if they’re taking place in a separate level at the start of that level you can use get all actors of class and put that in an array. Then when it comes time to select the actors you can cycle through them with the mouse wheel or arrows and just go to the next one in that array. That way you will already have a reference to the actor via the array that you made.
Edit: in order for that to include the player characters so you can select them and have their affects both the players and the enemies would have to inherit from the same parent class.
Now I understand better what your goal is.i also now realize your game is a grid and turn based game.
In this case you just need to set up an array and query it. I would recommend creating a “player manager” blueprint actor that would do all the selection logic (lowest HP, highest HP, most badass, etc.) This way you do not have to do the calculations in each of the actors.
So when you want to target for damage:
Get all actors of class, select the right character class. You will receive an array of actors in your scene.
And now you can work with this array. For instance do a for each loop, and for all element of the array check how much the HP is and store it into another (sorted array) depending on whether the HP is higher or lower than the previous element. Please check out the documentation on working with arrays in unreal. (insert node). Finally you save the actor that has the lowest hp and plug it into your attack /damage function (you do not even need to cast to character anymore since “get all actors of class” already returns the class you want.
The player manager could run this function every somebody gets damaged.
I think I want the Battle to be in a new level.
The part where both players and enemies have the same parents; I get that.
It’s the ‘act’ of referencing the target that I am still lost… Probably because I think of it as Casting to… something, still.
That’s the point of having them in an array. If you cycle through that array when you’re selecting them, you’ll already have a reference to the via the array. What I’d do is have the function that creates the array in a bp you know is always going to be in the combat level (like the main character or the game mode) and that way you only have to cast to that (if you’re using the game mode for it).
I understand that Blueprints doesn’t support 2-d Array ? What do you recommend I make this kind of Array
Also, is it ok if I use the Game Mode blueprint as the ‘Player Manager’ as well ?
I would need the GameMode/PlayerManager to hold all important data.
Then the Actor, say, uses Healing spell, will do Set Target’s Current HP = Target’s Current HP + [Caster’s Power + Spell Power]. (Target being the return from GameMode/Manager sorted Character with lowest HP)
Thanks much for the visual examples. It helps a lot when I’m still learning.
The question I have is: What is that Struct Array node ?
Ps. Right now I spawn Actors from GameMode. And those Actors (BP_Participant) get random stats in Construction Script. I will change it so that the Struct is made first, and filled up with random stats, then spawn Actors with those stats via Cast To Game Mode, I presume.
Creating a list of all the subclasses is the correct way to do it. Where ever you create all these characters, say at the beginning of a battle in a final fantasy game you might do this in a level blue print specific to the battle scene.
It might me useful to store this information in another BP (ie game instance) so you can access it. So first create the array where you want to access it.
Then in the Level Blueprint or where ever you create your characters(add them to the scene) add them individually to to that array.
Now you can access specific sub classes as elements of this array.
Alternatively you could handle this in a structure array which is like a 2d array.
And access variables within the structure including a subclass reference like so.
Variables with in structures can themselves be arrays thus this would be how you create a 2d array in ue4.
Hope this helps.
Sorry, you have to create a struct array variable just like you did with the battle array accept the array type is your struct type. I ran out of pictures to use in that one post, my bad. In you case it would be Struct_character instead of FFStructure.
@enearle Okay, I was trying something here, but I think it doesn’t quite work.
First, I spawn 2 BP_Participants
Then, I presume, Get all BP_Participants, put them in BattleArray. for each of the BP_Participant, put them in the Struct. And for each of BattleArray, put them in Struct with Array Index as ID (1,2,3,), with random Name, random Health and random Speed.
And this for Debugging purpose… (as you can see… I think everything gonna breaks… for good reason). Anyhow, when SpaceBar is pressed, print BP_Participant, Name, Health and Speed of each of the data inside the Struct.
Which of course didn’t work <_<"
I find it really strange that the for each loop is still going through three cycles, which tells me its adding three structs to the array but not retaining the information in the structs. I’m really confused, it must me something really simple that we are overlooking.
I set up fundamentally the same system, and debugged it to figure this out and it worked.
Is there anything anywhere else that could change this information before you print string?
Ok, I made some changes here.
In structing array;
I replaced For Each Loop (of Battle Array) with For Loop (of each Participants) instead. (Default is 2 Participants.)
In print out;
Mostly the same I guess.
YAY, Progress. However, it seems there’s nothing in the Participant in the Struct. Everything else comes out except the Participant Variable(which returns None), which I presume, is used to reference the specific Character/BP_Participant.
I think that’s because its trying to convert a class reference into a string, have you tried seeing if it still works as a class reference? Say if you were to change the transform of “participant” from the struct, does it still move the corresponding character? The reference should still hopefully point to the right character.
That is a good point there. So I went ahead and try to set each character’s Stats upon their Spawn, Getting data from the Struct.
Widget Action set to invisible at the beginning (only visible when Character is Ready.) The problem I think I see… is the BP_Participant doesn’t know from which Index/Array Element to pull data from ??
And so the result is… both Participants have copy data. That means they both Get from the same Index/Array of Struct I guess.
And I’m not sure if the BP_Participant is of the right character either… with the lack of Battle Array, or the empty Participant BP Object Reference from the Break Struct.
… Wait… My logic is flawed… I will get back to this later… Gotta run for work.
→ Fill Struct
→ Spawn Characters with Stats based on the Struct
→ Spawn Characters
→ Match Characters’ Stats to Struct
→ Stats are assigned via Game Mode when it Spawns Characters.
→ and not via Characters’ Construction Script