2Create GameObject: Create new GameObject named "Player"
3Add Component: Add the generated "Character Attributes" component
4Assign Asset: Drag "CharacterAttributeData.asset" to the Data Asset field
Using Your Attributes in Code
Basic Player Controller
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private CharacterAttributes attributes;
void Start()
{
// Get the generated attribute component
attributes = GetComponent<CharacterAttributes>();
// Subscribe to health events
attributes.health.OnReachedZero += HandleDeath;
attributes.health.OnValueChanged += UpdateHealthUI;
Debug.Log("Player initialized with " + attributes.health.totalValue + " HP");
}
void Update()
{
// Test damage with spacebar
if (Input.GetKeyDown(KeyCode.Space))
{
TakeDamage(10f);
}
// Test heal with H key
if (Input.GetKeyDown(KeyCode.H))
{
Heal(15f);
}
// Add gold with G key
if (Input.GetKeyDown(KeyCode.G))
{
AddGold(50);
}
}
public void TakeDamage(float amount)
{
// Use ModifyValue for gameplay changes (triggers regeneration)
attributes.health.ModifyValue(-amount);
Debug.Log($"Took {amount} damage. Health: {attributes.health.currentValue}/{attributes.health.totalValue}");
}
public void Heal(float amount)
{
attributes.health.ModifyValue(amount);
Debug.Log($"Healed {amount} HP. Health: {attributes.health.currentValue}/{attributes.health.totalValue}");
}
public void AddGold(int amount)
{
attributes.gold.ModifyValue(amount);
Debug.Log($"Gained {amount} gold. Total: {attributes.gold.GetIntValue()}");
}
public void LevelUp()
{
attributes.level.ModifyValue(1);
// Permanent stat increases
attributes.strength.baseValue += 2;
attributes.intelligence.baseValue += 1;
attributes.health.baseValue += 20;
// Fill health on level up
attributes.health.FillToMax();
Debug.Log($"Level up! Now level {attributes.level.GetIntValue()}");
}
private void HandleDeath()
{
Debug.Log("Player died!");
// Handle death logic
}
private void UpdateHealthUI()
{
// Update your health bar UI here
float healthPercent = attributes.health.GetPercentage();
// healthBar.fillAmount = healthPercent;
}
}
Simple Combat System
public class SimpleCombat : MonoBehaviour
{
private CharacterAttributes playerAttributes;
private CharacterAttributes enemyAttributes;
void Start()
{
playerAttributes = GameObject.FindWithTag("Player").GetComponent<CharacterAttributes>();
enemyAttributes = GetComponent<CharacterAttributes>();
}
public void PlayerAttack()
{
// Calculate damage using totalValue (includes all bonuses)
float damage = playerAttributes.strength.totalValue * 1.5f;
// Deal damage to enemy
enemyAttributes.health.ModifyValue(-damage);
Debug.Log($"Player deals {damage:F1} damage!");
if (enemyAttributes.health.IsAtMin())
{
HandleEnemyDeath();
}
}
public void EnemyAttack()
{
float damage = enemyAttributes.strength.totalValue * 1.2f;
playerAttributes.health.ModifyValue(-damage);
Debug.Log($"Enemy deals {damage:F1} damage!");
}
private void HandleEnemyDeath()
{
// Give rewards
playerAttributes.gold.ModifyValue(Random.Range(10, 50));
Debug.Log("Enemy defeated! Gold gained.");
Destroy(gameObject);
}
}
Key Features Demonstrated
Automatic Regeneration
Health and Mana automatically regenerate after taking damage. No manual coroutines needed!
// Just deal damage - regeneration is automatic
health.ModifyValue(-30f);
// System handles delay and healing automatically
Three-Tier Values
Each attribute has baseValue, formulaBonus, modifierBonus, and calculated totalValue.
// Always use totalValue for gameplay
float damage = strength.totalValue * multiplier;
// Modify baseValue for permanent changes
strength.baseValue += 5; // Upgrade
Type-Safe Access
Generated enums and properties provide compile-time safety and IntelliSense support.
// Direct property access
var health = attributes.health;
// Enum-based access
var attr = attributes.GetAttributeByEnum(CharacterAttributesEnum.Health);
Event System
Rich event system for UI updates and gameplay reactions.
public enum CharacterAttributesEnum
{
Health = 0,
Mana = 1,
Strength = 2,
Intelligence = 3,
Gold = 4,
Level = 5
}
Generated Component
public class CharacterAttributes : MonoBehaviour, ISimpleAttributeDataSource
{
[Header("Vital Attributes")]
public SimpleRuntimeAttribute health;
public SimpleRuntimeAttribute mana;
[Header("Basic Attributes")]
public SimpleRuntimeAttribute strength;
public SimpleRuntimeAttribute intelligence;
[Header("Resource Attributes")]
public SimpleRuntimeAttribute gold;
public SimpleRuntimeAttribute level;
// Automatic regeneration management
// Component-wide events
// ISimpleAttributeDataSource implementation
// Type-safe access methods
}
Testing Your Setup
Runtime Testing
The generated component includes testing tools accessible via the inspector:
Context Menu: Right-click component → "Log All Attributes"
Test Values: Set inspector values and use "Set Attribute Value" context menu
Debug Regeneration: Use "Debug Active Regeneration" to see active coroutines
Play Mode Testing
// Test in Update() or with UI buttons
void Update()
{
if (Input.GetKeyDown(KeyCode.D))
{
// Test damage
attributes.health.ModifyValue(-20f);
Debug.Log("Took damage - watch regeneration!");
}
if (Input.GetKeyDown(KeyCode.S))
{
// Test stat increase
attributes.strength.baseValue += 1;
Debug.Log($"STR increased to {attributes.strength.totalValue}");
}
}
Next Steps
Learn Runtime Usage
Master the three-tier value system and proper gameplay patterns.
Congratulations! You now have a fully functional attribute system. The examples above demonstrate the key patterns you'll use in your game. Remember to always use totalValue for gameplay logic and let the system handle regeneration automatically.