using System.Collections.Generic; using UnityEngine; using NeonTea.Quakeball.Players; using NeonTea.Quakeball.Items; 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; public bool Ragdolling = false; private bool _Ragdolling = false; [Header("Gun holding")] public bool GunGluedToHand = true; private Animator Animator; private Transform BehindHand; private Transform FrontHand; private Transform Torso; private Transform Head; private float VisualYaw; private float VisualPitch; private List RagdollParts = new List(); public void StartRagdoll() { Animator.enabled = false; foreach (Rigidbody body in RagdollParts) { body.isKinematic = false; } } public void StopRagdoll() { foreach (Rigidbody body in RagdollParts) { body.isKinematic = true; } Animator.enabled = true; } public void OnItemSwitched() { if (GunGluedToHand) { Player.CurrentItem.transform.parent = Animator.transform; } } private void Awake() { foreach (Animator animator in Soldiers) { animator.gameObject.SetActive(false); } Animator = Soldiers[(int)Model].GetComponent(); Animator.gameObject.SetActive(true); Head = TransformUtil.FindChildWithName(Animator.transform, "HEAD"); Torso = TransformUtil.FindChildWithName(Animator.transform, "RIBS"); BehindHand = TransformUtil.FindChildWithName(Animator.transform, "HAND.R"); FrontHand = TransformUtil.FindChildWithName(Animator.transform, "HAND.L"); AddRigidbodyToRagdoll(Animator.transform); StopRagdoll(); } private void AddRigidbodyToRagdoll(Transform t) { Rigidbody body = t.GetComponent(); if (body != null) { RagdollParts.Add(body); } for (int i = 0; i < t.childCount; i++) { AddRigidbodyToRagdoll(t.GetChild(i)); } } private void Update() { float Right = Vector3.Dot(Player.GroundVelocity, transform.right) / Player.MoveStyle.TargetVelocity / 0.7f; float Forward = Vector3.Dot(Player.GroundVelocity, transform.forward) / Player.MoveStyle.TargetVelocity / 0.7f; Animator.SetFloat("Forward", Mathf.Clamp(Forward, -1, 1)); Animator.SetFloat("Right", Mathf.Clamp(Right, -1, 1)); if (Ragdolling != _Ragdolling) { if (Ragdolling) { StartRagdoll(); } else { StopRagdoll(); } _Ragdolling = Ragdolling; } } private void LateUpdate() { VisualYaw = Mathf.Lerp(VisualYaw, Player.Yaw, 10f * Time.deltaTime); VisualPitch = Mathf.Lerp(VisualPitch, -Player.Pitch, 10f * Time.deltaTime); transform.localEulerAngles = new Vector3(0, VisualYaw, 0); Torso.localEulerAngles = new Vector3(VisualPitch, 0, 0); HeadCollider.position = Head.position; HeadCollider.eulerAngles = Head.eulerAngles; if (GunGluedToHand && Player.CurrentItem != null) { Vector3 GunOffset = Player.CurrentItem.RightHandAnchor.position - Player.CurrentItem.transform.position; Vector3 GunDirection = (FrontHand.position - BehindHand.position).normalized; Player.CurrentItem.transform.position = BehindHand.position - GunOffset; Player.CurrentItem.transform.LookAt(Player.CurrentItem.transform.position + GunDirection); } } } }