141 lines
5.1 KiB
C#
141 lines
5.1 KiB
C#
#if INVECTOR_PLAYABLESANIMATOR
|
|
using System.Collections.Generic;
|
|
using InvectorCore.Playables;
|
|
using UnityEngine;
|
|
|
|
namespace Invector.vMelee
|
|
{
|
|
using vEventSystems;
|
|
|
|
/// <summary>
|
|
/// PlayablesAnimator counterpart of <see cref="vMeleeAttackControl"/>.
|
|
/// Serialized field names match the Animator behaviour so the PDM Animator Controller
|
|
/// conversion copies the authored values over automatically.
|
|
/// </summary>
|
|
public class vMeleeAttackControlPDM : PlayablesStateBehaviour
|
|
{
|
|
// Anchor for the read-only exit time / end damage note; not real data.
|
|
[vMeleeAttackControlInfo]
|
|
[SerializeField] private int infoAnchor;
|
|
|
|
[Tooltip("normalizedTime of Active Damage")]
|
|
public float startDamage = 0.05f;
|
|
[Tooltip("normalizedTime of Disable Damage")]
|
|
public float endDamage = 0.9f;
|
|
public int damageMultiplier;
|
|
public int recoilID;
|
|
public int reactionID;
|
|
|
|
public vAttackType meleeAttackType = vAttackType.Unarmed;
|
|
[Tooltip("You can use a name as reference to trigger a custom HitDamageParticle")]
|
|
public string damageType;
|
|
// Drawn by the vBodyPartList anchor below: a PropertyAttribute on a collection field targets
|
|
// its elements, not the list, so the list UI has to hang off a scalar field instead.
|
|
[HideInInspector]
|
|
[Tooltip("This work with vMeleeManager to active vMeleeAttackObject from bodyPart and id")]
|
|
public List<string> bodyParts = new List<string> { "RightLowerArm" };
|
|
public bool ignoreDefense;
|
|
public bool activeRagdoll;
|
|
[vHideInInspector("activeRagdoll"), Tooltip("Time to keep Ragdoll active")]
|
|
public float senselessTime;
|
|
[Tooltip("Check true in the last attack of your combo to reset the triggers")]
|
|
public bool resetAttackTrigger;
|
|
public bool debug;
|
|
|
|
// Anchor the body part list UI hangs off; not real data.
|
|
[vBodyPartList]
|
|
[SerializeField] private int bodyPartsAnchor;
|
|
|
|
// Behaviour instances are cloned per PDM row at runtime, so per-play state is safe here.
|
|
[System.NonSerialized] private bool isActive;
|
|
[System.NonSerialized] private bool isAttacking;
|
|
[System.NonSerialized] private vIAttackListener mFighter;
|
|
[System.NonSerialized] private vMeleeManager meleeManager;
|
|
|
|
public override void OnStateEnter(in PlayablesStateContext context)
|
|
{
|
|
GameObject owner = ResolveOwner(context);
|
|
mFighter = owner != null ? owner.GetComponent<vIAttackListener>() : null;
|
|
meleeManager = owner != null ? owner.GetComponent<vMeleeManager>() : null;
|
|
|
|
isActive = false;
|
|
isAttacking = true;
|
|
if (mFighter != null)
|
|
mFighter.OnEnableAttack();
|
|
|
|
if (debug)
|
|
Debug.Log("Enter " + damageType);
|
|
}
|
|
|
|
public override void OnStateUpdate(in PlayablesStateContext context)
|
|
{
|
|
float normalizedTime = context.normalizedTime % 1f;
|
|
|
|
if (normalizedTime >= startDamage && normalizedTime <= endDamage && !isActive)
|
|
{
|
|
if (debug)
|
|
Debug.Log(context.RowName + " attack " + damageType + " enable damage in " +
|
|
System.Math.Round(normalizedTime, 2));
|
|
isActive = true;
|
|
ActiveDamage(true);
|
|
}
|
|
else if (normalizedTime > endDamage && isActive)
|
|
{
|
|
if (debug)
|
|
Debug.Log(context.RowName + " attack " + damageType + " disable damage in " +
|
|
System.Math.Round(normalizedTime, 2));
|
|
isActive = false;
|
|
ActiveDamage(false);
|
|
}
|
|
|
|
if (normalizedTime > endDamage && isAttacking)
|
|
{
|
|
isAttacking = false;
|
|
if (mFighter != null)
|
|
mFighter.OnDisableAttack();
|
|
}
|
|
}
|
|
|
|
public override void OnStateExit(in PlayablesStateContext context)
|
|
{
|
|
if (debug)
|
|
Debug.Log("Exit " + damageType);
|
|
|
|
if (isActive)
|
|
{
|
|
isActive = false;
|
|
ActiveDamage(false);
|
|
}
|
|
|
|
if (isAttacking)
|
|
{
|
|
isAttacking = false;
|
|
if (mFighter != null)
|
|
mFighter.OnDisableAttack();
|
|
}
|
|
|
|
if (mFighter != null && resetAttackTrigger)
|
|
mFighter.ResetAttackTriggers();
|
|
|
|
if (debug)
|
|
Debug.Log(context.RowName + " attack " + damageType + " stateExit");
|
|
}
|
|
|
|
private void ActiveDamage(bool value)
|
|
{
|
|
if (meleeManager)
|
|
{
|
|
meleeManager.SetActiveAttack(
|
|
bodyParts, meleeAttackType, value, damageMultiplier, recoilID, reactionID,
|
|
ignoreDefense, activeRagdoll, senselessTime, damageType);
|
|
}
|
|
}
|
|
|
|
private static GameObject ResolveOwner(in PlayablesStateContext context)
|
|
{
|
|
return context.Animator != null ? context.Animator.gameObject : null;
|
|
}
|
|
}
|
|
}
|
|
#endif
|