Files
FueraDeEscala/Assets/Game Kit Controller/Scripts/Abilities System/Custom Abilities/Grappling Hook System/grapplingHookSystem.cs
Robii Aragon fd87a6ffd5 add ckg
plantilla base para movimiento básico
2026-02-05 05:07:55 -08:00

2164 lines
72 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using System.Linq;
public class grapplingHookSystem : MonoBehaviour
{
[Header ("Main Settings")]
[Space]
public bool grapplingHookEnabled = true;
public float maxRaycastDistance = 100;
public LayerMask layerToCheckSurfaces;
public float minDistanceToAttract = 0.5f;
public bool applySpeedOnHookStop;
public float extraSpeedOnHookStopMultiplier = 1;
public bool rotatePlayerTowardTargetDirection;
public float rotatePlayerSpeed;
public float minAngleDifferenceToRotatePlayer;
public float extraForceOnHookStopMultiplier = 4;
public float maxForceToApplyOnHookStop = 40;
[Space]
[Header ("Swing Settings")]
[Space]
public bool useSwingForcesActive;
public float gravityForceDown = 9.8f;
public float gravityForceDownMultiplier2_5d = 0.8f;
public float hookPullForceOnGround = 300;
public float hookPullForceOnAir = 300;
public float hookManualExtendForce = 130;
public float hookManualPullForce = 130;
public float hookPullForceMultiplier2_5d = 0.2f;
public ForceMode hookPullForceMode;
[Space]
public float swingDamper = 6;
public float swingDamper2_5d = 2;
[Space]
public float airControlPrecisionRegularSpeed = 3;
public float airControlPrecisionIncreasedSpeed = 7;
public float durationAutoPullOnThrowHookOnGround = 0.5f;
public float durationAutoPullOnThrowHookOnAir = 0.5f;
[Space]
public bool useMaxSwingLength;
public float maxSwingLength;
public float raycastDistanceToCheckBelowPlayer = 5;
public bool jumpOnSwingEnabled = true;
public Vector3 jumpOnSwingForceAmount;
public Vector3 jumpOnSwingForceAmount2_5d = new Vector3 (0, 5, 0);
public bool checkIfTooCloseToGroundToStopSwing;
public float minDistanceToStopSwingOnGroundDetected;
public bool onlyCheckIfCloseToGroundWhenAutomaticPullNotActive;
public ForceMode swingForceMode = ForceMode.Impulse;
public float maxSwingSpeedClamp = 40;
public bool manualPullEnabled = true;
public bool manualExtendEnabled = true;
[Space]
[Space]
public bool chainNextSwingIfInputHold;
public float minTimeToKeepSwingBeforeNext = 1;
public float minWaitTimeToThrowNextSwing = 0.5f;
public bool stopSwingHoldChainIfNotSurfaceLocated = true;
public bool getClosestSurfaceIfNotFoundOnMainRaycast;
public Vector2 swingClosestSurfaceAngleSearchRange = new Vector2 (-40, 40);
public float probabilityToUseJumpOnSwingEnd = 30;
[Space]
[Header ("Attract Objects Settings")]
[Space]
public bool attractObjectsEnabled = true;
public float regularAttractionForce;
public float increasedAttractionForce;
public float minDistanceToStopAttractObject;
public bool addUpForceForAttraction;
public float upForceForAttraction;
public float addUpForceForAttractionDuration;
[Space]
[Header ("Movement Settings")]
[Space]
public float regularMovementSpeed = 6;
public float increasedMovementSpeed;
public float inputMovementMultiplier = 3;
public float airControlAmount = 20;
public bool useVerticalMovementOnHook;
public bool ignoreBackWardsMovementOnHook;
public bool addVerticalFallingSpeed;
public float verticalFallingSpeed;
[Space]
[Header ("Other Settings")]
[Space]
public bool checkIfObjectStuck = true;
public float timeToStopHookIfStuck = 2;
public float minDistanceToCheckStuck = 1;
[Space]
[Header ("External Controller Settings")]
[Space]
public bool checkExternalControllerStatesToIgnore;
public List<otherExternalControllerInfo> otherExternalControllerInfoList = new List<otherExternalControllerInfo> ();
[Space]
public bool avoidListOfExternalControllerStates;
public List<string> externalControllerToAvoidList = new List<string> ();
[Space]
[Header ("Action System Settings")]
[Space]
public int customActionCategoryID = -1;
public int regularActionCategoryID = -1;
[Space]
[Header ("Camera Settings")]
[Space]
public bool changeCameraStateOnThirdPerson;
public string cameraStateNameOnGrapplingHookActivate;
public string cameraStateNameOnGrapplingHookDeactivate;
public bool keepCameraStateActiveWhileOnAir;
public bool changeFovOnHookActive;
public float changeFovSpeed;
public float regulaFov;
public float increaseSpeedFov;
public bool useCameraShake;
public string regularCameraShakeName;
public string increaseCamaraShakeName;
[Space]
[Header ("Animator Settings")]
[Space]
public bool setAnimatorState;
public string hookStartActionName;
public string hookEndActionName;
public int hookStartActionID;
public int hookEndActionID;
public string actionActiveAnimatorName = "Action Active";
public string actionIDAnimatorName = "Action ID";
public float minDistancePercentageToUseHookEndAction = 0.1f;
[Space]
[Header ("Swing Animation Settings")]
[Space]
public bool useSwingJumpOnAir;
public int swingJumpOnAirID = 39475;
public int swingMovingPassCenterID = 92783;
public int swingMovingForwardID = 92782;
[Space]
[Header ("Throw Hook Animation Settings")]
[Space]
public bool useAnimationToThrowHook;
public bool useAnimationToThrowHookOnlyOnGround;
public string throwHookAnimationName;
public float throwHookAnimationDuration;
public bool throwAnimationInProcess;
public bool checkIfSurfaceDetectedBeforeAnimation;
[Space]
[Header ("Debug")]
[Space]
public bool showDebugPrint;
public bool grapplingHookActive;
public bool grapplingHookUpdateActive;
public Vector3 currentForceToApply;
public Vector3 movementDirection;
public float currentDistance;
public float currentMovementSpeed;
public Transform currentGrapplingHookTarget;
public float angleToTargetDirection;
public bool attractingObjectActive;
public bool checkingToRemoveHookActive;
public bool manualExtendActive;
public bool manualPullActive;
public bool automaticPullActive;
public float currentMinDistanceToStopAttractObject;
public bool attractPlayerActive;
public bool ignoreApplySpeedOnHookStopOnPlayer;
public bool resetPlayerSpeedOnHookStop;
public bool isCameraTypeFree;
public bool isPlayerMovingOn3dWorld;
[Space]
[Header ("Debug Attract")]
[Space]
public bool useCustomForceAttractionValues;
public float customMinDistanceToStopAttractObject;
public bool customAddUpForceForAttraction;
public float customUpForceForAttraction;
public float customAddUpForceForAttractionDuration;
[Space]
[Header ("Debug Swing")]
[Space]
public bool showGizmo;
public Vector3 swingGravityForces = Vector3.zero;
public bool swingHoldInputActive;
public float angleWithCenter;
public bool swingPassCenterChecked;
public Vector3 swingMovementDirection;
[Space]
[Header ("Events Settings")]
[Space]
public bool useEventsOnGrapplingHook;
public UnityEvent eventOnGrapplingHookActivate;
public UnityEvent eventOnGrapplingHookDeactivate;
public eventParameters.eventToCallWithVector3 eventWithDirectionOnHookActive;
public bool useEventsOnChangeCameraView;
public UnityEvent eventOnSetFirstPersonView;
public UnityEvent eventOnSetThirdPersonView;
public eventParameters.eventToCallWithTransform eventToSendNewGrapplingHookTipTransform;
[Space]
[Header ("Components")]
[Space]
public Transform grapplingHookTipTransform;
public Transform playerControllerTransform;
public playerController mainPlayerController;
public gravitySystem mainGravitySystem;
public Transform mainCameraTransform;
public Rigidbody mainRigidbody;
public playerCamera mainPlayerCamera;
public remoteEventSystem mainRemoteEventSystem;
public Animator mainAnimator;
public Rigidbody mainSwingRigidbody;
public Collider mainSwingCollider;
public SpringJoint swingJoint;
RaycastHit hit;
bool increaseSpeedActive;
bool checkinGrapplingHookCameraStateAfterDeactivate;
Vector3 pullForceToApply;
Vector3 pullForceToApplyNormalize;
int actionActiveAnimatorID;
int actionIDAnimatorID;
bool closeToReachTargetChecked;
float initialDistanceToTarget;
bool firstPersonActive;
bool previoslyFirstPersonActive;
objectToAttractWithGrapplingHook currentobjectToAttractWithGrapplingHook;
GameObject currentObjectToAttract;
Rigidbody currentRigidbodyToAttract;
float lastTimeHookActive;
bool attractionHookRemovedByDistance;
Vector3 currentRaycastPosition;
Vector3 currentRaycastDirection;
Coroutine grapplingHookCoroutine;
float lastTimeObjectMoving;
float lastDistanceToObject;
Coroutine animationCoroutine;
Vector3 lastVelocityAdded;
float lastTimeAutomaticPullActive;
bool swingRaycastDetected;
RaycastHit swingRacyastCheck;
bool useHookTargetPostionOffset;
Vector3 hookTargetPositionOffset = Vector3.zero;
bool ignoreApplySpeedOnHookStopTemporally;
bool lastTimeHookActivatedPlayerOnGround;
bool addJointAfterFinishingThrowAnimationActive;
bool useObjectTargetPositionTransform;
Transform objectTargetPositionTransform;
void Start ()
{
actionActiveAnimatorID = Animator.StringToHash (actionActiveAnimatorName);
actionIDAnimatorID = Animator.StringToHash (actionIDAnimatorName);
}
public void stopGrapplingHookCoroutine ()
{
if (grapplingHookCoroutine != null) {
StopCoroutine (grapplingHookCoroutine);
}
grapplingHookUpdateActive = false;
}
IEnumerator activateGrapplingHookCorouine ()
{
var waitTime = new WaitForFixedUpdate ();
while (true) {
yield return waitTime;
updateGrapplingHookState ();
}
}
void updateGrapplingHookState ()
{
if (attractingObjectActive) {
applyAttractionForces ();
} else {
if (grapplingHookActive) {
applyHookForces ();
if (useEventsOnChangeCameraView) {
firstPersonActive = mainPlayerCamera.isFirstPersonActive ();
if (firstPersonActive != previoslyFirstPersonActive) {
previoslyFirstPersonActive = firstPersonActive;
if (firstPersonActive) {
eventOnSetFirstPersonView.Invoke ();
} else {
eventOnSetThirdPersonView.Invoke ();
}
}
}
}
}
}
public void stopCheckinGrapplingHookCameraStateAfterDeactivateCoroutine ()
{
if (updateCheckinGrapplingHookCameraStateAfterDeactivateCoroutine != null) {
StopCoroutine (updateCheckinGrapplingHookCameraStateAfterDeactivateCoroutine);
}
checkinGrapplingHookCameraStateAfterDeactivate = false;
}
Coroutine updateCheckinGrapplingHookCameraStateAfterDeactivateCoroutine;
IEnumerator checkinGrapplingHookCameraStateAfterDeactivateCoroutine ()
{
var waitTime = new WaitForFixedUpdate ();
while (true) {
yield return waitTime;
updateCheckinGrapplingHookCameraStateAfterDeactivate ();
}
}
void updateCheckinGrapplingHookCameraStateAfterDeactivate ()
{
if (checkinGrapplingHookCameraStateAfterDeactivate) {
if (mainPlayerController.isPlayerOnGround ()) {
if (!mainPlayerCamera.isFirstPersonActive () && mainPlayerCamera.isCameraTypeFree ()) {
mainPlayerCamera.setCameraStateExternally (cameraStateNameOnGrapplingHookDeactivate);
}
checkinGrapplingHookCameraStateAfterDeactivate = false;
stopGrapplingHookCoroutine ();
}
}
}
public Vector3 TransformDirectionHorizontal (Transform t, Vector3 v)
{
return ToHorizontal (t.TransformDirection (v)).normalized;
}
public Vector3 ToHorizontal (Vector3 v)
{
return Vector3.ProjectOnPlane (v, Vector3.up);
}
void updateSwingForces (Vector3 playerPosition, Vector3 targetPosition)
{
Vector2 rawAxisValues = mainPlayerController.getRawAxisValues ();
if (isPlayerMovingOn3dWorld) {
movementDirection = new Vector3 (rawAxisValues.x, 0, rawAxisValues.y).normalized;
} else {
movementDirection = new Vector3 (rawAxisValues.x, 0, 0).normalized;
}
if (lastTimeAutomaticPullActive > 0) {
if (Time.time > lastTimeAutomaticPullActive + 0.5f) {
lastTimeAutomaticPullActive = 0;
}
} else {
automaticPullActive = false;
}
if (isPlayerMovingOn3dWorld) {
if (Physics.Raycast (playerPosition, -playerControllerTransform.up, out hit, raycastDistanceToCheckBelowPlayer, layerToCheckSurfaces)) {
automaticPullActive = true;
lastTimeAutomaticPullActive = Time.time;
}
}
if (lastTimeHookActivatedPlayerOnGround) {
if (durationAutoPullOnThrowHookOnGround > 0) {
if (Time.time < durationAutoPullOnThrowHookOnGround + lastTimeHookActive) {
automaticPullActive = true;
lastTimeAutomaticPullActive = Time.time;
}
}
} else {
if (durationAutoPullOnThrowHookOnAir > 0) {
if (Time.time < durationAutoPullOnThrowHookOnAir + lastTimeHookActive) {
automaticPullActive = true;
lastTimeAutomaticPullActive = Time.time;
}
}
}
if (useMaxSwingLength) {
if (currentDistance > maxSwingLength) {
automaticPullActive = true;
lastTimeAutomaticPullActive = Time.time;
}
}
if (currentDistance < 3) {
removeHook ();
return;
}
float deltaTime = Time.smoothDeltaTime;
if (isPlayerMovingOn3dWorld) {
swingMovementDirection = TransformDirectionHorizontal (mainPlayerCamera.transform, movementDirection);
} else {
Transform currentLockedCameraTransform = mainPlayerCamera.getLockedCameraTransform ();
swingMovementDirection = currentLockedCameraTransform.right * movementDirection.x;
}
if (increaseSpeedActive) {
swingMovementDirection *= airControlPrecisionIncreasedSpeed;
} else {
swingMovementDirection *= airControlPrecisionRegularSpeed;
}
float currentGravityForceDown = gravityForceDown;
if (!isPlayerMovingOn3dWorld) {
currentGravityForceDown *= gravityForceDownMultiplier2_5d;
}
swingMovementDirection += -mainPlayerController.getCurrentNormal () * currentGravityForceDown;
mainSwingRigidbody.AddForce (swingMovementDirection, swingForceMode);
if (!isPlayerMovingOn3dWorld) {
if (!automaticPullActive) {
if (rawAxisValues.y != 0) {
if (rawAxisValues.y < 0) {
if (manualExtendEnabled) {
if (!manualExtendActive) {
manualExtendActive = true;
manualPullActive = false;
}
}
} else {
if (manualPullEnabled) {
if (!manualPullActive) {
manualExtendActive = false;
manualPullActive = true;
}
}
}
} else {
manualExtendActive = false;
manualPullActive = false;
}
}
}
if (automaticPullActive) {
Vector3 directionToPoint = targetPosition - mainSwingRigidbody.position;
float currentHookPullForce = hookPullForceOnAir;
if (lastTimeHookActivatedPlayerOnGround) {
currentHookPullForce = hookPullForceOnGround;
}
if (!isPlayerMovingOn3dWorld) {
currentHookPullForce *= hookPullForceMultiplier2_5d;
}
Vector3 extraForce = directionToPoint.normalized * currentHookPullForce * deltaTime;
mainSwingRigidbody.AddForce (extraForce, hookPullForceMode);
float distanceFromPoint = GKC_Utils.distance (mainSwingRigidbody.position, targetPosition);
swingJoint.maxDistance = distanceFromPoint * 0.8f;
swingJoint.minDistance = distanceFromPoint * 0.25f;
}
if (manualPullActive) {
float extendedDistanceFromPoint = GKC_Utils.distance (mainSwingRigidbody.position, targetPosition) - hookManualPullForce;
swingJoint.maxDistance = extendedDistanceFromPoint * 0.8f;
swingJoint.minDistance = extendedDistanceFromPoint * 0.25f;
}
if (manualExtendActive) {
float extendedDistanceFromPoint = GKC_Utils.distance (mainSwingRigidbody.position, targetPosition) + hookManualExtendForce;
swingJoint.maxDistance = extendedDistanceFromPoint * 0.8f;
swingJoint.minDistance = extendedDistanceFromPoint * 0.25f;
}
if (maxSwingSpeedClamp != 0) {
mainSwingRigidbody.linearVelocity = Vector3.ClampMagnitude (mainSwingRigidbody.linearVelocity, maxSwingSpeedClamp);
}
currentDistance = GKC_Utils.distance (playerPosition, grapplingHookTipTransform.position);
if (isPlayerMovingOn3dWorld) {
mainPlayerController.setExtraCharacterVelocity (mainSwingRigidbody.linearVelocity);
}
mainRigidbody.position = mainSwingRigidbody.position;
if (checkIfTooCloseToGroundToStopSwing && Time.time > lastTimeHookActive + 0.6f) {
if (!automaticPullActive || !onlyCheckIfCloseToGroundWhenAutomaticPullNotActive) {
Vector3 raycastPosition = playerControllerTransform.position + playerControllerTransform.up;
if (Physics.Raycast (raycastPosition, -playerControllerTransform.up, out hit, minDistanceToStopSwingOnGroundDetected, layerToCheckSurfaces)) {
removeHook ();
}
}
}
Vector3 heading = new Vector3 (targetPosition.x, 0, targetPosition.z) - new Vector3 (playerPosition.x, 0, playerPosition.z);
float distance = heading.magnitude;
Vector3 movementDirectionWithHookPoint = heading / distance;
angleWithCenter = Vector3.Angle (movementDirectionWithHookPoint, playerControllerTransform.forward);
bool swingCenterReached = Mathf.Abs (angleWithCenter) > 90;
if (swingCenterReached) {
if (!swingPassCenterChecked) {
if (setAnimatorState) {
mainAnimator.SetInteger (actionIDAnimatorID, swingMovingPassCenterID);
}
swingPassCenterChecked = true;
lastTimeSwingPassCenterChecked = Time.time;
if (showDebugPrint) {
print ("swing center reached");
}
}
} else {
if (swingPassCenterChecked) {
if (setAnimatorState) {
mainAnimator.SetInteger (actionIDAnimatorID, swingMovingForwardID);
}
swingPassCenterChecked = false;
lastTimeSwingPassCenterChecked = -1;
if (showDebugPrint) {
print ("swing moving forward reached");
}
}
}
}
float lastTimeSwingPassCenterChecked = -1;
public void applyHookForces ()
{
currentForceToApply = Vector3.zero;
Vector3 playerPosition = playerControllerTransform.position + playerControllerTransform.up;
Vector3 targetPosition = grapplingHookTipTransform.position;
if (useObjectTargetPositionTransform) {
targetPosition = objectTargetPositionTransform.position;
}
if (useHookTargetPostionOffset) {
targetPosition += hookTargetPositionOffset;
}
currentDistance = GKC_Utils.distance (playerPosition, targetPosition);
if (useSwingForcesActive) {
updateSwingForces (playerPosition, targetPosition);
} else {
if (attractPlayerActive) {
if (useCustomForceAttractionValues) {
currentMinDistanceToStopAttractObject = customMinDistanceToStopAttractObject;
} else {
currentMinDistanceToStopAttractObject = minDistanceToAttract;
}
} else {
currentMinDistanceToStopAttractObject = minDistanceToAttract;
}
if (currentDistance > currentMinDistanceToStopAttractObject) {
pullForceToApply = (targetPosition - playerPosition).normalized;
} else {
removeHook ();
return;
}
if (increaseSpeedActive) {
currentMovementSpeed = increasedMovementSpeed;
} else {
currentMovementSpeed = regularMovementSpeed;
}
currentForceToApply += pullForceToApply * currentMovementSpeed;
pullForceToApplyNormalize = pullForceToApply.normalized;
movementDirection =
(mainPlayerController.getHorizontalInput () * Vector3.Cross (playerControllerTransform.up, pullForceToApplyNormalize));
if (useVerticalMovementOnHook) {
movementDirection += (mainPlayerController.getVerticalInput () * playerControllerTransform.up);
} else {
float verticalInputValue = mainPlayerController.getVerticalInput ();
if (ignoreBackWardsMovementOnHook) {
verticalInputValue = Mathf.Clamp (verticalInputValue, 0, 1);
}
movementDirection += (verticalInputValue * pullForceToApplyNormalize);
}
movementDirection *= inputMovementMultiplier;
currentForceToApply += movementDirection;
if (addVerticalFallingSpeed) {
currentForceToApply -= playerControllerTransform.up * verticalFallingSpeed;
}
mainPlayerController.setExternalForceOnAir (currentForceToApply, airControlAmount);
lastVelocityAdded = currentForceToApply;
}
if (rotatePlayerTowardTargetDirection) {
if (mainPlayerController.isFullBodyAwarenessActive ()) {
Transform playerCameraTransform = mainPlayerCamera.transform;
pullForceToApplyNormalize -= playerCameraTransform.up * playerCameraTransform.InverseTransformDirection (pullForceToApplyNormalize).y;
angleToTargetDirection = Vector3.SignedAngle (playerCameraTransform.forward, pullForceToApplyNormalize, playerCameraTransform.up);
if (Mathf.Abs (angleToTargetDirection) > minAngleDifferenceToRotatePlayer) {
playerCameraTransform.Rotate (0, (angleToTargetDirection / 2) * rotatePlayerSpeed * Time.deltaTime, 0);
}
} else {
pullForceToApplyNormalize -= playerControllerTransform.up * playerControllerTransform.InverseTransformDirection (pullForceToApplyNormalize).y;
angleToTargetDirection = Vector3.SignedAngle (playerControllerTransform.forward, pullForceToApplyNormalize, playerControllerTransform.up);
if (Mathf.Abs (angleToTargetDirection) > minAngleDifferenceToRotatePlayer) {
playerControllerTransform.Rotate (0, (angleToTargetDirection / 2) * rotatePlayerSpeed * Time.deltaTime, 0);
}
}
}
if (!useSwingForcesActive) {
if (!closeToReachTargetChecked) {
if (currentDistance < initialDistanceToTarget * minDistancePercentageToUseHookEndAction) {
if (setAnimatorState) {
mainAnimator.SetInteger (actionIDAnimatorID, hookEndActionID);
mainAnimator.CrossFadeInFixedTime (hookEndActionName, 0.1f);
}
closeToReachTargetChecked = true;
}
}
checkIfObjectIsMoving ();
}
}
public void applyAttractionForces ()
{
bool stopHookResult = false;
if (currentRigidbodyToAttract == null) {
stopHookResult = true;
}
if (grapplingHookTipTransform == null) {
stopHookResult = true;
}
if (stopHookResult) {
if (grapplingHookTipTransform == null) {
GameObject grapplingHookTipTransformGameObject = new GameObject ();
grapplingHookTipTransform = grapplingHookTipTransformGameObject.transform;
grapplingHookTipTransform.name = "Grappling Hook Tip Transform";
eventToSendNewGrapplingHookTipTransform.Invoke (grapplingHookTipTransform);
}
removeGrapplingHook ();
attractingObjectActive = false;
return;
}
currentForceToApply = Vector3.zero;
Vector3 playerPosition = playerControllerTransform.position + playerControllerTransform.up;
currentDistance = GKC_Utils.distance (playerPosition, grapplingHookTipTransform.position);
if (useCustomForceAttractionValues) {
currentMinDistanceToStopAttractObject = customMinDistanceToStopAttractObject;
} else {
currentMinDistanceToStopAttractObject = minDistanceToStopAttractObject;
}
if (currentDistance > currentMinDistanceToStopAttractObject) {
pullForceToApply = (playerPosition - grapplingHookTipTransform.position).normalized;
} else {
attractionHookRemovedByDistance = true;
removeHook ();
return;
}
if (increaseSpeedActive) {
currentMovementSpeed = increasedAttractionForce;
} else {
currentMovementSpeed = regularAttractionForce;
}
currentForceToApply += pullForceToApply * currentMovementSpeed;
movementDirection *= inputMovementMultiplier;
currentForceToApply += movementDirection;
if (useCustomForceAttractionValues) {
if (customAddUpForceForAttraction) {
if (Time.time < lastTimeHookActive + customAddUpForceForAttractionDuration) {
currentForceToApply += playerControllerTransform.up * customUpForceForAttraction;
}
}
} else {
if (addUpForceForAttraction) {
if (Time.time < lastTimeHookActive + addUpForceForAttractionDuration) {
currentForceToApply += playerControllerTransform.up * upForceForAttraction;
}
}
}
if (currentRigidbodyToAttract != null) {
currentRigidbodyToAttract.linearVelocity = currentForceToApply;
lastVelocityAdded = currentForceToApply;
}
checkIfObjectIsMoving ();
}
public void checkIfObjectIsMoving ()
{
if (checkIfObjectStuck) {
if (lastTimeObjectMoving == 0) {
Vector3 targetPosition = grapplingHookTipTransform.position;
if (useHookTargetPostionOffset) {
targetPosition += hookTargetPositionOffset;
}
currentDistance = GKC_Utils.distance (playerControllerTransform.position, targetPosition);
lastDistanceToObject = currentDistance;
lastTimeObjectMoving = Time.time;
}
if (Time.time > lastTimeObjectMoving + timeToStopHookIfStuck) {
lastTimeObjectMoving = Time.time;
if ((currentDistance + minDistanceToCheckStuck) >= lastDistanceToObject) {
if (showDebugPrint) {
print ("position hasn't changed in " + timeToStopHookIfStuck + " time, stop hook");
}
removeHook ();
}
lastDistanceToObject = currentDistance;
}
}
}
public void removeHook ()
{
if (grapplingHookActive) {
grapplingHookActive = false;
setCurrentPlayerActionSystemCustomActionCategoryID (false);
if (attractingObjectActive) {
checkEventsOnGrapplingHook (false);
stopGrapplingHookCoroutine ();
} else {
pauseOrResumePlayerState (false);
mainPlayerController.disableExternalForceOnAirActive ();
}
increaseSpeedActive = false;
grapplingHookTipTransform.SetParent (transform);
if (attractObjectsEnabled) {
if (currentobjectToAttractWithGrapplingHook != null) {
if (currentobjectToAttractWithGrapplingHook.useRemoteEventsOnStateChange) {
if (mainRemoteEventSystem != null) {
for (int i = 0; i < currentobjectToAttractWithGrapplingHook.remoteEventNameListOnEnd.Count; i++) {
mainRemoteEventSystem.callRemoteEvent (currentobjectToAttractWithGrapplingHook.remoteEventNameListOnEnd [i]);
}
}
}
if (attractPlayerActive) {
} else {
currentobjectToAttractWithGrapplingHook.setAttractionHookRemovedByDistanceState (attractionHookRemovedByDistance);
currentobjectToAttractWithGrapplingHook.setAttractObjectState (false);
bool canUseExtraInteraction = currentobjectToAttractWithGrapplingHook.autoGrabObjectOnCloseDistance ||
currentobjectToAttractWithGrapplingHook.activateInteractionActionWithObject;
if (canUseExtraInteraction) {
if (currentRigidbodyToAttract != null) {
Vector3 playerPosition = playerControllerTransform.position + playerControllerTransform.up;
currentDistance = GKC_Utils.distance (playerPosition, currentRigidbodyToAttract.transform.position);
if (currentobjectToAttractWithGrapplingHook.autoGrabObjectOnCloseDistance) {
if (currentDistance < currentobjectToAttractWithGrapplingHook.minDistanceToAutoGrab) {
GKC_Utils.grabPhysicalObjectExternally (playerControllerTransform.gameObject, currentRigidbodyToAttract.gameObject);
}
}
if (currentobjectToAttractWithGrapplingHook.activateInteractionActionWithObject) {
if (currentDistance < currentobjectToAttractWithGrapplingHook.minDistanceToActivateInteractionActionWithObject) {
GKC_Utils.useObjectExternally (playerControllerTransform.gameObject, currentobjectToAttractWithGrapplingHook.objectToActivate);
}
}
}
}
attractingObjectActive = false;
currentobjectToAttractWithGrapplingHook = null;
currentObjectToAttract = null;
currentRigidbodyToAttract = null;
attractionHookRemovedByDistance = false;
}
}
}
}
}
public void setGrapplingHookTarget (Transform newTarget)
{
currentGrapplingHookTarget = newTarget;
}
public void setGrapplingHookEnabledState (bool state)
{
grapplingHookEnabled = state;
if (!grapplingHookEnabled) {
removeGrapplingHook ();
}
}
void calculateRaycastValues ()
{
currentRaycastPosition = mainCameraTransform.position;
currentRaycastDirection = mainCameraTransform.forward;
if (!mainPlayerCamera.isCameraTypeFree () && !mainPlayerCamera.isPlayerAiming ()) {
currentRaycastPosition = playerControllerTransform.position + playerControllerTransform.up * 1.3f;
if (useSwingForcesActive) {
currentRaycastDirection = playerControllerTransform.up;
} else {
currentRaycastDirection = playerControllerTransform.forward;
}
}
if (currentGrapplingHookTarget != null) {
currentRaycastDirection = currentGrapplingHookTarget.position - currentRaycastPosition;
currentRaycastDirection.Normalize ();
}
}
public void checkThrowGrapplingHook ()
{
if (grapplingHookEnabled) {
if (!grapplingHookActive) {
bool surfaceDetected = false;
if (useSwingForcesActive) {
if (swingRaycastDetected) {
hit = swingRacyastCheck;
surfaceDetected = true;
}
} else {
calculateRaycastValues ();
if (Physics.Raycast (currentRaycastPosition, currentRaycastDirection, out hit, maxRaycastDistance, layerToCheckSurfaces)) {
surfaceDetected = true;
}
}
if (surfaceDetected) {
if (showDebugPrint) {
print ("surface detected " + hit.collider.gameObject.name);
}
grapplingHookTipTransform.position = hit.point;
grapplingHookTipTransform.SetParent (hit.collider.gameObject.transform);
grapplingHookActive = true;
stopGrapplingHookCoroutine ();
grapplingHookCoroutine = StartCoroutine (activateGrapplingHookCorouine ());
grapplingHookUpdateActive = true;
lastTimeHookActive = Time.time;
lastTimeHookActivatedPlayerOnGround = mainPlayerController.isPlayerOnGround ();
lastTimeObjectMoving = 0;
ignoreApplySpeedOnHookStopOnPlayer = false;
resetPlayerSpeedOnHookStop = false;
grapplingHookTarget currentGrapplingHookTargetSystem = hit.collider.gameObject.GetComponent<grapplingHookTarget> ();
if (currentGrapplingHookTargetSystem != null) {
if (useSwingForcesActive) {
currentGrapplingHookTargetSystem.checkEventOnSwingReceived ();
} else {
currentGrapplingHookTargetSystem.checkEventOnHookReceived ();
}
}
if (attractObjectsEnabled) {
currentObjectToAttract = hit.collider.gameObject;
GameObject currentVehicle = applyDamage.getVehicle (currentObjectToAttract);
if (currentVehicle != null) {
currentObjectToAttract = currentVehicle;
}
currentobjectToAttractWithGrapplingHook = currentObjectToAttract.GetComponent<objectToAttractWithGrapplingHook> ();
if (currentobjectToAttractWithGrapplingHook == null) {
playerComponentsManager currentPlayerComponentsManager = currentObjectToAttract.GetComponent<playerComponentsManager> ();
if (currentPlayerComponentsManager != null) {
currentobjectToAttractWithGrapplingHook = currentPlayerComponentsManager.getObjectToAttractWithGrapplingHook ();
}
}
attractPlayerActive = false;
customMinDistanceToStopAttractObject = 0;
useCustomForceAttractionValues = false;
customAddUpForceForAttraction = false;
customUpForceForAttraction = 0;
customAddUpForceForAttractionDuration = 0;
useHookTargetPostionOffset = false;
hookTargetPositionOffset = Vector3.zero;
useObjectTargetPositionTransform = false;
objectTargetPositionTransform = null;
if (currentobjectToAttractWithGrapplingHook != null) {
if (showDebugPrint) {
print ("currentobjectToAttractWithGrapplingHook component found");
}
attractPlayerActive = currentobjectToAttractWithGrapplingHook.attractPlayerEnabled;
ignoreApplySpeedOnHookStopOnPlayer = currentobjectToAttractWithGrapplingHook.ignoreApplySpeedOnHookStopOnPlayer;
resetPlayerSpeedOnHookStop = currentobjectToAttractWithGrapplingHook.resetPlayerSpeedOnHookStop;
useHookTargetPostionOffset = currentobjectToAttractWithGrapplingHook.useHookTargetPostionOffset;
hookTargetPositionOffset = currentobjectToAttractWithGrapplingHook.hookTargetPositionOffset;
useObjectTargetPositionTransform = currentobjectToAttractWithGrapplingHook.useObjectTargetPositionTransform;
objectTargetPositionTransform = currentobjectToAttractWithGrapplingHook.objectTargetPositionTransform;
if (attractPlayerActive) {
} else {
attractingObjectActive = currentobjectToAttractWithGrapplingHook.setAttractObjectState (true);
if (attractingObjectActive) {
currentRigidbodyToAttract = currentobjectToAttractWithGrapplingHook.getRigidbodyToAttract ();
if (currentRigidbodyToAttract == null) {
print ("WARNING: No rigidbody has been configured in the object " + currentobjectToAttractWithGrapplingHook.name);
removeGrapplingHook ();
return;
}
grapplingHookTipTransform.SetParent (currentRigidbodyToAttract.transform);
grapplingHookTipTransform.position = currentRigidbodyToAttract.position;
}
}
customMinDistanceToStopAttractObject = currentobjectToAttractWithGrapplingHook.customMinDistanceToStopAttractObject;
useCustomForceAttractionValues = currentobjectToAttractWithGrapplingHook.useCustomForceAttractionValues;
customAddUpForceForAttraction = currentobjectToAttractWithGrapplingHook.customAddUpForceForAttraction;
customUpForceForAttraction = currentobjectToAttractWithGrapplingHook.customUpForceForAttraction;
customAddUpForceForAttractionDuration = currentobjectToAttractWithGrapplingHook.customAddUpForceForAttractionDuration;
if (currentobjectToAttractWithGrapplingHook.useRemoteEventsOnStateChange) {
if (mainRemoteEventSystem != null) {
for (int i = 0; i < currentobjectToAttractWithGrapplingHook.remoteEventNameListOnStart.Count; i++) {
mainRemoteEventSystem.callRemoteEvent (currentobjectToAttractWithGrapplingHook.remoteEventNameListOnStart [i]);
}
}
}
}
}
if (attractingObjectActive) {
checkEventsOnGrapplingHook (true);
} else {
pauseOrResumePlayerState (true);
}
checkingToRemoveHookActive = false;
eventWithDirectionOnHookActive.Invoke (currentRaycastDirection);
closeToReachTargetChecked = false;
swingPassCenterChecked = false;
lastTimeSwingPassCenterChecked = -1;
Vector3 playerPosition = playerControllerTransform.position + playerControllerTransform.up;
Vector3 targetPosition = grapplingHookTipTransform.position;
if (useHookTargetPostionOffset) {
targetPosition += hookTargetPositionOffset;
}
initialDistanceToTarget = GKC_Utils.distance (playerPosition, targetPosition);
swingGravityForces = Vector3.zero;
setCurrentPlayerActionSystemCustomActionCategoryID (true);
}
}
}
}
public void removeGrapplingHook ()
{
if (grapplingHookActive) {
if (checkingToRemoveHookActive) {
removeHook ();
}
checkingToRemoveHookActive = true;
}
}
public void checkRemoveGrapplingHook ()
{
if (grapplingHookEnabled) {
removeGrapplingHook ();
if (swingHoldInputActive) {
swingHoldInputActive = false;
stopUpdateSwingHoldInputActiveCoroutine ();
}
}
}
public void checkEventsOnGrapplingHook (bool state)
{
if (useEventsOnGrapplingHook) {
if (state) {
eventOnGrapplingHookActivate.Invoke ();
} else {
eventOnGrapplingHookDeactivate.Invoke ();
}
}
}
public void checkExternalControllerBehaviorToPause (string behaviorName)
{
if (grapplingHookActive) {
if (checkExternalControllerStatesToIgnore) {
externalControllerBehavior currentExternalControllerBehavior = mainPlayerController.getCurrentExternalControllerBehavior ();
if (currentExternalControllerBehavior != null && behaviorName.Equals (currentExternalControllerBehavior.behaviorName)) {
int currentIndex = otherExternalControllerInfoList.FindIndex (s => s.Name.Equals (behaviorName));
if (currentIndex > -1) {
currentExternalControllerBehavior.checkPauseStateDuringExternalForceOrBehavior ();
if (otherExternalControllerInfoList [currentIndex].useEventsOnExternalController) {
otherExternalControllerInfoList [currentIndex].eventToPauseExternalController.Invoke ();
}
}
}
}
}
}
public void pauseOrResumePlayerState (bool state)
{
if (state) {
bool isExternalControllBehaviorActive = mainPlayerController.isExternalControllBehaviorActive ();
bool isWallRunningActive = mainPlayerController.isWallRunningActive ();
if (isExternalControllBehaviorActive || isWallRunningActive) {
externalControllerBehavior currentExternalControllerBehavior = mainPlayerController.getCurrentExternalControllerBehavior ();
if (isWallRunningActive) {
currentExternalControllerBehavior = mainPlayerController.getExternalControllerBehaviorWallRunning ();
}
if (currentExternalControllerBehavior != null) {
bool canDisableExternalControllerState = true;
if (checkExternalControllerStatesToIgnore) {
int currentIndex = otherExternalControllerInfoList.FindIndex (s => s.Name.Equals (currentExternalControllerBehavior.behaviorName));
if (currentIndex > -1) {
currentExternalControllerBehavior.checkPauseStateDuringExternalForceOrBehavior ();
if (otherExternalControllerInfoList [currentIndex].useEventsOnExternalController) {
otherExternalControllerInfoList [currentIndex].eventToPauseExternalController.Invoke ();
}
canDisableExternalControllerState = false;
}
}
if (canDisableExternalControllerState) {
currentExternalControllerBehavior.disableExternalControllerState ();
}
}
if (mainPlayerController.isPlayerOnFreeFloatingMode ()) {
GKC_Utils.enableOrDisableFreeFloatingModeOnState (mainPlayerController.gameObject, false);
}
}
mainPlayerController.setGravityForcePuase (true);
mainPlayerController.setCheckOnGroungPausedState (true);
mainPlayerController.setPlayerOnGroundState (false);
mainGravitySystem.setCameraShakeCanBeUsedState (false);
mainPlayerController.setJumpLegExternallyActiveState (true);
mainPlayerController.setIgnoreExternalActionsActiveState (true);
mainPlayerController.setIKBodyPausedState (true);
} else {
mainPlayerController.setGravityForcePuase (false);
mainPlayerController.setCheckOnGroungPausedState (false);
mainGravitySystem.setCameraShakeCanBeUsedState (true);
mainPlayerController.setJumpLegExternallyActiveState (false);
mainPlayerController.setLastTimeFalling ();
mainPlayerController.setIgnoreExternalActionsActiveState (false);
mainPlayerController.setIKBodyPausedState (false);
mainPlayerController.resetLastMoveInputOnJumpValue ();
}
if (useSwingForcesActive) {
if (state) {
mainPlayerController.setOnGroundAnimatorIDValueWithoutCheck (false);
}
// mainPlayerController.setPauseMainRigidbodyVelocityUpdateState (state);
if (!state) {
removeJoint ();
}
if (!isPlayerMovingOn3dWorld) {
mainPlayerController.setUpdate2_5dClampedPositionPausedState (state);
}
}
checkEventsOnGrapplingHook (state);
bool stopCoroutine = false;
stopCheckinGrapplingHookCameraStateAfterDeactivateCoroutine ();
if (changeCameraStateOnThirdPerson) {
if (!mainPlayerCamera.isFirstPersonActive ()) {
if (state) {
if (mainPlayerCamera.isCameraTypeFree ()) {
mainPlayerCamera.setCameraStateExternally (cameraStateNameOnGrapplingHookActivate);
}
} else {
if (!keepCameraStateActiveWhileOnAir) {
if (mainPlayerCamera.isCameraTypeFree ()) {
mainPlayerCamera.setCameraStateExternally (cameraStateNameOnGrapplingHookDeactivate);
}
stopCoroutine = true;
} else {
checkinGrapplingHookCameraStateAfterDeactivate = true;
updateCheckinGrapplingHookCameraStateAfterDeactivateCoroutine =
StartCoroutine (checkinGrapplingHookCameraStateAfterDeactivateCoroutine ());
stopCoroutine = true;
}
}
} else {
stopCoroutine = true;
}
} else {
stopCoroutine = true;
}
if (changeFovOnHookActive) {
if (state) {
mainPlayerCamera.setMainCameraFov (regulaFov, changeFovSpeed);
} else {
mainPlayerCamera.setOriginalCameraFov ();
}
}
if (useCameraShake) {
if (state) {
mainPlayerCamera.setShakeCameraState (true, regularCameraShakeName);
} else {
mainPlayerCamera.setShakeCameraState (false, "");
mainPlayerCamera.stopShakeCamera ();
}
}
if (showDebugPrint) {
print ("set pause or resume climb state " + state);
}
if (applySpeedOnHookStop) {
if (!state) {
if (!ignoreApplySpeedOnHookStopOnPlayer && !ignoreApplySpeedOnHookStopTemporally) {
lastVelocityAdded *= extraForceOnHookStopMultiplier;
Vector3 forceOnHooKEnd = Vector3.ClampMagnitude (lastVelocityAdded, maxForceToApplyOnHookStop);
mainPlayerController.addExternalForce (forceOnHooKEnd * extraSpeedOnHookStopMultiplier);
if (showDebugPrint) {
print ("addExternalForce");
}
}
if (resetPlayerSpeedOnHookStop) {
mainPlayerController.setPlayerVelocityToZero ();
}
}
}
ignoreApplySpeedOnHookStopTemporally = false;
if (setAnimatorState) {
if (state) {
mainAnimator.SetInteger (actionIDAnimatorID, hookStartActionID);
mainAnimator.CrossFadeInFixedTime (hookStartActionName, 0.1f);
}
mainAnimator.SetBool (actionActiveAnimatorID, state);
}
if (rotatePlayerTowardTargetDirection) {
mainPlayerController.setAddExtraRotationPausedState (state);
}
if (state) {
firstPersonActive = mainPlayerCamera.isFirstPersonActive ();
previoslyFirstPersonActive = !firstPersonActive;
}
if (!state) {
if (stopCoroutine) {
stopGrapplingHookCoroutine ();
}
}
manualPullActive = false;
manualExtendActive = false;
lastTimeAutomaticPullActive = 0;
automaticPullActive = false;
if (avoidListOfExternalControllerStates) {
mainPlayerController.setAvoidListOfExternalControllerStatesActiveState (state, externalControllerToAvoidList);
}
if (!state) {
if (checkExternalControllerStatesToIgnore) {
if (mainPlayerController.isExternalControllBehaviorActive ()) {
externalControllerBehavior currentExternalControllerBehavior = mainPlayerController.getCurrentExternalControllerBehavior ();
if (currentExternalControllerBehavior != null) {
int currentIndex = otherExternalControllerInfoList.FindIndex (s => s.Name == currentExternalControllerBehavior.behaviorName);
if (currentIndex > -1) {
currentExternalControllerBehavior.checkResumeStateAfterExternalForceOrBehavior ();
if (otherExternalControllerInfoList [currentIndex].useEventsOnExternalController) {
otherExternalControllerInfoList [currentIndex].eventToResumeExternalController.Invoke ();
}
}
}
}
}
}
}
public void setIgnoreApplySpeedOnHookStopTemporallyState (bool state)
{
if (grapplingHookActive) {
ignoreApplySpeedOnHookStopTemporally = state;
}
}
void stopThrowHookAnimationCoroutine ()
{
if (animationCoroutine != null) {
StopCoroutine (animationCoroutine);
}
throwAnimationInProcess = false;
}
IEnumerator throwHookAnimationCoroutine ()
{
throwAnimationInProcess = true;
mainPlayerController.setIKBodyPausedState (true);
mainAnimator.CrossFade (throwHookAnimationName, 0.1f);
mainAnimator.SetBool (actionActiveAnimatorID, true);
WaitForSeconds delay = new WaitForSeconds (throwHookAnimationDuration);
yield return delay;
if (addJointAfterFinishingThrowAnimationActive) {
addJoint (swingRacyastCheck.point);
addJointAfterFinishingThrowAnimationActive = false;
}
mainAnimator.SetBool (actionActiveAnimatorID, false);
checkThrowGrapplingHook ();
if (grapplingHookActive) {
checkingToRemoveHookActive = true;
}
throwAnimationInProcess = false;
}
bool checkGetClosestSurfaceIfNotFoundOnMainRaycast (float rightAngle)
{
bool surfaceFoundResult = false;
Vector3 forward = Vector3.zero;
if (isPlayerMovingOn3dWorld) {
forward = mainPlayerCamera.transform.forward;
Vector3 right = mainPlayerCamera.transform.right;
forward = Quaternion.AngleAxis (-rightAngle, right) * forward;
} else {
bool isPlayerLookingAtRightOn2_5d = mainPlayerController.isPlayerLookingAtRightOn2_5d ();
Transform currentLockedCameraTransform = mainPlayerCamera.getLockedCameraTransform ();
forward = playerControllerTransform.forward;
Vector3 up = playerControllerTransform.up;
Quaternion rotation = Quaternion.identity;
if (isPlayerLookingAtRightOn2_5d) {
rotation = Quaternion.AngleAxis (-rightAngle, currentLockedCameraTransform.forward);
} else {
rotation = Quaternion.AngleAxis (-rightAngle, -currentLockedCameraTransform.forward);
}
forward = rotation * up;
}
if (showDebugPrint) {
print (isPlayerMovingOn3dWorld + " " + isCameraTypeFree);
}
if (showGizmo) {
Debug.DrawRay (currentRaycastPosition, forward * maxRaycastDistance * 200, Color.red, 5);
}
float startAngle = 0;
float endAngle = swingClosestSurfaceAngleSearchRange.y;
Vector3 currentForwardDirection = forward;
int loopCount = 0;
bool pointLocated = false;
float closestDistance = Mathf.Infinity;
RaycastHit closestHit = new RaycastHit ();
for (float angle = startAngle; angle <= endAngle; angle += 5f) {
Quaternion rotation = Quaternion.identity;
if (isPlayerMovingOn3dWorld) {
rotation = Quaternion.Euler (0, angle, 0);
} else {
rotation = Quaternion.Euler (0, 0, angle);
}
Vector3 direction = rotation * currentForwardDirection;
if (showGizmo) {
Debug.DrawRay (currentRaycastPosition, direction * maxRaycastDistance, Color.green, 5);
}
surfaceFoundResult = Physics.Raycast (currentRaycastPosition, direction, out hit, maxRaycastDistance, layerToCheckSurfaces);
if (surfaceFoundResult) {
currentRaycastDirection = direction;
float distance = hit.distance;
if (distance < closestDistance) {
closestDistance = distance;
closestHit = hit;
}
}
}
if (surfaceFoundResult) {
hit = closestHit;
}
if (!surfaceFoundResult) {
if (isPlayerMovingOn3dWorld) {
return surfaceFoundResult;
}
startAngle = 0;
endAngle = -swingClosestSurfaceAngleSearchRange.x;
currentForwardDirection = forward;
loopCount = 0;
pointLocated = false;
for (float angle = startAngle; angle <= endAngle; angle += 5f) {
if (!pointLocated) {
Quaternion rotation = Quaternion.identity;
if (isPlayerMovingOn3dWorld) {
rotation = Quaternion.Euler (0, -angle, 0);
} else {
rotation = Quaternion.Euler (-angle, 0, 0);
}
Vector3 direction = rotation * currentForwardDirection;
if (showGizmo) {
Debug.DrawRay (currentRaycastPosition, direction * maxRaycastDistance, Color.green, 5);
}
surfaceFoundResult = Physics.Raycast (currentRaycastPosition, direction, out hit, maxRaycastDistance, layerToCheckSurfaces);
if (surfaceFoundResult) {
pointLocated = true;
currentRaycastDirection = direction;
}
loopCount++;
if (loopCount > 100) {
pointLocated = true;
}
}
}
}
return surfaceFoundResult;
}
public void inputThrowGrapplingHook ()
{
if (!grapplingHookEnabled) {
return;
}
if (throwAnimationInProcess) {
return;
}
addJointAfterFinishingThrowAnimationActive = false;
bool useAnimationResult = false;
if (useAnimationToThrowHook && !mainPlayerCamera.isFirstPersonActive ()) {
useAnimationResult = true;
if (useAnimationToThrowHookOnlyOnGround) {
if (!mainPlayerController.isPlayerOnGround ()) {
useAnimationResult = false;
}
}
}
isCameraTypeFree = mainPlayerCamera.isCameraTypeFree ();
isPlayerMovingOn3dWorld = mainPlayerController.isPlayerMovingOn3dWorld ();
if (useAnimationResult) {
if (!grapplingHookActive) {
if (checkIfSurfaceDetectedBeforeAnimation) {
calculateRaycastValues ();
swingRaycastDetected = false;
bool surfaceFoundResult = false;
if (isPlayerMovingOn3dWorld) {
surfaceFoundResult = Physics.Raycast (currentRaycastPosition, currentRaycastDirection, out hit, maxRaycastDistance, layerToCheckSurfaces);
}
if (showDebugPrint) {
print ("first surface found result " + surfaceFoundResult);
}
if (showGizmo) {
if (surfaceFoundResult) {
Debug.DrawRay (currentRaycastPosition, currentRaycastDirection * maxRaycastDistance, Color.green, 5);
} else {
Debug.DrawRay (currentRaycastPosition, currentRaycastDirection * maxRaycastDistance, Color.red, 5);
}
}
if (!surfaceFoundResult) {
if (useSwingForcesActive) {
if (getClosestSurfaceIfNotFoundOnMainRaycast) {
if (isPlayerMovingOn3dWorld) {
surfaceFoundResult = checkGetClosestSurfaceIfNotFoundOnMainRaycast (60);
if (!surfaceFoundResult) {
surfaceFoundResult = checkGetClosestSurfaceIfNotFoundOnMainRaycast (50);
}
}
if (!surfaceFoundResult) {
surfaceFoundResult = checkGetClosestSurfaceIfNotFoundOnMainRaycast (40);
}
if (!surfaceFoundResult) {
surfaceFoundResult = checkGetClosestSurfaceIfNotFoundOnMainRaycast (30);
}
}
}
}
if (!surfaceFoundResult) {
return;
} else {
if (useSwingForcesActive) {
if (hit.point.y < playerControllerTransform.position.y ||
Mathf.Abs (Mathf.Abs (hit.point.y) - Mathf.Abs (playerControllerTransform.position.y)) < 2) {
if (GKC_Utils.distance (playerControllerTransform.position, hit.point) < 5) {
if (showDebugPrint) {
print ("point detected is below player, cancelling swing");
}
return;
}
}
swingRaycastDetected = true;
swingRacyastCheck = hit;
// addJoint (hit.point);
addJointAfterFinishingThrowAnimationActive = true;
}
}
}
stopThrowHookAnimationCoroutine ();
animationCoroutine = StartCoroutine (throwHookAnimationCoroutine ());
}
} else {
if (useSwingForcesActive) {
swingRaycastDetected = false;
calculateRaycastValues ();
bool surfaceFoundResult = false;
if (isPlayerMovingOn3dWorld) {
surfaceFoundResult = Physics.Raycast (currentRaycastPosition, currentRaycastDirection, out hit, maxRaycastDistance, layerToCheckSurfaces);
}
if (showDebugPrint) {
print ("first surface found result " + surfaceFoundResult);
}
if (showGizmo) {
if (surfaceFoundResult) {
Debug.DrawRay (currentRaycastPosition, currentRaycastDirection * maxRaycastDistance, Color.green, 5);
} else {
Debug.DrawRay (currentRaycastPosition, currentRaycastDirection * maxRaycastDistance, Color.red, 5);
}
}
if (!surfaceFoundResult) {
if (useSwingForcesActive) {
if (getClosestSurfaceIfNotFoundOnMainRaycast) {
if (isPlayerMovingOn3dWorld) {
surfaceFoundResult = checkGetClosestSurfaceIfNotFoundOnMainRaycast (60);
if (!surfaceFoundResult) {
surfaceFoundResult = checkGetClosestSurfaceIfNotFoundOnMainRaycast (50);
}
}
if (!surfaceFoundResult) {
surfaceFoundResult = checkGetClosestSurfaceIfNotFoundOnMainRaycast (40);
}
if (!surfaceFoundResult) {
surfaceFoundResult = checkGetClosestSurfaceIfNotFoundOnMainRaycast (30);
}
}
}
}
if (surfaceFoundResult) {
if (hit.point.y < playerControllerTransform.position.y ||
Mathf.Abs (Mathf.Abs (hit.point.y) - Mathf.Abs (playerControllerTransform.position.y)) < 2) {
if (GKC_Utils.distance (playerControllerTransform.position, hit.point) < 5) {
if (showDebugPrint) {
print ("point detected is below player, cancelling swing");
}
return;
}
}
swingRaycastDetected = true;
swingRacyastCheck = hit;
addJoint (hit.point);
}
}
checkThrowGrapplingHook ();
}
}
void addJoint (Vector3 jointPosition)
{
mainSwingRigidbody.transform.position = mainRigidbody.position;
mainSwingRigidbody.transform.rotation = mainRigidbody.rotation;
mainSwingRigidbody.linearVelocity = mainRigidbody.linearVelocity;
if (isPlayerMovingOn3dWorld) {
swingJoint.damper = swingDamper;
} else {
if (mainPlayerController.isMoveInXAxisOn2_5d ()) {
mainSwingRigidbody.constraints = RigidbodyConstraints.FreezePositionZ | RigidbodyConstraints.FreezeRotation;
} else {
mainSwingRigidbody.constraints = RigidbodyConstraints.FreezePositionX | RigidbodyConstraints.FreezeRotation;
}
swingJoint.damper = swingDamper2_5d;
}
swingJoint.autoConfigureConnectedAnchor = false;
swingJoint.connectedAnchor = jointPosition;
float distanceFromPoint = GKC_Utils.distance (playerControllerTransform.position, jointPosition);
swingJoint.maxDistance = distanceFromPoint * 0.8f;
swingJoint.minDistance = distanceFromPoint * 0.25f;
Physics.IgnoreCollision (mainSwingCollider, mainPlayerController.getMainCollider (), true);
mainSwingRigidbody.gameObject.SetActive (true);
}
void removeJoint ()
{
Vector3 lastVelocity = mainSwingRigidbody.linearVelocity;
mainPlayerController.setExtraCharacterVelocity (Vector3.zero);
mainSwingRigidbody.gameObject.SetActive (false);
mainPlayerController.addExternalForce (lastVelocity);
if (!isPlayerMovingOn3dWorld) {
mainSwingRigidbody.constraints = RigidbodyConstraints.None;
mainSwingRigidbody.constraints = RigidbodyConstraints.FreezeRotation;
}
swingJoint.connectedAnchor = Vector3.zero;
swingJoint.maxDistance = 0;
swingJoint.minDistance = 0;
}
public void inputRemoveGrapplingHook ()
{
checkRemoveGrapplingHook ();
}
public void inputIncreaseOrDecreaseMovementSpeed (bool state)
{
if (grapplingHookEnabled) {
if (grapplingHookActive) {
increaseSpeedActive = state;
if (changeFovOnHookActive) {
if (increaseSpeedActive) {
mainPlayerCamera.setMainCameraFov (increaseSpeedFov, changeFovSpeed);
} else {
mainPlayerCamera.setMainCameraFov (regulaFov, changeFovSpeed);
}
}
if (useCameraShake) {
if (increaseSpeedActive) {
mainPlayerCamera.setShakeCameraState (true, increaseCamaraShakeName);
} else {
mainPlayerCamera.setShakeCameraState (true, regularCameraShakeName);
}
}
}
}
}
public void inputThrowGrapplingHookIfTargetLocated ()
{
if (grapplingHookEnabled) {
if (currentGrapplingHookTarget != null) {
if (grapplingHookActive) {
checkRemoveGrapplingHook ();
} else {
inputThrowGrapplingHook ();
}
}
}
}
public void inputSetManualPullActiveState (bool state)
{
if (grapplingHookEnabled) {
if (!manualPullEnabled) {
return;
}
if (grapplingHookActive && useSwingForcesActive) {
manualPullActive = state;
manualExtendActive = false;
}
}
}
public void inputSetManualExtendActiveState (bool state)
{
if (grapplingHookEnabled) {
if (!manualExtendEnabled) {
return;
}
if (grapplingHookActive && useSwingForcesActive) {
manualExtendActive = state;
manualPullActive = false;
}
}
}
public void inputToggleManualPullActiveState ()
{
inputSetManualPullActiveState (!manualPullActive);
}
public void inputUseJumpOnSwing ()
{
if (grapplingHookEnabled) {
if (grapplingHookActive && useSwingForcesActive) {
if (jumpOnSwingEnabled) {
removeGrapplingHook ();
if (useSwingJumpOnAir) {
mainAnimator.SetInteger (actionIDAnimatorID, swingJumpOnAirID);
}
Vector3 totalForce = Vector3.zero;
if (isPlayerMovingOn3dWorld) {
totalForce = jumpOnSwingForceAmount.y * playerControllerTransform.up + jumpOnSwingForceAmount.z * playerControllerTransform.forward;
} else {
totalForce = jumpOnSwingForceAmount2_5d.y * playerControllerTransform.up + jumpOnSwingForceAmount2_5d.z * playerControllerTransform.forward;
}
mainPlayerController.useJumpPlatform (totalForce, ForceMode.Impulse);
lastTimeSwingHoldStopped = Time.time;
}
}
}
}
public void inputSetSwingHoldInputActive (bool state)
{
if (grapplingHookEnabled) {
if (chainNextSwingIfInputHold) {
swingHoldInputActive = state;
if (swingHoldInputActive) {
swingHoldInputActiveCoroutine = StartCoroutine (updateSwingHoldInputActiveCoroutine ());
} else {
stopUpdateSwingHoldInputActiveCoroutine ();
if (grapplingHookActive) {
float probabilityToUseJump = Random.Range (0, 100);
if (probabilityToUseJumpOnSwingEnd > probabilityToUseJump) {
inputUseJumpOnSwing ();
} else {
removeHook ();
}
}
}
}
}
}
Coroutine swingHoldInputActiveCoroutine;
float lastTimeSwingHoldStopped = -1;
void stopUpdateSwingHoldInputActiveCoroutine ()
{
if (swingHoldInputActiveCoroutine != null) {
StopCoroutine (swingHoldInputActiveCoroutine);
}
}
IEnumerator updateSwingHoldInputActiveCoroutine ()
{
var waitTime = new WaitForFixedUpdate ();
while (true) {
if (grapplingHookActive) {
bool removeHookResult = false;
if (swingPassCenterChecked) {
if (lastTimeSwingPassCenterChecked > -1 && Time.time > lastTimeSwingPassCenterChecked + minTimeToKeepSwingBeforeNext) {
removeHookResult = true;
}
} else {
if (Time.time > lastTimeHookActive + minTimeToKeepSwingBeforeNext * 3) {
removeHookResult = true;
}
}
if (removeHookResult) {
float probabilityToUseJump = Random.Range (0, 100);
if (probabilityToUseJumpOnSwingEnd > probabilityToUseJump) {
inputUseJumpOnSwing ();
} else {
removeHook ();
}
lastTimeSwingHoldStopped = Time.time;
}
} else {
if (Time.time > lastTimeSwingHoldStopped + minWaitTimeToThrowNextSwing) {
inputThrowGrapplingHook ();
if (grapplingHookActive) {
lastTimeSwingHoldStopped = -1;
} else {
if (stopSwingHoldChainIfNotSurfaceLocated) {
inputSetSwingHoldInputActive (false);
} else {
lastTimeSwingHoldStopped = Time.time;
}
}
}
}
yield return waitTime;
}
}
public void setAttractObjectsEnabled (bool state)
{
attractObjectsEnabled = state;
}
public void setUseSwingForcesActiveState (bool state)
{
useSwingForcesActive = state;
}
public void setCurrentPlayerActionSystemCustomActionCategoryID (bool state)
{
if (state) {
if (customActionCategoryID > -1) {
mainPlayerController.setCurrentCustomActionCategoryID (customActionCategoryID);
}
} else {
if (regularActionCategoryID > -1) {
mainPlayerController.setCurrentCustomActionCategoryID (regularActionCategoryID);
}
}
}
[System.Serializable]
public class otherExternalControllerInfo
{
public string Name;
[Space]
[Header ("Events Settings")]
[Space]
public bool useEventsOnExternalController;
public UnityEvent eventToPauseExternalController;
public UnityEvent eventToResumeExternalController;
}
}