The Attribute System is a framework designed to manage various values associated with entities within a game. These values can represent characteristics such as health, strength, agility, etc. The system provides a structured approach to handle these attributes, allowing for easy modification, tracking, and management throughout the game.
The AttributeComponent
is a component attached to gameobjects as a container of attributes and manages interactions with that value. It takes a list of AttributeSet
objects as startup sets. When the component starts, it creates an AttributeValue
for each ID within those sets. You interact with the component to deal with the values for each of those attributes. It will use the AttributeDefaultSource
within the set to initialize each of those AttributeValue
.
By hovering on the info icon, you will see detailed information about the attributes.
AttributeID
is an empty Scriptable Object that acts as a unique identifier for a specific attribute.
AttributeValue
is a Scriptable Object that holds the value and the modifiers of an attribute.
The AttributeSet
contains a set of AttributeID
instances. It also contains an AttributeDefaultSource
, which holds default values for each ID. Currently there are several built-in attribute set types:
List: It contains a list of AttributeID
instances and does nothing else.
MinMax: It makes sure that the value is always within Min attribute value and Max attribute value.
When extending an AttributeSet
you need to only deal with IDs. You access the values of those ID’s through a “context” parameter. (Check the MinMaxAttributeSet class for an example.)
public class MyAttributeSet : AttributeSet
{
public AttributeID testID1;
public AttributeID testID2;
// When trying to Set an Attribute's Base Value through the SetBaseValue(ID, newBaseValue) method on the AttributeComponent, this function is called BEFORE.
// The 'context' parameter will give you a way to access other attributes.
// The 'id' parameter determines the attribute being modified.
// The 'newBaseValue' is current base value going to be set to the attribute.
// Note that it is a ref parameters. Which means that it can be changed. Any change will be passed to other sets.
public override void PreValueChange(IAttributeContext context, AttributeID id, ref float newBaseValue)
{
//Always test against the set's ID's
if (id == testID1)
{
// Pre Modification Checks and Changes for testID1
}
else if (id == testID2)
{
// Pre Modification Checks and Changes for testID2
}
}
// When trying to Set an Attribute's Base Value through the SetBaseValue(ID, newBaseValue) method on the AttributeComponent, this function is called AFTER.
// The 'context' parameter will give you a way to access other attributes.
// The 'id' parameter determines the attribute being modified.
// The 'oldBaseValue' parameter will give you the last base value the attribute had before modification.
public override void PostValueChange(IAttributeContext context, AttributeID id, float oldBaseValue)
{
if (id == testID1)
{
// Post Modification Checks and Changes for testID1
}
else if (id == testID2)
{
// Post Modification Checks and Changes for testID2
}
}
// This function is used by the AttributeComponent to check if the PreValueChange and PostValueChange functions should be called on this attribute.
public override bool HasID(AttributeID id)
{
return id == testID1 || id == testID2;
}
// The function should return all IDs used for this attribute. It is used by the AttributeComponent when setting up the attributes.
public override IEnumerable<AttributeID> GetIDs()
{
yield return testID1;
yield return testID2;
}
}
The AttributeDefaultSource
is a Scriptable Object containing default values for each attribute ID. It holds a collection of AttributeDefault
structs, each representing a default base value and modifiers for an attribute ID.