EscapeShooter/My project/Assets/Project Files/Game/Scripts/Characters/BaseCharacterGraphics.cs

362 lines
15 KiB
C#

using UnityEngine;
using UnityEngine.Animations.Rigging;
using Watermelon;
namespace Watermelon.SquadShooter
{
public abstract class BaseCharacterGraphics : MonoBehaviour
{
private static readonly int PARTICLE_UPGRADE = "Upgrade".GetHashCode();
private readonly int ANIMATION_SHOT_HASH = Animator.StringToHash("Shot");
private readonly int ANIMATION_HIT_HASH = Animator.StringToHash("Hit");
private readonly int JUMP_ANIMATION_HASH = Animator.StringToHash("Jump");
private readonly int GRUNT_ANIMATION_HASH = Animator.StringToHash("Grunt");
[SerializeField]
protected Animator characterAnimator;
public Animator CharacterAnimator => characterAnimator;
[Space]
[SerializeField] SkinnedMeshRenderer meshRenderer;
public SkinnedMeshRenderer MeshRenderer => meshRenderer;
[Header("Movement")]
[SerializeField] MovementSettings movementSettings;
public MovementSettings MovementSettings => movementSettings;
[SerializeField] MovementSettings movementAimingSettings;
public MovementSettings MovementAimingSettings => movementAimingSettings;
[Header("Hands Rig")]
[SerializeField] TwoBoneIKConstraint leftHandRig;
public TwoBoneIKConstraint LeftHandRig => leftHandRig;
[SerializeField] Vector3 leftHandExtraRotation;
public Vector3 LeftHandExtraRotation => leftHandExtraRotation;
[SerializeField] TwoBoneIKConstraint rightHandRig;
public TwoBoneIKConstraint RightHandRig => rightHandRig;
[SerializeField] Vector3 rightHandExtraRotation;
public Vector3 RightHandExtraRotation => rightHandExtraRotation;
[Header("Weapon")]
[SerializeField] Transform weaponsTransform;
[SerializeField] Transform minigunHolderTransform;
public Transform MinigunHolderTransform => minigunHolderTransform;
[SerializeField] Transform shootGunHolderTransform;
public Transform ShootGunHolderTransform => shootGunHolderTransform;
[SerializeField] Transform rocketHolderTransform;
public Transform RocketHolderTransform => rocketHolderTransform;
[SerializeField] Transform teslaHolderTransform;
public Transform TeslaHolderTransform => teslaHolderTransform;
[Space]
[SerializeField] Rig mainRig;
[SerializeField] Transform leftHandController;
[SerializeField] Transform rightHandController;
protected CharacterBehaviour characterBehaviour;
protected CharacterAnimationHandler animationHandler;
protected Material characterMaterial;
public Material CharacterMaterial => characterMaterial;
private int animatorShootingLayerIndex;
private AnimatorOverrideController animatorOverrideController;
private TweenCase rigWeightCase;
protected RagdollBehavior ragdoll;
private TweenCase weaponsTransformCase;
private TweenCase leftHandCase;
private TweenCase rightHandCase;
private Vector3 saveWeaponsPosition;
private Vector3 saveLeftHandPosition;
private Vector3 saveRightHandPosition;
public virtual void Init(CharacterBehaviour characterBehaviour)
{
this.characterBehaviour = characterBehaviour;
ragdoll = new RagdollBehavior();
ragdoll.Init(characterAnimator.transform);
animationHandler = characterAnimator.GetComponent<CharacterAnimationHandler>();
animationHandler.Inititalise(characterBehaviour);
animatorOverrideController = new AnimatorOverrideController(characterAnimator.runtimeAnimatorController);
characterAnimator.runtimeAnimatorController = animatorOverrideController;
characterMaterial = meshRenderer.sharedMaterial;
animatorShootingLayerIndex = characterAnimator.GetLayerIndex("Shooting");
}
public abstract void OnMovingStarted();
public abstract void OnMovingStoped();
public abstract void OnMoving(float speedPercent, Vector3 direction, bool isTargetFound);
public virtual void OnDeath() { }
public void Jump()
{
characterAnimator.SetTrigger(JUMP_ANIMATION_HASH);
rigWeightCase.KillActive();
mainRig.weight = 0f;
}
public void Grunt()
{
characterAnimator.SetTrigger(GRUNT_ANIMATION_HASH);
var strength = 0.1f;
var durationIn = 0.1f;
var durationOut = 0.15f;
if (weaponsTransformCase.KillActive()) weaponsTransform.localPosition = saveWeaponsPosition;
if (leftHandCase.KillActive()) leftHandController.localPosition = saveLeftHandPosition;
if (rightHandCase.KillActive()) rightHandController.localPosition = saveRightHandPosition;
saveWeaponsPosition = weaponsTransform.localPosition;
saveLeftHandPosition = leftHandController.localPosition;
saveRightHandPosition = rightHandController.localPosition;
weaponsTransformCase = weaponsTransform.DOMoveY(weaponsTransform.position.y - strength, durationIn).SetEasing(Ease.Type.SineOut).OnComplete(() =>
{
weaponsTransformCase = weaponsTransform.DOMoveY(weaponsTransform.position.y + strength, durationOut).SetEasing(Ease.Type.SineInOut);
});
leftHandCase = leftHandController.DOMoveY(leftHandController.position.y - strength, durationIn).SetEasing(Ease.Type.SineOut).OnComplete(() =>
{
leftHandCase = leftHandController.DOMoveY(leftHandController.position.y + strength, durationOut).SetEasing(Ease.Type.SineInOut);
});
rightHandCase = rightHandController.DOMoveY(rightHandController.position.y - strength, durationIn).SetEasing(Ease.Type.SineOut).OnComplete(() =>
{
rightHandCase = rightHandController.DOMoveY(rightHandController.position.y + strength, durationOut).SetEasing(Ease.Type.SineInOut);
});
}
public void EnableRig()
{
rigWeightCase = Tween.DoFloat(0, 1, 0.2f, (value) => mainRig.weight = value);
}
public abstract void CustomFixedUpdate();
public void SetShootingAnimation(AnimationClip animationClip)
{
animatorOverrideController["Shot"] = animationClip;
}
public void OnShoot()
{
characterAnimator.Play(ANIMATION_SHOT_HASH, animatorShootingLayerIndex, 0);
}
public void PlayHitAnimation()
{
characterAnimator.SetTrigger(ANIMATION_HIT_HASH);
}
public void PlayBounceAnimation()
{
transform.localScale = Vector3.one * 0.6f;
transform.DOScale(Vector3.one, 0.4f).SetEasing(Ease.Type.BackOut);
}
public void PlayUpgradeParticle()
{
ParticleCase particleCase = ParticlesController.PlayParticle(PARTICLE_UPGRADE).SetPosition(transform.position + new Vector3(0, -0.25f, -0.25f)).SetScale((5).ToVector3());
}
public void EnableRagdoll()
{
mainRig.weight = 0.0f;
characterAnimator.enabled = false;
characterBehaviour.Weapon.gameObject.SetActive(false);
ragdoll?.ActivateWithForce(transform.position + transform.forward, 700, 100);
}
public void DisableRagdoll()
{
ragdoll?.Disable();
mainRig.weight = 1.0f;
characterBehaviour.Weapon.gameObject.SetActive(true);
characterAnimator.enabled = true;
}
public abstract void Unload();
public abstract void Reload();
public abstract void Disable();
public abstract void Activate();
#if UNITY_EDITOR
[Button("Prepare Model")]
public void PrepareModel()
{
// Get animator component
Animator tempAnimator = characterAnimator;
if (tempAnimator != null)
{
if (tempAnimator.avatar != null && tempAnimator.avatar.isHuman)
{
// Initialise rig
RigBuilder rigBuilder = tempAnimator.GetComponent<RigBuilder>();
if (rigBuilder == null)
{
rigBuilder = tempAnimator.gameObject.AddComponent<RigBuilder>();
GameObject rigObject = new GameObject("Main Rig");
rigObject.transform.SetParent(tempAnimator.transform);
rigObject.transform.ResetLocal();
Rig rig = rigObject.AddComponent<Rig>();
mainRig = rig;
rigBuilder.layers.Add(new RigLayer(rig, true));
// Left hand rig
GameObject leftHandRigObject = new GameObject("Left Hand Rig");
leftHandRigObject.transform.SetParent(rigObject.transform);
leftHandRigObject.transform.ResetLocal();
GameObject leftHandControllerObject = new GameObject("Controller");
leftHandControllerObject.transform.SetParent(leftHandRigObject.transform);
leftHandControllerObject.transform.ResetLocal();
leftHandController = leftHandControllerObject.transform;
Transform leftHandBone = tempAnimator.GetBoneTransform(HumanBodyBones.LeftHand);
leftHandControllerObject.transform.position = leftHandBone.position;
leftHandControllerObject.transform.rotation = leftHandBone.rotation;
TwoBoneIKConstraint leftHandRig = leftHandRigObject.AddComponent<TwoBoneIKConstraint>();
leftHandRig.data.target = leftHandControllerObject.transform;
leftHandRig.data.root = tempAnimator.GetBoneTransform(HumanBodyBones.LeftUpperArm);
leftHandRig.data.mid = tempAnimator.GetBoneTransform(HumanBodyBones.LeftLowerArm);
leftHandRig.data.tip = leftHandBone;
// Right hand rig
GameObject rightHandRigObject = new GameObject("Right Hand Rig");
rightHandRigObject.transform.SetParent(rigObject.transform);
rightHandRigObject.transform.ResetLocal();
GameObject rightHandControllerObject = new GameObject("Controller");
rightHandControllerObject.transform.SetParent(rightHandRigObject.transform);
rightHandControllerObject.transform.ResetLocal();
rightHandController = rightHandControllerObject.transform;
Transform rightHandBone = tempAnimator.GetBoneTransform(HumanBodyBones.RightHand);
rightHandControllerObject.transform.position = rightHandBone.position;
rightHandControllerObject.transform.rotation = rightHandBone.rotation;
TwoBoneIKConstraint rightHandRig = rightHandRigObject.AddComponent<TwoBoneIKConstraint>();
rightHandRig.data.target = rightHandControllerObject.transform;
rightHandRig.data.root = tempAnimator.GetBoneTransform(HumanBodyBones.RightUpperArm);
rightHandRig.data.mid = tempAnimator.GetBoneTransform(HumanBodyBones.RightLowerArm);
rightHandRig.data.tip = rightHandBone;
this.leftHandRig = leftHandRig;
this.rightHandRig = rightHandRig;
}
// Prepare ragdoll
RagdollHelper.CreateRagdoll(tempAnimator, 60, 1, LayerMask.NameToLayer("Ragdoll"));
movementSettings.RotationSpeed = 8;
movementSettings.MoveSpeed = 5;
movementSettings.Acceleration = 781.25f;
movementSettings.AnimationMultiplier = new DuoFloat(0, 1.4f);
movementAimingSettings.RotationSpeed = 8;
movementAimingSettings.MoveSpeed = 4.375f;
movementAimingSettings.Acceleration = 781.25f;
movementAimingSettings.AnimationMultiplier = new DuoFloat(0, 1.2f);
CharacterAnimationHandler tempAnimationHandler = tempAnimator.GetComponent<CharacterAnimationHandler>();
if (tempAnimationHandler == null)
tempAnimator.gameObject.AddComponent<CharacterAnimationHandler>();
// Create weapon holders
GameObject weaponHolderObject = new GameObject("Weapons");
weaponHolderObject.transform.SetParent(tempAnimator.transform);
weaponHolderObject.transform.ResetLocal();
weaponsTransform = weaponHolderObject.transform;
// Minigun
GameObject miniGunHolderObject = new GameObject("Minigun Holder");
miniGunHolderObject.transform.SetParent(weaponsTransform);
miniGunHolderObject.transform.ResetLocal();
miniGunHolderObject.transform.localPosition = new Vector3(0.204f, 0.7f, 0.375f);
minigunHolderTransform = miniGunHolderObject.transform;
// Shotgun
GameObject shotgunHolderObject = new GameObject("Shotgun Holder");
shotgunHolderObject.transform.SetParent(weaponsTransform);
shotgunHolderObject.transform.ResetLocal();
shotgunHolderObject.transform.localPosition = new Vector3(0.22f, 0.6735f, 0.23f);
shootGunHolderTransform = shotgunHolderObject.transform;
// Rocket
GameObject rocketHolderObject = new GameObject("Rocket Holder");
rocketHolderObject.transform.SetParent(weaponsTransform);
rocketHolderObject.transform.ResetLocal();
rocketHolderObject.transform.localPosition = new Vector3(0.234f, 0.726f, 0.369f);
rocketHolderObject.transform.localRotation = Quaternion.Euler(-23.68f, -4.74f, 7.92f);
rocketHolderTransform = rocketHolderObject.transform;
// Tesla
GameObject teslaHolderObject = new GameObject("Tesla Holder");
teslaHolderObject.transform.SetParent(weaponsTransform);
teslaHolderObject.transform.ResetLocal();
teslaHolderObject.transform.localPosition = new Vector3(0.213f, 0.783f, 0.357f);
teslaHolderTransform = teslaHolderObject.transform;
// Initialise mesh renderer
meshRenderer = tempAnimator.transform.GetComponentInChildren<SkinnedMeshRenderer>();
#if UNITY_EDITOR
UnityEditor.EditorUtility.SetDirty(this);
#endif
}
else
{
Debug.LogError("Avatar is missing or type isn't humanoid!");
}
}
else
{
Debug.LogWarning("Animator component can't be found!");
}
}
#endif
}
}