Ultimate Skills and Talents Component
Ultimate Skills and Talents Component
Documentation
Documentation
Features
Features
- Unlimited amount of skills - add as many skills or talents as you want using data tables.
- Different skill types - assign skills to groups to define their behavior (ie. active and passive).
- Cooldown - put skills on cooldown to add a delay between uses, you can also modify cooldown on runtime.
- Upgrade and degrade - skills power can be easily increased or decreased on demand.
- Requirements - set skills to require other skills (and their specific levels) to be available to players.
- Custom skills unlocking - enable player skills in certain scenarios (ie. on quest finished or on level reached).
- Quick Access Bar - provides instant access to most-needed skills.
- Skill Tree Creator - easily create customizable Skill Tree widgets, define their visuals and layout.
- Multiple Skill Trees - create separate Skill Tree for each class (ie. Warrior, Hunter, Mage).
- Drag&drop - select one of two drag&drop methods that suit your project.
- Save and load - save or load skills state to a game instance or a separate file with a single function.
Implementation
Implementation
Once the component is added to the actor we need to properly initialize it when the game starts. Steps to do:
- Create and add widget blueprints to your viewport (at least those related to skill system).
- Call AddWidgetsToRefresh function and pin in widgets that will display any data from skills manager (ie. Skill Tree or widget that displays a number of available skill points).
- Call InitializeQuickAccessBars function and pin in all Quick Access Bar widgets.
- Call InitializeSkillsManager, it will read default data from a skills data table and assign it to skills manager.
- (optionally) Call LoadSkillsData to read data from game instance to save file and overwrite skills default data.
Important: for multiplayer games, the last two functions have to be called on the server side because skills data should be handled on the server.
Check demo player controller blueprint for server-client initialization set up.
To implement skills system to your game just add AC_UTC_SkillsManager to your Character blueprint.
Steps to do:
Open blueprint actor that you want to add quests system to.
Steps to do:
Open blueprint actor that you want to add quests system to.
Navigate to its Components tab.
Click the green +AddComponent button and from the dropdown list choose AC_UTC_SkillsManager.
Click on newly added AC_UTC_SkillsManager and navigate to Details tab.
Find Config category and set up default data.
Click on newly added AC_UTC_SkillsManager and navigate to Details tab.
Find Config category and set up default data.
- SkillsDatatable - what data table will be used to read skills data from.
- NumberOfQuickSlots - how many quick slots each Hotbar will have.
- QuickSlotsPerRow - determines how quick slots should be positioned in Hotbar.
- UseClassicDragAndDrop - whether we want to use "classic" drag&drop method or "on click" one.
Creating new skills
Creating new skills
https://youtu.be/oJJ0ZzVM7HMFirst, you will need the skills data table that will contain all skills for a certain character. You duplicate one of existing data tables and erase its data or create a fresh one (click +AddNew button > Miscellaneous > Data Table > S_UTC_Skill_Static). Once you create data table you are ready to add new skills. Click the "+" button in row editor create new skills.
Each skill data consists of:
- ID - unique skill ID used in the system functionality. IMPORTANT: ID must be the same as the name of the row in the data table.
- DisplayName - the name of the skill displayed to players (ie. in widgets).
- TriviaText- meaningless description of the skill that will be displayed players (ie. in widgets).
- Type - determines the group skill belongs to. Different groups may allow different skill behavior. By default, there are active and passive skills (passive ones, because of their nature, cannot be added to Hotbar).
- Cooldown - default cooldown time, used to add a delay between skill uses. Can be also used to determine passive skills frequency.
- DefaultLevel - starting level of the skill. Skill will be at this level once it becomes available to a player (ie. after its requirements are met or when it is unlocked).
- UnlockedByDefault - determines whether a skill is available to a player (of course, once its requirements are met) or player needs to complete special action to unlock it (ie. finish a specific quest or reach a certain level).
- UnlockingRequirementText - a hint that will be displayed in skill tooltip to let a player know what he needs to do to unlock a certain skill.
- Icon - an image of the skill.
- RequiredSkills - all skill (and their levels) that player must possess to make this skill available. Used mainly to create larger, complex Skill Tree with a lot of subskills.
- Levels - contains data of all level of given skill. Each level has a few editable variables:
- PointsRequiredToUpgrade - how many points a player needs to spend to upgrade to this level.
- Description - description of a specific skill level that will be displayed to a player (ie. in skill tooltip).
- Stats - custom stats map (name + value) that is used to handle skills effects in blueprints.
- PointsRequiredToUpgrade - how many points a player needs to spend to upgrade to this level.
Additionally, inside level description, you can put stat name between "{" and "}" signs and system will swap it with value. It is useful if you are going to balance skills later and do not want to change both the description and stats values every time.
EXAMPLE
Description: Fireball deals {power}% magic damage and sets the target on fire for {duration} seconds.
Stats: power -140; duration - 3.
Final description displayed in skill tooltip: Fireball deals 140% magic damage and sets the target on fire for 3 seconds.
Skills management
Skills management
Skills management consists of 2 parts:
A. Functions called on the server side and executed on the server side, they should never be implemented to be called on the client side (of course if it is a single player it doesn't matter because there is no server-client relation). These functions are:
- UnlockSkill - manually unlocks given skill that isn't available to a player by default (use this to unlock skills after finishing quests, reaching certain level etc.)
- ReceiveSkillPoints - awards a player with skill points that he can spend to upgrade skills (can be used after level up event).
- ResetSkillTree - sets all skills to their default levels and restores all skill points spent on them. Using this will not lock skills that were unlocked manually (function can be tied to item effect).
- ResetSkill- as above but affects only given skill (it will also reset all skills that had this skill as a requirement).
B. Events called from client to execute the corresponding function on the server. Of course, the server first will check if given action can be executed.
- UpgradeSkill_SERVER - request to upgrade given skill.
- DegradeSkill_SERVER - request to degrade given skill and restore points spent on it.
- UseQuickAccessSkill_SERVER - use skill that is assigned to given Quick Access Slot.
- RegisterSkill_SERVER - request to assign given skill to Quick Access Slot.
- UnregisterSkill_SERVER - request to remove assigned skill from Quick Access Slot.
- UseSkill_SERVER - request to use given skill.
Skills cooldown
Skills cooldown
Cooldown functionality can be utilized in two ways:
A. A delay between active skill uses.
In most games skills usage is limited by cooldown so you cannot spam single skill all the time. Built-in cooldown system allows to easily achieve it. After using certain skill just call ActivateCooldown function and enter skill and cooldown time. Skill manager will automatically update all quick slots so they reflect actual cooldown state. Once cooldown ends skill can be used again.
B. A frequency of passive skill activation.
Sometimes passive skills have special effects (ie. on hit has 30% chance to damage all enemies around) but sometimes we also want these effects to happen only once in a while, like not often than every 3 seconds. To add such a limit we just need to use ActivateCooldown function when passive skills effect occurs and the next time effect has a chance to happen it will check if its cooldown already ended.
Additionally, there are two functions that let us modify cooldown on runtime:
- DeactivateCooldown - completely removes cooldown from the skill and it can be used again.
- ModifyCooldown - this one is used to increase or decrease cooldown time by a given amount of time (ie. one skill can decrease the cooldown of other skill by 1 second). Cooldown time cannot be increased above its default time. Decreasing cooldown below 0 results in removing the cooldown from the skill.
Skills usage
Skills usage
You can use skill by calling one of two events UseSkill_SERVER and UseQuickAccessSkill_SERVER. Once a skill is used it will execute OnSkillUsed event dispatcher, which you should use to create your skills behavior in each character. This also allows on implementing skill effects on each character separately, so even the same skill can act differently on various characters (ie. different animation will be played).
You can also read skill stats that you have set in a skill data table (like power, duration etc.) by calling GetSkillStatValue function. You will need to enter what skill and its stat you are looking for. You can enter respectively “Fireball” and “power” and it will return the value of power stat of Fireball skill (it will also take into account current skill level). Of course, it works as long as you define “power” stat in Fireball data. This functionality is useful when it comes to balancing skills because all you need to do is opening skill data table and change given stat value. You won’t need to go through blueprints and look for given skill implementation only to change one value because that value is read from a data table.
Check demo character blueprints for several examples of how skills logic can be set and how skills data can be utilized.
Quick Access Bar
Quick Access Bar
Quick Access Bar (also known as Hotbar) provides immediate access to favorite and most-needed skills. You can define how many slots Quick Access Bar will have and how they are positioned (ie. in 2 rows). To do this access AC_UTC_SkillsManager and on its Details tab under Config category you will find two variables:
- NumberOfQuickSlots - how many quick slots each Hotbar will have.
- QuickSlotsPerRow - determines how quick slots should be positioned in Hotbar.
Passive skills because of their nature cannot be assigned to quick slots.
To add Hotbar to your game just place WBP_UTC_QuickAccessBar in one of your user interface widgets. Then you will need to assign these widgets to skills manager, to do this just call InitializeQuickAccessBars function and pin all needed widgets. This function was also used during the initialization process in the Implementation section.
Skills can be used directly from Quick Access Bar with a right mouse click or you can tie slots to specific buttons (ie. from 1 to 6).
Save and load
Save and load
To save actor skills data use SaveSkillsData function. It has three inputs:
SaveName - how save file will be named, remember to use different names for different actors, unless you want to overwrite the data.
SaveToGameInstance - determines whether the game should be saved to the game instance or to separate save file on a device.
SaveToGameInstance - determines whether the game should be saved to the game instance or to separate save file on a device.
IncludeCooldowns - determines whether cooldown times should be saved or not.
Data saved to the game instance will be stored only during a single game session and it will be wiped after the game is closed. Use it to temporarily store data, ie. when changing levels. Data saved to file (using standard SaveGame object) will be stored on a device even when the game was closed. It can be accessed each time the game is started to load stats data. Depending on your needs you may use a single method or mix them.
To load actor skills data use LoadSkillsData function. It also has two inputs:
SaveName - name of the save file to load skills data from or a name of a key of map variable stored in the game instance.
LoadFromGameInstance - determines if skills data should be loaded from a game instance or from save file stored on a device.
LoadFromGameInstance - determines if skills data should be loaded from a game instance or from save file stored on a device.
To ensure smooth implementation of the saving system to your game project without overriding any of your data use BPI_UTC_SaveCommunication blueprint interface, which can be found in Blueprints>Interfaces folder. Open your custom game instance blueprints, navigate to ClassSettings and on details tab you will find the option to add interface and compile blueprint. Open BP_DemoUTC_GI_Custom blueprint located in Demo>Blueprints folder and copy or recreate its functions and variables.
If you don't use the custom game instance, but you still want to use save system with game instance you can use the one which is used in demo content (or a copy of it). It has the saving system already implemented.
Important: Remember that this save functionality is created primarily for single player games because of multiplayer games rather store data externally.
Drag&drop methods
Drag&drop methods
The system provides two drag&drop methods:
A. "OnClick"
This method is the one that the skills system uses by default. Dragging starts when a player clicks on skill in Skill tree or Quick Access Bar. Dragging finishes when the player clicks on a quick slot and then skill is assigned to the slot. Nothing happens when he clicks outside the quick slots. To stop dragging without assign skill to slot you can call CancelSkillDragging function (in demo tied to a right mouse button).
B. "Classic"
This method is the default one implemented in the engine. Dragging starts when a player press left a mouse button and finishes when he releases that button. If the button was released on quick slot then skill will be assigned to that slot otherwise drag&drop action will be canceled.
Only one of these methods can be active at a time. To switch between them access skill manager component Details tab and under Config category you will find UseClassicDragAndDrop variable (set it to true to use "Classic" method, false means "OnClick" method will be used).
Skill Tree Creator
Skill Tree Creator
To create your own Skill Tree just duplicate WBP_UTC_SkillTree widget. Once you open it click on widget name in Hierarchy panel (first item in Hierarchy equal to the name of the actual widget, ie. in default Skill Tree widget it is called WBP_UTC_SkillTree). In Details panel you will find Config category. There are a few variables which you can edit:
- InvertScrollingX – determines if scrolling along X axis should be inverted.
- InvertScrollingY – determines if scrolling along Y axis should be inverted.
- ScrollingSpeed – how fast it will scroll through Skill Tree. Different Skill Tree sizes may need slightly different speeds.
- MaxZoomOut – determines how much Skill Tree can be zoom out. Again, different Skill Tree sizes may need different scales.
- SkillSlotTypes – sets the style for skill slot buttons, thanks to this you can set different styles for skills that are active or passive types. If you add a new type of skill just add another element here and you will be able to create a special button style for it.
If you have a lot of skills and want to create large, complex Skill Tree you can change its size. To do it click on SizeBox_SkillTreeSize in the Hierarchy panel. In the Details tab find WidthOverride and Height Override, modify these values to adjust Skill Tree size to your needs. Remember that this SizeBox determines how large is the area of whole Skill Tree not how large it will be on screen. So you can create 4000px x 4000px Skill Tree but display to user only area of size 500px x 500px. A player will have a possibility to scroll in all direction as well as zoom in or out.
To define window size that will be displayed to the player (like that 500px x 500px mentioned above) once you add Skill Tree widget to your User Interface widget you will need to wrap it with Size Box panel and set its width and height to desired values. The example set up can be checked in WBP_DemoUTC_UserInterface, there you will find WBP_UTC_SkillTree widget wrapped with SizeBox_Display.
Skill Tree widget also contains a slider which can be used to zoom in/out Skill Tree. You can edit it to your likeness or simply hide it if you don’t need it.
The last and most fun part is adding Skill Slots that will create actual Skill Tree. In Palette panel, under UserCreated category find WBP_UTC_SkillSlot widget. Drag and drop it on CanvasPanel_SkillTree. You can change its name if you want (ie. to match the name of the skill). Once you add it will appear distorted, to fix this simply click it and in its Details panel set SizeToContent to true. Now you can move it to the desired position in Skill Tree, remember to keep it in widget bounds.
In Details tab you will also find Config category, there are several options divided into two parts that will help Skill Tree creation:
Part A - Slot
- SkillsDatatable - select what data table should be used for this Skill Tree. Useful if you have many character classes (ie. Warrior, Hunter, Mage) and they all have their own skill data tables.
- SkillID - determines what skill is assigned to the slot.
- SkillSlotSize - how big slot should be.
At this point, it should automatically populate RequiredSkill variable which is in the second part (Connection). To make sure it contains only needed data press little trash can icon at the end of RequiredSkills row.
Part B - Connection
- ConnectionType - determines the type of connection lines, choose the one that suits the best in your opinion.
- DesiredSnapOutPoint - used only when lines area created manually (ConnectionType is not set to Auto). In some cases, lines can be drawn in few different ways, use this to select the one that seems to connect slots in the best way.
- UseAlternativePath - used only when lines are created automatically (ConnectionType set to Auto). Same as above, automatically generated path sometimes have more two possibilities, use this to quickly swap between them to check which one suits better.
- LinesThickness - determines how thick the lines that connect skill slots are.
- LinesGenerationThreshold - used only when ConnectionType is set to TripleLine(Outer). Determines how far from the skill slots middle line should be generated.
In addition to these options, there is also AdditionalOffset variable. It determines a distance between skill slot and line start which is sometimes needed to match skill slot button visuals (ie. circular slots need it to be negative values so there are no gaps between skill slot image and generated line).
If you wish to change how connection lines look open WBP_UTC_SlotsConnection widget blueprint and edit Border_Line element. Keep in mind that this widget will be stretched in all direction depending on current connection type, so square shaped images will look the best.
Updating widgets data
Updating widgets data
Data displayed in widgets is mostly updated by BPI_UTC_SkillsUpdater blueprint interface. Add to it a widget that you wish to receive events from skill manager whenever its data changes (ie. on skill points amount changed or on skill upgraded). Once blueprint interface is implemented in a widget you can use the following events:
- SetReferenceToSkillManager - used to assign skill manager reference to a widget, so they can communicate easier.
- ZoomInSkillTree - received whenever Skill Tree should be zoomed in (in demo tied to mouse wheel).
- ZoomOutSkillTree - received whenever Skill Tree should be zoomed out (in demo tied to mouse wheel).
- UpdateSkillPointsAmount - received when the amount of available skill points changes.
- UpdateSkillData - received when skill data changes (ie. its requirements are met, it got unlocked etc.)
- UpdateTooltipData - used to pass information to skill tooltip widgets so they can be displayed to player.
By default, all widgets with implemented SkillsUpdater blueprint interface will be updated. To limit the system to refresh only specific widgets use AddWidgetsToRefresh function and pin in desired widgets. You can also notice that this function was used during the initialization process in the Implementation section as it is a recommended solution.
You can check detailed communication set up in premade widgets: WBP_UTC_SkillTree and WBP_DemoUTC_UserInterface.