コード例 #1
0
 void Start()
 {
     grapplingHook       = transform.Find("GrapplingHook");
     hookCord            = grapplingHook.Find("HookCord");
     actualHookTransform = grapplingHook.Find("ActualHook");
     actualHook          = actualHookTransform.gameObject.GetComponent <ActualHook>();
     hookLaunchPoint     = transform.Find("HookLaunchPoint");
     playerTransform     = transform.parent;
     currState           = GrapplingHookState.Inactive;
 }
コード例 #2
0
 /// <summary>
 /// Launches the player with slingshot velocity
 /// </summary>
 virtual protected void DoSlingShot()
 {
     // Launch (slingshot)
     direction = ((Vector2)grapple.transform.position - HandOffset) - (Vector2)character.Transform.position;
     direction.Normalize();
     // Overwrite velocity
     character.SetVelocityX(direction.x * slingshotLaunchVelocity.x);
     character.SetVelocityY(direction.y * slingshotLaunchVelocity.y);
     state = GrapplingHookState.NONE;
 }
コード例 #3
0
        /// <summary>
        /// Handle inputs during the grapple
        /// </summary>
        virtual protected void HandleInputs()
        {
            // Early out if no state
            if (state == GrapplingHookState.NONE)
            {
                return;
            }

            // Early out if no slingshot (further input has no effect)
            if (state == GrapplingHookState.SLINGSHOT)
            {
                return;
            }

            // Check if button released
            if (GetGrappleButtonState() == ButtonState.NONE || GetGrappleButtonState() == ButtonState.UP)
            {
                buttonReleased = true;
            }

            // Check if button pressed again
            if (buttonReleased && GetGrappleButtonState() == ButtonState.DOWN)
            {
                buttonHoldStarted = true;
                buttonHeldTimer   = 0;
            }

            // Launching we can't do anything more
            if (state == GrapplingHookState.LAUNCHING)
            {
                return;
            }

            // Check for button release
            if (buttonHoldStarted)
            {
                // Check if button held
                if (buttonHeldTimer > buttonHeldTime)
                {
                    travelledDistance       = 0;
                    slingshotLaunchDistance = Mathf.Min(MaxRopeSlingshotDistance, ropeDistance / 2.0f);
                    state = GrapplingHookState.SLINGSHOT;
                }
                // Else Cut hook
                else if (GetGrappleButtonState() == ButtonState.UP)
                {
                    // Apply velovity boosts
                    character.SetVelocityX(launchVelocityMultiplier.x * character.Velocity.x);
                    character.SetVelocityY(launchVelocityMultiplier.y * character.Velocity.y);
                    character.AddVelocity(launchVelocityBoost.x * character.FacingDirection, launchVelocityBoost.y, true);
                    CancelGrapple();
                }
            }
        }
コード例 #4
0
 /// <summary>
 /// Start the special mvoe
 /// </summary>
 override public void DoSpecialMove()
 {
     if (state == GrapplingHookState.NONE)
     {
         swingTime         = 0.0f;
         buttonReleased    = false;
         buttonHoldStarted = false;
         state             = GrapplingHookState.LAUNCHING;
         FireGrapple();
     }
 }
コード例 #5
0
 /// <summary>
 /// Cancels the grapple.
 /// </summary>
 virtual public void CancelGrapple()
 {
     state = GrapplingHookState.NONE;
     if (ropeGo != null)
     {
         ropeGo.SetActive(false);
     }
     if (grapple != null)
     {
         grapple.Hide();
     }
 }
コード例 #6
0
 /// <summary>
 /// Called when the movement loses control.
 /// </summary>
 override public void LosingControl()
 {
     buttonReleased    = false;
     buttonHoldStarted = false;
     state             = GrapplingHookState.NONE;
     if (grapple != null)
     {
         grapple.Hide();
     }
     if (ropeGo != null)
     {
         ropeGo.SetActive(false);
     }
     CancelGrapple();
 }
コード例 #7
0
 /// <summary>
 /// Called by the hook when it latches on to something.
 /// </summary>
 virtual public void Latch()
 {
     ropeDistance = Vector2.Distance(((Vector2)grapple.transform.position - HandOffset), (Vector2)character.Transform.position);
     if (maxRopeDistance < ropeDistance)
     {
         maxRopeDistance = Vector2.Distance(((Vector2)grapple.transform.position - HandOffset), (Vector2)character.Transform.position);
     }
     // TODO Make a constant
     if (ropeDistance < 0.25f)
     {
         CancelGrapple();
     }
     else
     {
         state = GrapplingHookState.CLINGING;
     }
 }
