787 lines
25 KiB
C#
787 lines
25 KiB
C#
|
|
using System.Collections;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using UnityEngine;
|
|||
|
|
using UnityEngine.Events;
|
|||
|
|
|
|||
|
|
public class damageHitReactionSystem : MonoBehaviour
|
|||
|
|
{
|
|||
|
|
[Header ("Main Settings")]
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public bool hitReactionsEnabled = true;
|
|||
|
|
|
|||
|
|
public string defaultCategoryReaction = "Melee";
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
[Header ("Reaction Probability Settings")]
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
[Range (0, 1)] public float probabilityToActivateReactionMultiplier = 1;
|
|||
|
|
|
|||
|
|
public bool canChangeProbabilityMultiplierExternally = true;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public bool ignoreMinWaitTimeToPlayHitReactionAgain;
|
|||
|
|
|
|||
|
|
public bool ignoreMinAmountToReceiveDamage;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
[Header ("Hit Reaction Settings")]
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public List<hitReactionInfo> hitReactionInfoList = new List<hitReactionInfo> ();
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public List<damageStateInfo> damageStateInfoList = new List<damageStateInfo> ();
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
[Header ("Debug")]
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public bool showDebugPrint;
|
|||
|
|
public bool hitReactionActive;
|
|||
|
|
|
|||
|
|
public int currentBlockID;
|
|||
|
|
|
|||
|
|
public string currentReactionCategory;
|
|||
|
|
|
|||
|
|
public bool damageReactionPaused;
|
|||
|
|
|
|||
|
|
public bool ignoreParryActive;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
[Header ("Events Settings")]
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public bool useMainEventOnHitReactionFound;
|
|||
|
|
public UnityEvent mainEventOnHitReactionFound;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
[Header ("Components")]
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public Transform playerControllerTransform;
|
|||
|
|
public playerActionSystem mainPlayerActionSystem;
|
|||
|
|
|
|||
|
|
hitReactionInfo currentHitReactionInfo;
|
|||
|
|
|
|||
|
|
Coroutine perfectBlockCoroutine;
|
|||
|
|
|
|||
|
|
float lastTimeBlockActive;
|
|||
|
|
|
|||
|
|
int currentBlockIDToCheck;
|
|||
|
|
|
|||
|
|
hitDamageDirection currenthitDamageDirection;
|
|||
|
|
|
|||
|
|
public void checkDamageReceived (float damageReceived, Vector3 damagePosition, GameObject objectBlocked)
|
|||
|
|
{
|
|||
|
|
if (!hitReactionsEnabled || !hitReactionActive) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (damageReactionPaused) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
checkHitReaction (damageReceived, 0, damagePosition, false, false, false, objectBlocked, -1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void checkDamageReceivedTemporally (float damageReceived, Vector3 damagePosition, GameObject objectBlocked)
|
|||
|
|
{
|
|||
|
|
if (!hitReactionsEnabled) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (damageReactionPaused) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
checkHitReaction (damageReceived, 0, damagePosition, false, false, false, objectBlocked, -1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void checkDamageBlocked (float damageReceived, float originalDamageAmountReceived, Vector3 damagePosition, bool damageBlocked, GameObject objectBlocked)
|
|||
|
|
{
|
|||
|
|
if (!hitReactionsEnabled || !hitReactionActive) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (damageReactionPaused) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
checkHitReaction (damageReceived, originalDamageAmountReceived, damagePosition, damageBlocked, true, false, objectBlocked, -1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void checkDamageReceivedUnblockable (float damageReceived, Vector3 damagePosition, GameObject objectBlocked)
|
|||
|
|
{
|
|||
|
|
if (!hitReactionsEnabled || !hitReactionActive) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (damageReactionPaused) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
checkHitReaction (damageReceived, 0, damagePosition, false, false, true, objectBlocked, -1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void checkReactionToTriggerExternally (float damageReceived, Vector3 damagePosition, GameObject objectBlocked)
|
|||
|
|
{
|
|||
|
|
if (!hitReactionsEnabled || !hitReactionActive) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (damageReactionPaused) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
checkHitReaction (damageReceived, 0, damagePosition, false, false, false, objectBlocked, -1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void activateDamageReactionByID (float damageReceived, Vector3 damagePosition, GameObject objectBlocked, int damageReactionID)
|
|||
|
|
{
|
|||
|
|
if (!hitReactionsEnabled) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (damageReactionPaused) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
checkHitReaction (damageReceived, 0, damagePosition, false, false, false, objectBlocked, damageReactionID);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void checkHitReaction (float damageReceived, float originalDamageAmountReceived, Vector3 damagePosition, bool damageBlocked,
|
|||
|
|
bool blockDamageActive, bool unblockableDamage, GameObject objectBlocked, int damageReactionID)
|
|||
|
|
{
|
|||
|
|
if (damageReactionID == -1) {
|
|||
|
|
Vector3 damageDirection = damagePosition - playerControllerTransform.position;
|
|||
|
|
|
|||
|
|
damageDirection = damageDirection / damageDirection.magnitude;
|
|||
|
|
|
|||
|
|
float damageAngle = Vector3.SignedAngle (playerControllerTransform.forward, damageDirection, playerControllerTransform.up);
|
|||
|
|
|
|||
|
|
float damageAngleAbs = Mathf.Abs (damageAngle);
|
|||
|
|
|
|||
|
|
currenthitDamageDirection = hitDamageDirection.front;
|
|||
|
|
|
|||
|
|
bool isPlayerMovingOn3dWorld = mainPlayerActionSystem.isPlayerMovingOn3dWorld ();
|
|||
|
|
|
|||
|
|
if (isPlayerMovingOn3dWorld) {
|
|||
|
|
if (damageAngleAbs > 45 && damageAngleAbs < 135) {
|
|||
|
|
if (damageAngle < 0) {
|
|||
|
|
currenthitDamageDirection = hitDamageDirection.left;
|
|||
|
|
} else {
|
|||
|
|
currenthitDamageDirection = hitDamageDirection.right;
|
|||
|
|
}
|
|||
|
|
} else if (damageAngleAbs > 135) {
|
|||
|
|
currenthitDamageDirection = hitDamageDirection.backward;
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
if (!isFacingToAttacker (objectBlocked.transform.position)) {
|
|||
|
|
currenthitDamageDirection = hitDamageDirection.backward;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (showDebugPrint) {
|
|||
|
|
print (currenthitDamageDirection);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int hitReactionIndex = -1;
|
|||
|
|
float maxDamageFound = -1;
|
|||
|
|
|
|||
|
|
bool damageStateFound = false;
|
|||
|
|
|
|||
|
|
if (damageReceived > 0) {
|
|||
|
|
for (int i = 0; i < damageStateInfoList.Count; i++) {
|
|||
|
|
damageStateInfo currentDamageStateInfo = damageStateInfoList [i];
|
|||
|
|
|
|||
|
|
if (!damageStateFound && currentDamageStateInfo.damageStateEnabled) {
|
|||
|
|
if (currentDamageStateInfo.damageStateRange.x <= damageReceived &&
|
|||
|
|
currentDamageStateInfo.damageStateRange.y >= damageReceived) {
|
|||
|
|
|
|||
|
|
if (showDebugPrint) {
|
|||
|
|
print (currentDamageStateInfo.Name);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
currentDamageStateInfo.eventOnDamageState.Invoke ();
|
|||
|
|
|
|||
|
|
damageStateFound = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!damageStateFound) {
|
|||
|
|
for (int i = 0; i < damageStateInfoList.Count; i++) {
|
|||
|
|
damageStateInfo currentDamageStateInfo = damageStateInfoList [i];
|
|||
|
|
|
|||
|
|
if (!damageStateFound && currentDamageStateInfo.damageStateEnabled) {
|
|||
|
|
if (currentDamageStateInfo.useAsDefaultState) {
|
|||
|
|
currentDamageStateInfo.eventOnDamageState.Invoke ();
|
|||
|
|
|
|||
|
|
if (showDebugPrint) {
|
|||
|
|
print (currentDamageStateInfo.Name);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
damageStateFound = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool canCheckReaction = false;
|
|||
|
|
|
|||
|
|
if (currentReactionCategory == "") {
|
|||
|
|
currentReactionCategory = defaultCategoryReaction;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool searchingReactionByID = damageReactionID > -1;
|
|||
|
|
|
|||
|
|
bool canCheckRegularReaction = false;
|
|||
|
|
|
|||
|
|
|
|||
|
|
for (int i = 0; i < hitReactionInfoList.Count; i++) {
|
|||
|
|
|
|||
|
|
currentHitReactionInfo = hitReactionInfoList [i];
|
|||
|
|
|
|||
|
|
if (currentHitReactionInfo.reactionEnabled) {
|
|||
|
|
|
|||
|
|
if (searchingReactionByID) {
|
|||
|
|
if (hitReactionIndex == -1) {
|
|||
|
|
if (damageReactionID == currentHitReactionInfo.damageReactionID) {
|
|||
|
|
canCheckRegularReaction = true;
|
|||
|
|
|
|||
|
|
if (showDebugPrint) {
|
|||
|
|
print ("Damage reaction activated by ID, checking reaction" + currentHitReactionInfo.Name);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
canCheckRegularReaction = false;
|
|||
|
|
|
|||
|
|
if (currentHitReactionInfo.reactionCategory == currentReactionCategory) {
|
|||
|
|
|
|||
|
|
if (currentHitReactionInfo.reactionOnBlock == blockDamageActive) {
|
|||
|
|
|
|||
|
|
if (!blockDamageActive || currentHitReactionInfo.blockID == currentBlockID) {
|
|||
|
|
canCheckRegularReaction = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (canCheckRegularReaction) {
|
|||
|
|
canCheckReaction = false;
|
|||
|
|
|
|||
|
|
if (damageReceived >= currentHitReactionInfo.minAmountToReceiveDamage) {
|
|||
|
|
canCheckReaction = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (ignoreMinAmountToReceiveDamage) {
|
|||
|
|
canCheckReaction = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (blockDamageActive && (damageBlocked || damageReceived == 0)) {
|
|||
|
|
canCheckReaction = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (showDebugPrint) {
|
|||
|
|
print (currentHitReactionInfo.Name + " " + damageReceived + " " + blockDamageActive + " " + damageBlocked + " " + canCheckReaction);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (canCheckReaction) {
|
|||
|
|
if (currentHitReactionInfo.minAmountToReceiveDamage > maxDamageFound) {
|
|||
|
|
if (damageReactionID > -1 ||
|
|||
|
|
(currentHitReactionInfo.damageDirection == hitDamageDirection.anyDirection ||
|
|||
|
|
currentHitReactionInfo.damageDirection == currenthitDamageDirection)) {
|
|||
|
|
|
|||
|
|
maxDamageFound = currentHitReactionInfo.minAmountToReceiveDamage;
|
|||
|
|
|
|||
|
|
hitReactionIndex = i;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (hitReactionIndex > -1) {
|
|||
|
|
activateHitReactionByIndex (hitReactionIndex, damageReceived, originalDamageAmountReceived, unblockableDamage, objectBlocked);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool isFacingToAttacker (Vector3 attackerPosition)
|
|||
|
|
{
|
|||
|
|
Vector3 directionDamage = (attackerPosition - playerControllerTransform.position).normalized;
|
|||
|
|
|
|||
|
|
Vector3 playerForward = playerControllerTransform.forward;
|
|||
|
|
|
|||
|
|
bool isFacingDamage = Vector2.Dot (directionDamage, playerForward) > 0;
|
|||
|
|
|
|||
|
|
if (isFacingDamage) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
float lastTimeHitReaction;
|
|||
|
|
|
|||
|
|
float currentReactionDelayUntilNextReaction = 0;
|
|||
|
|
|
|||
|
|
void activateHitReactionByIndex (int hitReactionIndex, float damageReceived, float originalDamageAmountReceived, bool unblockableDamage, GameObject objectBlocked)
|
|||
|
|
{
|
|||
|
|
if (hitReactionIndex > -1) {
|
|||
|
|
currentHitReactionInfo = hitReactionInfoList [hitReactionIndex];
|
|||
|
|
|
|||
|
|
if (currentHitReactionInfo.useProbabilityToActivateReaction) {
|
|||
|
|
float probabilityToActivateReaction = Random.Range (0, 100);
|
|||
|
|
|
|||
|
|
float currentProbability = currentHitReactionInfo.probabilityToActivateReaction * probabilityToActivateReactionMultiplier;
|
|||
|
|
|
|||
|
|
if (currentProbability < probabilityToActivateReaction) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!currentHitReactionInfo.ignoreReactionDelayFromPreviousReaction) {
|
|||
|
|
if (currentReactionDelayUntilNextReaction > 0 && Time.time < currentReactionDelayUntilNextReaction + lastTimeHitReaction) {
|
|||
|
|
if (showDebugPrint) {
|
|||
|
|
print ("\n reaction delay from previous reaction is active, disabling reaction activation \n");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
currentReactionDelayUntilNextReaction = 0;
|
|||
|
|
|
|||
|
|
if (currentHitReactionInfo.setReactionDelayUntilNextReaction) {
|
|||
|
|
currentReactionDelayUntilNextReaction = currentHitReactionInfo.reactionDelayUntilNextReaction;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
lastTimeHitReaction = Time.time;
|
|||
|
|
|
|||
|
|
bool checkMinWaitTimeResult = false;
|
|||
|
|
|
|||
|
|
if (Time.time > currentHitReactionInfo.minWaitTimeToPlayHitReactionAgain +
|
|||
|
|
currentHitReactionInfo.lastTimeHitReaction) {
|
|||
|
|
checkMinWaitTimeResult = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (ignoreMinWaitTimeToPlayHitReactionAgain) {
|
|||
|
|
checkMinWaitTimeResult = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (checkMinWaitTimeResult) {
|
|||
|
|
currentHitReactionInfo.lastTimeHitReaction = Time.time;
|
|||
|
|
|
|||
|
|
bool canActivateHitReaction = true;
|
|||
|
|
|
|||
|
|
bool perfectBlockActivated = false;
|
|||
|
|
|
|||
|
|
if (!currentHitReactionInfo.activateHitReactionOnPerfectBlock && !unblockableDamage) {
|
|||
|
|
if (currentHitReactionInfo.reactionOnBlock && currentHitReactionInfo.canUsePerfectBlock) {
|
|||
|
|
if (lastTimeBlockActive != 0) {
|
|||
|
|
if (Time.time < lastTimeBlockActive + currentHitReactionInfo.maxTimeToPerfectBlock) {
|
|||
|
|
canActivateHitReaction = false;
|
|||
|
|
|
|||
|
|
perfectBlockActivated = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (showDebugPrint) {
|
|||
|
|
print ("\n\n");
|
|||
|
|
print (currentHitReactionInfo.Name + " " + damageReceived + " " + playerControllerTransform.name + " " + perfectBlockActivated + " " + canActivateHitReaction);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (canActivateHitReaction) {
|
|||
|
|
if (useMainEventOnHitReactionFound) {
|
|||
|
|
mainEventOnHitReactionFound.Invoke ();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (currentHitReactionInfo.stopPreviousActionIfActive) {
|
|||
|
|
mainPlayerActionSystem.stopAllActions ();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (currentHitReactionInfo.playHitAction) {
|
|||
|
|
mainPlayerActionSystem.activateCustomAction (currentHitReactionInfo.hitActionName);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
if (perfectBlockActivated) {
|
|||
|
|
if (currentHitReactionInfo.stopPreviousActionIfActive) {
|
|||
|
|
mainPlayerActionSystem.stopAllActions ();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (currentHitReactionInfo.playHitAction) {
|
|||
|
|
mainPlayerActionSystem.activateCustomAction (currentHitReactionInfo.hitActionNameOnPerfectBlock);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (currentHitReactionInfo.useStaminaOnBlock) {
|
|||
|
|
float currentDamageReceived = damageReceived;
|
|||
|
|
|
|||
|
|
if (currentDamageReceived == 0) {
|
|||
|
|
currentDamageReceived = originalDamageAmountReceived;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
float staminaAmountToUse = currentHitReactionInfo.staminaToUseMultiplier * currentDamageReceived;
|
|||
|
|
|
|||
|
|
currentHitReactionInfo.eventToUseStamina.Invoke (staminaAmountToUse);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (canActivateHitReaction) {
|
|||
|
|
currentHitReactionInfo.eventOnHit.Invoke ();
|
|||
|
|
} else {
|
|||
|
|
if (perfectBlockActivated) {
|
|||
|
|
currentHitReactionInfo.eventOnHitReactionOnPerfectBlock.Invoke ();
|
|||
|
|
|
|||
|
|
if (currentHitReactionInfo.useRemoteEvent) {
|
|||
|
|
bool useRemoteEvents = false;
|
|||
|
|
|
|||
|
|
if (objectBlocked != null) {
|
|||
|
|
if (currentHitReactionInfo.checkObjectsToUseRemoteEventsOnDamage) {
|
|||
|
|
if ((1 << objectBlocked.layer & currentHitReactionInfo.layerToUseRemoteEventsOnDamage.value) == 1 << objectBlocked.layer) {
|
|||
|
|
useRemoteEvents = true;
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
useRemoteEvents = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (useRemoteEvents) {
|
|||
|
|
remoteEventSystem currentRemoteEventSystem = objectBlocked.GetComponent<remoteEventSystem> ();
|
|||
|
|
|
|||
|
|
if (currentRemoteEventSystem != null) {
|
|||
|
|
int remoteEventNameListCount = currentHitReactionInfo.remoteEventNameList.Count;
|
|||
|
|
|
|||
|
|
for (int j = 0; j < remoteEventNameListCount; j++) {
|
|||
|
|
currentRemoteEventSystem.callRemoteEvent (currentHitReactionInfo.remoteEventNameList [j]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!ignoreParryActive) {
|
|||
|
|
if (currentHitReactionInfo.useRemoteEventToEnableParryInteraction) {
|
|||
|
|
for (int j = 0; j < currentHitReactionInfo.remoteEventToEnableParryInteractionNameList.Count; j++) {
|
|||
|
|
currentRemoteEventSystem.callRemoteEvent (currentHitReactionInfo.remoteEventToEnableParryInteractionNameList [j]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void checkDamageStateTemporally (float damageReceived, bool damageBlockedByShieldSystem)
|
|||
|
|
{
|
|||
|
|
// print (damageReceived);
|
|||
|
|
|
|||
|
|
bool damageStateFound = false;
|
|||
|
|
|
|||
|
|
if (damageReceived > 0) {
|
|||
|
|
|
|||
|
|
if (damageBlockedByShieldSystem) {
|
|||
|
|
damageReceived /= 2;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (int i = 0; i < damageStateInfoList.Count; i++) {
|
|||
|
|
damageStateInfo currentDamageStateInfo = damageStateInfoList [i];
|
|||
|
|
|
|||
|
|
if (!damageStateFound && currentDamageStateInfo.damageStateEnabled) {
|
|||
|
|
if (currentDamageStateInfo.damageStateRange.x <= damageReceived &&
|
|||
|
|
currentDamageStateInfo.damageStateRange.y >= damageReceived) {
|
|||
|
|
// print (currentDamageStateInfoName);
|
|||
|
|
|
|||
|
|
currentDamageStateInfo.eventOnDamageState.Invoke ();
|
|||
|
|
|
|||
|
|
damageStateFound = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!damageStateFound) {
|
|||
|
|
for (int i = 0; i < damageStateInfoList.Count; i++) {
|
|||
|
|
damageStateInfo currentDamageStateInfo = damageStateInfoList [i];
|
|||
|
|
|
|||
|
|
if (!damageStateFound && currentDamageStateInfo.damageStateEnabled) {
|
|||
|
|
if (currentDamageStateInfo.useAsDefaultState) {
|
|||
|
|
currentDamageStateInfo.eventOnDamageState.Invoke ();
|
|||
|
|
|
|||
|
|
// print (currentDamageStateInfo.Name);
|
|||
|
|
|
|||
|
|
damageStateFound = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void setHitReactionActiveState (bool state)
|
|||
|
|
{
|
|||
|
|
hitReactionActive = state;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public bool getHitReactionActiveState ()
|
|||
|
|
{
|
|||
|
|
return hitReactionActive;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void setHitReactionBlockIDValue (int newBlockID)
|
|||
|
|
{
|
|||
|
|
currentBlockID = newBlockID;
|
|||
|
|
|
|||
|
|
if (currentBlockID != -1) {
|
|||
|
|
|
|||
|
|
currentBlockIDToCheck = -1;
|
|||
|
|
|
|||
|
|
for (int i = 0; i < hitReactionInfoList.Count; i++) {
|
|||
|
|
hitReactionInfo temporalReationInfo = hitReactionInfoList [i];
|
|||
|
|
|
|||
|
|
if (currentBlockIDToCheck == -1 &&
|
|||
|
|
temporalReationInfo.reactionOnBlock &&
|
|||
|
|
temporalReationInfo.reactionCategory.Equals (currentReactionCategory) &&
|
|||
|
|
temporalReationInfo.canUsePerfectBlock &&
|
|||
|
|
temporalReationInfo.blockID == currentBlockID) {
|
|||
|
|
|
|||
|
|
float probabilityForPerfectBlock = Random.Range (0, 100);
|
|||
|
|
|
|||
|
|
if (temporalReationInfo.probabilityForPerfectBlock >= probabilityForPerfectBlock) {
|
|||
|
|
currentBlockIDToCheck = i;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (currentBlockIDToCheck > -1) {
|
|||
|
|
|
|||
|
|
lastTimeBlockActive = Time.time;
|
|||
|
|
|
|||
|
|
setPerfectBlockDuration ();
|
|||
|
|
} else {
|
|||
|
|
lastTimeBlockActive = 0;
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
lastTimeBlockActive = 0;
|
|||
|
|
|
|||
|
|
stopSetPerfectBlockDurationCoroutine ();
|
|||
|
|
|
|||
|
|
if (currentBlockIDToCheck > -1) {
|
|||
|
|
hitReactionInfoList [currentBlockIDToCheck].eventOnDisablePerfectBlock.Invoke ();
|
|||
|
|
|
|||
|
|
currentBlockIDToCheck = -1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void setPerfectBlockDuration ()
|
|||
|
|
{
|
|||
|
|
stopSetPerfectBlockDurationCoroutine ();
|
|||
|
|
|
|||
|
|
perfectBlockCoroutine = StartCoroutine (setPerfectBlockDurationCoroutine ());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void stopSetPerfectBlockDurationCoroutine ()
|
|||
|
|
{
|
|||
|
|
if (perfectBlockCoroutine != null) {
|
|||
|
|
StopCoroutine (perfectBlockCoroutine);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
IEnumerator setPerfectBlockDurationCoroutine ()
|
|||
|
|
{
|
|||
|
|
hitReactionInfo temporalReationInfo = hitReactionInfoList [currentBlockIDToCheck];
|
|||
|
|
|
|||
|
|
temporalReationInfo.eventOnEnablePerfectBlock.Invoke ();
|
|||
|
|
|
|||
|
|
float maxTimeToPerfectBlock = temporalReationInfo.maxTimeToPerfectBlock;
|
|||
|
|
|
|||
|
|
var currentWaitTime = new WaitForSeconds (maxTimeToPerfectBlock);
|
|||
|
|
|
|||
|
|
yield return currentWaitTime;
|
|||
|
|
|
|||
|
|
temporalReationInfo.eventOnDisablePerfectBlock.Invoke ();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void setCurrentReactionCategory (string newCategory)
|
|||
|
|
{
|
|||
|
|
currentReactionCategory = newCategory;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void setNewProbabilityToActivateReactionMultiplierValue (float newValue)
|
|||
|
|
{
|
|||
|
|
if (!canChangeProbabilityMultiplierExternally) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
probabilityToActivateReactionMultiplier = newValue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void setHitReactionsEnabledState (bool state)
|
|||
|
|
{
|
|||
|
|
hitReactionsEnabled = state;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void setDamageReactionPausedState (bool state)
|
|||
|
|
{
|
|||
|
|
damageReactionPaused = state;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public bool isDamageReactionPaused ()
|
|||
|
|
{
|
|||
|
|
return damageReactionPaused;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void setIgnoreParryActiveState (bool state)
|
|||
|
|
{
|
|||
|
|
ignoreParryActive = state;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void setHitReactionsEnabledStateFromEditor (bool state)
|
|||
|
|
{
|
|||
|
|
setHitReactionsEnabledState (state);
|
|||
|
|
|
|||
|
|
updateComponent ();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void updateComponent ()
|
|||
|
|
{
|
|||
|
|
GKC_Utils.updateComponent (this);
|
|||
|
|
|
|||
|
|
GKC_Utils.updateDirtyScene ("Updating Damage Reaction System " + gameObject.name, gameObject);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[System.Serializable]
|
|||
|
|
public class hitReactionInfo
|
|||
|
|
{
|
|||
|
|
[Header ("Main Settings")]
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public string Name;
|
|||
|
|
public bool reactionEnabled = true;
|
|||
|
|
|
|||
|
|
public int damageReactionID = -1;
|
|||
|
|
|
|||
|
|
public string reactionCategory;
|
|||
|
|
|
|||
|
|
public float minAmountToReceiveDamage;
|
|||
|
|
|
|||
|
|
public hitDamageDirection damageDirection;
|
|||
|
|
|
|||
|
|
public bool useProbabilityToActivateReaction = true;
|
|||
|
|
|
|||
|
|
public float probabilityToActivateReaction = 100;
|
|||
|
|
|
|||
|
|
public float minWaitTimeToPlayHitReactionAgain;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
[Header ("Pause Reaction Activation Settings")]
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public bool setReactionDelayUntilNextReaction;
|
|||
|
|
public float reactionDelayUntilNextReaction;
|
|||
|
|
|
|||
|
|
public bool ignoreReactionDelayFromPreviousReaction;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
[Header ("Action Settings")]
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public bool playHitAction;
|
|||
|
|
public string hitActionName;
|
|||
|
|
|
|||
|
|
public string hitActionNameOnPerfectBlock;
|
|||
|
|
|
|||
|
|
public bool stopPreviousActionIfActive;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
[Header ("Hit Reaction On Block Settings")]
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public bool reactionOnBlock;
|
|||
|
|
public int blockID;
|
|||
|
|
|
|||
|
|
public bool useStaminaOnBlock;
|
|||
|
|
public float staminaToUseMultiplier = 1;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public eventParameters.eventToCallWithAmount eventToUseStamina;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
[Header ("Perfect Block Settings")]
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public bool canUsePerfectBlock;
|
|||
|
|
|
|||
|
|
public bool activateHitReactionOnPerfectBlock;
|
|||
|
|
|
|||
|
|
public float probabilityForPerfectBlock = 100;
|
|||
|
|
|
|||
|
|
public float maxTimeToPerfectBlock = 0.5f;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public UnityEvent eventOnEnablePerfectBlock;
|
|||
|
|
public UnityEvent eventOnDisablePerfectBlock;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
[Header ("Events Settings")]
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public UnityEvent eventOnHit;
|
|||
|
|
|
|||
|
|
[HideInInspector] public float lastTimeHitReaction;
|
|||
|
|
|
|||
|
|
public UnityEvent eventOnHitReactionOnPerfectBlock;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
[Header ("Remote Events Settings")]
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public bool checkObjectsToUseRemoteEventsOnDamage;
|
|||
|
|
public LayerMask layerToUseRemoteEventsOnDamage;
|
|||
|
|
|
|||
|
|
public bool useRemoteEvent;
|
|||
|
|
public List<string> remoteEventNameList;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public bool useRemoteEventToEnableParryInteraction;
|
|||
|
|
public List<string> remoteEventToEnableParryInteractionNameList;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public enum hitDamageDirection
|
|||
|
|
{
|
|||
|
|
front,
|
|||
|
|
backward,
|
|||
|
|
right,
|
|||
|
|
left,
|
|||
|
|
anyDirection
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[System.Serializable]
|
|||
|
|
public class damageStateInfo
|
|||
|
|
{
|
|||
|
|
public string Name;
|
|||
|
|
|
|||
|
|
public bool damageStateEnabled;
|
|||
|
|
|
|||
|
|
public Vector2 damageStateRange;
|
|||
|
|
|
|||
|
|
public bool useAsDefaultState;
|
|||
|
|
|
|||
|
|
public UnityEvent eventOnDamageState;
|
|||
|
|
}
|
|||
|
|
}
|