This is great work you are putting into this toolkit. I have small question: is it possible and if not, is it hard to change toolkit to be able to place few units on the same tile? I have map where one tile represent bigger part of terrain and I need to be able to place more units on one tile. Is toolkint flexible enough or it will require massive changes?
Hi tutkarz, that depends a lot on what you are aiming for. Is it something like in Civilization, where one unit of troops still pretty much functions like a unit in my toolkit only that it has multiple skeletal meshes, then no, that is quite easy. If you want something else, where two different units can move onto the same tile and you want to be able to selectively select one of these units while they are on the same tile, you would need to rework several core systems.
I think my post might have been missed due to being held up in moderation. I’ve been playing with a few delays on the setups to let the units spawn on BeginPlay before it looks for the units on the grid and that seems to work with a few problems, but I’m not sure it’d work once I get spawners set up. With your experience, do you know if there’d be a simple way to accommodate them, or would it require a major rework on the toolkit?
I’m not at my work pc right now so I can’t take any pics for you, but I did something similar in my project. Basically, I added a boolean variable to units that marked them as a spawner entity, and modified the grid manager function that adds pawns to the pawn array to ignore those units effectively hiding them from the game. It’s been a while since I played disgaea, so I don’t remember exactly how it works, but iirc you click your spawner and you get a menu of your units, and you can pick one to spawn.
If that’s what you want to do, you could pull it off by doing what I did, and then creating an array for your spawner(s) within the grid manager, and having it add your spawner to that array at startup (like it does with pawns). Then add the functionality within the player controller to call a menu that lists your available units when you click the spawner, then when you select one add it to the pawn array at the spawner location.
as long as you use the Spawn Unit function in BP_GridManager, spawning units during gameplay should not be a problem. What this function does is spawn a Unit actor and add it to the Pawn Array and Initiative Order array.
Thank you! That’s pretty much exactly what I’m trying to do. I’ll make some changes and try it out.
Yeah, that’s what I’ve been using. I’ve just had a few problems when trying to use it while starting with an empty grid. I guess the grid manager is looking for units on BeginPlay before they’re even being spawned and it’s causing some errors.
This looks very sophisticated and awesome! Would it be possible to show us some high detail screenshots of the ‘Activate Skill’ and ‘Player’ parts of one the skill Blueprints you are working on? Will players be able to choose between several skills from a UI menu like in XCOM? How will each skill interact with the ‘Unit’ blueprints? I’m really looking forward to getting this working!
@AdventPalace: Ok, it seems I misunderstood you then. Thankfully Selentic understood perfectly and gave a great solution. Having thought it through I really think this is a great way to make a unit spawner, so I would go with Selentic’s method.
@cbdeakin: I’m glad you like the toolkit! I’m modeling the skill system in this game example after XCOM, so you can indeed choose between several skills from an UI menu. The UI is pretty basic, but functional. This is how it looks:
I’m not sure if taking screenshots of parts of the skill blueprints will make much sense in a vacuum. They are all dependent on a lot of parented functions and interactions with the HUD and Grid Manager, so I would need to post a whole lot for it to make sense. If you have any specific questions about the skill blueprints I can answer them more easily.
The way the skills interact with the unit blueprints is that the units have an array of skill classes which decides what skills each unit has. At the start of the game each unit spawns a child actor of each skill class. On the start of a unit’s turn the UI is updated based on the current unit’s array of skills and each button in the HUD gets passed a reference to each of the skill blueprints. When a skill button is clicked, the activate skill event is called in the skill, which sets it as the current unit’s active skill, enables its tick and opens gates to enable mouse hover and mouse click events.
The AI works differently and has a separate decision tree for each skill. At the start of an AI controlled unit’s turn it cycles through all of its available skills and runs The AI Check Value event, where it considers all possible targets for its skill and assigns a value depending on the likely outcome. Then it chooses the skill with the best predicted outcome and executes it. Work on AI has been by far the most time consuming part of work on this update, but I feel a skill system would be half baked if the AI units could not also utilize it well.
I just found a bit of a glitch, or maybe I just missed a step, but when I added empty tiles to the basic toolkit and turned off collision plane walkable, the range trace meshes, and path line didn’t show up. I think they are hidden below the new tiles? I can walk around, I just can’t see where I can walk to.
Here’s a screenshot of the gameplay.
Huh, odd. It seems like the Static Mesh of Tile_Hex_Empty was set to 0.5 unreal units above its CustomGridAnchor, meaning it occludes the marker meshes. Set it to 0 and it should be fine. I’ve now fixed it for the in-progress version for the next update. Thanks!
I’ve now come far enough with the update, that I’m pretty confident I will be able to release it around the same time as UE4.15 is out, by the way.
Thanks for your helpful reply. I’m pleased to see how much progress you’ve made with the UI and skills. I’m sure I’ll be able to learn a lot from the AI trees you are making as well. Is there anyway we can try out the additions you’ve made to skills and the UI in our own projects, before the next version is officially released?
That worked, Now I just need to make sure my units are slightly higher than the ground, as they are clipping into it now.
I’m having a new problem with the fog of war. I added the fog of war to my map and there seems to be two problems, the first is that it doesn’t seem to be covering my entire map, and I have suspicions that it must have something to do with it being a hex map.
The second problem is that I added the reveal visible tiles event to the unit’s begin play, however it doesn’t seem to be working. I copied it down from a separate project (though I may have made a mistake.)
Here’s a picture of the fog on the grid:
Here’s my reveal visible tiles nodes:
Sounds great! looking forward to it!
EDIT: Well, I found the second glitch where the visible tiles were not clearing. I didn’t split a struct pin and had all the cords attached to the array element instead of the array element index. I still however don’t know why the fog doesn’t cover the entire grid.
EDIT: I had some glitches with the fog of war, but they sorted themselves out after I found a discrepancy in my reveal visible tiles function.
Here’s a sneak peak of the world map.
Sounds great! looking forward to it!
So I have a working bubble shield (protects allies) that I can currently only place on the ground or on an enemy. However, I want to only be able to place it on empty tiles (already working) and Friendly units, while NOT being able to place it on enemies.
Currently, I added two new booleans: CanTargetFriendlies and CanNotTargetEnemies. With the first boolean I placed a CanTargetFriendlies branch after clicking a tile of a unit in the player’s faction or allied faction. On true it goes straight to the first node in the, “Attack clicked target if within reach, or move towards it if it is not,” comment box. However, right off the bat, something is wrong. It seems that the cost of the move, and the path-finding are not set, since it either uses the previous path-finding results or sends the unit to grid index 0, but the movement cost prints as 0. I have implemented the CanNotTargetEnemies bool, by placing a branch right after it checks the faction (working as intended).
This would be a very helpful feature for including friendly abilities, like shields and healing abilities.
After playing for some time with this great toolkit I have small problem with making roads.
I was thinking to make default tile cost 2 to be able to place tile_cost_1 as roads but now I have to place all tiles as tile_cost_2 and then tile_cost_1 as roads because they need separate mesh. Is there better way to do this? Or where can I look to change default tile cost from 1 to 2?
Second and more complicated thing would be to have separate cost to enter tile, based on vehicle type. For example truck should not be able to enter forest (without road) and boat should not be able to enter land. And plane should always have tile cost 1. I think It would require much more work, is there any chance it will be added to toolkit any time soon?
Another small tip/request would be to change Can_attack_with_0_move to “Attack cost” instead because some units should be able to attack few times in one turn or be able to move after attack. And maybe separate option for “attack ends turn” for that unit.
I would try to add all this to the toolkit somehow but I’m afraid how I will update it to new version without losing any changes.
Thanx and keep up great work!
Lots of stuff to reply to Sorry for the late reply. I worked all of yesterday preparing a lecture for work.
No worries! I will want to do a lot more bug testing, cleaning up and commenting before I release the update, and I would not feel comfortable sending out early updates before this was mostly done. I’ll consider it when I get there, though.
Looks awesome! Glad you managed to solve your fog of war problem.
Hmm, I need more info to understand what is wrong here. How are you detecting what tile has been clicked and if it is a friendly unit? Are you using the default On Click nodes in ATBTT_Player_Controller or are you doing something else? Pathfinding should always run at the beginning of a unit’s activation, before input is enabled. Have you made any changes to the Activate Unit part of the player controller that could affect this?
Hi tutkarz. For your first question I agree that setting the default tile cost to 2 would probably be the easiest way of achieving this. This can be done in the grid manager when the edge array is originally filled, but adding the roads afterwards is a bit more complicated. The toolkit is built on the assumption that the default tile cost is the lowest, and the default Spawn Tile function ignores the edge costs of an added tile if they are lower than the current costs. It is certainly doable, but I will need to play around with it a bit. I’ll report back with my results when I have something
Separate pathfinding for different sorts of units can be done in a few different ways, and the best implementation depends on the desired results. For units ignoring movement cost (such as your plane), there is such a pathfinding type implemented by default which you can select in the pathfinding type public variable of unit_parent. For the differing pathfinding of trucks and boats the easiest way to do this would be to add another such custom pathfinding (expanding the pathfinding type enum as necessary). This can be done by modifying the use custom pathfinding macro inside the pathfinding function in BP_GridManager. During the search step of a unit with pathfinding set to, say, truck, after checking if a tile has not already been added to the CanMoveTo array you would check if that tile was a forest, and if it did you would not add this tile index to the Open List or CanMoveTo array. You would create a similar branch to the custom search step for boat units to check if the considered tile was an ocean tile. To do this efficiently you would want to create an array where you can easily look up what terrain is contained in each tile. I would use an array of enums the size of the grid (GridSizeX*GridSizeY), with the enums designating terrain type. For terrain tiles I would create a new actor based on Tile_Parent with an enum variable designating its terrain type. On Event Begin Play, after resizing your new terrain enum array in BP_GridManager to the size of your grid I would loop through all actors of your new custom tile type and set the array elements of your enum array to the value contained in your custom tile blueprints at the grid indexes corresponding to the tile actors’ index variable values. Hope that makes sense.
As for the attack cost stuff, this is something I am slowly implementing, and the example game in the coming update will have something much closer to an action point system (though it is not fully realized yet).
I just added a branch to the pre-existing click event for when you click an allied tile. I didn’t change anything with pathfinding, etc. I simply turned the Boolean to true when switching to the proper ability.
On true it goes into the nodes for when you click an enemy.
When clicking an allied unit with this ability, it successfully places a shield around the allied unit, but the unit that places it, either follows the wrong path-finding or will teleport to index 0. Sometimes it seems to work correctly. I should also mention this seems to only happen when show all possible visible tiles is set to True. I also noticed it will use the path from the last time it displayed a path while hovering.
I will send you a video.
Per-Unit edge costs
I have seen some mention of this before. Just wondering at current best practices. Say you have a forest tile where it costs an infantry unit 1 point to move through it, but a vehicle takes 2.
Would it be better to keep separate edge cost arrays for each unit type and then use custom pathfinding or just update the one edge cost array when the unit selection change to a new unit type? The second option seem simpler, but I’m unsure if there would be a real performance cost.
We have to make this flexible enough so when we make a game that will allow players to create their own units, they will have to be able to specify cost to enter for each tile for their unit. This makes choosing pathfinding method useless. I don’t think there is any other method that will be better than making an array of movement types for each terrain type. Because even if we will come with some kind of modifier for difficult terrrain it still will be limited and will create other problems for unusual units.
Btw is this really important to have cost to enter neighbor tiles saved as array in each tile? In my previous game I had cost to enter tile as number in that tile. So when you wanted to enter neighbor tile you were asking it how much it will cost to move there. I don’t know why current solution is better, maybe I am missing something.
Maybe we could do something like this: leave current array with entering neighbour tile cost but change it for cost multiplier and add base tile cost for each movement type for that tile. That way if in base tile cost will be 1 as default then old mechanic will be saved and by changing it to other numbers we could have plenty of flexibility. For example:
(base tile cost that is hardcoded) 1 x 2 edge cost N = 2 cost to enter forest north tile
(value stored in tile for each move type) base tile cost for forest 2 x 1 edge cost changed to multiplier = 2 cost to enter forest
but it is possible now for example to do
base tile cost for forest 2 x 1.5 edge multiplier cost when moving NE = 3 cost to enter NE tile
I don’t know if this is making any sense
Okay, I figured out the problem. You need to also modify the nodes in Display Path on Hover as well. Add the following:
Since you are modifying the very core of the pathfinding it is worth thinking about performance. The Search And Add Adjacent Tiles function is repeated a ton of times during pathfinding, so it pays to keep it as efficient as possible. I have worked hard to make it as efficient as possible, so you should be able to add a lot to it without noticing any frame dips for most games, but you should still try to be smart about it. The simplest and most efficient way I can think of is to add new custom Search And Add Adjacent Tiles functions and add them to the Custom Pathfinding macro and use these in conjunction with a new grid sized array for terrain.
First create a new enum for terrain, including the terrain types you wany (I added none, forest, ocean and mountain). Then create a new actor parented to GridActor (which has code for getting the correct index based on its placed location), maybe called GA_Terrain. Add a terrain enum variable to this class. Make a separate child actor of this actor for each type of terrain and add meshes/sprites to those (for my tests I just used a text render).
Then in BP_GridManager add a new array of terrain enums called Terrain Array (or whatever) and resize this to be the size of the grid. This probably makes the most sense to do in the Generate Gameplay Grids function. Like so:
In the Add Viewport Terrain to Arrays function add the terrain enum values of the terrain tiles you have placed in the world to the Terrain Array at the appropriate indexes like so:
Next expand the PathfindingType enum and add names for the various movement setups, like infantry, naval and heavy. For planes you can just use the Ignore Difficult Terrain pathfinding type. Duplicate the Search And Add Adjacent Tiles function and follow the example of implementation of other such functions in the Custom Pathfinding macro in BP_GridManager. Like so:
In these custom functions add a switch on the enum of the tile edge to be checked and set a terrain cost/refrain from adding the tile to be searched in the open list based on the terrain enum value of the Terrain Array at the grid index you are considering. Also, replace connections from the the EdgeArray ForEachLoop with a terrain cost based on the result of the switch. Like so:
In the function I made for infantry above I set cost to be 1 if no terrain is specified, 2 for forest and impassable for ocean and mountains. For naval units I only proceeded with the function if the terrain was ocean. Heavy is the same as infantry, but without proceeding with the function if the terrain is forest. You would add more such types of pathfinding is necessary. There are more elegant ways to do this where you can contain everything in one function, but it will be less efficient. If you have a limited amout of such movement classes this would be my recommended solution. Here is a screenshot of Mr. unit_boat being a boat:
If the method above is not flexible enough (though I think it should be in most cases) you could add a terrain array and a cost array to Unit_Parent. Then you would get a reference to the current unit during Search And Add (make sure to set this up early in the pathfinding so you do not need to cast every loop), and check the cost value of the unit’s cost array against the terrain type of the tile being entered. It would be a lot less efficient, though. If the first method is impossible and you need to do something like this instead I’ll try to think up a more efficient solution.
For most games it does indeed not make a difference, but I’ve always strived to make the toolkit as flexible as possible and having the possibility of having various costs for entering the same tile from various directions can be utilized in some games. You could for instance set things up so that it costs more to walk up, but not down a slope, have rivers that slow you down when you walk upstream, but speed you up downstream etc.
I hope my answers have been helpful and that they will help you add the features you need.