using UnityEngine; using NeonTea.Quakeball.Players; using NeonTea.Quakeball.Util; namespace NeonTea.Quakeball.Animation { /// Animates the parts that can't be animated via the animation system, e.g. aiming. public class SoldierProceduralAnimator : MonoBehaviour { public enum SoldierModel { Female = 0, Male = 1, } public Animator[] Soldiers; public SoldierModel Model; public Player Player; public Transform HeadCollider; [Header("Gun holding")] public bool GunGluedToHand = true; public Transform Gun; public Transform GunHandle; private Animator Animator; private float BodyYaw = 0; private Transform BehindHand; private Transform FrontHand; private void Awake() { foreach (Animator animator in Soldiers) { animator.gameObject.SetActive(false); } Animator = Soldiers[(int)Model].GetComponent(); Animator.gameObject.SetActive(true); Transform Head = TransformUtil.FindChildWithName(Animator.transform, "HEAD"); HeadCollider.parent = Head; BehindHand = TransformUtil.FindChildWithName(Animator.transform, "HAND.R"); FrontHand = TransformUtil.FindChildWithName(Animator.transform, "HAND.L"); } private void Update() { float Right = Vector3.Dot(Player.GroundVelocity.normalized, transform.right); float Forward = Vector3.Dot(Player.GroundVelocity.normalized, transform.forward); float RelativeSpeed = Player.GroundVelocity.magnitude / Player.MoveStyle.TargetVelocity; Right = Mathf.Clamp(Right * RelativeSpeed, -0.999f, 0.999f); Forward = Mathf.Clamp(Forward * RelativeSpeed, -.999f, 0.999f); // Square the circle: Forward = 0.5f * Mathf.Sqrt(2 - Right * Right + Forward * Forward + 2 * Forward * Mathf.Sqrt(2)) - 0.5f * Mathf.Sqrt(2 - Right * Right + Forward * Forward - 2 * Forward * Mathf.Sqrt(2)); Right = 0.5f * Mathf.Sqrt(2 + Right * Right - Forward * Forward + 2 * Right * Mathf.Sqrt(2)) - 0.5f * Mathf.Sqrt(2 + Right * Right - Forward * Forward - 2 * Right * Mathf.Sqrt(2)); Animator.SetFloat("Forward", Forward); Animator.SetFloat("Right", Right); } private void LateUpdate() { transform.localEulerAngles = new Vector3(0, Player.Yaw, 0); if (GunGluedToHand) { Vector3 GunOffset = GunHandle.position - Gun.position; Vector3 GunDirection = (FrontHand.position - BehindHand.position).normalized; Gun.position = BehindHand.position - GunOffset; Gun.LookAt(Gun.position + GunDirection); } } } }