### C# Initialize NumericWatcherComponent and Log Watcher Info Source: https://context7.com/et-packages/cn.etetet.numeric/llms.txt This C# code shows how the NumericWatcherComponent is initialized automatically and how to manually trigger watcher execution for debugging. It details the event flow from value change to watcher invocation and provides an example of custom watcher inspection. ```csharp using ET; namespace ET { // The component initializes automatically via ISingletonAwake // Manual initialization example: public class GameEntry { public static void Initialize() { // Watcher component auto-registers all [NumericWatcher] classes NumericWatcherComponent.Instance.Awake(); // Example: 3 watchers registered for NumericType.Hp // - Client UI watcher (SceneType.Current) // - Server death logic (SceneType.Map) // - Analytics logger (SceneType.All) } } // Custom watcher info inspection public static class NumericDebugHelper { public static void LogWatcherInfo(Unit unit, NumbericChange change) { // Watchers are automatically invoked via event system // This shows the flow: // 1. Value changes in NumericComponent // 2. NumbericChange event published // 3. NumericChangeEvent_NotifyWatcher handles event // 4. NumericWatcherComponent.Run() invokes matching watchers NumericWatcherComponent.Instance.Run(unit, change); } } } // Complete example with multiple watchers Unit boss = UnitFactory.Create(scene, SceneType.Map); NumericComponent bossStats = boss.AddComponent(); bossStats[NumericType.MaxHpBase] = 10000; bossStats[NumericType.HpBase] = 10000; // Triggers watchers: UI update + server logic + analytics bossStats[NumericType.Hp] = 5000; // 50% HP triggers rage phase in watcher bossStats[NumericType.Hp] = 0; // Death triggers loot drop in watcher ``` -------------------------------- ### C# Implement INumericWatcher for HP Changes Source: https://context7.com/et-packages/cn.etetet.numeric/llms.txt This C# code demonstrates how to implement the INumericWatcher interface to react to changes in the 'Hp' numeric type. It includes examples for client-side UI updates and server-side death detection, showcasing how to access old and new values and trigger events. ```csharp using ET; using UnityEngine; namespace ET { // Client-side watcher for HP changes [NumericWatcher(SceneType.Current, NumericType.Hp)] public class NumericWatcher_Hp_ShowUI : INumericWatcher { public void Run(Unit unit, NumbericChange args) { // Update UI when HP changes int oldHp = (int)args.Old; int newHp = (int)args.New; float percentage = (float)newHp / unit.GetComponent().GetAsInt(NumericType.MaxHp); Debug.Log($"HP Changed: {oldHp} -> {newHp} ({percentage:P0})"); // Update health bar UI // UIComponent.Instance.GetHealthBar(unit.Id).SetValue(percentage); } } // Server-side watcher for death detection [NumericWatcher(SceneType.Map, NumericType.Hp)] public class NumericWatcher_Hp_Death : INumericWatcher { public void Run(Unit unit, NumbericChange args) { if (args.New <= 0 && args.Old > 0) { // Handle death Debug.Log($"Unit {unit.Id} died!"); // EventSystem.Instance.Publish(unit.Scene(), new UnitDeathEvent { Unit = unit }); } } } } // Usage - watchers trigger automatically when values change Unit player = UnitFactory.Create(scene); NumericComponent numeric = player.AddComponent(); numeric[NumericType.MaxHp] = 1000; numeric[NumericType.Hp] = 1000; // This will trigger all registered Hp watchers numeric[NumericType.Hp] = 500; // Logs: "HP Changed: 1000 -> 500 (50%)" numeric[NumericType.Hp] = 0; // Logs: "Unit died!" ``` -------------------------------- ### Define Custom Numeric Types and Modifiers in C# Source: https://context7.com/et-packages/cn.etetet.numeric/llms.txt Provides a C# example of defining custom numeric attribute identifiers using constants within the `NumericType` static class. It shows the pattern for creating base constants and their corresponding modifier constants (Base, Add, Pct, FinalAdd, FinalPct) for new attributes like Attack and Defense. ```csharp namespace ET { public static partial class NumericType { public const int Max = 10000; // Attack attribute family public const int Attack = 1004; public const int AttackBase = Attack * 10 + 1; // 10041 public const int AttackAdd = Attack * 10 + 2; // 10042 public const int AttackPct = Attack * 10 + 3; // 10043 public const int AttackFinalAdd = Attack * 10 + 4; // 10044 public const int AttackFinalPct = Attack * 10 + 5; // 10045 // Defense attribute family public const int Defense = 1005; public const int DefenseBase = Defense * 10 + 1; public const int DefenseAdd = Defense * 10 + 2; public const int DefensePct = Defense * 10 + 3; public const int DefenseFinalAdd = Defense * 10 + 4; public const int DefenseFinalPct = Defense * 10 + 5; } } // Usage Unit unit = UnitFactory.Create(scene); NumericComponent nc = unit.AddComponent(); nc[NumericType.AttackBase] = 50; nc[NumericType.AttackAdd] = 10; int finalAttack = nc.GetAsInt(NumericType.Attack); // Calculated automatically ``` -------------------------------- ### Manage Unit Attributes with NumericComponent in C# Source: https://context7.com/et-packages/cn.etetet.numeric/llms.txt Demonstrates the core functionalities of the NumericComponent in Unity C#. It covers creating a unit, adding the component, setting and retrieving integer and float values, direct indexer access, and setting values without triggering events. This component is essential for managing entity attributes like HP and Speed. ```csharp using ET; // Create a unit with numeric component Unit player = UnitFactory.Create(scene); NumericComponent numeric = player.AddComponent(); // Set integer value numeric.Set(NumericType.Hp, 100); // Set float value (internally stored as long * 10000) numeric.Set(NumericType.Speed, 5.5f); // Get values in different formats int currentHp = numeric.GetAsInt(NumericType.Hp); // Returns: 100 float currentSpeed = numeric.GetAsFloat(NumericType.Speed); // Returns: 5.5 long rawValue = numeric.GetAsLong(NumericType.Hp); // Returns: 100 // Direct indexer access (triggers events) numeric[NumericType.MaxHp] = 1000; long maxHp = numeric[NumericType.MaxHp]; // Set value without triggering events numeric.SetNoEvent(NumericType.Hp, 50); // Check value change Console.WriteLine($"HP: {currentHp}, Max HP: {maxHp}"); ``` -------------------------------- ### C# Combat System with Numeric Types and Watchers Source: https://context7.com/et-packages/cn.etetet.numeric/llms.txt Defines numeric types for combat, implements a damage calculation system, a buff application method, and an HP watcher for UI updates. It relies on the ET framework and its NumericComponent. ```csharp using ET; namespace ET { // Define combat attributes public static partial class NumericType { public const int Damage = 2001; public const int DamageBase = Damage * 10 + 1; public const int DamageAdd = Damage * 10 + 2; public const int DamagePct = Damage * 10 + 3; } // HP UI watcher [NumericWatcher(SceneType.Current, NumericType.Hp)] public class NumericWatcher_Hp_UI : INumericWatcher { public void Run(Unit unit, NumbericChange args) { float hpPercent = (float)args.New / unit.GetComponent()[NumericType.MaxHp]; // UIHelper.UpdateHealthBar(unit.Id, hpPercent); Log.Info($"[UI] Unit {unit.Id} HP: {args.New} ({hpPercent:P0})"); } } // Damage system public static class CombatSystem { public static void ApplyDamage(Unit attacker, Unit target, int baseDamage) { NumericComponent attackerStats = attacker.GetComponent(); NumericComponent targetStats = target.GetComponent(); // Calculate final damage with attacker bonuses attackerStats[NumericType.DamageBase] = baseDamage; int finalDamage = attackerStats.GetAsInt(NumericType.Damage); // Apply to target HP int currentHp = targetStats.GetAsInt(NumericType.Hp); int newHp = Math.Max(0, currentHp - finalDamage); targetStats[NumericType.Hp] = newHp; // Triggers HP watcher Log.Info($"Damage: {finalDamage}, Remaining HP: {newHp}"); } public static void ApplyBuff(Unit unit, int damageBonus, int durationSeconds) { NumericComponent stats = unit.GetComponent(); int currentBonus = stats.GetAsInt(NumericType.DamageAdd); stats[NumericType.DamageAdd] = currentBonus + damageBonus; // Schedule buff removal (simplified) // await TimerComponent.Instance.WaitAsync(durationSeconds * 1000); // stats[NumericType.DamageAdd] = currentBonus; } } } // Complete combat scenario Unit player = UnitFactory.Create(scene, SceneType.Current); Unit enemy = UnitFactory.Create(scene, SceneType.Current); // Initialize player stats NumericComponent playerStats = player.AddComponent(); playerStats[NumericType.MaxHpBase] = 1000; playerStats[NumericType.HpBase] = 1000; playerStats[NumericType.DamageBase] = 50; // Initialize enemy stats NumericComponent enemyStats = enemy.AddComponent(); enemyStats[NumericType.MaxHpBase] = 500; enemyStats[NumericType.HpBase] = 500; // Apply damage buff: +20 damage, +50% damage playerStats[NumericType.DamageAdd] = 20; playerStats[NumericType.DamagePct] = 50 * 10000; // 50% // Attack enemy CombatSystem.ApplyDamage(player, enemy, 50); // Output: // - Final damage: (50 + 20) * 150% = 105 // - [UI] Unit HP: 395 (79%) CombatSystem.ApplyDamage(player, enemy, 50); // Output: [UI] Unit HP: 290 (58%) ``` -------------------------------- ### Handle Numeric Change Events in C# - ET Framework Source: https://context7.com/et-packages/cn.etetet.numeric/llms.txt This C# code demonstrates how to subscribe to and handle NumericChange events within the ET framework. It includes a default handler that notifies all watchers and a custom handler for managing buff durations based on speed changes. Events are automatically published by the framework or can be manually published using EventSystem.Instance.Publish. ```csharp using ET; namespace ET { // Event handler for numeric changes (already implemented in framework) [Event(SceneType.All)] public class NumericChangeEvent_NotifyWatcher : AEvent { protected override async ETTask Run(Scene scene, NumbericChange args) { // Automatically dispatches to all registered watchers NumericWatcherComponent.Instance.Run(args.Unit, args); await ETTask.CompletedTask; } } // Custom event handler example - buff system [Event(SceneType.Map)] public class NumericChangeEvent_BuffDuration : AEvent { protected override async ETTask Run(Scene scene, NumbericChange args) { // React to speed changes to update buff duration if (args.NumericType == NumericType.Speed) { BuffComponent buffs = args.Unit.GetComponent(); if (buffs != null) { // Recalculate movement-based buff durations buffs.RecalculateMovementBuffs(args.New, args.Old); } } await ETTask.CompletedTask; } } } // Usage - events fire automatically Unit character = UnitFactory.Create(scene); NumericComponent stats = character.AddComponent(); // Manual event publishing (normally automatic) NumbericChange changeData = new NumbericChange { Unit = character, NumericType = NumericType.Speed, Old = 100, New = 150 }; // Publish to all scene handlers EventSystem.Instance.Publish(character.Scene(), changeData); // Both NumericChangeEvent_NotifyWatcher and NumericChangeEvent_BuffDuration execute ``` -------------------------------- ### Complex Attribute Calculation with Modifiers in C# Source: https://context7.com/et-packages/cn.etetet.numeric/llms.txt Illustrates how ET.Numeric handles complex attribute calculations using five modifier types: Base, Add, Pct, FinalAdd, and FinalPct. It shows how to set these modifiers for an attribute like 'Speed' and how the final value is automatically recalculated using the system's formula. ```csharp using ET; Unit hero = UnitFactory.Create(scene); NumericComponent stats = hero.AddComponent(); // Setup base speed: 100 stats[NumericType.SpeedBase] = 100; // Add flat bonus: +20 speed from boots stats[NumericType.SpeedAdd] = 20; // Add percentage bonus: +30% speed from skill stats[NumericType.SpeedPct] = 30 * 10000; // Store as 300000 (30 * 10000) // Add final flat bonus: +15 speed from buff stats[NumericType.SpeedFinalAdd] = 15; // Add final percentage: +10% from passive stats[NumericType.SpeedFinalPct] = 10 * 10000; // Store as 100000 // Formula: final = (((base + add) * (100 + pct) / 100) + finalAdd) * (100 + finalPct) / 100 // Result: (((100 + 20) * (100 + 30) / 100) + 15) * (100 + 10) / 100 // = ((120 * 130 / 100) + 15) * 110 / 100 // = (156 + 15) * 110 / 100 // = 171 * 1.1 = 188.1 float finalSpeed = stats.GetAsFloat(NumericType.Speed); Console.WriteLine($"Final Speed: {finalSpeed}"); // Output: 188.1 ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.