3359 lines
115 KiB
C#
3359 lines
115 KiB
C#
using UnityEngine;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using GameKitController.Audio;
|
|
using UnityEngine.Events;
|
|
|
|
[System.Serializable]
|
|
public class closeCombatSystem : MonoBehaviour
|
|
{
|
|
public bool combatSystemEnabled;
|
|
public LayerMask layerMaskToDamage;
|
|
|
|
[Tooltip ("If this option is changed, used the button 'Update Hit Combat Triggers Info' to set the new value")]
|
|
public bool useCustomIgnoreTags;
|
|
|
|
[Tooltip ("Tags name list to be ignored by the damage of close combat of this character")]
|
|
public List<string> customTagsToIgnoreList = new List<string> ();
|
|
|
|
public float generalAttackDamageMultiplier = 1;
|
|
|
|
public float addForceMultiplier;
|
|
|
|
public bool setCanActivateReactionSystemTemporallyState;
|
|
public bool canActivateReactionSystemTemporally;
|
|
|
|
float defaultArmHitDamage = 10;
|
|
float defaultLegHitDamage = 15;
|
|
|
|
public string attackIDAnimatorName = "Attack ID";
|
|
|
|
public List<combatTypeInfo> combatTypeInfoList = new List<combatTypeInfo> ();
|
|
|
|
public List<combatLimbInfo> combatLimbList = new List<combatLimbInfo> ();
|
|
|
|
public bool currentPlayerMode;
|
|
|
|
public bool useAnimationPercentageDuration = true;
|
|
public bool useAnimationPercentageOver100;
|
|
|
|
public bool setCombatIdleID;
|
|
public int combatIdleID = 1;
|
|
|
|
public bool setCombatIdleAfterFirstAttack;
|
|
|
|
public bool setRegularIdleAfterAttackActive;
|
|
public float minWaitToSetRegularIdAfterAttackActive;
|
|
|
|
public bool keepCombatIdleOnFBAActiveEnabled = true;
|
|
|
|
public int combatTypeID = 0;
|
|
|
|
public enum colliderPlace
|
|
{
|
|
leg,
|
|
arm,
|
|
both,
|
|
right_leg,
|
|
left_leg,
|
|
right_arm,
|
|
left_arm,
|
|
both_legs,
|
|
both_arms,
|
|
in_front
|
|
}
|
|
|
|
public bool useEventsOnStateChange;
|
|
public UnityEvent evenOnStateEnabled;
|
|
public UnityEvent eventOnStateDisabled;
|
|
|
|
public bool useEventOnFBAViewChange;
|
|
public UnityEvent eventOnEnableFBA;
|
|
public UnityEvent eventOnDisableFBA;
|
|
|
|
|
|
public bool useStrafeMode;
|
|
public int strafeIDUsed;
|
|
public bool setPreviousStrafeModeOnDisableMode;
|
|
|
|
bool previousStrafeMode;
|
|
int previousStrafeID = -1;
|
|
|
|
public bool activateStrafeModeOnLockOnTargetActive;
|
|
|
|
public bool toggleStrafeModeIfRunningActive;
|
|
|
|
public headTrack mainHeadTrack;
|
|
public playerController playerControllerManager;
|
|
public Animator animator;
|
|
|
|
public bool useMatchTargetSystemOnAttack;
|
|
public bool ignoreAttackSettingToMatchTarget;
|
|
public bool useMainMatchPositionOffset;
|
|
public float mainMatchPositionOffset;
|
|
public matchPlayerToTargetSystem mainMatchPlayerToTargetSystem;
|
|
|
|
public bool placeTriggerInFrontOfCharacterOnAllAttacks;
|
|
|
|
bool originalUseMatchTargetSystemOnAttack;
|
|
|
|
public GameObject hitCombatPrefab;
|
|
|
|
public float timerCombat = 0;
|
|
|
|
public bool combatPlaying;
|
|
|
|
float lastTimeComboAttack;
|
|
|
|
public string currentComboInProcessName;
|
|
public string previousComboInProcessName;
|
|
|
|
public bool checkSurfaceInfoEnabled = true;
|
|
|
|
public string surfaceInfoOnMeleeAttackNameForNotFound = "Regular";
|
|
public string surfaceInfoOnMeleeAttackNameForSwingOnAir = "Swing On Air";
|
|
public List<grabbedObjectMeleeAttackSystem.surfaceInfoOnMeleeAttack> surfaceInfoOnMeleeAttackList =
|
|
new List<grabbedObjectMeleeAttackSystem.surfaceInfoOnMeleeAttack> ();
|
|
|
|
public AudioSource mainAudioSource;
|
|
|
|
|
|
//Block Settings
|
|
public bool blockEnabled;
|
|
|
|
public bool blockActive;
|
|
|
|
public float generalBlockProtectionMultiplier = 1;
|
|
|
|
public string cancelBlockReactionStateName = "Disable Has Exit Time State";
|
|
|
|
public string mainMeleeCombatBlockInputName = "Block Attack";
|
|
|
|
public string blockActionName = "Block Close Combat";
|
|
|
|
public int blockID;
|
|
|
|
public bool blockActivePreviously;
|
|
|
|
public healthManagement mainHealth;
|
|
public playerInputManager playerInput;
|
|
|
|
public bool useMaxBlockRangeAngle;
|
|
public float maxBlockRangeAngle;
|
|
|
|
public float blockDamageProtectionAmount;
|
|
|
|
public float reducedBlockDamageProtectionAmount;
|
|
|
|
public bool reducedBlockDamageProtectionActive;
|
|
|
|
public bool canCancelBlockToStartAttackActive;
|
|
|
|
public bool blockInputPaused;
|
|
|
|
public bool useEventsOnBlockDamage;
|
|
public UnityEvent eventOnBlockActivate;
|
|
public UnityEvent eventOnBlockDeactivate;
|
|
|
|
public bool useEventsOnAttackCantBeBlocked;
|
|
public UnityEvent eventOnAttackCantBeBlocked;
|
|
|
|
public bool attackInputPaused;
|
|
|
|
public bool useStaminaOnAttackEnabled;
|
|
public bool attackInputPausedForStamina;
|
|
public string attackStaminaStateName = "Close Combat";
|
|
public float generalStaminaUseMultiplier = 1;
|
|
public staminaSystem mainStaminaSystem;
|
|
|
|
bool staminaSystemLocated;
|
|
|
|
public bool playerOnGroundToActivateAttack = true;
|
|
|
|
public bool ignoreGetHealthFromDamagingObjects = true;
|
|
|
|
public bool getHealthFromBlocks;
|
|
public float healthAmountFromBlocks = 1;
|
|
|
|
public bool getHealthFromPerfectBlocks;
|
|
public float healthAmountFromPerfectBlocks = 1;
|
|
|
|
//Gizmo Settings
|
|
public bool showDebugPrint;
|
|
|
|
public bool showGizmo;
|
|
public Color gizmoColor;
|
|
public float gizmoRadius;
|
|
public Color gizmoLabelColor;
|
|
|
|
int attackIDAnimatorID;
|
|
|
|
public bool canMoveStatePaused;
|
|
|
|
public bool rootMotionStateChanged;
|
|
|
|
public bool headTrackStateChanged;
|
|
|
|
public bool headTrackLookInOppositeDirectionStateChanged;
|
|
|
|
bool keepCameraRotationToHeadOnFullBodyAwarenessStateChanged;
|
|
|
|
bool combatModeActivatedTemporally;
|
|
|
|
public bool canUseAttacksWithoutCombatActiveEnabled;
|
|
|
|
public bool hideMeleeWeaponsOnExternalCombat = true;
|
|
public bool hideFireWeaponsOnExternalCombat;
|
|
|
|
bool carryingWeaponsPreviously;
|
|
|
|
|
|
Coroutine damageTriggerCoroutine;
|
|
|
|
damageTriggerActiveInfo currentTriggerInfo;
|
|
|
|
Coroutine eventInfoListCoroutine;
|
|
|
|
List<int> limbIndexListOnCurrentAttack = new List<int> ();
|
|
|
|
Coroutine resetAttackIDCoroutine;
|
|
|
|
bool currentAttackCanBeBlocked;
|
|
|
|
Coroutine pauseMeleeAttackInputCoroutine;
|
|
Coroutine pauseBlockInputCoroutine;
|
|
|
|
public bool activateCloseCombatSystemAtStart;
|
|
|
|
//Editor variables
|
|
public bool showMovementSettings;
|
|
public bool showMatchPositionSettings;
|
|
public bool showBlockSettings;
|
|
public bool showSurfaceSettings;
|
|
public bool showCombatLimbListSettings;
|
|
public bool showAttackListSettings;
|
|
|
|
public bool showEventsSettings;
|
|
|
|
public bool showDebugSettings;
|
|
public bool showAllSettings;
|
|
public bool showComponents;
|
|
|
|
bool checkIfActivateCloseCombatSystemAtStart;
|
|
|
|
bool gravityChangedActive;
|
|
public bool checkExternalControllerBehaviorActiveList;
|
|
|
|
public List<string> externalControllerBehaviorNameListToUseCloseCombat;
|
|
|
|
public bool usingAttacksOnAir;
|
|
|
|
public bool ignoreParryOnPerfectBlock;
|
|
|
|
float lastTimeClombatPlaying;
|
|
|
|
public bool useDelayToResetAttackIndex;
|
|
public float delayToResetAttackIndex;
|
|
float lastTimeCheckResetAttackIndex = 0;
|
|
|
|
public bool useAttackInputStack;
|
|
public int maxAmountOfAttackInputStack;
|
|
|
|
bool attackInputStackComplete;
|
|
|
|
List<string> attackInputStackList = new List<string> ();
|
|
|
|
bool attackInputStackActive;
|
|
|
|
bool ignoreAddAttackInputToStackActive;
|
|
|
|
bool playerInputLocated;
|
|
|
|
bool pauseCheckAlternativeAttackIfMovingActive = false;
|
|
|
|
[TextArea (3, 10)]
|
|
public string explanation = "Min Time To Play Next Attack field is the min time that will pass before the " +
|
|
"input is taken into account, as during that time, the attack input will be ignored, so the current attack " +
|
|
"can be played to at least that duration before allowing the next one.\n\n " +
|
|
"Make sure to match the values of duration and speed on the attack info and the animator for each attack animation.";
|
|
|
|
|
|
private void InitializeAudioElements ()
|
|
{
|
|
foreach (var surfaceInfoOnMeleeAttack in surfaceInfoOnMeleeAttackList) {
|
|
if (surfaceInfoOnMeleeAttack.soundsList != null && surfaceInfoOnMeleeAttack.soundsList.Count > 0) {
|
|
surfaceInfoOnMeleeAttack.soundsAudioElements = new List<AudioElement> ();
|
|
|
|
foreach (var sound in surfaceInfoOnMeleeAttack.soundsList) {
|
|
surfaceInfoOnMeleeAttack.soundsAudioElements.Add (new AudioElement { clip = sound });
|
|
}
|
|
}
|
|
|
|
if (mainAudioSource != null) {
|
|
foreach (var audioElement in surfaceInfoOnMeleeAttack.soundsAudioElements) {
|
|
audioElement.audioSource = mainAudioSource;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Start ()
|
|
{
|
|
InitializeAudioElements ();
|
|
|
|
attackIDAnimatorID = Animator.StringToHash (attackIDAnimatorName);
|
|
|
|
if (useStaminaOnAttackEnabled) {
|
|
staminaSystemLocated = mainStaminaSystem != null;
|
|
}
|
|
|
|
originalUseMatchTargetSystemOnAttack = useMatchTargetSystemOnAttack;
|
|
|
|
playerInputLocated = playerInput != null;
|
|
}
|
|
|
|
void Update ()
|
|
{
|
|
if (timerCombat > 0) {
|
|
timerCombat -= Time.deltaTime;
|
|
|
|
if (timerCombat < 0) {
|
|
if (useDelayToResetAttackIndex) {
|
|
if (lastTimeCheckResetAttackIndex == 0) {
|
|
ignoreResetAttackIndexActive = true;
|
|
|
|
disableCombat ();
|
|
|
|
lastTimeCheckResetAttackIndex = Time.time;
|
|
}
|
|
} else {
|
|
disableCombat ();
|
|
}
|
|
}
|
|
} else {
|
|
if (lastTimeCheckResetAttackIndex > 0) {
|
|
if (Time.time > lastTimeCheckResetAttackIndex + delayToResetAttackIndex) {
|
|
resetAttacksIndex (-1);
|
|
|
|
if (showDebugPrint) {
|
|
print ("reset index for delay to reset attack index");
|
|
}
|
|
|
|
lastTimeCheckResetAttackIndex = 0;
|
|
}
|
|
}
|
|
|
|
if (setCombatIdleID) {
|
|
if (setRegularIdleAfterAttackActive) {
|
|
if (!combatPlaying) {
|
|
if (lastTimeClombatPlaying != 0) {
|
|
if (!fullBodyAwarenessActive || !keepCombatIdleOnFBAActiveEnabled) {
|
|
if (Time.time > lastTimeClombatPlaying + minWaitToSetRegularIdAfterAttackActive) {
|
|
playerControllerManager.setCurrentIdleIDValue (0);
|
|
|
|
lastTimeClombatPlaying = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (lastTimeClombatPlaying != 0) {
|
|
lastTimeClombatPlaying = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (useAttackInputStack && attackInputStackActive) {
|
|
if (attackInputStackList.Count > 0 && !combatPlaying) {
|
|
ignoreAddAttackInputToStackActive = true;
|
|
|
|
useAttack (attackInputStackList [0]);
|
|
|
|
attackInputStackList.RemoveAt (0);
|
|
|
|
ignoreAddAttackInputToStackActive = false;
|
|
|
|
if (attackInputStackList.Count == 0) {
|
|
attackInputStackComplete = false;
|
|
|
|
attackInputStackActive = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!checkIfActivateCloseCombatSystemAtStart) {
|
|
if (activateCloseCombatSystemAtStart) {
|
|
setCurrentPlayerMode (true);
|
|
}
|
|
|
|
checkIfActivateCloseCombatSystemAtStart = true;
|
|
}
|
|
|
|
if (useAttackInputStack && attackInputStackActive) {
|
|
if (playerControllerManager.isActionActive ()) {
|
|
resetAttackInputStack ();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void disableCurrentAttackInProcess ()
|
|
{
|
|
stopAllAttacks ();
|
|
}
|
|
|
|
float currentWaitTimeToNextAttack = 0;
|
|
|
|
public bool canActivateAttack ()
|
|
{
|
|
if (currentWaitTimeToNextAttack == 0) {
|
|
return true;
|
|
} else {
|
|
if (Time.time > lastTimeComboAttack + currentWaitTimeToNextAttack) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
void playAttackByName (string attackName, string attackCategoryName)
|
|
{
|
|
combatTypeInfo combatTypeInfo = getCombatTypeInfoByName (attackCategoryName);
|
|
|
|
int attackIndex = combatTypeInfo.combatAttackInfoList.FindIndex (s => s.Name.Equals (attackName));
|
|
|
|
if (showDebugPrint) {
|
|
print ("checking alternative attack " + attackIndex + " " + attackCategoryName + " " + attackName);
|
|
}
|
|
|
|
if (attackIndex > -1) {
|
|
combatTypeInfo.currentAttackIndex = attackIndex;
|
|
|
|
combatTypeInfo.comboCounter = attackIndex - 1;
|
|
|
|
if (combatTypeInfo.comboCounter < 0) {
|
|
combatTypeInfo.comboCounter = 0;
|
|
}
|
|
|
|
combatTypeInfo.attackActive = attackIndex > 0;
|
|
|
|
if (showDebugPrint) {
|
|
print ("can play the alternative attack, calling use attack function");
|
|
}
|
|
|
|
useAttack (attackCategoryName);
|
|
}
|
|
}
|
|
|
|
public void useAttack (string attackName)
|
|
{
|
|
if (!canUseCombat ()) {
|
|
return;
|
|
}
|
|
|
|
if (useAttackInputStack && attackInputStackActive) {
|
|
if (attackInputStackComplete || attackInputStackList.Count >= maxAmountOfAttackInputStack) {
|
|
print ("stack complete, cancelling input");
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
bool canActivateAttackOnAir = false;
|
|
|
|
bool isPlayerOnGround = playerControllerManager.isPlayerOnGround ();
|
|
|
|
if (isPlayerOnGround) {
|
|
if (usingAttacksOnAir) {
|
|
|
|
usingAttacksOnAir = false;
|
|
}
|
|
|
|
} else {
|
|
if (playerOnGroundToActivateAttack) {
|
|
return;
|
|
} else {
|
|
canActivateAttackOnAir = true;
|
|
|
|
if (!usingAttacksOnAir) {
|
|
|
|
|
|
usingAttacksOnAir = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (showDebugPrint) {
|
|
print ("\n\n");
|
|
|
|
print (attackName);
|
|
}
|
|
|
|
if (usingAttacksOnAir) {
|
|
playerControllerManager.relaseJumpButtonIfAddForceWhileButtonPressedActive ();
|
|
}
|
|
|
|
int combatTypeInfoListCount = combatTypeInfoList.Count;
|
|
|
|
for (int i = 0; i < combatTypeInfoListCount; i++) {
|
|
|
|
bool canPlayAttack = true;
|
|
|
|
combatTypeInfo currentCombatTypeInfo = combatTypeInfoList [i];
|
|
|
|
if (combatTypeID == currentCombatTypeInfo.combatTypeID) {
|
|
|
|
if (isPlayerOnGround) {
|
|
if (currentCombatTypeInfo.attacksUsedOnAir) {
|
|
canPlayAttack = false;
|
|
}
|
|
} else {
|
|
if (!currentCombatTypeInfo.attacksUsedOnAir) {
|
|
canPlayAttack = false;
|
|
}
|
|
|
|
if (!canActivateAttackOnAir) {
|
|
canPlayAttack = false;
|
|
}
|
|
}
|
|
|
|
if (canPlayAttack && currentCombatTypeInfo.Name.Equals (attackName)) {
|
|
currentComboInProcessName = attackName;
|
|
|
|
//Check changes between previous and new combo
|
|
if (currentComboInProcessName != previousComboInProcessName && currentComboInProcessName != "" && previousComboInProcessName != "") {
|
|
|
|
if (showDebugPrint) {
|
|
print ("changing from " + previousComboInProcessName + " to " + currentComboInProcessName);
|
|
}
|
|
|
|
combatTypeInfo previousCombatTypeInfo = getCombatTypeInfoByName (previousComboInProcessName);
|
|
|
|
bool cancelCombo = false;
|
|
|
|
if (!previousCombatTypeInfo.canChangeOfComboWhenPreviousNotComplete) {
|
|
if (previousCombatTypeInfo.comboCounter < previousCombatTypeInfo.combatAttackInfoList.Count ||
|
|
previousCombatTypeInfo.attackActive) {
|
|
|
|
if (showDebugPrint) {
|
|
print ("trying to change of combo when current is not complete");
|
|
}
|
|
|
|
cancelCombo = true;
|
|
}
|
|
}
|
|
|
|
if (previousCombatTypeInfo.useMinTimeToChangeCombo) {
|
|
if (showDebugPrint) {
|
|
print ("checking if combo change is possible");
|
|
}
|
|
|
|
float minTimeToPlayNextAttack = previousCombatTypeInfo.combatAttackInfoList [previousCombatTypeInfo.comboCounter].minTimeToPlayNextAttack;
|
|
|
|
if (Time.time < lastTimeComboAttack + minTimeToPlayNextAttack) {
|
|
if (showDebugPrint) {
|
|
print ("change of combo is not possible yet for time");
|
|
}
|
|
|
|
cancelCombo = true;
|
|
|
|
currentWaitTimeToNextAttack = 0;
|
|
} else {
|
|
currentWaitTimeToNextAttack = minTimeToPlayNextAttack;
|
|
}
|
|
}
|
|
|
|
if (cancelCombo) {
|
|
if (showDebugPrint) {
|
|
print ("combo cancelled");
|
|
}
|
|
|
|
currentComboInProcessName = previousComboInProcessName;
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
previousComboInProcessName = currentComboInProcessName;
|
|
|
|
if (currentCombatTypeInfo.waitingToStartAttackActive) {
|
|
if (Time.time < currentCombatTypeInfo.lastTimeFullCombo + currentCombatTypeInfo.delayToStartAttackAfterFullCombo) {
|
|
|
|
return;
|
|
} else {
|
|
currentCombatTypeInfo.waitingToStartAttackActive = false;
|
|
}
|
|
}
|
|
|
|
//Check the info of the current attack to make from the selected combo
|
|
if (currentCombatTypeInfo.currentAttackIndex < currentCombatTypeInfo.combatAttackInfoList.Count) {
|
|
|
|
string debugInfo = combatTypeInfoList [i].Name;
|
|
|
|
bool newAttackPerformedCorrectly = false;
|
|
|
|
if (currentCombatTypeInfo.attackActive) {
|
|
|
|
combatAttackInfo currentCombatAttackInfo = currentCombatTypeInfo.combatAttackInfoList [currentCombatTypeInfo.comboCounter];
|
|
|
|
if (showDebugPrint) {
|
|
print ("Checking info of the combo counter of " + currentCombatAttackInfo.Name);
|
|
}
|
|
|
|
//checking if enough time has passed to allow to play the next attack
|
|
|
|
bool canPlayNextAttackWaitResult = false;
|
|
|
|
float minTimeToPlayNextAttack = currentCombatAttackInfo.minTimeToPlayNextAttack;
|
|
|
|
if (Time.time > lastTimeComboAttack + minTimeToPlayNextAttack || ignoreTimeToPlayNextAttackActive) {
|
|
canPlayNextAttackWaitResult = true;
|
|
}
|
|
|
|
if (canPlayNextAttackWaitResult) {
|
|
//check if the current attack can use the alternative attack if the character is moving
|
|
|
|
combatAttackInfo temporaryCombatAttackInfo = currentCombatTypeInfo.combatAttackInfoList [currentCombatTypeInfo.currentAttackIndex];
|
|
|
|
//print (temporaryCombatAttackInfo.Name + " " + temporaryCombatAttackInfo.useAlternativeAttackIfMoving);
|
|
|
|
if (temporaryCombatAttackInfo.useAlternativeAttackIfMoving && !pauseCheckAlternativeAttackIfMovingActive) {
|
|
if (isPlayerMoving ()) {
|
|
pauseCheckAlternativeAttackIfMovingActive = true;
|
|
|
|
playAttackByName (temporaryCombatAttackInfo.alternativeAttackIfMovingName, currentCombatTypeInfo.Name);
|
|
|
|
pauseCheckAlternativeAttackIfMovingActive = false;
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (canPlayNextAttackWaitResult) {
|
|
if (!currentCombatAttackInfo.playingNextAttack) {
|
|
if (showDebugPrint) {
|
|
print ("can play next attack");
|
|
}
|
|
|
|
currentCombatAttackInfo.playingNextAttack = true;
|
|
|
|
currentCombatTypeInfo.comboCounter++;
|
|
|
|
if (currentCombatTypeInfo.comboCounter < currentCombatTypeInfo.combatAttackInfoList.Count) {
|
|
|
|
stopResetAttackIdOnAnimatorCoroutine ();
|
|
|
|
resetAttackIDAnimatorID ();
|
|
|
|
combatAttackInfo nextAttackInfo = currentCombatTypeInfo.combatAttackInfoList [currentCombatTypeInfo.comboCounter];
|
|
|
|
bool useOnlyUpperBodyAnimationResult = false;
|
|
|
|
if (nextAttackInfo.useOnlyUpperBodyAnimationIfMoving) {
|
|
if (isPlayerMoving ()) {
|
|
useOnlyUpperBodyAnimationResult = true;
|
|
}
|
|
}
|
|
|
|
if (nextAttackInfo.ignoreAttackAnimationAndDamageTrigger) {
|
|
activateAttackWithoutAnimation (nextAttackInfo.Name);
|
|
} else {
|
|
if (nextAttackInfo.useAttackID) {
|
|
|
|
int nextAttackID = nextAttackInfo.attackID;
|
|
|
|
if (useOnlyUpperBodyAnimationResult) {
|
|
nextAttackID = nextAttackInfo.onlyUpperBodyAnimationIfMovingID;
|
|
}
|
|
|
|
animator.SetInteger (attackIDAnimatorID, nextAttackID);
|
|
|
|
resetAttackIdOnAnimator ();
|
|
} else {
|
|
string nextAttackName = nextAttackInfo.Name;
|
|
|
|
if (useOnlyUpperBodyAnimationResult) {
|
|
nextAttackName = nextAttackInfo.onlyUpperBodyAnimationIfMovingName;
|
|
}
|
|
|
|
animator.CrossFadeInFixedTime (nextAttackName, 0.1f);
|
|
}
|
|
}
|
|
|
|
if (showDebugPrint) {
|
|
print ("next attack " + nextAttackInfo.Name);
|
|
}
|
|
|
|
lastTimeComboAttack = Time.time;
|
|
|
|
newAttackPerformedCorrectly = true;
|
|
|
|
bool moveInputPausedResult = true;
|
|
|
|
if (nextAttackInfo.canMoveWhileAttackActive || useOnlyUpperBodyAnimationResult) {
|
|
moveInputPausedResult = false;
|
|
}
|
|
|
|
setMoveInputPausedState (moveInputPausedResult);
|
|
|
|
setRootMotionState (nextAttackInfo.useRootMotionOnAttack, nextAttackInfo.forceUseRootMotionActive);
|
|
|
|
setHeadTrackState (nextAttackInfo.pauseHeadTrackOnAttack);
|
|
|
|
setHeadTrackLookInOppositeDirection (nextAttackInfo.pauseHeadTrackLookInOppositeDirection);
|
|
|
|
checkKeepCameraRotationToHeadOnFullBodyAwareness (nextAttackInfo.keepCameraRotationToHeadOnFullBodyAwareness);
|
|
|
|
if (nextAttackInfo.disableGravityOnAttacks) {
|
|
disablePlayerGravityDuringAttack (true);
|
|
}
|
|
|
|
currentWaitTimeToNextAttack = minTimeToPlayNextAttack;
|
|
}
|
|
}
|
|
} else {
|
|
if (currentCombatAttackInfo.resetComboIfIncorrectMinTime) {
|
|
if (showDebugPrint) {
|
|
print ("incorrect timing, resetting combo when animation ends");
|
|
}
|
|
|
|
currentCombatTypeInfo.resetingCombo = true;
|
|
|
|
currentWaitTimeToNextAttack = 0;
|
|
} else {
|
|
if (showDebugPrint) {
|
|
print ("min wait time in process, cancelling");
|
|
}
|
|
|
|
if (useAttackInputStack && !attackInputStackComplete) {
|
|
if (!ignoreAddAttackInputToStackActive) {
|
|
if (attackInputStackList.Count < maxAmountOfAttackInputStack) {
|
|
attackInputStackList.Add (attackName);
|
|
|
|
attackInputStackActive = true;
|
|
} else {
|
|
attackInputStackComplete = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
currentCombatTypeInfo.attackActive = true;
|
|
|
|
combatAttackInfo currentCombatAttackInfo = currentCombatTypeInfo.combatAttackInfoList [0];
|
|
|
|
//print (currentCombatAttackInfo.Name + " " + currentCombatAttackInfo.useAlternativeAttackIfMoving);
|
|
|
|
//check if the current attack can use the alternative attack if the character is moving
|
|
|
|
if (currentCombatAttackInfo.useAlternativeAttackIfMoving && !pauseCheckAlternativeAttackIfMovingActive) {
|
|
if (isPlayerMoving ()) {
|
|
pauseCheckAlternativeAttackIfMovingActive = true;
|
|
|
|
playAttackByName (currentCombatAttackInfo.alternativeAttackIfMovingName, currentCombatTypeInfo.Name);
|
|
|
|
pauseCheckAlternativeAttackIfMovingActive = false;
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
stopResetAttackIdOnAnimatorCoroutine ();
|
|
|
|
resetAttackIDAnimatorID ();
|
|
|
|
bool useOnlyUpperBodyAnimationResult = false;
|
|
|
|
if (currentCombatAttackInfo.useOnlyUpperBodyAnimationIfMoving) {
|
|
if (isPlayerMoving ()) {
|
|
useOnlyUpperBodyAnimationResult = true;
|
|
}
|
|
}
|
|
|
|
if (currentCombatAttackInfo.ignoreAttackAnimationAndDamageTrigger) {
|
|
activateAttackWithoutAnimation (currentCombatAttackInfo.Name);
|
|
} else {
|
|
if (currentCombatAttackInfo.useAttackID) {
|
|
int nextAttackID = currentCombatAttackInfo.attackID;
|
|
|
|
if (useOnlyUpperBodyAnimationResult) {
|
|
nextAttackID = currentCombatAttackInfo.onlyUpperBodyAnimationIfMovingID;
|
|
}
|
|
|
|
animator.SetInteger (attackIDAnimatorID, nextAttackID);
|
|
|
|
resetAttackIdOnAnimator ();
|
|
} else {
|
|
string nextAttackName = currentCombatAttackInfo.Name;
|
|
|
|
if (useOnlyUpperBodyAnimationResult) {
|
|
nextAttackName = currentCombatAttackInfo.onlyUpperBodyAnimationIfMovingName;
|
|
}
|
|
|
|
animator.CrossFadeInFixedTime (nextAttackName, 0.1f);
|
|
}
|
|
}
|
|
|
|
if (showDebugPrint) {
|
|
print (" attack " + currentCombatAttackInfo.Name);
|
|
}
|
|
|
|
lastTimeComboAttack = Time.time;
|
|
|
|
newAttackPerformedCorrectly = true;
|
|
|
|
bool moveInputPausedResult = true;
|
|
|
|
if (currentCombatAttackInfo.canMoveWhileAttackActive || useOnlyUpperBodyAnimationResult) {
|
|
moveInputPausedResult = false;
|
|
}
|
|
|
|
setMoveInputPausedState (moveInputPausedResult);
|
|
|
|
setRootMotionState (currentCombatAttackInfo.useRootMotionOnAttack, currentCombatAttackInfo.forceUseRootMotionActive);
|
|
|
|
setHeadTrackState (currentCombatAttackInfo.pauseHeadTrackOnAttack);
|
|
|
|
setHeadTrackLookInOppositeDirection (currentCombatAttackInfo.pauseHeadTrackLookInOppositeDirection);
|
|
|
|
checkKeepCameraRotationToHeadOnFullBodyAwareness (currentCombatAttackInfo.keepCameraRotationToHeadOnFullBodyAwareness);
|
|
|
|
if (currentCombatAttackInfo.disableGravityOnAttacks) {
|
|
disablePlayerGravityDuringAttack (true);
|
|
}
|
|
}
|
|
|
|
combatPlaying = true;
|
|
|
|
if (setCombatIdleID) {
|
|
if (lastTimeClombatPlaying == 0) {
|
|
if (setCombatIdleAfterFirstAttack || setRegularIdleAfterAttackActive) {
|
|
lastTimeClombatPlaying = Time.time;
|
|
playerControllerManager.setCurrentIdleIDValue (combatIdleID);
|
|
}
|
|
}
|
|
}
|
|
|
|
playerControllerManager.setCloseCombatAttackInProcessState (true);
|
|
|
|
resetAttacksIndex (i);
|
|
|
|
bool increaseAttackIndex = false;
|
|
|
|
if (currentCombatTypeInfo.increaseAttackIndexOnlyOnAttackPerformedCorrectly) {
|
|
if (newAttackPerformedCorrectly) {
|
|
increaseAttackIndex = true;
|
|
}
|
|
} else {
|
|
increaseAttackIndex = true;
|
|
}
|
|
|
|
if (increaseAttackIndex) {
|
|
// add to the timer the time of the animation
|
|
timerCombat += (currentCombatTypeInfo.combatAttackInfoList [currentCombatTypeInfo.currentAttackIndex].attackDuration /
|
|
currentCombatTypeInfo.combatAttackInfoList [currentCombatTypeInfo.currentAttackIndex].animationSpeed);
|
|
|
|
currentCombatTypeInfo.currentAttackIndex++;
|
|
}
|
|
|
|
if (showDebugPrint) {
|
|
print (debugInfo + " performed correctly " + newAttackPerformedCorrectly + " increase index " + increaseAttackIndex);
|
|
}
|
|
|
|
lastTimeCheckResetAttackIndex = 0;
|
|
|
|
} else {
|
|
if (currentCombatTypeInfo.useDelayToStartAttackAfterFullCombo) {
|
|
currentCombatTypeInfo.waitingToStartAttackActive = true;
|
|
|
|
currentCombatTypeInfo.lastTimeFullCombo = Time.time;
|
|
} else {
|
|
if (useDelayToResetAttackIndex) {
|
|
if (lastTimeCheckResetAttackIndex > 0) {
|
|
resetAttacksIndex (-1);
|
|
|
|
if (showDebugPrint) {
|
|
print ("reset close combat index");
|
|
}
|
|
|
|
lastTimeCheckResetAttackIndex = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool isPlayerMoving ()
|
|
{
|
|
return (playerControllerManager.isPlayerUsingInput () ||
|
|
playerControllerManager.isPlayerMoving (0.4f) ||
|
|
isPlayerRawAxisPressed ());
|
|
}
|
|
|
|
bool isPlayerRawAxisPressed ()
|
|
{
|
|
if (playerInputLocated) {
|
|
return playerInput.getPlayerRawMovementAxis () != Vector2.zero;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public combatTypeInfo getCombatTypeInfoByName (string comboName)
|
|
{
|
|
int combatTypeInfoListCount = combatTypeInfoList.Count;
|
|
|
|
for (int i = 0; i < combatTypeInfoListCount; i++) {
|
|
combatTypeInfo currentCombatTypeInfo = combatTypeInfoList [i];
|
|
|
|
if (combatTypeID == currentCombatTypeInfo.combatTypeID) {
|
|
if (currentCombatTypeInfo.Name.Equals (comboName)) {
|
|
return currentCombatTypeInfo;
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public void setAttackStartState (string attackName)
|
|
{
|
|
int combatTypeInfoListCount = combatTypeInfoList.Count;
|
|
|
|
for (int i = 0; i < combatTypeInfoListCount; i++) {
|
|
combatTypeInfo currentCombatTypeInfo = combatTypeInfoList [i];
|
|
|
|
if (combatTypeID == currentCombatTypeInfo.combatTypeID) {
|
|
|
|
int combatAttackInfoListCount = currentCombatTypeInfo.combatAttackInfoList.Count;
|
|
|
|
for (int j = 0; j < combatAttackInfoListCount; j++) {
|
|
|
|
combatAttackInfo currentCombatAttackInfo = currentCombatTypeInfo.combatAttackInfoList [j];
|
|
|
|
if (currentCombatAttackInfo.Name.Equals (attackName)) {
|
|
|
|
if (currentCombatAttackInfo.useEventOnAttackStart) {
|
|
|
|
if (currentCombatAttackInfo.useDelayOnEventOnAttackStart) {
|
|
callEventWithDelay (currentCombatAttackInfo, true);
|
|
} else {
|
|
currentCombatAttackInfo.eventOnAttackStart.Invoke ();
|
|
}
|
|
}
|
|
|
|
if (showDebugPrint) {
|
|
print ("starting " + attackName);
|
|
}
|
|
|
|
changeCollidersState (true, currentCombatAttackInfo.limbForAttack, i, j);
|
|
|
|
checkEventInfoList (currentCombatAttackInfo);
|
|
|
|
if (currentCombatAttackInfo.useExtraDamageMultiplier) {
|
|
setCollidersExtraDamageValue (currentCombatAttackInfo.extraDamageMultiplier);
|
|
} else {
|
|
setCollidersExtraDamageValue (1);
|
|
}
|
|
|
|
if (useMatchTargetSystemOnAttack && !usingAttacksOnAir) {
|
|
|
|
if (currentCombatAttackInfo.useMatchPositionSystem || ignoreAttackSettingToMatchTarget) {
|
|
float currentMatchOffset = mainMatchPositionOffset;
|
|
|
|
if (!useMainMatchPositionOffset) {
|
|
currentMatchOffset = currentCombatAttackInfo.matchPositionOffset;
|
|
}
|
|
|
|
mainMatchPlayerToTargetSystem.activateMatchPosition (currentMatchOffset);
|
|
}
|
|
}
|
|
|
|
if (useStaminaOnAttackEnabled) {
|
|
if (currentCombatAttackInfo.useStaminaOnAttack) {
|
|
if (staminaSystemLocated) {
|
|
mainStaminaSystem.activeStaminaStateWithCustomAmount (attackStaminaStateName,
|
|
currentCombatAttackInfo.staminaUsedOnAttack * generalStaminaUseMultiplier,
|
|
currentCombatAttackInfo.customRefillStaminaDelayAfterUse);
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void setGeneralStaminaUseMultiplierValue (float newValue)
|
|
{
|
|
generalStaminaUseMultiplier = newValue;
|
|
}
|
|
|
|
public void setAttackInputPausedForStaminaState (bool state)
|
|
{
|
|
attackInputPausedForStamina = state;
|
|
}
|
|
|
|
public void setAttackEndState (string attackName)
|
|
{
|
|
int combatTypeInfoListCount = combatTypeInfoList.Count;
|
|
|
|
for (int i = 0; i < combatTypeInfoListCount; i++) {
|
|
combatTypeInfo currentCombatTypeInfo = combatTypeInfoList [i];
|
|
|
|
if (combatTypeID == currentCombatTypeInfo.combatTypeID) {
|
|
|
|
int combatAttackInfoListCount = currentCombatTypeInfo.combatAttackInfoList.Count;
|
|
|
|
for (int j = 0; j < combatAttackInfoListCount; j++) {
|
|
|
|
combatAttackInfo currentCombatAttackInfo = currentCombatTypeInfo.combatAttackInfoList [j];
|
|
|
|
if (currentCombatAttackInfo.Name.Equals (attackName)) {
|
|
if (showDebugPrint) {
|
|
print ("end " + attackName);
|
|
}
|
|
|
|
if (currentCombatAttackInfo.useEventOnAttackEnd) {
|
|
if (currentCombatAttackInfo.useDelayOnEventOnAttackEnd) {
|
|
callEventWithDelay (currentCombatAttackInfo, false);
|
|
} else {
|
|
currentCombatAttackInfo.eventOnAttackEnd.Invoke ();
|
|
}
|
|
}
|
|
|
|
if (currentCombatTypeInfo.resetingCombo) {
|
|
if (showDebugPrint) {
|
|
print ("reset combo");
|
|
}
|
|
|
|
disableCombat ();
|
|
|
|
return;
|
|
}
|
|
|
|
if ((currentCombatTypeInfo.currentAttackIndex - 1) > currentCombatTypeInfo.comboCounter || currentCombatAttackInfo.playingNextAttack) {
|
|
if (currentCombatTypeInfo.comboCounter <= j) {
|
|
currentCombatAttackInfo.playingNextAttack = false;
|
|
|
|
currentCombatTypeInfo.comboCounter++;
|
|
|
|
if (currentCombatTypeInfo.comboCounter < currentCombatTypeInfo.combatAttackInfoList.Count) {
|
|
combatAttackInfo attackToUse = currentCombatTypeInfo.combatAttackInfoList [currentCombatTypeInfo.comboCounter];
|
|
|
|
stopResetAttackIdOnAnimatorCoroutine ();
|
|
|
|
resetAttackIDAnimatorID ();
|
|
|
|
bool useOnlyUpperBodyAnimationResult = false;
|
|
|
|
if (attackToUse.useOnlyUpperBodyAnimationIfMoving) {
|
|
if (isPlayerMoving ()) {
|
|
useOnlyUpperBodyAnimationResult = true;
|
|
}
|
|
}
|
|
|
|
if (attackToUse.ignoreAttackAnimationAndDamageTrigger) {
|
|
activateAttackWithoutAnimation (attackToUse.Name);
|
|
} else {
|
|
if (attackToUse.useAttackID) {
|
|
int nextAttackID = attackToUse.attackID;
|
|
|
|
if (useOnlyUpperBodyAnimationResult) {
|
|
nextAttackID = attackToUse.onlyUpperBodyAnimationIfMovingID;
|
|
}
|
|
|
|
animator.SetInteger (attackIDAnimatorID, nextAttackID);
|
|
|
|
resetAttackIdOnAnimator ();
|
|
} else {
|
|
string nextAttackName = attackToUse.Name;
|
|
|
|
if (useOnlyUpperBodyAnimationResult) {
|
|
nextAttackName = attackToUse.onlyUpperBodyAnimationIfMovingName;
|
|
}
|
|
|
|
animator.CrossFadeInFixedTime (nextAttackName, 0.1f);
|
|
}
|
|
}
|
|
|
|
lastTimeComboAttack = Time.time;
|
|
|
|
if (showDebugPrint) {
|
|
print ("next attack " + attackToUse.Name);
|
|
}
|
|
|
|
bool moveInputPausedResult = true;
|
|
|
|
if (attackToUse.canMoveWhileAttackActive || useOnlyUpperBodyAnimationResult) {
|
|
moveInputPausedResult = false;
|
|
}
|
|
|
|
setMoveInputPausedState (moveInputPausedResult);
|
|
|
|
setRootMotionState (currentCombatAttackInfo.useRootMotionOnAttack, currentCombatAttackInfo.forceUseRootMotionActive);
|
|
|
|
setHeadTrackState (currentCombatAttackInfo.pauseHeadTrackOnAttack);
|
|
|
|
setHeadTrackLookInOppositeDirection (currentCombatAttackInfo.pauseHeadTrackLookInOppositeDirection);
|
|
|
|
checkKeepCameraRotationToHeadOnFullBodyAwareness (currentCombatAttackInfo.keepCameraRotationToHeadOnFullBodyAwareness);
|
|
|
|
if (currentCombatAttackInfo.disableGravityOnAttacks) {
|
|
disablePlayerGravityDuringAttack (true);
|
|
}
|
|
}
|
|
} else {
|
|
if (showDebugPrint) {
|
|
print ("combo counter higher than attack index " + currentCombatTypeInfo.comboCounter);
|
|
}
|
|
}
|
|
} else {
|
|
if (currentCombatTypeInfo.attackActive) {
|
|
if (showDebugPrint) {
|
|
print ("combo is over");
|
|
}
|
|
|
|
if (useDelayToResetAttackIndex) {
|
|
if (lastTimeCheckResetAttackIndex == 0) {
|
|
ignoreResetAttackIndexActive = true;
|
|
|
|
disableCombat ();
|
|
|
|
lastTimeCheckResetAttackIndex = Time.time;
|
|
}
|
|
} else {
|
|
disableCombat ();
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void resetAttacksIndex (int combatTypeIndexToIgnore)
|
|
{
|
|
bool otherAttacksTypeActive = false;
|
|
|
|
int combatTypeInfoListCount = combatTypeInfoList.Count;
|
|
|
|
for (int i = 0; i < combatTypeInfoListCount; i++) {
|
|
combatTypeInfo currentCombatTypeInfo = combatTypeInfoList [i];
|
|
|
|
if (combatTypeID == currentCombatTypeInfo.combatTypeID) {
|
|
if (i != combatTypeIndexToIgnore && currentCombatTypeInfo.attackActive) {
|
|
|
|
currentCombatTypeInfo.attackActive = false;
|
|
|
|
currentCombatTypeInfo.resetingCombo = false;
|
|
|
|
currentCombatTypeInfo.currentAttackIndex = 0;
|
|
|
|
currentCombatTypeInfo.comboCounter = 0;
|
|
|
|
int combatAttackInfoListCount = currentCombatTypeInfo.combatAttackInfoList.Count;
|
|
|
|
for (int j = 0; j < combatAttackInfoListCount; j++) {
|
|
currentCombatTypeInfo.combatAttackInfoList [j].playingNextAttack = false;
|
|
}
|
|
|
|
otherAttacksTypeActive = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (otherAttacksTypeActive) {
|
|
timerCombat = 0;
|
|
}
|
|
|
|
pauseCheckAlternativeAttackIfMovingActive = false;
|
|
}
|
|
|
|
public void setDamageDetectedOnTriggerById (int newId)
|
|
{
|
|
combatLimbInfo currentcombatLimbInfo = combatLimbList [newId];
|
|
|
|
checkEventOnDamage (currentcombatLimbInfo.hitCombatManager.currentCombatTypeIndex,
|
|
currentcombatLimbInfo.hitCombatManager.currentAttackIndex,
|
|
currentcombatLimbInfo.hitCombatManager.getLastSurfaceDetected (),
|
|
newId);
|
|
}
|
|
|
|
public void checkEventOnDamage (int combatTypeIndex, int attackIndex, GameObject objectDetected, int combatLimbID)
|
|
{
|
|
if (combatTypeInfoList.Count > combatTypeIndex) {
|
|
|
|
combatTypeInfo currentCombatTypeInfo = combatTypeInfoList [combatTypeIndex];
|
|
|
|
if (currentCombatTypeInfo.combatAttackInfoList.Count > attackIndex) {
|
|
combatAttackInfo currentCombatAttackInfo = currentCombatTypeInfo.combatAttackInfoList [attackIndex];
|
|
|
|
if (currentCombatAttackInfo != null) {
|
|
if (currentCombatAttackInfo.useEventOnDamage) {
|
|
currentCombatAttackInfo.eventOnDamage.Invoke ();
|
|
}
|
|
|
|
if (currentCombatAttackInfo.useRemoteEvent) {
|
|
bool useRemoteEvents = false;
|
|
|
|
if (objectDetected != null) {
|
|
if (currentCombatAttackInfo.checkObjectsToUseRemoteEventsOnDamage) {
|
|
if ((1 << objectDetected.layer & currentCombatAttackInfo.layerToUseRemoteEventsOnDamage.value) == 1 << objectDetected.layer) {
|
|
useRemoteEvents = true;
|
|
}
|
|
} else {
|
|
useRemoteEvents = true;
|
|
}
|
|
|
|
if (useRemoteEvents) {
|
|
remoteEventSystem currentRemoteEventSystem = objectDetected.GetComponent<remoteEventSystem> ();
|
|
|
|
if (currentRemoteEventSystem != null) {
|
|
int remoteEventNameListCount = currentCombatAttackInfo.remoteEventNameList.Count;
|
|
|
|
for (int j = 0; j < remoteEventNameListCount; j++) {
|
|
currentRemoteEventSystem.callRemoteEvent (currentCombatAttackInfo.remoteEventNameList [j]);
|
|
}
|
|
|
|
if (currentCombatAttackInfo.useRemoteEventWithString) {
|
|
currentRemoteEventSystem.callRemoteEventWithString (currentCombatAttackInfo.remoteEventWithStringName,
|
|
currentCombatAttackInfo.remoteEventString);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (objectDetected != null) {
|
|
checkSurfaceFoundOnAttack (true, objectDetected, combatLimbID);
|
|
|
|
if (!ignoreGetHealthFromDamagingObjects) {
|
|
if (currentCombatAttackInfo.getHealthFromDamagingObjects) {
|
|
float totalHealthAmount = combatLimbList [combatLimbID].hitCombatManager.getLastDamageApplied ()
|
|
* currentCombatAttackInfo.healthFromDamagingObjectsMultiplier;
|
|
|
|
if (totalHealthAmount > 0 && !mainHealth.checkIfMaxHealthWithHealthManagement ()) {
|
|
|
|
mainHealth.setHealWithHealthManagement (totalHealthAmount);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void activateAttackWithoutAnimation (string attackName)
|
|
{
|
|
StartCoroutine (activateAttackWithoutAnimationCoroutine (attackName));
|
|
}
|
|
IEnumerator activateAttackWithoutAnimationCoroutine (string attackName)
|
|
{
|
|
WaitForSeconds delay = new WaitForSeconds (0.03f);
|
|
|
|
yield return delay;
|
|
|
|
setAttackStartState (attackName);
|
|
}
|
|
|
|
public void resetAttackIdOnAnimator ()
|
|
{
|
|
stopResetAttackIdOnAnimatorCoroutine ();
|
|
|
|
resetAttackIDCoroutine = StartCoroutine (resetAttackIdOnAnimatorCoroutine ());
|
|
}
|
|
|
|
void stopResetAttackIdOnAnimatorCoroutine ()
|
|
{
|
|
if (resetAttackIDCoroutine != null) {
|
|
StopCoroutine (resetAttackIDCoroutine);
|
|
}
|
|
}
|
|
|
|
IEnumerator resetAttackIdOnAnimatorCoroutine ()
|
|
{
|
|
WaitForSeconds delay = new WaitForSeconds (0.1f);
|
|
|
|
yield return delay;
|
|
|
|
resetAttackIDAnimatorID ();
|
|
}
|
|
|
|
public void callEventWithDelay (combatAttackInfo currentCombatAttackInfoEvent, bool playAtStart)
|
|
{
|
|
if (currentCombatAttackInfoEvent.delayCoroutine != null) {
|
|
StopCoroutine (currentCombatAttackInfoEvent.delayCoroutine);
|
|
}
|
|
|
|
currentCombatAttackInfoEvent.delayCoroutine = StartCoroutine (callEventWithDelayCoroutine (currentCombatAttackInfoEvent, playAtStart));
|
|
}
|
|
|
|
IEnumerator callEventWithDelayCoroutine (combatAttackInfo currentCombatAttackInfoEvent, bool playAtStart)
|
|
{
|
|
if (playAtStart) {
|
|
WaitForSeconds delay = new WaitForSeconds (currentCombatAttackInfoEvent.delayOnEventOnAttackStart);
|
|
|
|
yield return delay;
|
|
|
|
currentCombatAttackInfoEvent.eventOnAttackStart.Invoke ();
|
|
} else {
|
|
WaitForSeconds delay = new WaitForSeconds (currentCombatAttackInfoEvent.delayOnEventOnAttackEnd);
|
|
|
|
yield return delay;
|
|
|
|
currentCombatAttackInfoEvent.eventOnAttackStart.Invoke ();
|
|
}
|
|
}
|
|
|
|
bool canUseCombat ()
|
|
{
|
|
if (currentPlayerMode) {
|
|
bool canUseCombatResult = true;
|
|
|
|
if (!combatSystemEnabled) {
|
|
canUseCombatResult = false;
|
|
}
|
|
|
|
if (playerControllerManager.isGravityPowerActive ()) {
|
|
canUseCombatResult = false;
|
|
}
|
|
|
|
if (playerControllerManager.isPlayerUsingPowers ()) {
|
|
canUseCombatResult = false;
|
|
}
|
|
|
|
if (playerControllerManager.isPlayerUsingWeapons () && !combatModeActivatedTemporally) {
|
|
canUseCombatResult = false;
|
|
}
|
|
|
|
if (!canUseInput ()) {
|
|
canUseCombatResult = false;
|
|
}
|
|
|
|
if (playerControllerManager.isPlayerNavMeshEnabled ()) {
|
|
canUseCombatResult = false;
|
|
}
|
|
|
|
if (playerControllerManager.isExternalControllBehaviorActive ()) {
|
|
if (checkExternalControllerBehaviorActiveList) {
|
|
if (!externalControllerBehaviorNameListToUseCloseCombat.Contains (playerControllerManager.getCurrentExternalControllerBehaviorName ())) {
|
|
canUseCombatResult = false;
|
|
|
|
if (showDebugPrint) {
|
|
print ("External Controller behavior active not included on the behavior " +
|
|
"list " + playerControllerManager.getCurrentExternalControllerBehaviorName () + ", avoid to use close combat");
|
|
}
|
|
}
|
|
} else {
|
|
canUseCombatResult = false;
|
|
|
|
if (showDebugPrint) {
|
|
print ("External Controller behavior active, avoid to use close combat");
|
|
}
|
|
}
|
|
}
|
|
|
|
return canUseCombatResult;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool canUseInput ()
|
|
{
|
|
if (playerControllerManager.isUsingDevice ()) {
|
|
return false;
|
|
}
|
|
|
|
if (playerControllerManager.isPlayerDead ()) {
|
|
return false;
|
|
}
|
|
|
|
if (playerControllerManager.isTurnBasedCombatActionActive ()) {
|
|
return true;
|
|
}
|
|
|
|
if (playerControllerManager.isPlayerMenuActive ()) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public void activateNextAttackIgnoringWaitingTimes ()
|
|
{
|
|
if (combatPlaying) {
|
|
if (currentComboInProcessName != "") {
|
|
ignoreTimeToPlayNextAttackActive = true;
|
|
|
|
ignoreAddAttackInputToStackActive = true;
|
|
|
|
useAttack (currentComboInProcessName);
|
|
|
|
ignoreTimeToPlayNextAttackActive = false;
|
|
|
|
ignoreAddAttackInputToStackActive = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool ignoreTimeToPlayNextAttackActive;
|
|
|
|
public void activateAttackWithoutCombatActive (string attackName)
|
|
{
|
|
if (!canUseAttacksWithoutCombatActiveEnabled) {
|
|
return;
|
|
}
|
|
|
|
if (currentPlayerMode && !combatModeActivatedTemporally) {
|
|
return;
|
|
}
|
|
|
|
if (!canUseInput ()) {
|
|
return;
|
|
}
|
|
|
|
if (playerControllerManager.isActionActive ()) {
|
|
return;
|
|
}
|
|
|
|
if (!playerControllerManager.checkPlayerIsNotCarringWeapons ()) {
|
|
return;
|
|
}
|
|
|
|
if (playerControllerManager.isIgnoreExternalActionsActiveState ()) {
|
|
return;
|
|
}
|
|
|
|
combatModeActivatedTemporally = true;
|
|
|
|
currentPlayerMode = true;
|
|
|
|
enableOrDisableCloseCombatTriggers (true);
|
|
|
|
playerControllerManager.setUsingCloseCombatActiveState (currentPlayerMode);
|
|
|
|
if (ignoreParryOnPerfectBlock) {
|
|
mainHealth.setIgnoreParryActiveState (true);
|
|
}
|
|
|
|
inputAttack (attackName);
|
|
|
|
|
|
if (!combatPlaying) {
|
|
print ("attack wasn't able to be activated, cancelling temporal state");
|
|
|
|
disableCombatModeActivatedTemporallyValues ();
|
|
} else {
|
|
carryingWeaponsPreviously = GKC_Utils.enableOrDisableIKOnWeaponsDuringAction (playerControllerManager.gameObject, false);
|
|
|
|
if (hideFireWeaponsOnExternalCombat) {
|
|
GKC_Utils.enableOrDisableFireWeaponMeshActiveState (playerControllerManager.gameObject, false);
|
|
}
|
|
|
|
if (hideMeleeWeaponsOnExternalCombat) {
|
|
GKC_Utils.enableOrDisableMeleeWeaponMeshActiveState (playerControllerManager.gameObject, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void setCurrentPlayerMode (bool state)
|
|
{
|
|
if (currentPlayerMode == state) {
|
|
return;
|
|
}
|
|
|
|
currentPlayerMode = state;
|
|
|
|
playerControllerManager.setUsingCloseCombatActiveState (currentPlayerMode);
|
|
|
|
if (ignoreParryOnPerfectBlock) {
|
|
if (currentPlayerMode) {
|
|
mainHealth.setIgnoreParryActiveState (true);
|
|
} else {
|
|
mainHealth.setIgnoreParryActiveState (false);
|
|
}
|
|
}
|
|
|
|
checkEventsOnStateChange (currentPlayerMode);
|
|
|
|
if (currentPlayerMode) {
|
|
enableOrDisableCloseCombatTriggers (true);
|
|
|
|
if (setCombatIdleID) {
|
|
if (!setCombatIdleAfterFirstAttack) {
|
|
playerControllerManager.setCurrentIdleIDValue (combatIdleID);
|
|
|
|
lastTimeClombatPlaying = Time.time;
|
|
}
|
|
}
|
|
} else {
|
|
if (timerCombat <= 0) {
|
|
enableOrDisableCloseCombatTriggers (false);
|
|
}
|
|
|
|
if (setCombatIdleID) {
|
|
playerControllerManager.setCurrentIdleIDValue (0);
|
|
}
|
|
}
|
|
|
|
if (toggleStrafeModeIfRunningActive) {
|
|
playerControllerManager.setDisableStrafeModeExternallyIfIncreaseWalkSpeedActiveState (currentPlayerMode);
|
|
}
|
|
|
|
if (currentPlayerMode) {
|
|
previousStrafeMode = playerControllerManager.isStrafeModeActive ();
|
|
|
|
if (previousStrafeID == -1) {
|
|
previousStrafeID = playerControllerManager.getCurrentStrafeIDValue ();
|
|
}
|
|
|
|
if (useStrafeMode) {
|
|
playerControllerManager.activateOrDeactivateStrafeMode (useStrafeMode);
|
|
|
|
playerControllerManager.setCurrentStrafeIDValue (strafeIDUsed);
|
|
}
|
|
|
|
} else {
|
|
if (useStrafeMode) {
|
|
if (setPreviousStrafeModeOnDisableMode) {
|
|
playerControllerManager.activateOrDeactivateStrafeMode (previousStrafeMode);
|
|
} else {
|
|
playerControllerManager.setOriginalLookAlwaysInCameraDirectionState ();
|
|
}
|
|
|
|
if (previousStrafeID != -1) {
|
|
playerControllerManager.setCurrentStrafeIDValue (previousStrafeID);
|
|
}
|
|
}
|
|
|
|
previousStrafeMode = false;
|
|
|
|
previousStrafeID = -1;
|
|
}
|
|
|
|
if (!currentPlayerMode) {
|
|
if (blockActive) {
|
|
blockActivePreviously = false;
|
|
|
|
disableBlockState ();
|
|
}
|
|
|
|
blockActive = false;
|
|
|
|
if (attackInputPaused) {
|
|
stopDisableMeleeAttackInputPausedStateWithDurationCoroutine ();
|
|
|
|
attackInputPaused = false;
|
|
}
|
|
}
|
|
|
|
bool isFullBodyAwarenessActive = playerControllerManager.isFullBodyAwarenessActive ();
|
|
|
|
setFullBodyAwarenessActiveState (isFullBodyAwarenessActive);
|
|
|
|
lastTimeCheckResetAttackIndex = 0;
|
|
|
|
if (useAttackInputStack && attackInputStackActive) {
|
|
resetAttackInputStack ();
|
|
}
|
|
}
|
|
|
|
public void resetIdleStateOnCloseCombat ()
|
|
{
|
|
if (setCombatIdleID) {
|
|
if (setRegularIdleAfterAttackActive) {
|
|
if (lastTimeClombatPlaying != 0) {
|
|
if (!fullBodyAwarenessActive || !keepCombatIdleOnFBAActiveEnabled) {
|
|
playerControllerManager.setCurrentIdleIDValue (0);
|
|
|
|
lastTimeClombatPlaying = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void resetAttackInputStack ()
|
|
{
|
|
if (attackInputStackActive) {
|
|
attackInputStackList.Clear ();
|
|
|
|
attackInputStackActive = false;
|
|
|
|
attackInputStackComplete = false;
|
|
}
|
|
}
|
|
|
|
public void enableOrDisableUseAttackInputStack (bool state)
|
|
{
|
|
useAttackInputStack = state;
|
|
}
|
|
|
|
public void checkEventsOnStateChange (bool state)
|
|
{
|
|
if (useEventsOnStateChange) {
|
|
if (state) {
|
|
evenOnStateEnabled.Invoke ();
|
|
} else {
|
|
eventOnStateDisabled.Invoke ();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void checkEventsOnFBAStateChange (bool state)
|
|
{
|
|
if (useEventOnFBAViewChange) {
|
|
if (state) {
|
|
eventOnEnableFBA.Invoke ();
|
|
} else {
|
|
eventOnDisableFBA.Invoke ();
|
|
}
|
|
}
|
|
}
|
|
|
|
//the combo has finished, so disable the combat mode
|
|
|
|
bool ignoreResetAttackIndexActive;
|
|
|
|
void disableCombat ()
|
|
{
|
|
if (!ignoreResetAttackIndexActive) {
|
|
resetAttacksIndex (-1);
|
|
}
|
|
|
|
timerCombat = 0;
|
|
|
|
changeCollidersState (false, colliderPlace.both, -1, -1);
|
|
|
|
combatPlaying = false;
|
|
|
|
previousComboInProcessName = "";
|
|
currentComboInProcessName = "";
|
|
|
|
resetAttackIDAnimatorID ();
|
|
|
|
stopResetAttackIdOnAnimatorCoroutine ();
|
|
|
|
if (canMoveStatePaused) {
|
|
setMoveInputPausedState (false);
|
|
}
|
|
|
|
if (rootMotionStateChanged) {
|
|
setRootMotionState (false, false);
|
|
}
|
|
|
|
if (headTrackStateChanged) {
|
|
setHeadTrackState (false);
|
|
}
|
|
|
|
if (headTrackLookInOppositeDirectionStateChanged) {
|
|
setHeadTrackLookInOppositeDirection (false);
|
|
}
|
|
|
|
if (!currentPlayerMode) {
|
|
enableOrDisableCloseCombatTriggers (false);
|
|
}
|
|
|
|
if (gravityChangedActive) {
|
|
disablePlayerGravityDuringAttack (false);
|
|
}
|
|
|
|
if (keepCameraRotationToHeadOnFullBodyAwarenessStateChanged) {
|
|
checkKeepCameraRotationToHeadOnFullBodyAwareness (false);
|
|
}
|
|
|
|
blockActivePreviously = false;
|
|
|
|
currentWaitTimeToNextAttack = 0;
|
|
|
|
if (combatModeActivatedTemporally) {
|
|
|
|
disableCombatModeActivatedTemporallyValues ();
|
|
}
|
|
|
|
playerControllerManager.setCloseCombatAttackInProcessState (false);
|
|
|
|
lastTimeClombatPlaying = Time.time;
|
|
|
|
ignoreResetAttackIndexActive = false;
|
|
|
|
lastTimeCheckResetAttackIndex = 0;
|
|
}
|
|
|
|
void disableCombatModeActivatedTemporallyValues ()
|
|
{
|
|
if (combatModeActivatedTemporally) {
|
|
currentPlayerMode = false;
|
|
|
|
enableOrDisableCloseCombatTriggers (false);
|
|
|
|
playerControllerManager.setUsingCloseCombatActiveState (false);
|
|
|
|
if (ignoreParryOnPerfectBlock) {
|
|
mainHealth.setIgnoreParryActiveState (false);
|
|
}
|
|
|
|
combatModeActivatedTemporally = false;
|
|
|
|
if (carryingWeaponsPreviously) {
|
|
GKC_Utils.enableOrDisableIKOnWeaponsDuringAction (playerControllerManager.gameObject, true);
|
|
|
|
carryingWeaponsPreviously = false;
|
|
}
|
|
|
|
if (hideMeleeWeaponsOnExternalCombat) {
|
|
GKC_Utils.enableOrDisableMeleeWeaponMeshActiveState (playerControllerManager.gameObject, true);
|
|
}
|
|
|
|
if (hideFireWeaponsOnExternalCombat) {
|
|
GKC_Utils.enableOrDisableFireWeaponMeshActiveState (playerControllerManager.gameObject, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool isAttackInProcess ()
|
|
{
|
|
return combatPlaying;
|
|
}
|
|
|
|
void setMoveInputPausedState (bool state)
|
|
{
|
|
if (canMoveStatePaused != state) {
|
|
playerControllerManager.setMoveInputPausedState (state);
|
|
|
|
if (state) {
|
|
playerControllerManager.resetPlayerControllerInput ();
|
|
}
|
|
}
|
|
|
|
canMoveStatePaused = state;
|
|
}
|
|
|
|
void setRootMotionState (bool state, bool forceUseRootMotionActive)
|
|
{
|
|
if (rootMotionStateChanged != state) {
|
|
playerControllerManager.setApplyRootMotionAlwaysActiveState (state);
|
|
|
|
playerControllerManager.setActionActiveWithMovementState (state);
|
|
|
|
playerControllerManager.setForceUseRootMotionActiveState (forceUseRootMotionActive);
|
|
}
|
|
|
|
rootMotionStateChanged = state;
|
|
}
|
|
|
|
void setHeadTrackState (bool state)
|
|
{
|
|
if (headTrackStateChanged != state) {
|
|
playerControllerManager.setHeadTrackCanBeUsedState (!state);
|
|
}
|
|
|
|
headTrackStateChanged = state;
|
|
}
|
|
|
|
void setHeadTrackLookInOppositeDirection (bool state)
|
|
{
|
|
if (headTrackLookInOppositeDirectionStateChanged != state) {
|
|
if (mainHeadTrack != null) {
|
|
mainHeadTrack.setLookInOppositeDirectionOutOfRangeValue (!state);
|
|
}
|
|
}
|
|
|
|
headTrackLookInOppositeDirectionStateChanged = state;
|
|
}
|
|
|
|
void checkKeepCameraRotationToHeadOnFullBodyAwareness (bool state)
|
|
{
|
|
// print (fullBodyAwarenessActive);
|
|
|
|
if (keepCameraRotationToHeadOnFullBodyAwarenessStateChanged != state) {
|
|
if (fullBodyAwarenessActive) {
|
|
if (state) {
|
|
playerControllerManager.setPivotCameraTransformParentCurrentTransformToFollow ();
|
|
} else {
|
|
playerControllerManager.setPivotCameraTransformOriginalParent ();
|
|
|
|
playerControllerManager.resetPivotCameraTransformLocalRotation ();
|
|
}
|
|
}
|
|
}
|
|
|
|
keepCameraRotationToHeadOnFullBodyAwarenessStateChanged = state;
|
|
}
|
|
|
|
bool fullBodyAwarenessActive;
|
|
|
|
void setFullBodyAwarenessActiveState (bool state)
|
|
{
|
|
if (fullBodyAwarenessActive == state && !state) {
|
|
return;
|
|
}
|
|
|
|
fullBodyAwarenessActive = state;
|
|
|
|
if (fullBodyAwarenessActive && currentPlayerMode) {
|
|
mainHeadTrack.setCameraBodyWeightValue (1);
|
|
} else {
|
|
mainHeadTrack.setOriginalCameraBodyWeightValue ();
|
|
}
|
|
|
|
if (currentPlayerMode) {
|
|
if (fullBodyAwarenessActive) {
|
|
if (setCombatIdleID) {
|
|
if (keepCombatIdleOnFBAActiveEnabled) {
|
|
playerControllerManager.setCurrentIdleIDValue (combatIdleID);
|
|
|
|
lastTimeClombatPlaying = Time.time;
|
|
}
|
|
}
|
|
} else {
|
|
if (setCombatIdleID) {
|
|
playerControllerManager.setCurrentIdleIDValue (0);
|
|
}
|
|
}
|
|
}
|
|
|
|
checkEventsOnFBAStateChange (state);
|
|
}
|
|
|
|
public void checkIfFullBodyAwarenessActive ()
|
|
{
|
|
if (currentPlayerMode) {
|
|
bool isFullBodyAwarenessActive = playerControllerManager.isFullBodyAwarenessActive ();
|
|
|
|
if (isFullBodyAwarenessActive != fullBodyAwarenessActive) {
|
|
setFullBodyAwarenessActiveState (isFullBodyAwarenessActive);
|
|
}
|
|
}
|
|
}
|
|
|
|
void resetAttackIDAnimatorID ()
|
|
{
|
|
animator.SetInteger (attackIDAnimatorID, 0);
|
|
}
|
|
|
|
void disablePlayerGravityDuringAttack (bool state)
|
|
{
|
|
if (state) {
|
|
if (!gravityChangedActive) {
|
|
playerControllerManager.setGravityForcePuase (true);
|
|
|
|
playerControllerManager.setCheckOnGroungPausedState (true);
|
|
|
|
playerControllerManager.setPlayerVelocityToZero ();
|
|
}
|
|
} else {
|
|
if (gravityChangedActive) {
|
|
playerControllerManager.setGravityForcePuase (false);
|
|
|
|
playerControllerManager.setCheckOnGroungPausedState (false);
|
|
|
|
playerControllerManager.setLastTimeFalling ();
|
|
}
|
|
}
|
|
|
|
gravityChangedActive = state;
|
|
}
|
|
|
|
//disable or enable the triggers in the hands and foot of the player, to damage the enemy when they touch it
|
|
void changeCollidersState (bool state, colliderPlace place, int combatTypeIndex, int attackIndex)
|
|
{
|
|
//check what colliders have to be activated or deactivated, the hands or the foot, to damage the enemy with
|
|
//the correct triggers according to the type of combo
|
|
stopCheckEventInfoList ();
|
|
|
|
stopActivateDamageTriggerCoroutine ();
|
|
|
|
int combatLimbListCount = combatLimbList.Count;
|
|
|
|
for (int i = 0; i < combatLimbListCount; i++) {
|
|
hitCombat temporalHitCombat = combatLimbList [i].hitCombatManager;
|
|
|
|
temporalHitCombat.setCurrentState (false);
|
|
|
|
temporalHitCombat.setIgnoreDetectedObjectsOnListState (false);
|
|
|
|
temporalHitCombat.setNewSphereColliderTriggerRadius (combatLimbList [i].originalTriggerRadius);
|
|
|
|
temporalHitCombat.setCustomDamageCanBeBlockedState (currentAttackCanBeBlocked);
|
|
|
|
if (setCanActivateReactionSystemTemporallyState) {
|
|
temporalHitCombat.setCanActivateReactionSystemTemporallyState (canActivateReactionSystemTemporally);
|
|
}
|
|
}
|
|
|
|
if (state) {
|
|
|
|
combatAttackInfo currentCombatAttackInfo = combatTypeInfoList [combatTypeIndex].combatAttackInfoList [attackIndex];
|
|
|
|
bool useDamageTriggerActiveInfo = currentCombatAttackInfo.useDamageTriggerActiveInfo;
|
|
|
|
bool placeTriggerInFrontOfCharacter = placeTriggerInFrontOfCharacterOnAllAttacks ||
|
|
combatTypeInfoList [combatTypeIndex].placeTriggerInFrontOfCharacter;
|
|
|
|
limbIndexListOnCurrentAttack.Clear ();
|
|
|
|
combatLimbListCount = combatLimbList.Count;
|
|
|
|
for (int i = 0; i < combatLimbListCount; i++) {
|
|
combatLimbInfo currentCombatLimbInfo = combatLimbList [i];
|
|
colliderPlace currentColliderPlace = currentCombatLimbInfo.limbType;
|
|
|
|
if (state) {
|
|
bool canUseLimb = false;
|
|
|
|
if (place == currentColliderPlace) {
|
|
canUseLimb = true;
|
|
}
|
|
|
|
if (place == colliderPlace.both) {
|
|
canUseLimb = true;
|
|
}
|
|
|
|
if (place == colliderPlace.both_arms && (currentColliderPlace == colliderPlace.right_arm || currentColliderPlace == colliderPlace.left_arm)) {
|
|
canUseLimb = true;
|
|
}
|
|
|
|
if (place == colliderPlace.both_legs && (currentColliderPlace == colliderPlace.right_leg || currentColliderPlace == colliderPlace.left_leg)) {
|
|
canUseLimb = true;
|
|
}
|
|
|
|
if (place == colliderPlace.in_front && i == combatLimbList.Count - 1) {
|
|
canUseLimb = true;
|
|
}
|
|
|
|
if (placeTriggerInFrontOfCharacter) {
|
|
if (currentColliderPlace == colliderPlace.in_front) {
|
|
canUseLimb = true;
|
|
} else {
|
|
canUseLimb = false;
|
|
}
|
|
}
|
|
|
|
if (canUseLimb) {
|
|
if (!useDamageTriggerActiveInfo) {
|
|
if (!currentCombatAttackInfo.ignoreAttackAnimationAndDamageTrigger) {
|
|
currentCombatLimbInfo.hitCombatManager.setCurrentState (true);
|
|
|
|
currentCombatLimbInfo.hitCombatManager.setMainColliderEnabledState (true);
|
|
}
|
|
|
|
if (setCanActivateReactionSystemTemporallyState && canActivateReactionSystemTemporally && currentCombatAttackInfo.ignoreActivateReactionSystem) {
|
|
currentCombatLimbInfo.hitCombatManager.setCanActivateReactionSystemTemporallyState (false);
|
|
}
|
|
|
|
currentCombatLimbInfo.hitCombatManager.setNewDamageReactionID (currentCombatAttackInfo.damageReactionID);
|
|
}
|
|
|
|
limbIndexListOnCurrentAttack.Add (i);
|
|
|
|
currentCombatLimbInfo.hitCombatManager.setCurrentAttackInfoIndex (combatTypeIndex, attackIndex);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (useDamageTriggerActiveInfo) {
|
|
damageTriggerCoroutine = StartCoroutine (activateDamageTriggerCoroutine (combatTypeIndex, attackIndex));
|
|
}
|
|
}
|
|
}
|
|
|
|
public void stopActivateDamageTriggerCoroutine ()
|
|
{
|
|
if (damageTriggerCoroutine != null) {
|
|
StopCoroutine (damageTriggerCoroutine);
|
|
}
|
|
}
|
|
|
|
IEnumerator activateDamageTriggerCoroutine (int combatTypeIndex, int attackIndex)
|
|
{
|
|
if (blockActive) {
|
|
blockActivePreviously = true;
|
|
|
|
disableBlockState ();
|
|
}
|
|
|
|
|
|
if (canCancelBlockToStartAttackActive) {
|
|
if (showDebugPrint) {
|
|
print ("cancel block");
|
|
}
|
|
|
|
animator.SetBool (cancelBlockReactionStateName, true);
|
|
|
|
WaitForSeconds delay = new WaitForSeconds (0.3f);
|
|
|
|
yield return delay;
|
|
|
|
animator.SetBool (cancelBlockReactionStateName, false);
|
|
|
|
// checkDisableHasExitTimeAnimator ();
|
|
|
|
canCancelBlockToStartAttackActive = false;
|
|
}
|
|
|
|
|
|
combatAttackInfo currentCombatAttackInfo = combatTypeInfoList [combatTypeIndex].combatAttackInfoList [attackIndex];
|
|
|
|
currentAttackCanBeBlocked = true;
|
|
|
|
if (currentCombatAttackInfo.attackCantBeBlocked) {
|
|
currentAttackCanBeBlocked = false;
|
|
}
|
|
|
|
if (!currentAttackCanBeBlocked) {
|
|
if (useEventsOnAttackCantBeBlocked) {
|
|
eventOnAttackCantBeBlocked.Invoke ();
|
|
}
|
|
}
|
|
|
|
|
|
// print ("start attack " + currentCombatAttackInfo.Name);
|
|
|
|
int numberOfEvents = currentCombatAttackInfo.damageTriggerActiveInfoList.Count;
|
|
|
|
int numberOfEventsTriggered = 0;
|
|
|
|
float timer = Time.time;
|
|
|
|
bool allEventsTriggered = false;
|
|
|
|
List<damageTriggerActiveInfo> damageTriggerActiveInfoList = currentCombatAttackInfo.damageTriggerActiveInfoList;
|
|
|
|
int damageTriggerActiveInfoListCount = damageTriggerActiveInfoList.Count;
|
|
|
|
for (int i = 0; i < damageTriggerActiveInfoListCount; i++) {
|
|
|
|
currentTriggerInfo = damageTriggerActiveInfoList [i];
|
|
|
|
currentTriggerInfo.delayTriggered = false;
|
|
|
|
if (useAnimationPercentageDuration) {
|
|
float currentDelay = currentTriggerInfo.delayToActiveTrigger;
|
|
|
|
if (currentTriggerInfo.delayToActiveTrigger > 1) {
|
|
if (showDebugPrint) {
|
|
print ("ERRRORORORROOROROR: DELAY IS HIGHER THAN 1 FIXXXXXXXXXXX----------------------------------------" +
|
|
".............................................");
|
|
}
|
|
}
|
|
|
|
if (useAnimationPercentageOver100) {
|
|
currentDelay /= 100;
|
|
}
|
|
|
|
currentTriggerInfo.calculatedPercentageAttackDuration =
|
|
(currentCombatAttackInfo.attackDuration / currentCombatAttackInfo.animationSpeed) * currentDelay;
|
|
}
|
|
}
|
|
|
|
bool canActivateCurrentEvent = false;
|
|
|
|
while (!allEventsTriggered) {
|
|
|
|
damageTriggerActiveInfoListCount = damageTriggerActiveInfoList.Count;
|
|
|
|
for (int i = 0; i < damageTriggerActiveInfoListCount; i++) {
|
|
currentTriggerInfo = damageTriggerActiveInfoList [i];
|
|
|
|
if (!currentTriggerInfo.delayTriggered) {
|
|
// print (currentTriggerInfo.delayToActiveTrigger + " " + i);
|
|
|
|
canActivateCurrentEvent = false;
|
|
|
|
if (useAnimationPercentageDuration) {
|
|
if (Time.time > timer + currentTriggerInfo.calculatedPercentageAttackDuration) {
|
|
canActivateCurrentEvent = true;
|
|
}
|
|
} else {
|
|
if (Time.time > timer + currentTriggerInfo.delayToActiveTrigger) {
|
|
canActivateCurrentEvent = true;
|
|
}
|
|
}
|
|
|
|
// print (currentTriggerInfo.delayToActiveTrigger + " " + i);
|
|
|
|
if (canActivateCurrentEvent) {
|
|
|
|
bool activateDamageTrigger = currentTriggerInfo.activateDamageTrigger;
|
|
|
|
int limbIndexListOnCurrentAttackCount = limbIndexListOnCurrentAttack.Count;
|
|
|
|
for (int j = 0; j < limbIndexListOnCurrentAttackCount; j++) {
|
|
|
|
hitCombat temporalhitCombat = combatLimbList [limbIndexListOnCurrentAttack [j]].hitCombatManager;
|
|
|
|
if (currentCombatAttackInfo.ignoreAttackAnimationAndDamageTrigger) {
|
|
activateDamageTrigger = false;
|
|
}
|
|
|
|
temporalhitCombat.setCurrentState (activateDamageTrigger);
|
|
|
|
if (activateDamageTrigger) {
|
|
temporalhitCombat.setMainColliderEnabledState (false);
|
|
temporalhitCombat.setMainColliderEnabledState (true);
|
|
|
|
if (currentCombatAttackInfo.ignoreForcesToApplyOnAttack) {
|
|
temporalhitCombat.setIgnoreForcesToApplyOnAttackActiveState (true);
|
|
}
|
|
|
|
if (setCanActivateReactionSystemTemporallyState && canActivateReactionSystemTemporally && currentCombatAttackInfo.ignoreActivateReactionSystem) {
|
|
temporalhitCombat.setCanActivateReactionSystemTemporallyState (false);
|
|
}
|
|
|
|
temporalhitCombat.setNewDamageReactionID (currentCombatAttackInfo.damageReactionID);
|
|
|
|
if (currentCombatAttackInfo.ignoreStoreDetectedObjectOnList) {
|
|
temporalhitCombat.setIgnoreDetectedObjectsOnListState (true);
|
|
}
|
|
}
|
|
|
|
if (activateDamageTrigger) {
|
|
temporalhitCombat.setUseCastAllDamageDetectionState (currentTriggerInfo.useCastAllDamageDetection);
|
|
}
|
|
|
|
if (activateDamageTrigger) {
|
|
checkSurfaceFoundOnAttack (false, null, -1);
|
|
}
|
|
|
|
if (currentTriggerInfo.setNewTriggerRadius) {
|
|
// if (currentTriggerInfo.setOriginalRadius) {
|
|
// temporalhitCombat.setNewSphereColliderTriggerRadius (currentTriggerInfo.originalRadius);
|
|
// } else {
|
|
temporalhitCombat.setNewSphereColliderTriggerRadius (currentTriggerInfo.newTriggerRadius);
|
|
// }
|
|
}
|
|
}
|
|
|
|
numberOfEventsTriggered++;
|
|
|
|
currentTriggerInfo.delayTriggered = true;
|
|
|
|
if (numberOfEvents == numberOfEventsTriggered) {
|
|
allEventsTriggered = true;
|
|
|
|
// print ("end of attack " + currentCombatAttackInfo.Name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
yield return null;
|
|
}
|
|
|
|
if (blockActivePreviously) {
|
|
if (!blockInputPaused) {
|
|
blockActivePreviously = false;
|
|
|
|
WaitForSeconds delay = new WaitForSeconds (0.3f);
|
|
|
|
yield return delay;
|
|
|
|
setBlockActiveState (true);
|
|
}
|
|
}
|
|
|
|
if (currentCombatAttackInfo.ignoreAttackAnimationAndDamageTrigger) {
|
|
setAttackEndState (currentCombatAttackInfo.Name);
|
|
}
|
|
}
|
|
|
|
void setCollidersExtraDamageValue (float extraDamageValue)
|
|
{
|
|
int combatLimbListCount = combatLimbList.Count;
|
|
|
|
for (int i = 0; i < combatLimbListCount; i++) {
|
|
combatLimbList [i].hitCombatManager.setCurrentExtraDamageValue (extraDamageValue);
|
|
}
|
|
}
|
|
|
|
public void enableOrDisableTriggers (bool value)
|
|
{
|
|
int combatLimbListCount = combatLimbList.Count;
|
|
|
|
for (int i = 0; i < combatLimbListCount; i++) {
|
|
if (combatLimbList [i].trigger != null) {
|
|
combatLimbList [i].trigger.enabled = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void enableTriggersIfCombatModeActive ()
|
|
{
|
|
if (currentPlayerMode) {
|
|
enableOrDisableTriggers (true);
|
|
}
|
|
}
|
|
|
|
public void stopCheckEventInfoList ()
|
|
{
|
|
if (eventInfoListCoroutine != null) {
|
|
StopCoroutine (eventInfoListCoroutine);
|
|
}
|
|
}
|
|
|
|
public void checkEventInfoList (combatAttackInfo currentCombatAttackInfo)
|
|
{
|
|
if (currentCombatAttackInfo != null && currentCombatAttackInfo.useEventInfoList) {
|
|
|
|
stopCheckEventInfoList ();
|
|
|
|
eventInfoListCoroutine = StartCoroutine (checkEventInfoListCoroutine (currentCombatAttackInfo));
|
|
}
|
|
}
|
|
|
|
IEnumerator checkEventInfoListCoroutine (combatAttackInfo currentCombatAttackInfo)
|
|
{
|
|
List<eventInfo> eventInfoList = currentCombatAttackInfo.eventInfoList;
|
|
|
|
int eventInfoListCount = eventInfoList.Count;
|
|
|
|
for (int i = 0; i < eventInfoListCount; i++) {
|
|
eventInfoList [i].eventTriggered = false;
|
|
}
|
|
|
|
eventInfo currentEventInfo;
|
|
|
|
if (currentCombatAttackInfo.useAccumulativeDelay) {
|
|
eventInfoListCount = eventInfoList.Count;
|
|
|
|
for (int i = 0; i < eventInfoListCount; i++) {
|
|
|
|
currentEventInfo = eventInfoList [i];
|
|
|
|
WaitForSeconds delay = new WaitForSeconds (currentEventInfo.delayToActivate);
|
|
|
|
yield return delay;
|
|
|
|
currentEventInfo.eventToUse.Invoke ();
|
|
|
|
if (currentEventInfo.sendCurrentPlayerOnEvent) {
|
|
currentEventInfo.eventToSendCurrentPlayer.Invoke (gameObject);
|
|
}
|
|
|
|
if (currentCombatAttackInfo == null) {
|
|
i = eventInfoList.Count - 1;
|
|
}
|
|
}
|
|
} else {
|
|
int numberOfEvents = eventInfoList.Count;
|
|
|
|
int numberOfEventsTriggered = 0;
|
|
|
|
float timer = Time.time;
|
|
|
|
bool allEventsTriggered = false;
|
|
|
|
while (!allEventsTriggered) {
|
|
if (currentCombatAttackInfo == null) {
|
|
allEventsTriggered = true;
|
|
} else {
|
|
for (int i = 0; i < numberOfEvents; i++) {
|
|
currentEventInfo = eventInfoList [i];
|
|
|
|
if (!currentEventInfo.eventTriggered) {
|
|
if (Time.time > timer + currentEventInfo.delayToActivate) {
|
|
currentEventInfo.eventToUse.Invoke ();
|
|
|
|
if (currentEventInfo.sendCurrentPlayerOnEvent) {
|
|
currentEventInfo.eventToSendCurrentPlayer.Invoke (gameObject);
|
|
}
|
|
|
|
currentEventInfo.eventTriggered = true;
|
|
|
|
numberOfEventsTriggered++;
|
|
|
|
if (numberOfEvents == numberOfEventsTriggered) {
|
|
allEventsTriggered = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
yield return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void stopAllAttacks ()
|
|
{
|
|
if (timerCombat <= 0) {
|
|
return;
|
|
}
|
|
|
|
stopActivateDamageTriggerCoroutine ();
|
|
|
|
stopCheckEventInfoList ();
|
|
|
|
stopResetAttackIdOnAnimatorCoroutine ();
|
|
|
|
disableCombat ();
|
|
}
|
|
|
|
public void checkLookAtTargetActiveState ()
|
|
{
|
|
if (currentPlayerMode) {
|
|
bool lookingAtTarget = playerControllerManager.isPlayerLookingAtTarget ();
|
|
|
|
if (lookingAtTarget) {
|
|
if (activateStrafeModeOnLockOnTargetActive) {
|
|
playerControllerManager.activateOrDeactivateStrafeMode (true);
|
|
}
|
|
} else {
|
|
if (activateStrafeModeOnLockOnTargetActive) {
|
|
playerControllerManager.activateOrDeactivateStrafeMode (false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void checkLookAtTargetDeactivateState ()
|
|
{
|
|
if (currentPlayerMode) {
|
|
if (activateStrafeModeOnLockOnTargetActive) {
|
|
playerControllerManager.activateOrDeactivateStrafeMode (false);
|
|
}
|
|
}
|
|
}
|
|
|
|
//CALL INPUT FUNCTIONS
|
|
public void inputAttack (string attackName)
|
|
{
|
|
if (attackInputPaused) {
|
|
return;
|
|
}
|
|
|
|
if (useStaminaOnAttackEnabled) {
|
|
if (attackInputPausedForStamina && generalStaminaUseMultiplier > 0) {
|
|
if (showDebugPrint) {
|
|
print ("Not enough stamina");
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
useAttack (attackName);
|
|
}
|
|
|
|
public void inputSetBlockState (bool state)
|
|
{
|
|
if (!canUseCombat ()) {
|
|
return;
|
|
}
|
|
|
|
setBlockStateWithoutInputCheck (state);
|
|
}
|
|
|
|
public void setBlockStateWithoutInputCheck (bool state)
|
|
{
|
|
if (!blockEnabled) {
|
|
return;
|
|
}
|
|
|
|
if (blockInputPaused) {
|
|
return;
|
|
}
|
|
|
|
if (!currentPlayerMode) {
|
|
blockActivePreviously = false;
|
|
|
|
return;
|
|
}
|
|
|
|
if (state) {
|
|
if (combatPlaying) {
|
|
blockActivePreviously = true;
|
|
|
|
return;
|
|
}
|
|
} else {
|
|
if (combatPlaying) {
|
|
blockActivePreviously = false;
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
blockActive = state;
|
|
|
|
if (blockActive) {
|
|
|
|
} else {
|
|
|
|
}
|
|
|
|
setBlockActiveState (blockActive);
|
|
}
|
|
//END OF INPUT FUNCTIONS
|
|
|
|
|
|
//START OF BLOCK FUNCTIONS
|
|
public void setBlockActiveState (bool state)
|
|
{
|
|
if (state) {
|
|
if (blockEnabled) {
|
|
playerControllerManager.activateCustomAction (blockActionName);
|
|
|
|
mainHealth.setBlockDamageActiveState (true);
|
|
|
|
if (reducedBlockDamageProtectionActive) {
|
|
mainHealth.setBlockDamageProtectionAmount (reducedBlockDamageProtectionAmount * generalBlockProtectionMultiplier);
|
|
} else {
|
|
mainHealth.setBlockDamageProtectionAmount (blockDamageProtectionAmount * generalBlockProtectionMultiplier);
|
|
}
|
|
|
|
mainHealth.setBlockDamageRangleAngleState (useMaxBlockRangeAngle, maxBlockRangeAngle);
|
|
|
|
mainHealth.setHitReactionBlockIDValue (blockID);
|
|
|
|
blockActive = true;
|
|
|
|
checkEventsOnBlockDamage (true);
|
|
}
|
|
} else {
|
|
if (blockEnabled) {
|
|
disableBlockState ();
|
|
}
|
|
}
|
|
}
|
|
|
|
void disableBlockState ()
|
|
{
|
|
playerControllerManager.stopCustomAction (blockActionName);
|
|
|
|
mainHealth.setBlockDamageActiveState (false);
|
|
|
|
blockActive = false;
|
|
|
|
checkEventsOnBlockDamage (false);
|
|
|
|
mainHealth.setHitReactionBlockIDValue (-1);
|
|
}
|
|
|
|
public void checkEventsOnBlockDamage (bool state)
|
|
{
|
|
if (useEventsOnBlockDamage) {
|
|
if (state) {
|
|
eventOnBlockActivate.Invoke ();
|
|
} else {
|
|
eventOnBlockDeactivate.Invoke ();
|
|
}
|
|
}
|
|
}
|
|
|
|
//CALLED BY THE STAMINA SYSTEM
|
|
public void updateRegularBlockDamageProtectionValue ()
|
|
{
|
|
setBlockDamageProtectionValue (false);
|
|
}
|
|
|
|
public void updateReducedBlockDamageProtectionValue ()
|
|
{
|
|
setBlockDamageProtectionValue (true);
|
|
}
|
|
|
|
public void setBlockDamageProtectionValue (bool state)
|
|
{
|
|
reducedBlockDamageProtectionActive = state;
|
|
|
|
if (blockActive) {
|
|
if (!currentPlayerMode) {
|
|
return;
|
|
}
|
|
|
|
if (blockEnabled) {
|
|
if (reducedBlockDamageProtectionActive) {
|
|
mainHealth.setBlockDamageProtectionAmount (reducedBlockDamageProtectionAmount * generalBlockProtectionMultiplier);
|
|
} else {
|
|
mainHealth.setBlockDamageProtectionAmount (blockDamageProtectionAmount * generalBlockProtectionMultiplier);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void setMeleeAttackInputPausedState (bool state)
|
|
{
|
|
attackInputPaused = state;
|
|
}
|
|
|
|
//Used to pause/resume the attack and block input
|
|
public void disableMeleeAttackInputPausedStateWithDuration (float pauseDuration)
|
|
{
|
|
stopDisableMeleeAttackInputPausedStateWithDurationCoroutine ();
|
|
|
|
pauseMeleeAttackInputCoroutine = StartCoroutine (disableMeleeAttackInputPausedStateWithDurationCoroutine (pauseDuration));
|
|
}
|
|
|
|
void stopDisableMeleeAttackInputPausedStateWithDurationCoroutine ()
|
|
{
|
|
if (pauseMeleeAttackInputCoroutine != null) {
|
|
StopCoroutine (pauseMeleeAttackInputCoroutine);
|
|
}
|
|
}
|
|
|
|
IEnumerator disableMeleeAttackInputPausedStateWithDurationCoroutine (float pauseDuration)
|
|
{
|
|
attackInputPaused = true;
|
|
|
|
WaitForSeconds delay = new WaitForSeconds (pauseDuration);
|
|
|
|
yield return delay;
|
|
|
|
attackInputPaused = false;
|
|
}
|
|
|
|
public void checkIfBlockActive ()
|
|
{
|
|
if (blockActive) {
|
|
setBlockActiveState (true);
|
|
}
|
|
}
|
|
|
|
public void disableBlockInputPausedStateWithDuration (float pauseDuration)
|
|
{
|
|
stopDisableBlockInputPausedStateWithDurationCoroutine ();
|
|
|
|
pauseBlockInputCoroutine = StartCoroutine (disableBlockInputPausedStateWithDurationCoroutine (pauseDuration));
|
|
}
|
|
|
|
void stopDisableBlockInputPausedStateWithDurationCoroutine ()
|
|
{
|
|
if (pauseBlockInputCoroutine != null) {
|
|
StopCoroutine (pauseBlockInputCoroutine);
|
|
}
|
|
}
|
|
|
|
IEnumerator disableBlockInputPausedStateWithDurationCoroutine (float pauseDuration)
|
|
{
|
|
blockInputPaused = true;
|
|
|
|
WaitForSeconds delay = new WaitForSeconds (pauseDuration);
|
|
|
|
yield return delay;
|
|
|
|
blockInputPaused = false;
|
|
|
|
if (blockActivePreviously) {
|
|
blockActivePreviously = false;
|
|
|
|
delay = new WaitForSeconds (0.3f);
|
|
|
|
yield return delay;
|
|
|
|
setBlockActiveState (true);
|
|
}
|
|
}
|
|
|
|
public void setCanCancelBlockToStartAttackActiveState (bool state)
|
|
{
|
|
canCancelBlockToStartAttackActive = state;
|
|
}
|
|
|
|
//CALLED ON DODGE/ROLL ACTION SYSTEM
|
|
public void checkIfBlockInputIsCurrentlyInUse ()
|
|
{
|
|
if (playerInputLocated && playerInput.isKeyboardButtonPressed (mainMeleeCombatBlockInputName, mainMeleeCombatBlockInputName)) {
|
|
if (showDebugPrint) {
|
|
print ("block is being pressed");
|
|
}
|
|
} else {
|
|
if (showDebugPrint) {
|
|
print ("block is not being pressed, disabling block.");
|
|
}
|
|
|
|
disableBlockStateInProcess ();
|
|
}
|
|
}
|
|
|
|
public void disableBlockStateInProcess ()
|
|
{
|
|
if (blockActive) {
|
|
blockActivePreviously = false;
|
|
|
|
setBlockActiveState (false);
|
|
}
|
|
}
|
|
|
|
public void checkOnAttackBlocked ()
|
|
{
|
|
if (blockActive) {
|
|
if (getHealthFromBlocks) {
|
|
float totalHealthAmount = healthAmountFromBlocks;
|
|
|
|
if (totalHealthAmount > 0 && !mainHealth.checkIfMaxHealthWithHealthManagement ()) {
|
|
|
|
mainHealth.setHealWithHealthManagement (totalHealthAmount);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void checkOnAttackBlockedPerfectly ()
|
|
{
|
|
if (blockActive) {
|
|
if (getHealthFromPerfectBlocks) {
|
|
float totalHealthAmount = healthAmountFromPerfectBlocks;
|
|
|
|
if (totalHealthAmount > 0 && !mainHealth.checkIfMaxHealthWithHealthManagement ()) {
|
|
|
|
mainHealth.setHealWithHealthManagement (totalHealthAmount);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//END OF BLOCK FUNCTIONS
|
|
|
|
//CHECK SURFACE ON ATTACK FUNCTIONS
|
|
public void setNoDamageDetectedOnTriggerById (GameObject objectDetected)
|
|
{
|
|
checkSurfaceFoundOnAttack (true, objectDetected, -1);
|
|
}
|
|
|
|
public void checkSurfaceFoundOnAttack (bool surfaceLocated, GameObject lastSurfaceDetected, int combatLimbID)
|
|
{
|
|
if (!checkSurfaceInfoEnabled) {
|
|
return;
|
|
}
|
|
|
|
string surfaceName = surfaceInfoOnMeleeAttackNameForSwingOnAir;
|
|
|
|
Vector3 attackPosition = Vector3.zero;
|
|
Vector3 attackNormal = Vector3.zero;
|
|
|
|
RaycastHit hit = new RaycastHit ();
|
|
|
|
if (surfaceLocated) {
|
|
GameObject surfaceFound = null;
|
|
|
|
if (lastSurfaceDetected != null && combatLimbID > -1) {
|
|
Collider lastSurfaceDetectedCollider = lastSurfaceDetected.GetComponent<Collider> ();
|
|
|
|
Vector3 limbPosition = combatLimbList [combatLimbID].limb.transform.position;
|
|
|
|
Vector3 raycastPositionTarget = lastSurfaceDetectedCollider.ClosestPointOnBounds (limbPosition);
|
|
|
|
if (!surfaceFound) {
|
|
Vector3 raycastPosition = limbPosition;
|
|
|
|
Vector3 raycastDirection = raycastPositionTarget - raycastPosition;
|
|
|
|
raycastDirection = raycastDirection / raycastDirection.magnitude;
|
|
|
|
float currentRaycastDistance = GKC_Utils.distance (raycastPosition, raycastPositionTarget);
|
|
|
|
currentRaycastDistance += 0.5f;
|
|
|
|
if (showGizmo) {
|
|
Debug.DrawLine (raycastPosition, raycastPositionTarget, Color.black, 6);
|
|
|
|
Debug.DrawLine (raycastPosition, raycastPosition + raycastDirection, Color.red, 4);
|
|
|
|
Debug.DrawLine (raycastPosition + raycastDirection,
|
|
raycastPosition + (0.5f * raycastDirection), Color.white, 4);
|
|
|
|
Debug.DrawLine (raycastPositionTarget, raycastPositionTarget - (0.5f * raycastDirection), Color.yellow, 4);
|
|
}
|
|
|
|
if (Physics.Raycast (raycastPosition, raycastDirection, out hit, currentRaycastDistance, layerMaskToDamage)) {
|
|
if (showDebugPrint) {
|
|
print ("detected " + lastSurfaceDetected.name + " and raycast " + hit.collider.gameObject.name);
|
|
}
|
|
|
|
if (hit.collider.gameObject != playerControllerManager.gameObject) {
|
|
surfaceFound = hit.collider.gameObject;
|
|
}
|
|
} else {
|
|
if (showDebugPrint) {
|
|
print ("detected " + lastSurfaceDetected.name + " no raycast found");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (surfaceFound != null) {
|
|
if (showDebugPrint) {
|
|
print ("SURFACE FOUND " + surfaceFound.name);
|
|
}
|
|
|
|
attackPosition = hit.point;
|
|
attackNormal = hit.normal;
|
|
} else {
|
|
if (showDebugPrint) {
|
|
print ("SURFACE NOT FOUND BY RAYCAST!!!!!!!!!!");
|
|
}
|
|
}
|
|
|
|
if (lastSurfaceDetected != null) {
|
|
meleeAttackSurfaceInfo currentMeleeAttackSurfaceInfo = lastSurfaceDetected.GetComponent<meleeAttackSurfaceInfo> ();
|
|
|
|
if (currentMeleeAttackSurfaceInfo != null) {
|
|
if (!currentMeleeAttackSurfaceInfo.isSurfaceEnabled ()) {
|
|
surfaceLocated = false;
|
|
} else {
|
|
|
|
surfaceName = currentMeleeAttackSurfaceInfo.getSurfaceName ();
|
|
}
|
|
} else {
|
|
GameObject currentCharacter = applyDamage.getCharacterOrVehicle (lastSurfaceDetected);
|
|
|
|
if (currentCharacter != null) {
|
|
currentMeleeAttackSurfaceInfo = currentCharacter.GetComponent<meleeAttackSurfaceInfo> ();
|
|
|
|
if (currentMeleeAttackSurfaceInfo != null) {
|
|
if (!currentMeleeAttackSurfaceInfo.isSurfaceEnabled ()) {
|
|
surfaceLocated = false;
|
|
} else {
|
|
surfaceName = currentMeleeAttackSurfaceInfo.getSurfaceName ();
|
|
}
|
|
}
|
|
} else {
|
|
surfaceLocated = false;
|
|
}
|
|
|
|
if (!surfaceLocated) {
|
|
return;
|
|
}
|
|
}
|
|
} else {
|
|
if (showDebugPrint) {
|
|
print ("SURFACE NOT FOUND BY TRIGGER!!!!!!!!!!");
|
|
}
|
|
}
|
|
}
|
|
|
|
bool ignoreBounceEvent = false;
|
|
if (!currentAttackCanBeBlocked) {
|
|
ignoreBounceEvent = true;
|
|
}
|
|
|
|
checkSurfaceFoundOnAttackToProcess (surfaceName, surfaceLocated, attackPosition, attackNormal, ignoreBounceEvent);
|
|
}
|
|
|
|
float lastTimeSurfaceAudioPlayed;
|
|
int lastSurfaceDetecetedIndex = -1;
|
|
|
|
public void checkSurfaceFoundOnAttackToProcess (string surfaceName, bool surfaceLocated, Vector3 attackPosition, Vector3 attackNormal, bool ignoreBounceEvent)
|
|
{
|
|
int surfaceInfoOnMeleeAttackListCount = surfaceInfoOnMeleeAttackList.Count;
|
|
|
|
for (int i = 0; i < surfaceInfoOnMeleeAttackListCount; i++) {
|
|
grabbedObjectMeleeAttackSystem.surfaceInfoOnMeleeAttack currentSurfaceInfo = surfaceInfoOnMeleeAttackList [i];
|
|
|
|
if (surfaceName.Equals (currentSurfaceInfo.surfaceName)) {
|
|
|
|
int soundIndex = 0;
|
|
|
|
if (currentSurfaceInfo.useSoundsListOnOrder) {
|
|
currentSurfaceInfo.currentSoundIndex++;
|
|
|
|
if (currentSurfaceInfo.currentSoundIndex >= currentSurfaceInfo.soundsAudioElements.Count) {
|
|
currentSurfaceInfo.currentSoundIndex = 0;
|
|
}
|
|
|
|
soundIndex = currentSurfaceInfo.currentSoundIndex;
|
|
} else {
|
|
soundIndex = Random.Range (0, currentSurfaceInfo.soundsAudioElements.Count);
|
|
}
|
|
|
|
bool soundCanBePlayed = false;
|
|
|
|
if (Time.time > lastTimeSurfaceAudioPlayed + 0.5f) {
|
|
soundCanBePlayed = true;
|
|
}
|
|
|
|
if (lastSurfaceDetecetedIndex == -1 || lastSurfaceDetecetedIndex != i) {
|
|
soundCanBePlayed = true;
|
|
}
|
|
|
|
if (soundCanBePlayed) {
|
|
// print (currentSurfaceInfo.surfaceName);
|
|
|
|
AudioPlayer.PlayOneShot (currentSurfaceInfo.soundsAudioElements [soundIndex], gameObject);
|
|
|
|
lastTimeSurfaceAudioPlayed = Time.time;
|
|
|
|
lastSurfaceDetecetedIndex = i;
|
|
}
|
|
|
|
if (surfaceLocated) {
|
|
if (!ignoreBounceEvent) {
|
|
if (currentSurfaceInfo.surfaceActivatesBounceOnCharacter) {
|
|
currentSurfaceInfo.eventOnBounceCharacter.Invoke ();
|
|
|
|
if (currentSurfaceInfo.stopAttackOnBounce) {
|
|
|
|
stopAllAttacks ();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (currentSurfaceInfo.useParticlesOnSurface && attackPosition != Vector3.zero) {
|
|
GameObject newParticles = null;
|
|
|
|
if (currentSurfaceInfo.useRandomParticlesOnSurfaceList) {
|
|
int randomIndex = Random.Range (0, currentSurfaceInfo.randomParticlesOnSurfaceList.Count);
|
|
|
|
newParticles = (GameObject)Instantiate (currentSurfaceInfo.randomParticlesOnSurfaceList [randomIndex],
|
|
Vector3.zero, Quaternion.identity);
|
|
|
|
} else {
|
|
newParticles = (GameObject)Instantiate (currentSurfaceInfo.particlesOnSurface,
|
|
Vector3.zero, Quaternion.identity);
|
|
}
|
|
|
|
newParticles.transform.position = attackPosition;
|
|
newParticles.transform.LookAt (attackPosition + 3 * attackNormal);
|
|
}
|
|
}
|
|
|
|
// print ("surface type detected " + surfaceName);
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void setCombatTypeID (int newValue)
|
|
{
|
|
combatTypeID = newValue;
|
|
}
|
|
|
|
public int getCombatTypeID ()
|
|
{
|
|
return combatTypeID;
|
|
}
|
|
|
|
Transform newDamageTriggerParent;
|
|
|
|
public void setNewParentForDamageTriggers (Transform newParent)
|
|
{
|
|
newDamageTriggerParent = newParent;
|
|
|
|
if (newDamageTriggerParent == null) {
|
|
return;
|
|
}
|
|
|
|
int combatLimbListCount = combatLimbList.Count;
|
|
|
|
for (int i = 0; i < combatLimbListCount; i++) {
|
|
hitCombat hitCombatToCheck = combatLimbList [i].hitCombatManager;
|
|
|
|
hitCombatToCheck.transform.SetParent (newDamageTriggerParent);
|
|
|
|
hitCombatToCheck.transform.localPosition = Vector3.zero;
|
|
|
|
Rigidbody newRigidbody = hitCombatToCheck.gameObject.GetComponent<Rigidbody> ();
|
|
|
|
if (newRigidbody == null) {
|
|
newRigidbody = hitCombatToCheck.gameObject.AddComponent<Rigidbody> ();
|
|
}
|
|
|
|
newRigidbody.isKinematic = true;
|
|
}
|
|
}
|
|
|
|
public void setOriginalParentForDamageTriggers ()
|
|
{
|
|
if (newDamageTriggerParent == null) {
|
|
return;
|
|
}
|
|
|
|
int combatLimbListCount = combatLimbList.Count;
|
|
|
|
for (int i = 0; i < combatLimbListCount; i++) {
|
|
hitCombat hitCombatToCheck = combatLimbList [i].hitCombatManager;
|
|
|
|
if (combatLimbList [i].originalParent != null) {
|
|
hitCombatToCheck.transform.SetParent (combatLimbList [i].originalParent);
|
|
|
|
hitCombatToCheck.transform.localPosition = combatLimbList [i].originalLocalPosition;
|
|
|
|
hitCombatToCheck.setNewSphereColliderTriggerRadius (combatLimbList [i].originalTriggerRadius);
|
|
|
|
Rigidbody newRigidbody = hitCombatToCheck.gameObject.GetComponent<Rigidbody> ();
|
|
|
|
if (newRigidbody != null) {
|
|
Destroy (newRigidbody);
|
|
}
|
|
}
|
|
}
|
|
|
|
newDamageTriggerParent = null;
|
|
}
|
|
|
|
public void setUseMatchTargetSystemOnAttackState (bool state)
|
|
{
|
|
useMatchTargetSystemOnAttack = state;
|
|
}
|
|
|
|
public void setOriginalUseMatchTargetSystemOnAttackState ()
|
|
{
|
|
setUseMatchTargetSystemOnAttackState (originalUseMatchTargetSystemOnAttack);
|
|
}
|
|
|
|
public void setGeneralAttackDamageMultiplierValue (float newValue)
|
|
{
|
|
generalAttackDamageMultiplier = newValue;
|
|
}
|
|
|
|
public void generalAttackDamageMultiplierIncreaseStat (float extraValue)
|
|
{
|
|
generalAttackDamageMultiplier += extraValue;
|
|
}
|
|
|
|
public void initializeGeneralAttackDamageMultiplierStatAmount (float newValue)
|
|
{
|
|
generalAttackDamageMultiplier = newValue;
|
|
}
|
|
|
|
public float getGeneralAttackDamageMultiplierValue ()
|
|
{
|
|
return generalAttackDamageMultiplier;
|
|
}
|
|
|
|
//EDITOR FUNCTIONS
|
|
public void getCombatPrefabs (GameObject combatPrefab)
|
|
{
|
|
hitCombatPrefab = combatPrefab;
|
|
|
|
updateComponent ();
|
|
}
|
|
|
|
public void addCombatPlace (string name, float hitDamage, GameObject limb, colliderPlace limbType)
|
|
{
|
|
combatLimbInfo newLimb = new combatLimbInfo ();
|
|
newLimb.name = name;
|
|
newLimb.hitDamage = hitDamage;
|
|
newLimb.limb = limb;
|
|
newLimb.limbType = limbType;
|
|
newLimb.hitCombatManager = limb.GetComponent<hitCombat> ();
|
|
newLimb.trigger = limb.GetComponent<Collider> ();
|
|
combatLimbList.Add (newLimb);
|
|
|
|
updateComponent ();
|
|
}
|
|
|
|
public void assignBasicCombatTriggers ()
|
|
{
|
|
if (hitCombatPrefab) {
|
|
animator = transform.GetChild (0).GetComponentInChildren<Animator> ();
|
|
|
|
if (animator != null) {
|
|
|
|
combatLimbList.Clear ();
|
|
|
|
//another list of bones, to the triggers in hands and feet for the combat
|
|
Transform [] hitCombatPositions = new Transform [] {
|
|
animator.GetBoneTransform (HumanBodyBones.LeftFoot),
|
|
animator.GetBoneTransform (HumanBodyBones.RightFoot),
|
|
animator.GetBoneTransform (HumanBodyBones.LeftHand),
|
|
animator.GetBoneTransform (HumanBodyBones.RightHand)
|
|
};
|
|
|
|
for (int i = 0; i < hitCombatPositions.Length; i++) {
|
|
GameObject hitCombatClone = (GameObject)Instantiate (hitCombatPrefab, Vector3.zero, Quaternion.identity);
|
|
|
|
hitCombatClone.transform.SetParent (hitCombatPositions [i]);
|
|
hitCombatClone.transform.localPosition = Vector3.zero;
|
|
hitCombatClone.transform.localRotation = Quaternion.identity;
|
|
string name = hitCombatPositions [i].gameObject.name;
|
|
|
|
hitCombat currentHitCombat = hitCombatClone.GetComponent<hitCombat> ();
|
|
|
|
currentHitCombat.setMainColliderEnabledState (false);
|
|
|
|
string hitCombatTriggerName = "";
|
|
|
|
if (hitCombatPositions [i] == animator.GetBoneTransform (HumanBodyBones.LeftFoot) ||
|
|
hitCombatPositions [i] == animator.GetBoneTransform (HumanBodyBones.RightFoot)) {
|
|
|
|
colliderPlace newColliderPlace = colliderPlace.right_leg;
|
|
|
|
if (hitCombatPositions [i] == animator.GetBoneTransform (HumanBodyBones.LeftFoot)) {
|
|
newColliderPlace = colliderPlace.left_leg;
|
|
|
|
hitCombatTriggerName = "Hit Combat Left Foot";
|
|
} else {
|
|
hitCombatTriggerName = "Hit Combat Right Foot";
|
|
}
|
|
|
|
addCombatPlace (name, defaultLegHitDamage, hitCombatClone, newColliderPlace);
|
|
|
|
currentHitCombat.setNewHitDamage (defaultLegHitDamage * generalAttackDamageMultiplier);
|
|
} else {
|
|
colliderPlace newColliderPlace = colliderPlace.right_arm;
|
|
|
|
if (hitCombatPositions [i] == animator.GetBoneTransform (HumanBodyBones.LeftHand)) {
|
|
newColliderPlace = colliderPlace.left_arm;
|
|
|
|
hitCombatTriggerName = "Hit Combat Left Hand";
|
|
} else {
|
|
hitCombatTriggerName = "Hit Combat Right Hand";
|
|
}
|
|
|
|
addCombatPlace (name, defaultArmHitDamage, hitCombatClone, newColliderPlace);
|
|
|
|
currentHitCombat.setNewHitDamage (defaultArmHitDamage + generalAttackDamageMultiplier);
|
|
}
|
|
|
|
hitCombatClone.name = hitCombatTriggerName;
|
|
}
|
|
} else {
|
|
print ("Animator not found in character, make sure it has one assigned");
|
|
}
|
|
|
|
animator = GetComponentInChildren<Animator> ();
|
|
|
|
udpateHitCombatInfo ();
|
|
|
|
updateComponent ();
|
|
} else {
|
|
print ("Assign the hit combat prefab to create the combat limbs");
|
|
}
|
|
}
|
|
|
|
public void udpateHitCombatInfo ()
|
|
{
|
|
int combatLimbListCount = combatLimbList.Count;
|
|
|
|
for (int i = 0; i < combatLimbListCount; i++) {
|
|
hitCombat hitCombatToCheck = combatLimbList [i].hitCombatManager;
|
|
|
|
hitCombatToCheck.getOwner (gameObject);
|
|
|
|
hitCombatToCheck.layerMask = layerMaskToDamage;
|
|
|
|
hitCombatToCheck.setNewHitDamage (combatLimbList [i].hitDamage * generalAttackDamageMultiplier);
|
|
|
|
hitCombatToCheck.setAddForceMultiplierValue (addForceMultiplier);
|
|
|
|
hitCombatToCheck.setTriggerIdOnEditor (i);
|
|
|
|
hitCombatToCheck.setNewSphereColliderTriggerRadius (combatLimbList [i].originalTriggerRadius);
|
|
|
|
combatLimbList [i].originalParent = hitCombatToCheck.transform.parent;
|
|
|
|
combatLimbList [i].originalLocalPosition = hitCombatToCheck.transform.localPosition;
|
|
|
|
if (useCustomIgnoreTags) {
|
|
hitCombatToCheck.setCustomTagsToIgnore (customTagsToIgnoreList);
|
|
} else {
|
|
hitCombatToCheck.setCustomTagsToIgnore (null);
|
|
}
|
|
|
|
hitCombatToCheck.updateComponent ();
|
|
}
|
|
|
|
updateComponent ();
|
|
|
|
print ("Info in hit triggers for combat updated");
|
|
}
|
|
|
|
public void removeLimbParts ()
|
|
{
|
|
int combatLimbListCount = combatLimbList.Count;
|
|
|
|
for (int i = 0; i < combatLimbListCount; i++) {
|
|
if (combatLimbList [i].limb != null) {
|
|
DestroyImmediate (combatLimbList [i].limb);
|
|
}
|
|
}
|
|
|
|
combatLimbList.Clear ();
|
|
|
|
Component [] components = GetComponentsInChildren (typeof (hitCombat));
|
|
foreach (Component c in components) {
|
|
DestroyImmediate (c.gameObject);
|
|
}
|
|
|
|
updateComponent ();
|
|
}
|
|
|
|
public void enableOrDisableCloseCombatTriggers (bool state)
|
|
{
|
|
int combatLimbListCount = combatLimbList.Count;
|
|
|
|
for (int i = 0; i < combatLimbListCount; i++) {
|
|
combatLimbList [i].hitCombatManager.setMainColliderEnabledState (state);
|
|
}
|
|
}
|
|
|
|
public void addOrRemoveObjectToIgnoreByHitTriggers (GameObject newObject, bool state)
|
|
{
|
|
int combatLimbListCount = combatLimbList.Count;
|
|
|
|
for (int i = 0; i < combatLimbListCount; i++) {
|
|
combatLimbList [i].hitCombatManager.addOrRemoveObjectToIgnore (newObject, state);
|
|
}
|
|
}
|
|
|
|
public void enableOrDisableUseAttackInputStackFromEditor (bool state)
|
|
{
|
|
enableOrDisableUseAttackInputStack (state);
|
|
|
|
updateComponent ();
|
|
}
|
|
|
|
public void setCustomIgnoreTagsForCharacterFromEditor ()
|
|
{
|
|
if (playerControllerManager != null) {
|
|
useCustomIgnoreTags = true;
|
|
|
|
customTagsToIgnoreList.Clear ();
|
|
|
|
customTagsToIgnoreList.Add (playerControllerManager.gameObject.tag);
|
|
|
|
updateComponent ();
|
|
}
|
|
}
|
|
|
|
public void setUseMatchTargetSystemOnAttackStateFromEditor (bool state)
|
|
{
|
|
useMatchTargetSystemOnAttack = state;
|
|
|
|
updateComponent ();
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
void OnDrawGizmos ()
|
|
{
|
|
if (!showGizmo) {
|
|
return;
|
|
}
|
|
|
|
if (GKC_Utils.isCurrentSelectionActiveGameObject (gameObject)) {
|
|
DrawGizmos ();
|
|
}
|
|
}
|
|
|
|
void OnDrawGizmosSelected ()
|
|
{
|
|
DrawGizmos ();
|
|
}
|
|
|
|
void DrawGizmos ()
|
|
{
|
|
if (showGizmo) {
|
|
int combatLimbListCount = combatLimbList.Count;
|
|
|
|
for (int i = 0; i < combatLimbListCount; i++) {
|
|
if (combatLimbList [i].limb != null) {
|
|
Gizmos.color = gizmoColor;
|
|
Gizmos.DrawWireSphere (combatLimbList [i].limb.transform.position, gizmoRadius);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
public void updateComponent ()
|
|
{
|
|
GKC_Utils.updateComponent (this);
|
|
|
|
GKC_Utils.updateDirtyScene ("Update close combat info", gameObject);
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class combatLimbInfo
|
|
{
|
|
public string name;
|
|
public float hitDamage;
|
|
public GameObject limb;
|
|
public colliderPlace limbType;
|
|
public hitCombat hitCombatManager;
|
|
public Collider trigger;
|
|
public float originalTriggerRadius = 0.15f;
|
|
public Transform originalParent;
|
|
public Vector3 originalLocalPosition;
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class combatTypeInfo
|
|
{
|
|
public string Name;
|
|
|
|
public string combatTypeDescription;
|
|
|
|
public int combatTypeID = 0;
|
|
|
|
public bool attacksUsedOnAir;
|
|
|
|
public List<combatAttackInfo> combatAttackInfoList = new List<combatAttackInfo> ();
|
|
|
|
public bool attackActive;
|
|
|
|
public bool useDelayToStartAttackAfterFullCombo;
|
|
public float delayToStartAttackAfterFullCombo;
|
|
|
|
public bool useDelayToStartSameAttack;
|
|
|
|
public bool useMinTimeToChangeCombo;
|
|
|
|
public bool canChangeOfComboWhenPreviousNotComplete = true;
|
|
|
|
public bool increaseAttackIndexOnlyOnAttackPerformedCorrectly;
|
|
|
|
public float lastTimeFullCombo;
|
|
|
|
public bool waitingToStartAttackActive;
|
|
|
|
public int currentAttackIndex;
|
|
|
|
public int comboCounter;
|
|
|
|
public bool resetingCombo;
|
|
|
|
public bool placeTriggerInFrontOfCharacter;
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class combatAttackInfo
|
|
{
|
|
public string Name;
|
|
|
|
public bool useAttackID;
|
|
public int attackID;
|
|
|
|
public colliderPlace limbForAttack;
|
|
|
|
public float attackDuration;
|
|
|
|
public float animationSpeed = 1;
|
|
|
|
public float minTimeToPlayNextAttack;
|
|
public bool resetComboIfIncorrectMinTime;
|
|
|
|
public bool playingNextAttack;
|
|
|
|
public bool ignoreAttackAnimationAndDamageTrigger;
|
|
|
|
public bool useExtraDamageMultiplier;
|
|
public float extraDamageMultiplier;
|
|
|
|
public bool canMoveWhileAttackActive;
|
|
public bool useRootMotionOnAttack;
|
|
public bool forceUseRootMotionActive;
|
|
|
|
public bool useOnlyUpperBodyAnimationIfMoving;
|
|
public string onlyUpperBodyAnimationIfMovingName;
|
|
public int onlyUpperBodyAnimationIfMovingID;
|
|
|
|
public bool useAlternativeAttackIfMoving;
|
|
public string alternativeAttackIfMovingName;
|
|
|
|
public bool pauseHeadTrackOnAttack;
|
|
|
|
public bool pauseHeadTrackLookInOppositeDirection;
|
|
|
|
public bool keepCameraRotationToHeadOnFullBodyAwareness;
|
|
|
|
public bool disableGravityOnAttacks;
|
|
|
|
public bool useEventOnAttackStart;
|
|
public UnityEvent eventOnAttackStart;
|
|
|
|
|
|
public bool useEventOnAttackEnd;
|
|
public UnityEvent eventOnAttackEnd;
|
|
|
|
public bool useDelayOnEventOnAttackStart;
|
|
public float delayOnEventOnAttackStart;
|
|
|
|
public bool useDelayOnEventOnAttackEnd;
|
|
public float delayOnEventOnAttackEnd;
|
|
|
|
|
|
public bool useEventOnDamage;
|
|
public UnityEvent eventOnDamage;
|
|
|
|
public bool checkObjectsToUseRemoteEventsOnDamage;
|
|
public LayerMask layerToUseRemoteEventsOnDamage;
|
|
|
|
public bool useRemoteEvent;
|
|
public List<string> remoteEventNameList;
|
|
|
|
public bool useRemoteEventWithString;
|
|
public string remoteEventWithStringName;
|
|
public string remoteEventString;
|
|
|
|
public Coroutine delayCoroutine;
|
|
|
|
public bool useDamageTriggerActiveInfo;
|
|
|
|
public List<damageTriggerActiveInfo> damageTriggerActiveInfoList = new List<damageTriggerActiveInfo> ();
|
|
|
|
public bool useEventInfoList;
|
|
|
|
public bool useAccumulativeDelay;
|
|
public Coroutine eventInfoListCoroutine;
|
|
public List<eventInfo> eventInfoList = new List<eventInfo> ();
|
|
|
|
public bool ignoreActivateReactionSystem;
|
|
|
|
public int damageReactionID = -1;
|
|
|
|
public bool useMatchPositionSystem = true;
|
|
public float matchPositionOffset = 1.6f;
|
|
|
|
public bool attackCantBeBlocked;
|
|
|
|
public bool ignoreStoreDetectedObjectOnList;
|
|
|
|
public bool ignoreForcesToApplyOnAttack;
|
|
|
|
public bool useStaminaOnAttack;
|
|
public float staminaUsedOnAttack;
|
|
public float customRefillStaminaDelayAfterUse;
|
|
|
|
public bool getHealthFromDamagingObjects;
|
|
public float healthFromDamagingObjectsMultiplier = 1;
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class damageTriggerActiveInfo
|
|
{
|
|
public float delayToActiveTrigger;
|
|
public bool activateDamageTrigger = true;
|
|
public bool delayTriggered;
|
|
|
|
public float calculatedPercentageAttackDuration;
|
|
|
|
public bool setNewTriggerRadius;
|
|
public float newTriggerRadius;
|
|
public bool setOriginalRadius = true;
|
|
public float originalRadius = 0.07f;
|
|
|
|
public bool useCastAllDamageDetection;
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class eventInfo
|
|
{
|
|
public float delayToActivate;
|
|
|
|
public UnityEvent eventToUse;
|
|
|
|
public bool eventTriggered;
|
|
|
|
public bool sendCurrentPlayerOnEvent;
|
|
public eventParameters.eventToCallWithGameObject eventToSendCurrentPlayer;
|
|
}
|
|
} |