[SUPPORT] Advanced Turn Based Tile Toolkit

Hi leo! Thank you for such an extensive reply! To be honest I was looking forward to hearing from you, because I knew you had made something similar haha.

I must ask - if we put efficiency as our focus, would it not make sense to have a copy of the characters as a Character blueprint, and simply replace them as Actor blueprints once the turn based combat begins? If not, our units would have all these character movement properties that would be unused during combat, right? I’m just wondering how worth is it really to change actors for characters, and why not instead have both and swap them according to the game mode.

Also, do you happen to know why if I duplicate the BP_PlayerController_ATBTT, it creates errors, specially regarding the pins that read Self? Why does this happen, and how can i overcome this?

Thank you again for the informative reply! It really helps to learn more on this :slight_smile:

hi

regard your duplicate BP_PlayerController_ATBTT, i am not sure what you are trying to do with that, but you get an error (self pin) because the reference to the BP_PlayerController_ATBTT in other blueprints are all referred to your old playercontroller(not your duplicated one), if you want to fix it you need to change all the reference to your new BP_PlayerController_ATBTT name.

as regard as you ask “efficiency as our focus”, if you scroll back a few pages, when i just wanted to implement my game play i asked what he thinks the best approach to do it, one of his solution was to do what you describe - replace the unit actor with a unit character when needed. this will work fine and for sure it is much less work at the beginning. i didn’t use this method because for my project, it is “less clean”. for example if i move my character in real time and there is an overwatch by the enemy then i need to consider the unit actor and not the character actor and i will have to swap the character unit to the actor unit ect… it will be more easily implemented in the beginning, but as you progress it will require much more swapping and work. both ways work fine.

hope its help

leo

hey everyone, sorry for the late response. The last couple of days have been really busy. Thanks a lot [USER=“641905”]leo bar[/USER] for helping @. I’ll add my own thoughts to your discussion.

So yeah, a Fallot 1 & 2 style setup with free movement normally and turn-based when in combat can be done in a few ways, and all have benefits and drawbacks. In an earlier version of ATBTT BP_Unit was actually a child blueprint of Character, meaning that it had access to all the movement component stuff. However, I felt that this added a lot of clutter and complication for stuff that most users were not going to use, so I refactored it out.

ou don’t just get the movement components, but also a capsule component and a skeletal mesh, which is useless for many different types of units. The origin of the capsule component is also at its center, which means that you have to take this offset into account whenever you want to get or set the location of a unit. It also meant I could not share the grid snapping/grid index calculation code from BP_GridActor to BP_Unit, meaning I had to code a lot of stuff twice, which is not really best practice. Taking all of these concerns into account I decided to refactor out the character stuff.

The fact that the movement components are included for all units, as you say, is highly unlikely to have any impact on performance. UE4 can handle an extremely large number of invisible actors without any issue (as long as they don’t have separate tick events etc.), so that is not really a concern.

So what to do if you want to have this sort of movement? Well you have discussed two of these already. One is to change it back to how it worked in earlier versions, and leo has explained this process in detail, so I don’t have anything to add there. Another is the one you are mentioning, which is to use characters outside of combat and then switch to units in combat. I would probably go with something like this personally, though I sympathize with leo’s concerns about elegance. Basically I would have each unit spawn a character blueprint and then attach itself to that blueprint. That way, whenever the character moves the unit moves with it. The unit would not have a skeletal mesh, but when animating it would call on interface events on the animation blueprint contained in the skeletal mesh of the character in the same way it normally does with its own skeletal mesh. I might be overlooking some potential issues, but as far as I can see that should be enough to get it working.

For moving to the center of a tile when combats starts you can convert the current location of the character to a grid index with ConvertLocationToIndex3D and find the value of that index in GridLocations. That will give you the center of the tile it is at. Then you can use MoveTo from the character component to move to the center. And if you’re not using character ( @wortek ) you can use a timeline instead and interpolate from the current location to the center of the tile, at the same time playing a short move or shuffling animation.

There is another possiblity to do this stuff without using character at all, though it has some limitations. Look at the ability BP_Ability_FreeRoam. This ability lets your unit move to an arbitrary distance and change directions mid-movement and is set up so the turn of the unit never ends. Depending on what you intend to do, this might be enough to get the result you want.

