Overview
The Character Template System allows you to define distinct starting configurations for different character classes (Warrior, Mage, Rogue, etc.). Each template specifies which attributes to override from their default values.
Visual Wizard
4-step wizard for creating character classes with per-attribute overrides.
Code Generation
Generates enum, manager, helper, and validator classes automatically.
ScriptableObject Assets
Each template is a .asset file that can be edited in the Inspector.
Vital Attribute Filtering
Automatically identifies derived attributes (Vital type) that shouldn't be manually overridden.
Integration: Character Templates set base attribute values. The Influence System then calculates derived stats, and the Modifier System applies temporary effects on top.
Generated Code
The wizard generates four files, each serving a different purpose:
Enum
Type-safe identifiers for each character class. Useful for code readability and IntelliSense.
// Generated: SoulslikeCharacterTemplateEnum.cs
public enum SoulslikeCharacterTemplateEnum
{
AshKnight,
BlightRogue,
BloodHerald,
BoneArcher,
DuskPriest,
EmberSeer,
GraveWarden,
HollowPilgrim,
HollowScholar,
IronWanderer,
Oathbreaker,
PaleWitch,
VeilDancer
}
Helper (Static Utility Class)
Static methods for applying templates from anywhere in your code. This is the primary API for template operations.
// Get all available templates in the project
List<SimpleCharacterTemplateData> templates = SoulslikeCharacterTemplatesHelper.GetAllTemplates();
// Find a specific template by name
SimpleCharacterTemplateData template = SoulslikeCharacterTemplatesHelper.FindTemplateByName("Ash Knight");
// Apply template to a GameObject with an attribute system
SoulslikeCharacterTemplatesHelper.ApplyTemplateToGameObject(playerGameObject, template);
// Apply template to multiple GameObjects at once
SoulslikeCharacterTemplatesHelper.ApplyTemplateToGameObjects(enemyArray, template);
// Get an attribute value from a template (returns default 10 if not overridden)
float strength = SoulslikeCharacterTemplatesHelper.GetAttributeValue(template, "Strength");
// Check if template is compatible with an attribute system
bool compatible = SoulslikeCharacterTemplatesHelper.IsTemplateCompatible(template, attributeSource);
// Compare two templates and get attribute differences
Dictionary<string, float> diff = SoulslikeCharacterTemplatesHelper.GetAttributeDifferences(templateA, templateB);
// Get total attribute points used by a template
float totalPoints = SoulslikeCharacterTemplatesHelper.GetTotalAttributePoints(template);
// Switch templates while optionally preserving non-overridden values
SoulslikeCharacterTemplatesHelper.SwitchTemplate(playerGameObject, newTemplate, preserveCurrentValues: true);
Manager (MonoBehaviour Component)
Optional component you attach to a GameObject. Provides Inspector configuration, auto-discovery, and convenient instance methods for that specific GameObject.
When to use the Manager: Attach it to your player or NPC prefabs when you want Inspector-configurable template management, auto-apply on Start, or runtime template switching buttons in the editor.
// The Manager is a MonoBehaviour - attach it to a GameObject in the Inspector
// or add it via code:
var manager = player.AddComponent<SoulslikeCharacterTemplateManager>();
// Apply a template to THIS GameObject (uses Helper internally)
manager.ApplyTemplate(template);
// Apply template by name
manager.ApplyTemplate("Ash Knight");
// Get template by name from the manager's available templates list
SimpleCharacterTemplateData t = manager.GetTemplateByName("Ash Knight");
// Get the template that best matches current attribute values
SimpleCharacterTemplateData current = manager.GetCurrentTemplate();
// Switch to a new template
manager.SwitchTemplate(newTemplate, preserveCurrentValues: true);
// Validate template compatibility
bool valid = manager.ValidateTemplate(template);
Manager Inspector Features:
- Available Templates - List of templates this manager can apply
- Default Template - Template to auto-apply on Start (if enabled)
- Auto Apply Default On Start - Automatically apply default template when game starts
- Allow Runtime Template Change - Enable/disable template switching at runtime
- Auto Discover Templates - Automatically find all template assets in project
Validator (Static Validation Utilities)
Runtime validation to check template compatibility with attribute systems.
// Validate a single template against an attribute source
List<string> errors;
bool isValid = SoulslikeCharacterTemplatesValidator.ValidateTemplate(
template,
attributeSource, // ISimpleAttributeDataSource
out errors
);
if (!isValid)
{
foreach (var error in errors)
Debug.LogError(error);
}
// Validate all templates in a list
bool allValid = SoulslikeCharacterTemplatesValidator.ValidateAllTemplates(
templateList,
attributeSource
);
Complete Integration Example
Character Creation Screen
using UnityEngine;
using UnityEngine.UI;
using SimpleAttributeForge;
using SimpleAttributeForge.CharacterTemplate;
using Soulslike.CharacterTemplates;
public class CharacterCreationUI : MonoBehaviour
{
[SerializeField] private Transform classButtonContainer;
[SerializeField] private GameObject classButtonPrefab;
[SerializeField] private GameObject playerObject;
void Start()
{
PopulateClassButtons();
}
void PopulateClassButtons()
{
// Get all available templates using the static Helper
var templates = SoulslikeCharacterTemplatesHelper.GetAllTemplates();
foreach (var template in templates)
{
var button = Instantiate(classButtonPrefab, classButtonContainer);
// Setup button text
button.GetComponentInChildren<Text>().text = template.templateName;
// Capture template in closure and add click handler
var capturedTemplate = template;
button.GetComponent<Button>().onClick.AddListener(() =>
SelectClass(capturedTemplate)
);
}
}
void SelectClass(SimpleCharacterTemplateData template)
{
// Apply the template to player GameObject
bool success = SoulslikeCharacterTemplatesHelper.ApplyTemplateToGameObject(
playerObject,
template
);
if (success)
{
Debug.Log($"Selected class: {template.templateName}");
// The Influence System will automatically recalculate derived stats
// (Health from Vigor, Stamina from Endurance, etc.)
}
}
}
Using Template Manager on Player Prefab
using UnityEngine;
using SimpleAttributeForge.CharacterTemplate;
using Soulslike.CharacterTemplates;
public class PlayerSetup : MonoBehaviour
{
// Reference to the manager component on this GameObject
private SoulslikeCharacterTemplateManager templateManager;
void Awake()
{
templateManager = GetComponent<SoulslikeCharacterTemplateManager>();
}
// Called from UI when player selects a class
public void OnClassSelected(string className)
{
templateManager.ApplyTemplate(className);
}
// Called when player wants to respec
public void OnRespec(SimpleCharacterTemplateData newTemplate)
{
// Switch template while keeping any leveled-up attributes
templateManager.SwitchTemplate(newTemplate, preserveCurrentValues: true);
}
}
Vital Attribute Filtering
The wizard automatically identifies "Vital" type attributes (Health, Stamina, Mana, etc.) and marks them as derived. These attributes shouldn't be directly overridden because they're calculated by the Influence System.
Best Practice: Override base stats (Vigor, Strength, Intelligence) and let the Influence System calculate derived stats (Health, Damage, Defense).
| Type | Override? | Examples |
| Basic | Yes | Strength, Dexterity, Intelligence |
| Resource | Yes | Level, Souls, Humanity |
| Vital | No (Derived) | Health, Stamina, Mana, Focus |
| Percentage | Depends | Equipment Load (may be derived) |