quakeball/Assets/Scripts/Animation/SoldierProceduralAnimator.cs

115 lines
4.2 KiB
C#
Raw Permalink Normal View History

2020-08-10 17:41:07 +02:00
using System.Collections.Generic;
using UnityEngine;
2020-08-08 20:02:17 +02:00
using NeonTea.Quakeball.Players;
using NeonTea.Quakeball.Items;
2020-08-09 19:33:23 +02:00
using NeonTea.Quakeball.Util;
2020-08-08 20:02:17 +02:00
namespace NeonTea.Quakeball.Animation {
/// <summary>Animates the parts that can't be animated via the animation system, e.g. aiming.</summary>
public class SoldierProceduralAnimator : MonoBehaviour {
2020-08-09 19:33:23 +02:00
public enum SoldierModel {
Female = 0,
Male = 1,
}
public Animator[] Soldiers;
public SoldierModel Model;
2020-08-08 20:02:17 +02:00
public Player Player;
2020-08-08 21:30:13 +02:00
public Transform HeadCollider;
2020-08-08 20:02:17 +02:00
2020-08-10 17:41:07 +02:00
public bool Ragdolling = false;
private bool _Ragdolling = false;
2020-08-09 19:33:23 +02:00
[Header("Gun holding")]
public bool GunGluedToHand = true;
2020-08-08 20:02:17 +02:00
2020-08-09 19:33:23 +02:00
private Animator Animator;
private Transform BehindHand;
private Transform FrontHand;
2020-08-10 01:42:55 +02:00
private Transform Torso;
2020-08-10 18:04:28 +02:00
private Transform Head;
2020-08-10 01:42:55 +02:00
private float VisualYaw;
private float VisualPitch;
2020-08-08 21:30:13 +02:00
2020-08-10 17:41:07 +02:00
private List<Rigidbody> RagdollParts = new List<Rigidbody>();
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;
}
2020-08-14 19:48:27 +02:00
public void OnItemSwitched() {
if (GunGluedToHand) {
Player.CurrentItem.transform.parent = Animator.transform;
}
}
2020-08-08 20:02:17 +02:00
private void Awake() {
2020-08-09 19:33:23 +02:00
foreach (Animator animator in Soldiers) {
animator.gameObject.SetActive(false);
}
Animator = Soldiers[(int)Model].GetComponent<Animator>();
Animator.gameObject.SetActive(true);
2020-08-10 18:04:28 +02:00
Head = TransformUtil.FindChildWithName(Animator.transform, "HEAD");
2020-08-10 01:42:55 +02:00
Torso = TransformUtil.FindChildWithName(Animator.transform, "RIBS");
2020-08-09 19:33:23 +02:00
BehindHand = TransformUtil.FindChildWithName(Animator.transform, "HAND.R");
FrontHand = TransformUtil.FindChildWithName(Animator.transform, "HAND.L");
2020-08-10 17:41:07 +02:00
AddRigidbodyToRagdoll(Animator.transform);
StopRagdoll();
}
private void AddRigidbodyToRagdoll(Transform t) {
Rigidbody body = t.GetComponent<Rigidbody>();
if (body != null) {
RagdollParts.Add(body);
}
for (int i = 0; i < t.childCount; i++) {
AddRigidbodyToRagdoll(t.GetChild(i));
}
2020-08-08 20:02:17 +02:00
}
2020-08-08 21:30:13 +02:00
private void Update() {
2020-08-10 00:16:06 +02:00
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));
2020-08-10 17:41:07 +02:00
if (Ragdolling != _Ragdolling) {
if (Ragdolling) {
StartRagdoll();
} else {
StopRagdoll();
}
_Ragdolling = Ragdolling;
}
2020-08-08 21:30:13 +02:00
}
2020-08-08 20:02:17 +02:00
private void LateUpdate() {
2020-08-10 01:42:55 +02:00
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);
2020-08-10 18:04:28 +02:00
HeadCollider.position = Head.position;
HeadCollider.eulerAngles = Head.eulerAngles;
2020-08-08 21:30:13 +02:00
2020-08-14 19:48:27 +02:00
if (GunGluedToHand && Player.CurrentItem != null) {
Vector3 GunOffset = Player.CurrentItem.RightHandAnchor.position - Player.CurrentItem.transform.position;
2020-08-09 19:33:23 +02:00
Vector3 GunDirection = (FrontHand.position - BehindHand.position).normalized;
2020-08-14 19:48:27 +02:00
Player.CurrentItem.transform.position = BehindHand.position - GunOffset;
Player.CurrentItem.transform.LookAt(Player.CurrentItem.transform.position + GunDirection);
2020-08-09 19:33:23 +02:00
}
2020-08-08 20:02:17 +02:00
}
}
}