Regarding duplicating the player controller, using duplicate creates a copy of a blueprint that does not have any references to the blueprint it is duplicated from. It is essentially the same thing as if you made a new blueprint from scratch and built it identical to another one, node by node. UE4 has no way of knowing these two blueprints do the same thing, and so trying to cast or call events for the other blueprint will not work. You can get around this a few ways; some more hacky than others. Firstly, you could create a child blueprint of the player controller instead. That way, casting to the parent class will work, and you can choose to override or keep whatever you want from the parent blueprint. Another is to replace all regular events the player controller has with interface events, so they can be called on any blueprint that implements the interface. Lasty, you can just change all references and casts to the old player controller in the toolkit with the new one.

lastly regarding the bug with height maps, [USER=“641905”]leo bar[/USER], thanks for letting me know. As mentioned I’m busy enough that it might take a few days, but I’ll track down the problem and fix it. I expected there to be some issues with heightmaps after the thorough refactoring I did this update, so I’m not too surprised. Hopefully it is just something minor that needs tweaking.

Thanks for the explanation guys. I’ll try going for the method of having both character and unit blueprints for now - it sounds like the most flexible, and since I’m mostly prototyping game ideas for the moment, i would rather go for the option that makes it easier for me if i decide to upgrade the toolkit when a new version comes out.

Speaking of new versions, a new one showed up today. I suppose this is the hotfix version you spoke of recently, :slight_smile: I’ll try moving over my current stuff to there.

Indeed, just a hotfix. No need for anyone to convert to this one. All I changed was to set the DefaultCost value of BP_Ability from 2 back to 1.

[USER=“641905”]leo bar[/USER]: I’ve investigated the heightmap issue, and there seems that there was a problem with the new FindCloseValidOverlappingGridIndex function. On closer inspection how it was coded did not make sense in a lot of circumstances. I have altered the function to something that now seems to be working as intended. It is not the most elegant of functions, but it gets the job done. It might seem less efficient than it is, as the heavier parts of the function are unlikely to be checked often.

Replace the contents of FindCloseValidOverlappingGridIndex with these nodes to fix the heightmap issue. Let me know if you run into any issues with it. If not I will send another hotfix with this modification to Epic soon.

hi

i have tested the new FindCloseValidOverlappingGridIndex function and its seem to fix the problem and its working fine now( i didn’t have much time today so i tested it not too extensive).

hope all is good with you

cheers
leo

Thanks for testing. All is well, thanks. Just the PhD work getting progressively more stressful as the end of the year approaches.

By the way, to people following this thread who have not bought the toolkit, it is currently 30% off as part of the UE4 fall sale!

Good day again,

I need help/ideas on how to implement a Square type Ranged attack? … so like a ranged unit(AI) can only attack a unit that is North/South/East/West of HIM.

I need for the ranged Units to NOT be able to attack diagonally. :slight_smile: is that possible? (USING ATBTT for UE4.18 )

thank you :slight_smile:

I’m afraid you’ll have to clarify a bit. Visibility is normally already in a square for square grids. Do you mean something like a ‘+’ shape? This should be realtively simple to do. The FindTilesInRange function in BP_GridManager is split in two parts, where the first is GetIndexesInRange. The most performant way to implement this is to modify this function to have an optional parameter for getting indexes in a plus-shape, much like there is an option to get indexes in a diamond shape. This would essentially be two loops with one for adding tiles in the X-axis and the other in the Y-axis.

A less performant, but simpler implementation is to take the output from either GetIndexesInRange or FindTilesInRange, loop through this array of tiles and only keep elements where the tile is either directly north, south, east or west of the origin point. This can be done (in 4.18) by checking the rule that ((OriginIndex % GridSizeX) - (Tile Index % GridSizeX) == 0) OR ((OriginIndex / GridSizeX) - (Tile Index / GridSizeX) == 0).

(for people using the 4.21 version or later, replace GridSizeX with IndexX)

Ooo wise lords of the programming arts, let me invoke your wisdom…

BPs.jpg

It’s about the SpawnActor pin. I was trying to set everything up to run the turn-based grid combat, switching from this WASD realtime isometric movement…So to set things up, I wanted to spawn the GridCamera, and then run all the original code Mono has written. Yet for some reason, the camera does not spawn when I press F. I don’t think its a problem about my Event not triggering correctly for some reason - if I replace the spawnactor pin with a print pin, it prints the message without any problem…If I hook up the SpawnActor after a BeginPlay event, or put it in the Setup Core Blueprints function, it spawns the camera correctly…But not if I put it after the Press F event ha. Does anyone know the reason for this?

