using UnityEngine; namespace Ashwild.Player { /// /// Turns the arms rig's Animation Events into bus events, so gameplay reacts on the frame the /// animation says it should instead of on the frame the input arrived. That distinction is what /// makes a swing read as a swing: without it the axe deals its damage while it is still travelling /// backwards, and the tree loses a chunk before the blade has touched it. /// /// Must sit on the same GameObject as the Animator — Unity resolves Animation Events by method name /// against the components of the animated object. Every method is prefixed "Anim" on purpose: the /// PlayerInput component uses Send Messages, so any method named after an input action would be /// invoked by the Input System too and crash on the signature mismatch (see CLAUDE.md §5.6). /// /// This is owner-only local feedback — the arms exist only on the owning client — so it belongs in /// PlayerNetworkController.ownerOnlyBehaviours alongside the rest of the arms rig. /// [DisallowMultipleComponent] public class ArmsAnimationEvents : MonoBehaviour { #region Animation Events /// /// The frame the held tool or weapon actually connects. Place it on the contact pose of every /// attack clip; the swinging item resolves its hit here. /// public void AnimAttackImpact() => PlayerEvents.RaiseAttackImpact(); /// /// The draw animation has finished and the item is fully in hand. /// public void AnimEquipComplete() => PlayerEvents.RaiseEquipAnimComplete(); /// /// The put-away animation has finished and the item has left the frame — the cue for /// HotbarController to actually destroy the old prefab and draw the next one. /// public void AnimUnequipComplete() => PlayerEvents.RaiseUnequipAnimComplete(); #endregion } }