using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; public class wallRunningSystem : externalControllerBehavior { [Header ("Main Settings")] [Space] public bool wallRunningEnabled = true; public LayerMask raycastLayermask; public float wallRunningSpeed; public float wallSprintSpeed; public float wallRunningRotationSpeed; public bool wallRunningCanBeUsed = true; public Vector3 wallRunningImpulseOnJump; public Vector3 wallRunningStopMovemmentImpulse; public Vector3 wallRunningEndOfSurfaceImpulse; public Vector3 wallRunningImpulseOnJumpCameraDirection; public float raycastDistance = 0.6f; [Space] [Header ("2.5d Settings")] [Space] public float raycastDistance2_5d = 2; public float minWaitTimeToAdhereToWallAfterLastTime2_5d = 1; public Vector3 wallRunningImpulseOnJump2_5d = new Vector3 (5, 8, 10); [Space] [Header ("Other Settings")] [Space] public bool checkForObstaclesInFront = true; public float raycastDistanceObstaclesInFront = 1; public float minAngleForObstaclesInFront = 5; [Space] [Header ("Other Settings")] [Space] public bool useDownMovementOnWallRunning; public float downMovementOnWallRunningAmount; public float delayDownMovementOnWallRunning; public bool useUpAndDownMovementOnWallRunning; public float upAndDownMovementOnWallRunningDelay; public float upAndDownMovementOnWallRunningAmount; public bool useStopWallRunnigAfterDelay; public float stopWallRunningDelay; public bool useSurfaceAngleDiffToJumpInCameraDirection; public Vector2 surfaceAngleDiffRangeToWallRunning; public float maxVelocityChangeWallRunning; public bool keepWeaponsOnWallRunning; public bool drawWeaponsIfCarriedPreviously; [Space] [Header ("Third Person Settings")] [Space] public string wallRunningRightActionName = "Wall Running Right"; public string wallRunnigLeftActionName = "Wall Running Left"; public string actionActiveAnimatorName = "Action Active"; public bool useCharacterCOMOffset = true; public float rotationOffsetOnCharacterCOM = 10; public float positionOffsetOnCharacterCOM = 0.15f; public float offsetAdjustmentSpeed = 5; public float playerRotationToSurfaceSpeedThirdPerson = 14; public float playerRotationToSurfaceSpeedFirstPerson = 14; public float playerRotationToSurfaceSpeedFBA = 3; [Space] [Header ("Third Person Camera State Settings")] [Space] public bool setNewCameraStateOnThirdPerson; public string newCameraStateOnThirdPersonRightSide; public string newCameraStateOnThirdPersonLeftSide; [Space] [Header ("Ignore Surface Settings")] [Space] public bool useTagsToIgnore; public List tagsToIgnore = new List (); public bool ignoreRigidbodies; [Space] [Header ("Debug")] [Space] public bool showDebugPrint; public bool wallRunningActive; public bool isFirstPersonActive; public bool wallRunningOnRightSide; public bool wallRunningOnLeftSide; public bool carryingWeaponsPreviously; public Vector3 currentMovementDirection; public float extraYPosition; public float playerYPositionOnWallRunningStart; public Vector3 playerVelocity; public bool checkSurfaceDetected = true; public bool isPlayerMovingOn3dWorld; [Space] [Header ("First Person Events Settings")] [Space] public UnityEvent eventOnWallRunningStartFirstPerson; public UnityEvent eventOnWallRunningToRightFirstPerson; public UnityEvent eventOnWallRunningToLeftFirstPerson; public UnityEvent eventOnWallRunningEndFirstPerson; [Space] [Header ("Third Person Events Settings")] [Space] public UnityEvent eventOnWallRunningStartThirdPerson; public UnityEvent eventOnWallRunningToRightThirdPerson; public UnityEvent eventOnWallRunningToLeftThirdPerson; public UnityEvent eventOnWallRunningEndThirdPerson; [Space] [Header ("Components")] [Space] public playerController mainPlayerController; public Transform playerTransform; public Rigidbody mainRigidbody; public Transform playerCameraTransform; public playerCamera mainPlayerCamera; public playerWeaponsManager mainPlayerWeaponsManager; public Animator mainAnimator; public Transform COM; float lastTimeWallRunningActive; float lastTimeWallRunningDisabled; bool previouslyWallRunningOnRightSide; bool previouslyWallRunningOnLeftSide; float lastTimeWallRunningOnRightSide; RaycastHit wallRunningHit; bool autoUseDownMovementOnWallRunningActive; bool autoUseStopWallRunningAfterDelay; bool originalWallRunningEnabled; Vector3 playerTransformUp; Vector3 playerTransformForward; Vector3 playerTransformRight; RaycastHit hit; float half = 0.5f; Vector3 velocityChange; int actionActiveAnimatorID; float originalCOMYPosition; Coroutine resetCOMCoroutine; float currentRotationTarget; float currentPositionTarget; string previousCameraState; float rotationAmount; bool ignoreHorizontalCameraRotationInputState; GameObject currentSurfaceDetected; GameObject previousSurfaceDetected; void Start () { originalWallRunningEnabled = wallRunningEnabled; actionActiveAnimatorID = Animator.StringToHash (actionActiveAnimatorName); originalCOMYPosition = COM.localPosition.y; } public override void updateControllerBehavior () { if (!wallRunningActive) { return; } playerTransformUp = playerTransform.up; playerTransformForward = playerTransform.forward; playerTransformRight = playerTransform.right; Vector3 currentRaycastPosition = playerTransform.position + playerTransformUp; Vector3 currentRaycastDirection = playerTransformRight; if (!wallRunningOnRightSide) { currentRaycastDirection = -playerTransformRight; } bool movementInputActive = false; if (isPlayerMovingOn3dWorld) { movementInputActive = mainPlayerController.isPlayerMovingVertical (0.7f); } else { movementInputActive = mainPlayerController.isPlayerMovingHorizontal (0.7f); } if (movementInputActive) { Debug.DrawRay (currentRaycastPosition, currentRaycastDirection, Color.red, 5); float currentRaycastDistance = 1; if (!isPlayerMovingOn3dWorld) { currentRaycastDistance = raycastDistance2_5d; } if (Physics.Raycast (currentRaycastPosition, currentRaycastDirection, out hit, currentRaycastDistance, raycastLayermask)) { wallRunningHit = hit; float currentWallRunningSpeed = wallRunningSpeed; if (mainPlayerController.isPlayerRunning ()) { currentWallRunningSpeed = wallSprintSpeed; } currentMovementDirection = wallRunningHit.point + playerTransformForward; currentMovementDirection = currentMovementDirection - playerTransform.InverseTransformDirection (currentMovementDirection).y * playerTransformUp; currentMovementDirection += (playerYPositionOnWallRunningStart + extraYPosition) * playerTransformUp; if (useDownMovementOnWallRunning || autoUseDownMovementOnWallRunningActive) { if (Time.time > delayDownMovementOnWallRunning + lastTimeWallRunningActive) { extraYPosition -= downMovementOnWallRunningAmount; } } else { if (useUpAndDownMovementOnWallRunning && Time.time > upAndDownMovementOnWallRunningDelay + lastTimeWallRunningActive) { float wallRunningInput = 0; float horizontalInput = 0; if (isPlayerMovingOn3dWorld) { horizontalInput = mainPlayerController.getHorizontalInput (); } else { horizontalInput = mainPlayerController.getVerticalInput (); } if (horizontalInput > half) { wallRunningInput = upAndDownMovementOnWallRunningAmount * horizontalInput; } else if (horizontalInput < -half) { wallRunningInput = upAndDownMovementOnWallRunningAmount * horizontalInput; } if (isPlayerMovingOn3dWorld) { if (!wallRunningOnRightSide) { wallRunningInput *= (-1); } } if (showDebugPrint) { print (wallRunningInput); } extraYPosition += wallRunningInput; } } if (useStopWallRunnigAfterDelay || autoUseStopWallRunningAfterDelay) { if (Time.time > stopWallRunningDelay + lastTimeWallRunningActive) { setWallRunningActiveState (false); setWallRunningImpulseForce (wallRunningStopMovemmentImpulse, false); return; } } float currentFixedUpdateDeltaTime = mainPlayerController.getCurrentDeltaTime (); //probar moveposition m_Rigidbody.MovePosition(transform.position + m_Input * Time.deltaTime * m_Speed); mainRigidbody.position = Vector3.MoveTowards (mainRigidbody.position, currentMovementDirection, currentFixedUpdateDeltaTime * currentWallRunningSpeed); } else { setWallRunningActiveState (false); setWallRunningImpulseForce (wallRunningEndOfSurfaceImpulse, false); return; } if (checkForObstaclesInFront) { currentRaycastDirection = playerTransformForward; if (Physics.Raycast (currentRaycastPosition, currentRaycastDirection, out hit, raycastDistanceObstaclesInFront, raycastLayermask)) { float obstacleAngle = Vector3.SignedAngle (playerTransformForward, -hit.normal, playerTransformUp); if (minAngleForObstaclesInFront == 0 || Mathf.Abs (obstacleAngle) < minAngleForObstaclesInFront) { setWallRunningActiveState (false); setWallRunningImpulseForce (wallRunningEndOfSurfaceImpulse, false); return; } } } } else { setWallRunningActiveState (false); setWallRunningImpulseForce (wallRunningStopMovemmentImpulse, false); return; } mainPlayerController.setCurrentVelocityValue (mainRigidbody.linearVelocity); //Manage player rotation to adjust to wall normal Vector3 wallNormal = -wallRunningHit.normal; float angle = 0; bool isFullBodyAwarenessActive = mainPlayerCamera.isFullBodyAwarenessActive (); if (isFullBodyAwarenessActive) { Vector3 playerCameraRight = mainPlayerCamera.transform.right; if (wallRunningOnRightSide) { angle = Vector3.SignedAngle (playerCameraRight, wallNormal, playerTransformUp); } else { angle = Vector3.SignedAngle (-playerCameraRight, wallNormal, playerTransformUp); } } else { if (wallRunningOnRightSide) { angle = Vector3.SignedAngle (playerTransformRight, wallNormal, playerTransformUp); } else { angle = Vector3.SignedAngle (-playerTransformRight, wallNormal, playerTransformUp); } } if (showDebugPrint) { print ("running on right side value " + wallRunningOnRightSide); } float currentRotationSpeed = playerRotationToSurfaceSpeedThirdPerson; if (isFirstPersonActive) { currentRotationSpeed = playerRotationToSurfaceSpeedFirstPerson; } if (isFullBodyAwarenessActive) { currentRotationSpeed = playerRotationToSurfaceSpeedFBA; } if (isFullBodyAwarenessActive) { rotationAmount = Mathf.MoveTowards (rotationAmount, angle, currentRotationSpeed * Time.fixedDeltaTime); } else { rotationAmount = Mathf.Lerp (rotationAmount, angle, currentRotationSpeed * Time.fixedDeltaTime); } if (isFullBodyAwarenessActive) { if (!ignoreHorizontalCameraRotationInputState) { mainPlayerCamera.setIgnoreHorizontalCameraRotationOnFBAState (true); ignoreHorizontalCameraRotationInputState = true; } Quaternion targetRotation = mainPlayerCamera.transform.rotation * Quaternion.Euler (mainPlayerCamera.transform.up * angle); mainPlayerCamera.transform.rotation = Quaternion.Lerp (mainPlayerCamera.transform.rotation, targetRotation, currentRotationSpeed * Time.fixedDeltaTime); } else { if (Mathf.Abs (rotationAmount) > 0.001f) { playerTransform.Rotate (0, rotationAmount, 0); if (ignoreHorizontalCameraRotationInputState) { mainPlayerCamera.setIgnoreHorizontalCameraRotationOnFBAState (false); ignoreHorizontalCameraRotationInputState = false; } } } //Set foot step state and head bob mainPlayerController.setCurrentFootStepsState (); if (mainPlayerController.updateHeadbobState) { mainPlayerController.setCurrentHeadBobState (); } if (useCharacterCOMOffset) { if (wallRunningOnRightSide) { currentRotationTarget = -rotationOffsetOnCharacterCOM; currentPositionTarget = -positionOffsetOnCharacterCOM; } else { currentRotationTarget = rotationOffsetOnCharacterCOM; currentPositionTarget = positionOffsetOnCharacterCOM; } Quaternion COMTargetRotation = Quaternion.Euler (currentRotationTarget * Vector3.forward); COM.localRotation = Quaternion.Lerp (COM.localRotation, COMTargetRotation, offsetAdjustmentSpeed * Time.fixedDeltaTime); Vector3 COMTargetPosition = currentPositionTarget * Vector3.right + originalCOMYPosition * Vector3.up; COM.localPosition = Vector3.Lerp (COM.localPosition, COMTargetPosition, offsetAdjustmentSpeed * Time.fixedDeltaTime); } playerVelocity = mainRigidbody.linearVelocity; } public override void checkIfActivateExternalForce () { if (wallRunningEnabled && wallRunningCanBeUsed && !mainPlayerController.useFirstPersonPhysicsInThirdPersonActive) { if (!wallRunningActive && !mainPlayerController.pauseAllPlayerDownForces && !mainPlayerController.ignoreExternalActionsActiveState) { isPlayerMovingOn3dWorld = mainPlayerController.isPlayerMovingOn3dWorld (); bool wallRunningSurfaceFound = false; bool movementInputActive = false; if (isPlayerMovingOn3dWorld) { movementInputActive = (Mathf.Abs (mainPlayerController.getVerticalInput ()) > 0); } else { movementInputActive = (Mathf.Abs (mainPlayerController.getHorizontalInput ()) > 0); } bool waitToNextWallRunningActiveResult = false; if (isPlayerMovingOn3dWorld) { waitToNextWallRunningActiveResult = (Time.time > lastTimeWallRunningActive + 0.05f); } else { waitToNextWallRunningActiveResult = (lastTimeWallRunningActive == 0 || (Time.time > lastTimeWallRunningActive + minWaitTimeToAdhereToWallAfterLastTime2_5d)); } if (movementInputActive && !mainPlayerController.isCrouching () && waitToNextWallRunningActiveResult) { playerTransformUp = playerTransform.up; playerTransformRight = playerTransform.right; Vector3 currentRaycastPosition = playerTransform.position + playerTransformUp; Vector3 currentRaycastDirection = playerTransformRight; float currentRaycastDistance = raycastDistance; if (!isPlayerMovingOn3dWorld) { currentRaycastDistance = raycastDistance2_5d; } if (Physics.Raycast (currentRaycastPosition, currentRaycastDirection, out hit, currentRaycastDistance, raycastLayermask)) { currentSurfaceDetected = hit.collider.gameObject; if (currentSurfaceDetected != previousSurfaceDetected) { previousSurfaceDetected = currentSurfaceDetected; checkSurfaceDetected = true; if (ignoreRigidbodies) { if (hit.collider.attachedRigidbody != null) { checkSurfaceDetected = false; } } if (checkSurfaceDetected && useTagsToIgnore) { if (tagsToIgnore.Contains (previousSurfaceDetected.tag)) { checkSurfaceDetected = false; } } } if (!isPlayerMovingOn3dWorld && checkSurfaceDetected) { Transform currentLockedCameraTransform = mainPlayerCamera.getLockedCameraTransform (); float raycastDirectionAngle = Vector3.SignedAngle (currentLockedCameraTransform.forward, currentRaycastDirection, playerTransformUp); float raycastDirectionAngleABS = Mathf.Abs (raycastDirectionAngle); if (raycastDirectionAngleABS > 160) { if (raycastDirectionAngleABS > 165) { checkSurfaceDetected = false; } } else { if (raycastDirectionAngleABS > 15) { checkSurfaceDetected = false; } } if (!checkSurfaceDetected) { previousSurfaceDetected = null; previouslyWallRunningOnRightSide = false; return; } } if (previouslyWallRunningOnRightSide != wallRunningOnRightSide) { previouslyWallRunningOnRightSide = wallRunningOnRightSide; lastTimeWallRunningOnRightSide = Time.time; if (showDebugPrint) { print ("Running Right Side"); } } if (checkForObstaclesInFront && checkSurfaceDetected) { currentRaycastDirection = playerTransformForward; currentRaycastPosition -= playerTransformRight; if (Physics.Raycast (currentRaycastPosition, currentRaycastDirection, out hit, raycastDistanceObstaclesInFront, raycastLayermask)) { float obstacleAngle = Vector3.SignedAngle (playerTransformForward, -hit.normal, playerTransformUp); if (minAngleForObstaclesInFront == 0 || Mathf.Abs (obstacleAngle) < minAngleForObstaclesInFront) { checkSurfaceDetected = false; previouslyWallRunningOnLeftSide = false; previouslyWallRunningOnRightSide = false; wallRunningOnRightSide = false; wallRunningOnLeftSide = false; currentSurfaceDetected = null; previousSurfaceDetected = null; } } } if (checkSurfaceDetected) { wallRunningOnRightSide = true; wallRunningOnLeftSide = false; previouslyWallRunningOnLeftSide = false; if (!previouslyWallRunningOnRightSide || Time.time > lastTimeWallRunningOnRightSide + 0.3f) { setWallRunningActiveState (true); previouslyWallRunningOnRightSide = false; } wallRunningSurfaceFound = true; } } else { currentRaycastDirection = -playerTransformRight; if (Physics.Raycast (currentRaycastPosition, currentRaycastDirection, out hit, currentRaycastDistance, raycastLayermask)) { currentSurfaceDetected = hit.collider.gameObject; if (currentSurfaceDetected != previousSurfaceDetected) { previousSurfaceDetected = currentSurfaceDetected; checkSurfaceDetected = true; if (ignoreRigidbodies) { if (hit.collider.attachedRigidbody != null) { checkSurfaceDetected = false; } } if (checkSurfaceDetected && useTagsToIgnore) { if (tagsToIgnore.Contains (previousSurfaceDetected.tag)) { checkSurfaceDetected = false; } } } if (!isPlayerMovingOn3dWorld && checkSurfaceDetected) { Transform currentLockedCameraTransform = mainPlayerCamera.getLockedCameraTransform (); float raycastDirectionAngle = Vector3.SignedAngle (currentLockedCameraTransform.forward, currentRaycastDirection, playerTransformUp); float raycastDirectionAngleABS = Mathf.Abs (raycastDirectionAngle); if (raycastDirectionAngleABS > 160) { if (raycastDirectionAngleABS > 165) { checkSurfaceDetected = false; } } else { if (raycastDirectionAngleABS > 15) { checkSurfaceDetected = false; } } if (!checkSurfaceDetected) { previousSurfaceDetected = null; previouslyWallRunningOnLeftSide = false; return; } } if (previouslyWallRunningOnLeftSide != wallRunningOnLeftSide) { previouslyWallRunningOnLeftSide = wallRunningOnLeftSide; lastTimeWallRunningOnRightSide = Time.time; if (showDebugPrint) { print ("Running Left Side"); } } if (checkForObstaclesInFront && checkSurfaceDetected) { currentRaycastDirection = playerTransformForward; currentRaycastPosition += playerTransformRight; if (Physics.Raycast (currentRaycastPosition, currentRaycastDirection, out hit, raycastDistanceObstaclesInFront, raycastLayermask)) { float obstacleAngle = Vector3.SignedAngle (playerTransformForward, -hit.normal, playerTransformUp); if (minAngleForObstaclesInFront == 0 || Mathf.Abs (obstacleAngle) < minAngleForObstaclesInFront) { checkSurfaceDetected = false; previouslyWallRunningOnLeftSide = false; previouslyWallRunningOnRightSide = false; wallRunningOnRightSide = false; wallRunningOnLeftSide = false; currentSurfaceDetected = null; previousSurfaceDetected = null; } } } if (checkSurfaceDetected) { wallRunningOnRightSide = false; wallRunningOnLeftSide = true; previouslyWallRunningOnRightSide = false; if (!previouslyWallRunningOnLeftSide || Time.time > lastTimeWallRunningOnRightSide + 0.3f) { setWallRunningActiveState (true); previouslyWallRunningOnLeftSide = false; } wallRunningSurfaceFound = true; } } } } if (!wallRunningSurfaceFound && Time.time > lastTimeWallRunningDisabled + half) { previouslyWallRunningOnLeftSide = false; previouslyWallRunningOnRightSide = false; wallRunningOnRightSide = false; wallRunningOnLeftSide = false; } } } } public override void setExtraImpulseForce (Vector3 forceAmount, bool useCameraDirection) { setWallRunningImpulseForce (forceAmount, useCameraDirection); } public void setWallRunningImpulseForce (Vector3 forceAmount, bool useCameraDirection) { Transform mainImpulseTransform = playerTransform; isPlayerMovingOn3dWorld = mainPlayerController.isPlayerMovingOn3dWorld (); if (useCameraDirection && isPlayerMovingOn3dWorld) { mainImpulseTransform = playerCameraTransform; } Vector3 impulseForce = forceAmount.z * mainImpulseTransform.forward + forceAmount.y * mainImpulseTransform.up; if (wallRunningOnRightSide) { impulseForce -= forceAmount.x * mainImpulseTransform.right; } else { impulseForce += forceAmount.x * mainImpulseTransform.right; } if (maxVelocityChangeWallRunning > 0) { velocityChange = impulseForce - mainRigidbody.linearVelocity; velocityChange = Vector3.ClampMagnitude (velocityChange, maxVelocityChangeWallRunning); } else { velocityChange = impulseForce; } mainPlayerController.setVelocityChangeValue (velocityChange); mainRigidbody.AddForce (velocityChange, ForceMode.VelocityChange); } public override void setJumpActiveForExternalForce () { setJumpActive (); } public void setJumpActive () { if (wallRunningActive) { isPlayerMovingOn3dWorld = mainPlayerController.isPlayerMovingOn3dWorld (); if (useSurfaceAngleDiffToJumpInCameraDirection && isPlayerMovingOn3dWorld) { float angleSurface = Vector3.SignedAngle (playerCameraTransform.forward, playerTransform.forward, playerTransform.up); if (Mathf.Abs (angleSurface) > surfaceAngleDiffRangeToWallRunning.x && Mathf.Abs (angleSurface) < surfaceAngleDiffRangeToWallRunning.y) { setWallRunningImpulseForce (wallRunningImpulseOnJumpCameraDirection, true); } else { setWallRunningImpulseForce (wallRunningImpulseOnJump, false); } } else { if (isPlayerMovingOn3dWorld) { setWallRunningImpulseForce (wallRunningImpulseOnJump, false); } else { setWallRunningImpulseForce (wallRunningImpulseOnJump2_5d, false); } } mainPlayerController.setCurrentVelocityValue (mainRigidbody.linearVelocity); lastTimeWallRunningActive = Time.time; mainPlayerController.setWallRunningActiveValue (false); setWallRunningActiveState (false); } } public override void setExternalForceActiveState (bool state) { setWallRunningActiveState (state); } public void setWallRunningActiveState (bool state) { if (!wallRunningEnabled) { return; } if (wallRunningActive == state) { return; } if (!state) { lastTimeWallRunningDisabled = Time.time; } if (state) { if (mainPlayerController.isFreeClimbActive ()) { return; } } wallRunningActive = state; setBehaviorCurrentlyActiveState (state); setCurrentPlayerActionSystemCustomActionCategoryID (); mainPlayerController.setWallRunningActiveValue (state); mainPlayerController.setUpdate2_5dClampedPositionPausedState (state); isPlayerMovingOn3dWorld = mainPlayerController.isPlayerMovingOn3dWorld (); if (showDebugPrint) { print ("Wall running active state " + state); } isFirstPersonActive = mainPlayerController.isPlayerOnFirstPerson (); if (wallRunningActive) { if (isFirstPersonActive) { eventOnWallRunningStartFirstPerson.Invoke (); if (wallRunningOnRightSide) { eventOnWallRunningToRightFirstPerson.Invoke (); } else { eventOnWallRunningToLeftFirstPerson.Invoke (); } } else { eventOnWallRunningStartThirdPerson.Invoke (); if (wallRunningOnRightSide) { eventOnWallRunningToRightThirdPerson.Invoke (); } else { eventOnWallRunningToLeftThirdPerson.Invoke (); } if (wallRunningOnRightSide) { mainAnimator.CrossFadeInFixedTime (wallRunningRightActionName, 0.1f); } else { mainAnimator.CrossFadeInFixedTime (wallRunnigLeftActionName, 0.1f); } mainAnimator.SetBool (actionActiveAnimatorID, state); } extraYPosition = 0; playerYPositionOnWallRunningStart = playerTransform.position.y; mainPlayerController.setJumpsAmountValue (0); lastTimeWallRunningActive = Time.time; mainPlayerCamera.enableOrDisableChangeCameraView (false); if (useCharacterCOMOffset) { stopResetCOMRotationCoroutine (); } if (!isFirstPersonActive) { if (keepWeaponsOnWallRunning) { carryingWeaponsPreviously = mainPlayerWeaponsManager.isPlayerCarringWeapon (); if (carryingWeaponsPreviously) { mainPlayerWeaponsManager.checkIfDisableCurrentWeapon (); } mainPlayerWeaponsManager.setGeneralWeaponsInputActiveState (false); } } } else { if (isFirstPersonActive) { eventOnWallRunningEndFirstPerson.Invoke (); } else { eventOnWallRunningEndThirdPerson.Invoke (); mainAnimator.SetBool (actionActiveAnimatorID, state); } mainPlayerCamera.setOriginalchangeCameraViewEnabledValue (); if (useCharacterCOMOffset) { resetCOMRotation (); } if (keepWeaponsOnWallRunning) { mainPlayerWeaponsManager.setGeneralWeaponsInputActiveState (true); } if (carryingWeaponsPreviously) { if (!drawWeaponsIfCarriedPreviously) { carryingWeaponsPreviously = false; } } if (ignoreHorizontalCameraRotationInputState) { mainPlayerCamera.setIgnoreHorizontalCameraRotationOnFBAState (false); ignoreHorizontalCameraRotationInputState = false; } } mainPlayerCamera.setCameraPositionMouseWheelEnabledState (!wallRunningActive); mainPlayerController.stepManager.setWallRunningState (wallRunningActive, wallRunningOnRightSide); mainPlayerController.setLastTimeFalling (); if (setNewCameraStateOnThirdPerson && !isFirstPersonActive) { if (state) { previousCameraState = mainPlayerCamera.getCurrentStateName (); if (wallRunningOnRightSide) { mainPlayerCamera.setCameraStateOnlyOnThirdPerson (newCameraStateOnThirdPersonRightSide); } else { mainPlayerCamera.setCameraStateOnlyOnThirdPerson (newCameraStateOnThirdPersonLeftSide); } } else { if (previousCameraState != "") { if (wallRunningOnRightSide) { if (previousCameraState != newCameraStateOnThirdPersonRightSide) { mainPlayerCamera.setCameraStateOnlyOnThirdPerson (previousCameraState); } } else { if (previousCameraState != newCameraStateOnThirdPersonLeftSide) { mainPlayerCamera.setCameraStateOnlyOnThirdPerson (previousCameraState); } } previousCameraState = ""; } } } rotationAmount = 0; currentSurfaceDetected = null; previousSurfaceDetected = null; checkSurfaceDetected = true; } public override void setExternalForceEnabledState (bool state) { setWallRunningEnabledState (state); } public void setWallRunningEnabledState (bool state) { if (!state) { if (wallRunningActive) { setWallRunningActiveState (false); setWallRunningImpulseForce (wallRunningStopMovemmentImpulse, false); previouslyWallRunningOnLeftSide = false; previouslyWallRunningOnRightSide = false; wallRunningOnRightSide = false; wallRunningOnLeftSide = false; } } wallRunningEnabled = state; } public void setWallRunningCanBeUsedState (bool state) { wallRunningCanBeUsed = state; } public void setOriginalWallRunningEnabledState () { setWallRunningEnabledState (originalWallRunningEnabled); } public void setAutoUseDownMovementOnWallRunningActiveState (bool state) { autoUseDownMovementOnWallRunningActive = state; } public void setAutoUseStopWallRunningAfterDelayState (bool state) { autoUseStopWallRunningAfterDelay = state; } public void resetCOMRotation () { stopResetCOMRotationCoroutine (); resetCOMCoroutine = StartCoroutine (resetCOMRotationCoroutine ()); } void stopResetCOMRotationCoroutine () { if (resetCOMCoroutine != null) { StopCoroutine (resetCOMCoroutine); } } public IEnumerator resetCOMRotationCoroutine () { bool targetReached = false; float movementTimer = 0; float t = 0; float duration = 0.5f; float angleDifference = 0; float positionDifference = 0; Vector3 targetPosition = originalCOMYPosition * Vector3.up; Quaternion targetRotation = Quaternion.identity; while (!targetReached) { t += Time.deltaTime / duration; COM.localPosition = Vector3.Slerp (COM.localPosition, targetPosition, t); COM.localRotation = Quaternion.Slerp (COM.localRotation, targetRotation, t); angleDifference = Quaternion.Angle (COM.localRotation, targetRotation); positionDifference = GKC_Utils.distance (COM.localPosition, targetPosition); movementTimer += Time.deltaTime; if ((positionDifference < 0.01f && angleDifference < 0.2f) || movementTimer > (duration + 1)) { targetReached = true; } yield return null; } if (drawWeaponsIfCarriedPreviously) { WaitForSeconds delay = new WaitForSeconds (1); yield return delay; if (carryingWeaponsPreviously) { if (!mainPlayerController.isPlayerOnFirstPerson () && !wallRunningActive && mainPlayerController.canPlayerMove ()) { mainPlayerWeaponsManager.checkIfDrawSingleOrDualWeapon (); } carryingWeaponsPreviously = false; } } } public override void setCurrentPlayerActionSystemCustomActionCategoryID () { if (behaviorCurrentlyActive) { if (customActionCategoryID > -1) { mainPlayerController.setCurrentCustomActionCategoryID (customActionCategoryID); } } else { if (regularActionCategoryID > -1) { mainPlayerController.setCurrentCustomActionCategoryID (regularActionCategoryID); } } } public override void disableExternalControllerState () { if (showDebugPrint) { print ("check to stop traversal movement " + wallRunningActive); } if (wallRunningActive) { setWallRunningActiveState (false); } } public void setWallRunningEnabledStateFromEditor (bool state) { setWallRunningEnabledState (state); updateComponent (); } void updateComponent () { GKC_Utils.updateComponent (this); GKC_Utils.updateDirtyScene ("Update Wall Running System", gameObject); } }