Hi 皮皮耍, sorry to hear that you’re struggling with the new puppet system, but good that you are making progress. I’ll readily admit that the new system of using puppets instead of just having everything inside units is more complicated, but the benefits greatly outweigh the drawbacks, I feel. I’ll start by explaining my rationale for making this system.
So in the older versions of ATBTT BP_Unit actors were responsible both for game logic (keeping track of health, moving references to BP_Unit across GridUnits etc.) and for animation. The action system of ATBTT is designed to keep game logic and what is shown to the player separate, and BP_Unit was always an awkward in-between blueprint. An example of a problem this could casue was that you might want to destroy a unit (if it is killed), but you cannot simply destroy it, because the unit might still be needed for Actions that show the unit being shot and dying, for instance. So ATBTT had to put the unit into an array and periodically check if it was still used in any actions and destroy it if it was not. That is just one example.
Another problem was that the visual actor representing a unit would always have to be a child of BP_Unit. This meant that it was impossible to for example to have units be of the Character class (which many developers wanted to use for the included movement code). It also meant that you could easily end up with very deep class hierarchies.
So to solve both these problems I decided to split units into Units (invisible and just for handling game logic) and Puppets (just for visualizing stuff. No impact on game logic). Doing this makes ATBTT much more modular, meaning you don’t have to make big changes to any core blueprints because you need a unit that is visualized in a different way. However, this came with some difficulties. I want to be able to communicate between the unit and its Puppet, but since the Puppet can be any type of class I have to use interface events.
Another problem is that I want to use even dispatchers in the puppet, in order to communicate with actions when animations are done etc. Actions referencing puppets do not know the class of the puppet (which could be anything), so I cannot bind any events in an action to an event dispatcher within the puppet (without lots of awkward casting), so my solution was to add a Puppet Component, whose only purpose is to hold event dispatchers. Now actions can communicate through event dispatcher with any Puppet of any class provided it implements the Puppet Component.
Regarding OnAnimationEnd, you are correct that they are not used in the included actions. They are there for you if you need them for some other action. They are not used because the attack animation uses OnAnimationHit instead, proceeding when the attack animation hits instead of when it is done. For the hurt animation I do not wait for it to stop before I proceed by default. So yes, neither of those are currently used, but are included to make things simpler if you want to add actions that wait for the attack or hurt animation to end before proceeding with the next action.