Hey all, version 3.01 of the ATBTT is live. This is not a feature update, but a hotfix that fixes several issues introduced in the last, big refactor. There are also a few minor changes and additions. Below are some of the bigger changes and fixes. For the full changelog see my Trello.
New pathfinding type preferring snaking paths to long turns on hex grids
Added animation input pin to PuppetComponent event dispatchers, allowing bound events to know what animation has triggered.
Custom Game Over text re-added.
Fixed Place Actor at Anchor (was broken).
Various fixes to units spawned at runtime.
Fixed PassThroughFriendly pathfinding type. No longer removed units passed over from GridUnits.
Fixed issue where some puppets would sporadically not spawn for clients in networked games.
Hi ser.man94. This is a pretty broad question so we’ll have to take it one step at a time. First lets start with the HoMM-style unit stacks. The general approach here would be to add a new variable to BP_Unit holding the amount of units. When a unit takes damage so that current health reaches 0, the number of units would be subtracted rather than killing the unit (until number of units reaches 0). Also in your abilities you would multiply damage by number of units in the stack.
As I mentioned on Discord I have given an explanation in the support thread on how to achieve this before, which can be found here. However, this is for an older version of the toolkit and I understand that it might be difficult to convert if you’re new to the toolkit. I’ll give you a more detailed description on how to achieve this in the new version when time permits.
Create a duplicate of BP_Unity_Anim. Remove the HealthBar component and the functions referring to it (ModifyHealthBar and SetupHealthBar). Add a text render component to display the unit amount (a bit basic, but works for demo purposes). Enable tick and rotate the text render to face the camera on tick:
You’re welcome Apologies if I gave you a headache.
The reason things look different in the older post is because it is from an older version of ATBTT. In the new versions I do things like the Health Bar a bit differently. If you want to use the old version you can use the UE4.25 version of ATBTT, but I recommend using the new version, as I’ve made many improvements.
If you can have the patience to wait a few more days I will soon enter paternity leave and will have more time to help out with support. I just have a lot of work until then and this is a pretty complicated question to answer. I will need to test things out in the engine myself and post screenshots of my code. I should be able to help you sometime mid to late next week. I recommend you focus on some other part of your game until then. Hope you understand.
hi @ monokkel . had some busy weeks but finally i have same time and my pc is working again XD
maybe you can remember of my chat plays project
so my goal is to have some form of free roam like in the hydra map .
i would like to skip the atk phase if im not in combat and the enemy should only activate/ detect if he can see/hear the player in range X .
also the camera should focus the enemy only if we are in combat. if not the cam focus should be on the player all the time
i tried to have a look in the hydras map but my understanding of the turn system is apparently to low so i hope you can help me with some screenshots or something else
Hey, so it seems like you want something like the 2D map. The way this is done in the 2D map is first, that only the player unit is added to InitiativeOrderActors in BP_TurnManager at the start of the game. The player unit is thus the only unit that will be activated. Next, the unit uses the BP_Ability_FreeRoam ability. This is an ability that never runs out of AP and that can move any number of spaces. This is probably not what you want in your game, since you always want to show the blue tiles.
I think using ATBTT’s stealth system should get you pretty close to where you want to be. Add the BP_GridManager_StealthSystem component to your Grid Manager. In its properties set UnawareFactions to the factions of your enemies. This will cause them not to be added to initiative at the start of the game. Next you want the enemies to be added to initiative when they detect the player. You can do this by calling the WakeNearbyUnits function, which can be accessed in BP_Ability and its child blueprints. The stealth system will also automatically let enemies detect your units when they move. Check out the EventGraph of BP_StealthSystem where you can change the ranges at which units will hear or spot units.
Hi, sorry that you are experiencing this issue. I am not able to reproduce this bug at my end. Does this happen with a fresh, unmodified project built with the newest version of ATBTT? Could you tell me the precise steps I need to do in order to reproduce the issue?
Ok, thanks for the patience. I’ll try to get around to this soon. While trying to find a solution to your question I ran into an issue with the health bar UI which I need to fix in order to help you, so it will take some more work.
Hey, I finally managed to reproduce this bug. Seems like it only happens if you spam the End Turn button repeatedly, but that will consistently cause the game to crash. Thanks a lot for letting me know, as this was a serious bug. I will be adding it to a hotfix soon. Until then, here is how you can fix it on your own:
Add the following branch to the Player Controller:
Delete the Queue function in BP_Action_ShowSelection. After deleting it should look like this:
Hi. I recently got the toolkit and am enjoying the tutorials and looking around. However I have only been using unreal for just over a year and am a slow learner. I’m finding it hard to penetrate a lot of whats going on in the toolkit especially when it comes to changing things and adding my own features. I’m getting the hang of the puppet basics and have managed to edit the camera BPs to my liking but I’m rapidly starting to feel out of my depth.
One thing I don’t really understand is the HUD for puppets. I am trying to work out how to get the HUD to display current health as a numeric value rather than a bar. I am also trying to figure out how to get current AP to display in the same way. I am only really familiar with the basics of widget binding so any specifics you can give as to how its working in your toolkit would be greatly appreciated.
Hey Dijon, stairs should work fine. However if there are gaps you need to make sure that the line traces that are fired at startup which create the grid locations don’t fall through the gaps. So you need to make sure that your stairs have collision volumes that block the PathTrace channel at the appropriate height at any place that might end up in the center of a tile. If you aren’t using the stair’s collision for anything else you might as well just make the collision volume for it one large wedge.
Hi Corum, don’t fret if you’re struggling. There are a lot of different systems to learn for ATBTT (not to mention UE4 itself) and not all of it is super intuitive. I tend to prioritize flexibility and modularity over simplicity when implementing features and the health bar UI stuff is kind of an extreme example of this. Actually health bars are even more tricky to understand than most ATBTT stuff since using it properly involves both understanding puppets and the action system well, both which are somewhat complicated topics. I’m planning to a tutorial on them at one point, but until then here is the step-by-step:
Find the WBP_UnitHUD blueprint in Core/Units. Add your health number text and current AP text.
Modify BPI_UnitHUD. Add a new interface function for setting AP. Have an integer as input.
Add this interface event to WBP_UnitHUD. Use the integer input to set the AP text.
In BP_UnitHUD add the same interface function. Have it call the same interface function in GetUserWidgetObject
In BP_Actor_Puppet (or whatever puppet you are using) add a new variable for holding the AP currently displayed to the player. You can call it DisplayedCurrentAP to keep it consistent with the others.
In the UpdateHUD function in BP_ActorPuppet call your custom interface event on UnitHudRef, with DisplayedCurrentAP as input.
In BPI_Puppet create a new interface function for updating AP. Implement it in your puppet and use it to set DisplayedCurrentAP and call UpdateHud.
Create a new action for updating the unit HUD. Have an integer for CurrentAP and an actor for the affected puppet as input. Within the action call your new interface event for updating displayed AP on the puppet.
Whenever CurrentAP changes, such as in abilities, spawn said action.
So yeah, quite a few steps to do what is a very small thing. There are faster ways to do this if you don’t mind that your HUD widget does more stuff on tick or if you don’t mind if the displayed AP changes immediately when CurrentAP is altered and don’t need to go through the action system (which would probably work fine for action points, come to think of it).
Writing all of this down makes me realize I should try to think of possible simpler ways to do this. The benefit is extreme modularity, though. You can swap out the way I display health etc. with whatever type of actor or widget you would like as long as it implements the correct interface. SImilarly your puppet can be any type of actor that has the correct interface set up.
One thing to note, by the way. I’m currently working on figuring out HoMM-style combat for @ser.man94 and in the process I realized that there is a problem with UI scaling with the current health bar. It looks fine with just the current health bar and status effect icons, but if you have text in the HUD it will look pixelated if you zoom in close. I have fixed this and it will be corrected in the next hotfix. If you need to fix it before then, though, I’ll let you know how to tweak it.
Hello, thankyou so much for your quick and detailed reply! I think I managed to follow steps 1 to 6 correctly though I wasn’t super sure about steps 3 and 6. I’m attaching some screen shots to this post so you can tell me if I’ve done it correctly. I set APtext as a varibable and called SetAPvalue as a message with the target being the APtext in the widget and the int values connecting.
Steps 4 and 5 seemed to go well but in 6 I wasn’t sure I’d got it right. In BPI_Puppet i created a new interface and set “update AP text” as an INT input. Then in the puppets event graph I called the interface event and linked that directly to set ‘displayedcurrentAP’ then called update HUD after that.
Hopefully I did all that correctly. However I didn’t understand step 7. I’m not familiar with creating actions and i’m honestly not even sure what it means. Also in which blueprint would I create this ‘action’? I did look ahead to step 8 and that is very clear of course. Perhaps you could go into more specific detail about what to do in step 7?
Thankyou so much for your help it is greatly appreciated!
Next question lol, I’ve been playing with the toolkit every night and have admittedly modified it quite to my turn style preferences so this might be on me. When I click on an enemy unit and it displays the unit’s range then click back to one of my own units it seems to keep the tiles highlights by the enemy there for the rest of the match. I’ve tried tracing it through with breakpoints to find why it isn’t clearing the tiles but can’t seem to figure it out, are the enemy tiles or the enemy ability made differently?
I’m also struggling why there is a need for BP_Ability and BP_AbilityBase and when to use which, I know BP_Ability is a child of the base but why not just have the movement blueprints a child of the base?
Hi Monokkel. I am now pretty sure I have steps 1 through 6 sorted. In the picture attached you can see that HP and AP appear on the unit HUD no problem but I still cannot get the numbers to react to changes in AP an HP like the healthbar does. I think this is because I don’t really understand step 7. Would you be able to go into more detail? Where do I create this ‘action’ and what does creating an ‘action’ entail?
Hey, what version of ATBTT are you using? The range highligting stuff for enemy units has changed a bit over the versions and is not implemented in the current live version. Do you want to be able to display this or are you trying to disable this feature?
BP_Ability is a child of BP_AbilityBase. AbilityBase has funcitonality for finding, validating and displaying tiles the player hovers over and clicks, instantiating any custom GridUI used for the ability and some other minor stuff. It is intended to be the minimum you might want to use for all sorts of player interaction. BP_Ability has a lot more stuff built in, like finding and displaying things in the ability’s range, action point costs, AI, functions for adding status effects +++. If you want to have an ability that is tied to and used by a unit and more or less resembles the example abilities used in the game, Ability is a good starting point.
Hi, good to see you’re making progress. Before proceeding to adding an action have you checked that calling the interface event in your puppet directly leads to the numbers chaning? If you have successfully done steps 1-6 that should be the case. If that works and you only need to add the action I recommend first watching a couple of tutorials on the action system, as it is essential for understanding how the toolkit works.
ATBTT keeps gameplay logic separate from what is displayed from the player and these things might frequently be asynchronous. For instance, if an AI unit decides to move to an enemy, attack it and end its turn, in the game logic this all happens instantly during a single tick. During the execution of this code various actions are queued. Then these actions play out in sequence (the AI moving across the movement spline, the attack animation playing, the health bar of the attacked enemy decreasing etc.). If you change the displayed health immediately when damage is dealt in the game logic it will happen immediately, before the unit has played its attack animation or even moved to its target. Instead you want to queue an action for displaying the health change which happens only after the attack lands.
This video is a bit old now, but in it I explain the general idea behind the action system:
I must have made some mistake in steps 1-6. The AP and HP are currently static. That is to say, if I go into BP_Unit_Anim and change the attributes this does not effect the values of DisplayedAP and DisplayedHP in WBP_UnitHUD. Maybe If I go through it step by step you can tell me where I’ve gone wrong?
No problems here as I just added the text to the widget and set them as variables.
In BPI_UnitHUD I created SetAPValue and SetHPValue as functions and set their inputs as int.
Looking through this I don’t know what would not be working here. There is one performance optimization I would do, though. Don’t bind the text in the widget to the variables. Binding runs on tick, so that means that all your health bar widgets will have two text objects ticking. You only need to update the text when the value actually changes. So instead of binding and setting variable, just set the text of the text objects directly from your SetHPValue etc interface events.
How are you testing if this is working though? If you call UpdateAP text with some arbitrary value does nothing change? If you try printing the values at the various points of the execution chain what do you see?
I have placed string prints in BP_UnitHUD to show AP/HP text current value. I have also placed string prints in WBP_UnitHUD. In BP_Actor_Puppet I have placed some default values into DisplayedCurrentAP and DisplayedCurrentHP (5 and 10) and it is these values that are being displayed in game and that the print strings are quoting, if I change those default values then certainly the strings and the in game display change accordingly.
If I go into BP_Unit_Anim (Whose puppet class is BP_Actor_Puppet) and change the attributes Current Hp and Current Ap there is no change in the displayed values in the strings or the on screen widget. If I get two units (both BP_Unit_Anim) to damage eachother the healthbar visibly drops but my HP value text remains unchanged.
If I just plug the currently extant float ‘Displayed max health’ directly into my own int "DisplayedCurrentHP’ and then reference that float in UpdateHUD instead of my int. Then when in game the HP number displayed gets updated on damage and correspons to the changing health bar.
(edit, this also worked with AP in a similar way - by taking ‘current AP’ from paired unit and plugging it into my own int ‘DisplayedCurrentAP’)
I’m now going to carry on trying to get to grips with the action system through your tutorial videos. Just wanted to say thanks for being so quick to respond and ready to help. That said I’m sure I will have more questions for you in the near future!