コード例 #8
0
    /**
     * Retracts the grappling hook
     */
    public IEnumerator Retract()
    {
        anchorPoint = Vector3.zero;
        State       = GrapplingHookState.Retracting;
        if (dontBring)
        {
            actualHook.DetachInteractable();
            dontBring = false;
        }

        Vector3 currScale = hookCord.transform.localScale;
        float   length    = currScale.y * 2; //since scale for a cylinder corresponds to # of units from centre to either side

        while (length > 0)
        {
            //Adjust scale
            currScale.y -= retractSpeed * Time.deltaTime;
            length       = currScale.y * 2;
            hookCord.transform.localScale = currScale;

            //Adjust position to stay "anchored" to anchor point
            hookCord.transform.position = hookLaunchPoint.position + (hookLaunchPoint.forward * currScale.y);
            //Ensure actual hook stays on far end of hook cord
            AdjustActualHookPos(currScale.y);
            yield return(null);
        }

        //Prevent scale from going negative
        currScale.y = 0;
        hookCord.transform.localScale = currScale;
        //Interactable will now be controlled by mech hand rather than the grappling hook
        actualHook.SwitchToMechHand();
        //Grappling hook is left disabled unless in use
        //to avoid problems with collisions
        grapplingHook.gameObject.SetActive(false);
        actualHook.gameObject.SetActive(false); //actual hook is disabled to not interfere with mech hand grabbing
        State = GrapplingHookState.Inactive;
    }
コード例 #9
0
    /**
     * Extends the grappling hook
     */
    public IEnumerator Extend()
    {
        //Shoot a raycast out in the direction the grappling hook would fire
        //if the raycast happens to hit something, the grappling hook will hit it too
        //store this position as the anchor point
        //this is to ensure that the destination is on the surface of the object
        //as sometimes the grappling hook goes inside objects
        RaycastHit hit;

        if (Physics.Raycast(hookLaunchPoint.position, hookLaunchPoint.forward, out hit, maxLength))
        {
            if (hit.collider.gameObject.GetComponent <Hookable>())
            {
                anchorPoint = hit.point;
            }
        }
        else
        {
            anchorPoint = Vector3.zero;
        }
        grapplingHook.gameObject.SetActive(true);
        actualHook.gameObject.SetActive(true); //actual hook is disabled to not interfere with mech hand grabbing
        State = GrapplingHookState.Extending;
        Vector3 currScale = hookCord.transform.localScale;
        Vector3 currPos   = hookCord.transform.position;
        float   length    = currScale.y * 2; //since scale for a cylinder corresponds to # of units from centre to either side

        while (length < maxLength)
        {
            //Adjust scale
            currScale.y += extendSpeed * Time.deltaTime;
            length       = currScale.y * 2;
            hookCord.transform.localScale = currScale;

            //Adjust position to stay "anchored" to mech hand
            hookCord.transform.position = hookLaunchPoint.position + (hookLaunchPoint.forward * currScale.y);
            //Ensure actual hook stays on far end of hook cord
            AdjustActualHookPos(currScale.y);
            //ActualHook has hooked something, so stop extending
            if (actualHook.Hooked)
            {
                State = GrapplingHookState.Hooked;
                //move actual hook back out to the anchored position which is on surface
                actualHookTransform.position = anchorPoint;
                /* Change length of hook cord to make sure it doesnt overshoot the actual hook */

                length = Vector3.Distance(anchorPoint, hookLaunchPoint.position);
                //Adjust scale
                currScale.y = length / 2;
                hookCord.transform.localScale = currScale;
                //Adjust position to stay "anchored" to mech hand
                hookCord.transform.position = hookLaunchPoint.position + (hookLaunchPoint.forward * currScale.y);

                //If the Hookable is an Interactable
                if (actualHook.target)
                {
                    State = GrapplingHookState.Held;
                    actualHook.AttachInteractable();
                }

                yield break;
            }

            if (actualHook.obstructed)
            {
                StartCoroutine(Retract());
                yield break;
            }


            yield return(null);
        }

        //Start retract process after reaching maximum length
        StartCoroutine(Retract());
    }