@: I’m a bit confused about your setup here. I’ve never called on a parent event from an event that is not the child version of said event. Does that even work? Even if it does what is your intention for calling it?

Anyways I have a suggestion that might be simpler than what you’re going for. Spawn and setup the grid camera as per ATBTT’s defaults and then possess your custom pawn. Then instead of spawning the grid camera when needed, simply possess it instead.

@ Thank you for answering!

No, atm it does not work. My intent was to try and leave your code untouched as much as possible for now, so that future updates are as easy as possible, but my lack of knowledge in some areas leads to lots of mistakes as I learn more about blueprints. What you see is a child blueprint of your Player Controller that you made, as you previously suggested, and my intention was to put in there all custom events like the topdown player controller stuff, and then link to your code once Combat Entered was activated. I’m spawning a Grid Camera because that BP is no longer the Default Pawn Class, so I should make one. Parent: Begin Play executes automatically for now haha, which is something I need to fix somehow. Docs dont say much about that, so I’m still digging on how to fix it.

I was wondering though why the SpawnActor pin does not spawn the camera after the press F event is executed, whereas other pins, like simple Print functions, do so without a problem.

You mean make the camera spawn in the Setup Core Blueprints function, right? Yeah, that totally works, and I think it’s the more logical and organized solution, looking at it as a finished product. I was trying to not do that though to keep your BPs as unmodified as possible, in case I replace them in the future with updates, and put all my dirty pleb code in one place for now for convenience sake.

But yeah, I say it makes sense, and yet I’m confident that you know mountains more than I do, so what you say is most likely what I need to do ha…Thank you for taking the time to reply to me .

hi @
Sorry if this issue has been discussed somewhere else but maybe you can point me out where to look. I have a problem with adding custom geometry to the grid manager. This works fine on the hexagonal grid but seems broken in square one. Grid manager ignoring any custom geometry and always using square planar geometry.

To replicate:

v UE. 4.21

add grid manager

change the geometry in Default Move Marker Mesh

Play

Geometry stays unchanged

See attached image:

hi PanAtoman

i hope i can help you (probably will do a better job)

**but if you want to change your **Default Move Marker Mesh, then just do it in the ability blueprint (for example if you use the move\attack ability - change the mesh in there) you are using not in the grid manager

hope its help
leo

Not sure about your spawning issue, to be honest. Maybe the unconventional calling of a parent event is screwing something up somehow. When spawning new actors you often have to wait a tick to be able to manipulate it, so if you are checking if it has spawned the same tick as you spawned it, that might also cause it to seem like the camera seemingly hasn’t spawned yet. Try using a delay of 0.0 seconds (which defaults to 1 tick) after spawning and see if you can get a valid reference.

As [USER=“641905”]leo bar[/USER] has noted, you can change the meshes in the defaults of the ability. In older versions of the toolkit marker meshes were all set in the grid manager. I changed this so that it is instead set in the abilities themselves to improve flexibility. BP_Ability_Base and BP_Ability are now set up so that they only use the grid manager defaults if there is nothing specified in the abilities themselves.

@ , [USER=“641905”]leo bar[/USER] Thank you, guys. Works perfectly!

It’s too early in development to implement right now, but eventually I think I’m going to want sky tiles and underwater tiles that are over and under the land tiles. How practical do you think this would be? (These would need to be adjacent to the tiles in their own columns, and perhaps diagonally)

@Lachnor: Not sure if I follow. Why can’t you just use regular multi-level grids for this?

Is there a function available that can give me an array of tile indexes that pawn can attack CONSIDERING tiles it can move to from its current position in a single turn? Normally I’d run “Find tiles in range” adding move range to attack range and taking output BUT there may be an obstacle (usually another pawn) in the path of the pawn that won’t allow that pawn to move and attack a specific tile. Maybe I could run “Pathfinding” with input of “move range+attack range” but I need to loop through a number of specific pawns on the grid and find that “can attack the tile with this index” array for each.

Update: I duplicated “patfinding” function and all related variables and I’m using it for my purposes - seems to be working. I’m afraid it could be helluva slow though to loop through all tiles each turn and during each tile check to loop through all pawns to check if they are able to attack this tile during their next turn.

What I need it for is to add a danger value to each tile based on how many pawns can reach and attack this tile and their damage.