using System.Collections; using System.Collections.Generic; using UnityEngine; public class AerialGrappleAirState : AerialBaseState { float distanceBeneathHook = -10f; // Distance Beneath Hook float distanceAfterHook = 8f; // Distance After Hook Vector3 initialForceDirection; // Initial Force Direction Vector3 desiredPosition; // Desired Player Position Vector3 tempForceDir; // Temporary Force Direction for calculating if the position has been reached Vector3 updatedYHookPoint; // updated y position of the hook bool pointReached; // Whether the player has reached the desired position bool handReached = false; // Whether the grapple hand has reached float initialForcePower; // How much force to apply initially public override void EnterState(AerialStateManager aSM, AerialBaseState previousState) { //Reset these Variables pointReached = false; handReached = false; initialForcePower = 120; aSM.currentForcePower = initialForcePower; //refresh jump number aSM.curJumpNum = 0; aSM.release = false; //Calculate the update y position for the hook updatedYHookPoint = new Vector3(aSM.hookPoint.transform.position.x, aSM.hookPoint.transform.position.y - distanceBeneathHook, aSM.hookPoint.transform.position.z); } public override void ExitState(AerialStateManager aSM, AerialBaseState nextState) { //Reset Hand Rotation aSM.stickyHandParent.transform.localEulerAngles = Vector3.zero; //Deactivate Visuals aSM.handController.enabled = false; aSM.stickyHandParent.SetActive(false); aSM.lr.enabled = false; //if the next state is grounded or wallrun if (nextState == aSM.GroundedState || nextState == aSM.WallRunState) { //don't apply the release force aSM.release = false; } else { //apply release force aSM.release = true; //give the player a slight upwards direction on releasing aSM.pStats.GravVel = 10; } } public override void UpdateState(AerialStateManager aSM) { //if the player has reached the calculated point if (pointReached) { //if grounded if (aSM.isGrounded) { //switch to grounded state aSM.SwitchState(aSM.GroundedState); } //if isn't grounded else if (!aSM.isGrounded) { //switch to falling state aSM.SwitchState(aSM.FallingState); } //if wallrunning else if (aSM.isWallRunning) { //switch to wallrun state aSM.SwitchState(aSM.WallRunState); } } } public override void FixedUpdateState(AerialStateManager aSM) { //If the grapple hand hasn't reached if (!handReached) { //Throw player hand ThrowStickyHand(aSM); //Apply Regular gravity aSM.GravityCalculation(aSM.pStats.PlayerGrav); } //If the grapple hand has reached and the player hasn't reached the correct point else if (!pointReached && handReached) { //Start Retrieving the grapple hand RetrieveStickyHand(aSM); //Move the player using the calculated direction and power aSM.moveController.Move(initialForceDirection * initialForcePower * Time.deltaTime); //Disable gravity while moving aSM.GravityCalculation(0); //Set Gravity to 0 aSM.pStats.GravVel = 0; //Calculate A temporary force direction for checking if point is reached tempForceDir = desiredPosition - aSM.transform.position; tempForceDir = tempForceDir.normalized; tempForceDir = new Vector3(tempForceDir.x, 0, tempForceDir.z).normalized; //if the player has approximately reached the right position if ((aSM.postForceDirection - tempForceDir).magnitude >= .1f && !pointReached) { //Player has reached the calculated position pointReached = true; } } else { //normal gravity if grapple is finished aSM.GravityCalculation(aSM.pStats.PlayerGrav); } //Offset parent rotation for the hand if (aSM.stickyHandParent.active) { aSM.stickyHandParent.transform.localRotation = Quaternion.Euler(0.0f, 0.0f, aSM.stickyHandParent.transform.parent.rotation.z * -1.0f); } } //Throw Hand toward hookpoint & calculate desired position public void ThrowStickyHand(AerialStateManager aSM) { //If the sticky hand isn't active if (!aSM.stickyHandParent.active) { //enable hand aSM.stickyHandParent.SetActive(true); //enable line renderer aSM.lr.enabled = true; //move hand position to hand aSM.stickyHandParent.transform.position = aSM.handPosition.position; //enable the character controller on the hand aSM.handController.enabled = true; } //set positioning for the line renderer aSM.lr.SetPosition(0, aSM.stickyHandParent.transform.position); aSM.lr.SetPosition(1, aSM.handPosition.transform.position); //Hand Throw Direction Vector3 throwDir = (aSM.hookPoint.transform.position - aSM.stickyHandParent.transform.position).normalized; //move the hand aSM.stickyHandParent.GetComponent().Move(throwDir * 140 * Time.deltaTime); //if the hand approximately reaches the correct point if (Vector3.Distance(aSM.hookPoint.transform.position, aSM.stickyHandParent.transform.position) <= 4f) { //Calculate the desired position using current position when hook reaches Vector3 updatedXHookPointDirection = (new Vector3(aSM.transform.position.x, 0, aSM.transform.position.z) - new Vector3(aSM.hookPoint.transform.position.x, 0, aSM.hookPoint.transform.position.z)).normalized; desiredPosition = updatedYHookPoint + (updatedXHookPointDirection * -distanceAfterHook); initialForceDirection = desiredPosition - aSM.transform.position; initialForceDirection = initialForceDirection.normalized; aSM.postForceDirection = new Vector3(initialForceDirection.x, 0, initialForceDirection.z).normalized; //Hand has Reached handReached = true; } } //Retrieve Grapple Hand public void RetrieveStickyHand(AerialStateManager aSM) { aSM.lr.SetPosition(0, aSM.stickyHandParent.transform.position); aSM.lr.SetPosition(1, aSM.handPosition.transform.position); Vector3 catchDir = (aSM.handPosition.transform.position - aSM.stickyHandParent.transform.position).normalized; if (Vector3.Distance(aSM.handPosition.transform.position, aSM.stickyHandParent.transform.position) > .5f) { aSM.stickyHandParent.GetComponent().Move(catchDir * 30 * Time.deltaTime); } } }