コード例 #10
0
    /**
     * Pull player towards hooked location
     */
    public IEnumerator Pull()
    {
        State = GrapplingHookState.Pulling;
        Vector3 currScale = hookCord.transform.localScale;
        float   length    = currScale.y * 2; //since scale for a cylinder corresponds to # of units from centre to either side

        //Direction from player to the hooked point, the direction we will be pulled towards
        Vector3 dirToMove = (anchorPoint - playerTransform.position).normalized;

        //This is to make sure we dont move downwards if we aim lower (or higher!)
        dirToMove.y = 0;


        while (length > 0)
        {
            float oldScale = currScale.y;
            //Adjust scale
            currScale.y -= retractSpeed * Time.deltaTime;
            length       = currScale.y * 2;
            hookCord.transform.localScale = currScale;

            /**1. We move the coord to the mech hand, just like in Extend()/Retract()  **/

            //Adjust position to stay "anchored" to anchor point
            hookCord.transform.position = hookLaunchPoint.position + (hookLaunchPoint.forward * currScale.y);
            //Ensure actual hook stays on far end of hook cord
            AdjustActualHookPos(currScale.y);

            /** 2. We move the mech hand (and as a result, the hook cord attached to the mech hand)
             *     in the hook cord's up direction (the direction it moves in) by the amount
             *     the hook cord has shrunk multiplied by 2. Mulitiplication because the hook cord
             *     is no longer in the center
             *     (below is pic demonstrating what this horrible explanation is trying to say)
             *
             *  A)  , = center of hook cord
             *     currently, scale of 4
             *     [M.Hand]----,----[HookedObj]
             *
             *  B) hook cord scaled down, now scale of 3
             *     4 - 3 = 1 (deltaScale), distance from HookedObj
             *     [M.Hand] ---,--- [HookedObj]
             *
             *  C) hook cord moved to mech hand, (which is also deltaScale units away)
             *     increasing the distance b/w hook cord and HookedObj to be 2 * deltaScale
             *     [M.Hand]---,---  [HookedObj]
             *
             *  D) translate mech hand by 2 * deltaScale and the hook cord is shorter and the mech
             *     hand has moved
             *       [M.Hand]---,---[HookedObj]
             *
             *
             **/
            float deltaScale = oldScale - currScale.y;
            playerTransform.Translate(dirToMove * deltaScale * 2, Space.World);

            yield return(null);
        }

        //Prevent scale from going negative
        currScale.y = 0;
        hookCord.transform.localScale = currScale;

        //Grappling hook is left disabled unless in use
        //to avoid problems with collisions
        grapplingHook.gameObject.SetActive(false);
        State = GrapplingHookState.Inactive;
    }
コード例 #11
0
        /// <summary>
        /// Moves the character.
        /// </summary>
        override public void DoMove()
        {
            if (grapple == null)
            {
                state = GrapplingHookState.NONE;
                return;
            }

            // Check for hitting head
            if (character.WouldHitHeadThisFrame || WouldHitSides())
            {
                CancelGrapple();
                return;
            }

            // Cancel swing if we hit ground again
            if (hasLeftGround && character.Grounded)
            {
                CancelGrapple();
                return;
            }

            // have we left the ground?
            if (!hasLeftGround && !character.Grounded)
            {
                hasLeftGround = true;
            }

            // Hnadle input
            HandleInputs();

            switch (state)
            {
            case GrapplingHookState.LAUNCHING:
                if (!character.Grounded)
                {
                    // Apply acceleration
                    character.AddVelocity(0, TimeManager.FrameTime * character.Gravity, false);
                    // Limit to terminal velocity
                    if (character.Velocity.y < character.terminalVelocity)
                    {
                        character.SetVelocityY(character.terminalVelocity);
                    }
                    // Keep moving according to residual velocity
                    character.Translate(character.Velocity.x * TimeManager.FrameTime, character.Velocity.y * TimeManager.FrameTime, true);
                }
                // Update rope distance
                ropeDistance = Vector2.Distance(((Vector2)grapple.transform.position - HandOffset), (Vector2)character.Transform.position);
                if (maxDistance < ropeDistance)
                {
                    maxDistance = ropeDistance;
                }
                break;

            case GrapplingHookState.CLINGING:
                if (controlType == GrapplingHookControlType.AUTO_RETRACT)
                {
                    state = GrapplingHookState.AUTO_RETRACTING;
                }
                DoSwing();
                if (controlType != GrapplingHookControlType.AUTO_RETRACT && character.Input.VerticalAxisDigital == 1)
                {
                    DoRetract(1);
                }
                if (controlType == GrapplingHookControlType.UP_AND_DOWN && character.Input.VerticalAxisDigital == -1 && !character.Grounded)
                {
                    DoRetract(-1);
                }
                break;

            case GrapplingHookState.AUTO_RETRACTING:
                DoSwing();
                DoRetract(1);
                break;

            case GrapplingHookState.SLINGSHOT:
                // DoSwing();
                DoRetract(1);
                break;
            }
            // Draw Rope
            DrawRope();
        }