Inheritance: StateClass
示例#1
0
    //=================================================================================================================o

    // Check for ledge collider in front
    void CheckLedge()
    {
        if (hMove.Grounded)
        {
            RaycastHit hit;

            if (!Physics.Raycast(hero.position + hero.up, hero.forward, 1f, climbLayers))
            {
                return;
            }

            else if (Physics.Raycast(hero.position + hero.up, hero.forward, out hit, 1f, climbLayers))
            {
                if (hit.collider.name == "climbLedge")
                {
                    isClimbing     = true;
                    rb.isKinematic = true;
                    hMove.canMove  = false;

                    isLedgeEnd = false;

                    curT        = hit.transform;
                    lastHeroPos = hero.position;

                    if (doClimbDel != null)
                    {
                        doClimbDel("Ledge");
                    }
                    climbState = ClimbState.LedgeJump;
                }
            }
        }
    }
示例#2
0
    //=================================================================================================================o

    // At corner change climb handle
    void CornerLerp(float speed)
    {
        Vector3 v = nextPoint -
                    (hero.right * cornerSideOffset) - (hero.forward * offsetToWall) - (hero.up * heightOffsetToEdge);

        float angleTo = Vector3.Angle(hero.right, curT.transform.right);

        // Faster if angle is rel small
        speed = angleTo <= 15.0f ?  speed *= 15 : speed *= 4;

        // Apply
        hero.position = Vector3.Lerp(hero.position, v, Time.deltaTime * speed);
        hero.rotation = Quaternion.Lerp(hero.rotation, curT.rotation, Time.deltaTime * speed);

        // Shift inward a bit
        if (angleTo <= 0.01f)
        {
            Vector3 relPoint = curT.InverseTransformPoint(hero.position);
            SmoothToSpot(Mathf.Abs(relPoint.z), offsetToWall, Vector3.forward, Vector3.back);

            if (doClimbDel != null)
            {
                doClimbDel("Edge");
            }
            climbState = ClimbState.Edge; // Out
        }                                 // Reset hang
        atHangR = false;
        atHangL = false;
    }
示例#3
0
    //=================================================================================================================o

    // Jump over ledge
    void LedgeJump()
    {
        Vector3 topVec = new Vector3(lastHeroPos.x, curT.position.y + 0.3f, lastHeroPos.z);
        Vector3 fwdVec = topVec + hero.forward * 2.0f;
        Vector3 dwnVec = hero.position - (hero.up * 3f);

        // Up
        if (((hero.position.y - curT.position.y) <= 0.0f) && !isLedgeEnd)
        {
            hero.position = Vector3.Lerp(hero.position, topVec, Time.deltaTime * climbSpeed * 5f);
        }
        else
        {
            // Forward
            if (!isLedgeEnd)
            {
                hero.position = Vector3.Lerp(hero.position, fwdVec, Time.deltaTime * climbSpeed * 9f);
            }

            // Down & Exit
            if (Vector3.Distance(topVec, hero.position) >= 1.8f)             // Forward distance to go over the ledge
            {
                isLedgeEnd    = true;
                hero.position = Vector3.Lerp(hero.position, dwnVec, Time.deltaTime * climbSpeed * 1.0f);
                if (hMove.Grounded)
                {
                    climbState = ClimbState.None;
                }
            }
        }
    }
示例#4
0
    //=================================================================================================================o

    IEnumerator Prepare()
    {
        isPreparing = true;
        if (doClimbDel != null)
        {
            doClimbDel("Prepare");
        }
        climbState = ClimbState.Prepare;

        yield return(new WaitForSeconds(0.9f));

        if (Input.GetKey(KeyCode.E) && climbState == ClimbState.Prepare)         // Climb up
        {
            if (doClimbDel != null)
            {
                doClimbDel("Climb");
            }
            climbState = ClimbState.Climb; // Move to edge
        }
        else                               // Stay at position
        {
            isPullUp   = false;
            isOverhang = false;
            yield return(new WaitForSeconds(0.2f));                                                         // Fade to hang pose

            nextPoint  = hero.position - ((hero.up * -heightOffsetToEdge) - (hero.forward * offsetToWall)); //Current position
            curT       = lastT;
            climbState = ClimbState.Climb;                                                                  // To last position
        }
        isPreparing = false;
    }
示例#5
0
    //=================================================================================================================o

    // Reset if leaving Climb modus
    public void ExitClimb()
    {
        rb.isKinematic = false;
        hMove.canMove  = true;
        atHangR        = false;
        atHangL        = false;
        isWall         = false;
        isPullUp       = false;
        curT           = null;
        lastT          = null;

        rb.AddForce(Vector3.down * 2, ForceMode.VelocityChange);

        // Restore Rotation
        if (inClimbRot)
        {
            hero.rotation = Quaternion.Euler(0, rot.eulerAngles.y, 0);
            inClimbRot    = false;
        }

        isClimbing = false;

        if (doClimbDel != null)
        {
            doClimbDel("None");
        }
        climbState = ClimbState.None;

        // Out
        reset = true;
    }
示例#6
0
 //=================================================================================================================o
 void Start()
 {
     hero       = transform;
     rb         = rigidbody;
     climbState = ClimbState.None;
     Physics.IgnoreLayerCollision(8, 9);        // ignore player / climb collision
     hMove     = GetComponent <HeroMotor> () as HeroMotor;
     hSwim     = GetComponent <HeroSwim> () as HeroSwim;
     cacheDist = checkDistance;
 }
示例#7
0
 protected override void CustomStartState()
 {
     foreach (var state in possibleNextStates)
     {
         ClimbState cs = state as ClimbState;
         if (cs)
         {
             nextClimbUpState = cs;
             break;
         }
     }
 }
示例#8
0
    //=================================================================================================================o

    // Wall climb handling
    void WallClimb()
    {
        Vector3 relV = curT.InverseTransformPoint(hero.position);

        float distY = Mathf.Abs(relV.y);
        float distZ = Mathf.Abs(relV.z);

        // Limit is almost the edge
        if (distY >= heightOffsetToEdge * 1.1f)
        {
            SmoothToSpot(distZ, offsetToWall, Vector3.forward, Vector3.back);

            // Input
            if (Input.GetAxis("Vertical") != 0.0f)
            {
                if (Input.GetAxis("Vertical") > 0.0f)
                {
                    inputVec = hero.TransformPoint(Vector3.up);
                }
                else
                {
                    inputVec = hero.TransformPoint(Vector3.down);

                    if (!Physics.Raycast(hero.position, hero.forward, offsetToWall, climbLayers) || hMove.Grounded)
                    {
                        climbState = ClimbState.None;
                    }
                }

                // Apply movement
                hero.position = Vector3.Lerp(hero.position, inputVec, Time.deltaTime * climbSpeed * 1.3f);
            }
            else             // Stop if there's no input
            {
                inputVec = hero.TransformPoint(Vector3.zero);
            }
        }
        else         // Reached the edge
        {
            if (doClimbDel != null)
            {
                doClimbDel("Edge");
            }
            climbState = ClimbState.Edge;             // Out
        }

        // Drop
        // Action key down to Exit
        if (Input.GetKeyDown(KeyCode.E) && !hMove.Grounded)
        {
            climbState = ClimbState.None;             // Out
        }
    }
示例#9
0
    //=================================================================================================================o

    // Jump to next spot
    void WallJump()
    {
        if (hMove.Grounded)         // Jump to wall
        {
            // if Grounded and edge is very close, just snap!
            if (Vector3.Distance(hero.position, nextPoint) <= 2.5f)
            {
                Climb();
            }
            else             // do a walljump
            {
                hero.Translate(hero.up * Time.deltaTime * climbSpeed * 8);
            }
        }
        else         // Air/Edge
        {
            if (curT.name == "climbArea")
            {
                // Jump to position
                Vector3 edgePos = nextPoint + ((hero.up * -heightOffsetToEdge) - (hero.forward * offsetToWall));

                // Apply lift up
                hero.position = Vector3.Lerp(hero.position, edgePos, Time.deltaTime * climbSpeed * 8);                   // 10

                // At position
                if (Vector3.Distance(hero.position, edgePos) <= 0.1f)
                {
                    if (doClimbDel != null)
                    {
                        doClimbDel("WallClimb");
                    }
                    climbState = ClimbState.WallClimb;                     // Out
                }
            }
            else if (curT.name == "climbWall")
            {
                if (doClimbDel != null)
                {
                    doClimbDel("WallClimb");
                }
                climbState = ClimbState.WallClimb;                 // Out
            }
            else
            {
                Climb();                 // Climb to --> Edge and Out
            }
        }
    }
示例#10
0
        void LookForClimbSpot()
        {
            Transform camTrans = Camera.main.transform;

            var        ray = new Ray(camTrans.position, camTrans.forward);
            RaycastHit hit;
            LayerMask  mask        = ~((1 << gameObject.layer) | (1 << 3));
            float      maxDistance = 20;

            if (!Physics.Raycast(ray, out hit, maxDistance, mask))
            {
                Debug.Log("No hit");
                return;
            }

            Debug.Log(hit.transform.gameObject.name);

            var manager = hit.transform.GetComponent <GridManager>();

            if (manager == null)
            {
                Debug.Log("No manager");
                return;
            }

            var   closestPoint = manager.GetClosestPoint(transform.position);
            float distance     = Vector3.Distance(transform.position, closestPoint.transform.parent.position);

            if (distance > 5)
            {
                Debug.Log("Too great distance");
                return;
            }

            _curManager     = manager;
            _targetPoint    = closestPoint;
            _targetPosition = closestPoint.transform.position;
            _curPoint       = closestPoint;
            climbing        = true;
            _lockInput      = true;
            _targetState    = ClimbState.onPoint;

            _anim.CrossFade("To_Climb", 0.4f);
            GetComponent <Controller.StateManager>().DisableController();

            _waitToStartClimb = true;
            Debug.Log("All o kay");
        }
示例#11
0
    void WallJump()
    {
        Debug.Log("Walljump");
        Vector3 walljumpWay = Vector3.right;

        walljumpWay.y = Mathf.Tan(LastWallAngle - 180);
        walljumpWay.Normalize();
        walljumpWay  *= wallJumpForce.x;
        walljumpWay.y = wallJumpForce.y;


        MoveForce f = new MoveForce(walljumpWay, wallJumpGravity, wallJumpTime, 0.1f);

        forces.Add(f);
        wallClimb = ClimbState.Jumping;
    }
示例#12
0
        IEnumerator WrapUpTransition(float t)
        {
            yield return(new WaitForSeconds(t));

            _climbState = _targetState;
            if (_climbState == ClimbState.onPoint)
            {
                _curPoint = _targetPoint;
                _anim.SetBool("Move", false);
            }

            _initTransit    = false;
            _lockInput      = false;
            _inputDirection = Vector3.zero;
            _waitForWrapUp  = false;
        }
示例#13
0
    //=================================================================================================================o

    IEnumerator PreShort(ClimbState cS)
    {
        isPreShort = true;

        // Switch fast to next step if falling
        float seconds = climbState != ClimbState.None ? 0.75f : 0.0f;

        // Delegate to trigger animation state
        if (doClimbDel != null)
        {
            doClimbDel("PreShort");
        }
        climbState = ClimbState.PreShort;                 // prepare for short distance climb (Animation)

        yield return(new WaitForSeconds(seconds));

        if (Input.GetKey(KeyCode.E) && climbState == ClimbState.PreShort)         // Climb up
        {
            if (doClimbDel != null)
            {
                doClimbDel("Short");
            }
            climbState = cS; //ClimbState.Climb; // Move to edge
        }
        else                 // Stay at position
        {
            isPullUp   = false;
            isOverhang = false;
            yield return(new WaitForSeconds(0.3f));             // Fade to hang pose

            if (curT != null && curT.name != "climbArea")
            {
                nextPoint  = hero.position - ((hero.up * -heightOffsetToEdge) - (hero.forward * offsetToWall)); //lastPoint;
                curT       = lastT;
                climbState = ClimbState.Climb;                                                                  // To last
            }
            else                                                                                                // We hit a Wall collider start climbing
            {
                if (doClimbDel != null)
                {
                    doClimbDel("WallClimb");
                }
                climbState = ClimbState.WallClimb;
            }
        }
        isPreShort = false;
    }
示例#14
0
        void OnPoint(Vector3 direction)
        {
            neighbour = _curPoint.GetNeighbour(direction);

            if (neighbour == null)
            {
                return;
            }

            _targetPoint = neighbour.target;
            _prevPoint   = _curPoint;
            _climbState  = ClimbState.inTransit;

            UpdateconnectionTransitByType(neighbour, direction);

            _lockInput = true;
        }
示例#15
0
    //=================================================================================================================o

    IEnumerator Overhang()
    {
        if (doClimbDel != null)
        {
            doClimbDel("Overhang");
        }
        climbState = ClimbState.Overhang;

        yield return(new WaitForSeconds(2.2f));

        if (doClimbDel != null)
        {
            doClimbDel("Edge");
        }
        climbState = ClimbState.Edge;

        isOverhang = false;
    }
示例#16
0
    //public Animator _animator;


    void Awake()
    {
        //_animator = GetComponent<Animator>();
        controller = GetComponent <CharacterController2D>();

        controller.onControllerCollidedEvent += onControllerCollider;
        controller.onTriggerEnterEvent       += onTriggerEnterEvent;
        controller.onTriggerExitEvent        += onTriggerExitEvent;

        // initialize all states
        jumpState    = new JumpState(this);
        runState     = new RunState(this);
        idleState    = new IdleState(this);
        climbState   = new ClimbState(this);
        stealthState = new StealthState(this);

        // set beginning state
        SetMovementState(idleState);
    }
示例#17
0
        void InitClimbing()
        {
            if (_initClimb)
            {
                return;
            }

            _initClimb = true;

            if (_ik != null)
            {
                _ik.UpdateAllPointsOnOne(_targetPoint);
                _ik.UpdateAllTargetPositions(_targetPoint);
                _ik.ImmediatePlaceHelpers();
            }

            curConnection = ConnectionType.direct;
            _targetState  = ClimbState.onPoint;
        }
示例#18
0
        void HandleMount()
        {
            if (!_initTransit)
            {
                _initTransit = true;

                _ikFollowSideReached = false;
                _ikLandSideReached   = false;
                _interpolT           = 0;
                _interpolStart       = transform.position;
                _interpolTarget      = _targetPosition + rootOffset;

                _curCurve = _mountCurve;
                _curCurve.transform.rotation = _targetPoint.transform.rotation;
                var points = _curCurve.GetAnchorPoints();
                points[0].transform.position = _interpolStart;
                points[points.Length - 1].transform.position = _interpolTarget;
            }

            if (enableRootMovement)
            {
                _interpolT += Time.deltaTime * 2;
            }

            if (_interpolT >= 1)
            {
                _interpolT         = 1;
                _waitToStartClimb  = false;
                _lockInput         = false;
                _initTransit       = false;
                _ikLandSideReached = false;
                _climbState        = _targetState;
            }

            var targetPos = _curCurve.GetPointAt(_interpolT);

            Debug.DrawLine(transform.position, targetPos, Color.gray);
            Debug.DrawLine(transform.position, _interpolTarget, Color.black);
            transform.position = targetPos;

            HandleWeightAll(_interpolT, mountCurve);
            HandleRotation();
        }
示例#19
0
    public override void Place()
    {
        base.Place();

        LevelController = FindObjectOfType <LevelController>();

        _stateMachine = new StateMachine();

        _walkState = new WalkState(this);
        var fallState  = new FallState(this);
        var climbState = new ClimbState(this);
        var dieState   = new DieState(this);

        _stateMachine.AddTransition(_walkState, fallState, () => !OnGround);
        _stateMachine.AddTransition(fallState, _walkState, () => OnGround);
        _stateMachine.AddTransition(_walkState, climbState, () => Climbing);
        _stateMachine.AddTransition(climbState, _walkState, () => !Climbing);

        _stateMachine.AddAnyTransition(dieState, () => _dead);
    }
示例#20
0
    //=================================================================================================================o

    IEnumerator PreTop()
    {
        isPreparing = true;
        if (curT.name == "climbObjectTopOh")
        {
            if (doClimbDel != null)
            {
                doClimbDel("PreOh");
            }                                                            // Overhang
        }
        else
        {
            if (doClimbDel != null)
            {
                doClimbDel("Prepare");
            }                                                              // Normal
        }
        climbState = ClimbState.Prepare;

        yield return(new WaitForSeconds(0.8f));

        if (Input.GetKey(KeyCode.E) && climbState == ClimbState.Prepare)         // Climb up
        {
            if (doClimbDel != null)
            {
                doClimbDel("Top");
            }
            climbState = ClimbState.Top;            // Out
        }
        else                                        // Stay at position
        {
            yield return(new WaitForSeconds(0.2f)); // Fade to hang pose

            if (doClimbDel != null)
            {
                doClimbDel("Edge");
            }
            climbState = ClimbState.Edge;
        }
        isPreparing = false;
    }
示例#21
0
        void UpdateconnectionTransitByType(Neighbour n, Vector3 inputDirection)
        {
            var desiredPosition = Vector3.zero;

            curConnection = n.cType;

            Vector3 direction = _targetPoint.transform.position - _curPoint.transform.position;

            direction.Normalize();

            switch (n.cType)
            {
            case ConnectionType.inBetween:

                var dist = Vector3.Distance(_curPoint.transform.position, _targetPoint.transform.position);
                desiredPosition = _curPoint.transform.position + (direction * (dist / 2));
                _targetState    = ClimbState.betweenPoints;
                TransitDir transitDir = TransitDirection(inputDirection, false);
                PlayAnim(transitDir);
                break;

            case ConnectionType.direct:

                desiredPosition = _targetPoint.transform.position;
                _targetState    = ClimbState.onPoint;
                transitDir      = TransitDirection(direction, false);
                Debug.Log(transitDir.ToString());
                PlayAnim(transitDir);
                break;

            case ConnectionType.dismount:

                desiredPosition = _targetPoint.transform.position;
                _anim.SetInteger("JumpType", 20);
                _anim.SetBool("Move", true);
                break;
            }

            _targetPosition = desiredPosition;
        }
示例#22
0
    //=================================================================================================================o

    // Reached the top, PullUp
    void PullUp()
    {
        Vector3 topVec = lastHeroPos + hero.up * 2.3f;
        Vector3 fwdVec = topVec + hero.forward * 1.5f;

        // Step uo
        if (Vector3.Distance(hero.position, lastHeroPos) <= 2.1f)
        {
            hero.position = Vector3.Lerp(hero.position, topVec, Time.deltaTime * climbSpeed * 4.5f);
        }
        else         // Step forward
        {
            hero.position = Vector3.Lerp(hero.position, fwdVec, Time.deltaTime * climbSpeed * 4);

            // Exit
            if (Vector3.Distance(topVec, hero.position) >= 0.7f)
            {
                climbState = ClimbState.None;
            }
        }
        isPullUp = false;
    }
示例#23
0
    private void Climb(ClimbState state)
    {
        if (state == ClimbState.climbUp)
        {
            climbAxis = 1;
        }

        if (state == ClimbState.wait)
        {
            climbAxis = 0;
        }

        if (state == ClimbState.climbDown)
        {
            climbAxis = -1;
        }

        anim.SetFloat("ClimbAxis", climbAxis * 2);


        rb.MovePosition(new Vector3(transform.position.x, transform.position.y + climbAxis * Time.deltaTime));
    }
示例#24
0
        void BetweenPoints(Vector3 direction)
        {
            var n = _targetPoint.GetNeighbour(_prevPoint);

            if (n != null)
            {
                if (direction == n.direction)
                {
                    _targetPoint = _prevPoint;
                    Debug.Log("Moving to pervpoint?");
                }
                else
                {
                    Debug.Log("Doing nothing");
                }
            }

            _targetPosition = _targetPoint.transform.position;
            _climbState     = ClimbState.inTransit;
            _targetState    = ClimbState.onPoint;
            _prevPoint      = _curPoint;
            _lockInput      = true;
            _anim.SetBool("Move", false);
        }
示例#25
0
    private void Detach(ClimbState climbState)
    {
        // Set player status
        playerState = climbState;

        if (climbState == ClimbState.DISMOUNTING)
        {
            // set start and end
            start = player.position;
            // have player dismount forward if climbing off top of ladder
            end = player.position + (-transform.forward * detachDistanceTop);
        }
        else
        {
            // Clear player values
            playerMotor.enabled = true;
            playerMotor         = null;
            playerCtrl          = null;
        }

        // Reset values to initial state
        isInTrigger = false;
        t_lerp      = 0;
    }
示例#26
0
    //=================================================================================================================o


    void Climb()
    {
        Vector3 edgePos = nextPoint + ((hero.up * -heightOffsetToEdge) - (hero.forward * offsetToWall));

        // Apply lift up
        hero.position = Vector3.Lerp(hero.position, edgePos, Time.deltaTime * climbSpeed * 8);

        // At edge
        if (Vector3.Distance(hero.position, edgePos) <= 0.1f)
        {
            if (isOverhang)
            {
                StartCoroutine(Overhang());
            }
            else
            {
                if (doClimbDel != null)
                {
                    doClimbDel("Edge");
                }
                climbState = ClimbState.Edge;
            }
        }
    }
    //=================================================================================================================o
    //==================================================Climb==========================================================o
    //=================================================================================================================o
    void _Climb()
    {
        // Current state info for layer Base
        animatorStateInfo = animator.GetCurrentAnimatorStateInfo(0);

        // Switch climb states
        switch (climbState)
        {
            case ClimbState.None:
                if (!reset)
                {
                    ExitClimb();
                }
                CheckClimb();
                break;

            case ClimbState.Climb:
                ClimbTo();
                reset = false;
                break;

            case ClimbState.Top:
                isTop = false;
                PullUp();
                reset = false;
                break;

            case ClimbState.Wall:
                WallClimb();
                reset = false;
                break;

            case ClimbState.Area:
                ClimbTo();
                reset = false;
                break;

            case ClimbState.Edge:
                EdgeClimb();
                reset = false;
                break;

            case ClimbState.Corner:
                CornerLerp(climbSpeed);
                reset = false;
                break;
        }

        if (doJumpDown)
        {
            if (v != 0)
                jumpOffNext = true;
            else
                jumpOffNext = false;

            climbState = ClimbState.None;
        }

        if (!animator.IsInTransition(0))
        {
            // Resetting--------------------------------------------------
            if (animatorStateInfo.IsTag("Jump"))
            {
                // Reset our parameter to avoid looping
                animator.SetBool("Jump", false); // RESET
            }
            if (animatorStateInfo.IsTag("Oh"))
            {
                animator.SetBool("Overhang", false); // RESET
                isOverhang = false;
            }
        }
    }
    //=================================================================================================================o
    // Jump to next spot
    void WallJump()
    {
        if (hMove.Grounded) // Jump to wall
        {
            // if Grounded and edge is very close, just snap!  And not wall and area climbing!
            if (Vector3.Distance ( hero.position, nextPoint ) <= 2.5f
                && (curT.name != "climbWall" && curT.name != "climbArea"))
            {
                Climb();
            }
            else // do a walljump
            {
                hero.Translate( hero.up * Time.deltaTime * climbSpeed * 8 );
            }
        }
        else // Air/Edge
        {
            if (curT.name == "climbArea")
            {
                // Jump to position
                Vector3 edgePos = nextPoint + ((hero.up * -heightOffsetToEdge) - (hero.forward * offsetToWall));

                // Apply lift up
                hero.position = Vector3.Lerp (hero.position, edgePos, Time.deltaTime * climbSpeed * 8 ); // 10

                // At position
                if (Vector3.Distance ( hero.position, edgePos ) <=  0.1f)
                {
                    if (doClimbDel != null) { doClimbDel("WallClimb"); }
                    climbState = ClimbState.WallClimb; // Out
                }
            }
            else if (curT.name == "climbWall")
            {
                if (doClimbDel != null) { doClimbDel("WallClimb"); }
                climbState = ClimbState.WallClimb; // Out
            }
            else
                Climb(); // Climb to --> Edge and Out
        }
    }
示例#29
0
    //=================================================================================================================o
    void Start()
    {
        hero = transform;
        //a = GetComponent <Animation>() as Animation;
        if (a.clip) {
            aC = a.clip;
        } else aC = a["idle"].clip;
        impactM = a["land"].clip;

        hMotor = GetComponent <HeroMotor>() as HeroMotor;
        hClimb = GetComponent <HeroClimb>() as HeroClimb;
        hPhys = GetComponent <HeroPhysic>() as HeroPhysic;
        hSwim = GetComponent <HeroSwim>() as HeroSwim;
        hKey = GetComponent <HeroKeymap>() as HeroKeymap;

        // Pass Delegates
        hMotor.doJumpDel += DoJump;
        hMotor.doBalanceDel += DoBalance;
        hMotor.doCombatDel += DoCombat;
        hMotor.doSwitchWeapDel += DoSwitchWeapons;
        hMotor.doEvadeDel += DoEvade;
        hMotor.doSneakDel += DoSneak;
        hClimb.doClimbDel += DoClimb;
        hSwim.doSwimDel += DoSwim;
        hPhys.doPhysDel += DoPhysx;

        currRot = 0.0f;
        leanRot = 0.0f;
        //sprintRot = 0.0f;
        lastRootForward = hero.forward;

        // Start is in Weaponstate.None, weaponless

        // Sword
        if (sword_Hand == null) // If no weapon is assigned
        {
            sword_Hand = new GameObject("emptyObj");
            sword_Hand.active = false;
        }
        else
            sword_Hand.active = false;
        if (sword_Holster == null) // If no weapon is assigned
        {
            sword_Holster = new GameObject("emptyObj");
            sword_Holster.active = false;
        }
        else
            sword_Holster.active = false;

        // Bow
        if (bow_Hand == null) // If no weapon is assigned
        {
            bow_Hand = new GameObject("emptyObj");
            bow_Hand.active = false;
        }
        else
            bow_Hand.active = false;
        if (bow_Holster == null) // If no weapon is assigned
        {
            bow_Holster = new GameObject("emptyObj");
            bow_Holster.active = false;
        }
        else
            bow_Holster.active = false;

        // Quiver
        if (bow_Quiver == null) // If no weapon is assigned
        {
            bow_Quiver = new GameObject("emptyObj");
            bow_Quiver.active = false;
        }
        else
            bow_Quiver.active = false;

        // Rifle
        if (rifle_Hand == null) // If no weapon is assigned
        {
            rifle_Hand = new GameObject("emptyObj");
            rifle_Hand.active = false;
        }
        else
            rifle_Hand.active = false;
        if (rifle_Holster == null)// If no weapon is assigned
        {
            rifle_Holster = new GameObject("emptyObj");
            rifle_Holster.active = false;
        }
        else
            rifle_Holster.active = false;

        // Pistol
        if (pistol_Hand == null)// If no weapon is assigned
        {
            pistol_Hand = new GameObject("emptyObj");
            pistol_Hand.active = false;
        }
        else
            pistol_Hand.active = false;
        if (pistol_Holster == null)// If no weapon is assigned
        {
            pistol_Holster = new GameObject("emptyObj");
            pistol_Holster.active = false;
        }
        else
            pistol_Holster.active = false;

        // Look for setup
        DoSwitchWeapons ();

        actionState = ActionState.None;
        evadeState = EvadeState.None;
        climbState = ClimbState.None;
    }
示例#30
0
    //=================================================================================================================o

    // Moving sideways on edge
    void EdgeMovement()
    {
        Vector3 relPoint = curT.InverseTransformPoint(hero.position);

        SmoothToSpot(Mathf.Abs(relPoint.z), offsetToWall, Vector3.forward, Vector3.back);
        SmoothToSpot(Mathf.Abs(relPoint.y), heightOffsetToEdge, Vector3.up, Vector3.down);

        // Drop down
        if (Input.GetAxis("Vertical") < 0.0f /* || relPoint.z > 5f*/)
        {
            climbState = ClimbState.None;
        }
        // One handed on edge, animation trigger
        else if (Mathf.Abs(relPoint.x) >= 0.44f)
        {
            // Right side
            if (relPoint.x >= 0.44f)
            {
                if (doClimbDel != null)
                {
                    doClimbDel("HangR");
                }
                atHangR = true;                 // Hang at right end

                if (relPoint.x >= 0.5f)
                {
                    climbState = ClimbState.None;                     // Out
                }
            }
            // Left side
            else if (relPoint.x <= -0.44f)
            {
                if (doClimbDel != null)
                {
                    doClimbDel("HangL");
                }
                atHangL = true;                 // Hang at left end

                if (relPoint.x <= -0.5f)
                {
                    climbState = ClimbState.None;                     // Out
                }
            }
        }

        // Early out
        if (Input.GetAxis("Horizontal") == 0.0f)
        {
            return;
        }

        // Left / Right check for new spots
        else
        {
            Vector3 origin = hero.position - (hero.forward * -offsetToWall) - (hero.up * -heightOffsetToEdge);
            float   xInpt  = Input.GetAxis("Horizontal") > 0.0f ? 1.0f : -1.0f;
            Vector3 dir    = Input.GetAxis("Horizontal") > 0.0f ? hero.right : -hero.right;
            cornerSideOffset = Input.GetAxis("Horizontal") > 0.0f ? -0.4f : 0.4f;
            RaycastHit hit;

            if (Physics.SphereCast(origin, 0.2f, dir, out hit, 0.3f, climbLayers))
            {
                nextPoint = hit.point;
                lastT     = curT;
                curT      = hit.transform;

                inClimbRot = true;
                rot        = hero.rotation;

                if (doClimbDel != null)
                {
                    doClimbDel("Corner");
                }
                climbState = ClimbState.Corner;                 // Out
            }

            // Speed interval
            if (!speedInterval)
            {
                StartCoroutine(SpeedInterval(0.2f, climbSpeed));                   // 0.2f, climbspeed
            }

            // Apply
            hero.Translate(xInpt * Time.deltaTime * edgeSpeed, 0, 0, curT);

            // If not close to end
            if ((Mathf.Abs(relPoint.x) < 0.44f) && (atHangR || atHangL))
            {
                if (doClimbDel != null)
                {
                    doClimbDel("Edge");
                }
                atHangR = false;
                atHangL = false;
            }
        }
    }
    //=================================================================================================================o
    IEnumerator Overhang()
    {
        if (doClimbDel != null) { doClimbDel("Overhang"); }
        climbState = ClimbState.Overhang;

        yield return new WaitForSeconds (0.05f);

        if (doClimbDel != null) { doClimbDel("Edge"); }
            climbState = ClimbState.Edge;

        isOverhang = false;
    }
    //=================================================================================================================o
    // At corner change climb handle
    void CornerLerp(float speed)
    {
        Vector3 tVec = nextPoint -
            (hero.right * -cornerReach) - (hero.forward * climbOffsetToWall) - (hero.up * heightOffsetToEdge);

        float angleTo = Vector3.Angle(hero.right, curT.transform.right);

        // Faster if angle is rel small
        speed = angleTo <= 15.0f ? speed *= 15 : speed *= 4;

        // Avoid hanging
        animator.SetBool("HangL", false); // RESET
        animator.SetBool("HangR", false); // RESET

        // Apply
        hero.position = Vector3.Lerp(hero.position, tVec, Time.deltaTime * speed);
        hero.rotation = Quaternion.Lerp(hero.rotation, curT.rotation, Time.deltaTime * speed);

        // Shift inward a bit
        if (angleTo <= 0.01f)
        {
            Vector3 relPoint = curT.InverseTransformPoint(hero.position);

            MatchP(Mathf.Abs(relPoint.z), climbOffsetToWall, Vector3.forward, Vector3.back);

            animator.SetBool("CornerL", false); // RESET
            animator.SetBool("CornerR", false); // RESET
            climbState = ClimbState.Edge; // Out

        }
    }
    //=================================================================================================================o
    IEnumerator PreShort(ClimbState cS)
    {
        isPreShort = true;

        // Switch fast to next step if falling
        float seconds = climbState != ClimbState.None ? 0.75f : 0.0f;

        // Delegate to trigger animation state
        if (doClimbDel != null) { doClimbDel("PreShort"); }
            climbState = ClimbState.PreShort; // prepare for short distance climb (Animation)

        yield return new WaitForSeconds (seconds);

        if (Input.GetAxis("Vertical") > .5 && climbState == ClimbState.PreShort) // Climb up
        {
            if (doClimbDel != null) { doClimbDel("Short"); }
            climbState = cS; //ClimbState.Climb; // Move to edge
        }
        else // Stay at position
        {
            isPullUp = false;
            isOverhang = false;
            yield return new WaitForSeconds (0.3f); // Fade to hang pose

            if ( curT != null && curT.name != "climbArea")
            {
                nextPoint = hero.position - ((hero.up * -heightOffsetToEdge) - (hero.forward * offsetToWall)); //lastPoint;
                curT = lastT;
                climbState = ClimbState.Climb; // To last
            }
            else // We hit a Wall collider start climbing
            {
                if (doClimbDel != null) { doClimbDel("WallClimb"); }
                climbState = ClimbState.WallClimb;
            }
        }
        isPreShort = false;
    }
    //=================================================================================================================o
    IEnumerator Prepare()
    {
        isPreparing = true;
        if (doClimbDel != null) { doClimbDel("Prepare"); }
        climbState = ClimbState.Prepare;

        yield return new WaitForSeconds (0.9f);

        if (Input.GetAxis("Vertical") > .5 && climbState == ClimbState.Prepare) // Climb up
        {
            if (doClimbDel != null) { doClimbDel("Climb"); }
            climbState = ClimbState.Climb; // Move to edge
        }
        else // Stay at position
        {
            isPullUp = false;
            isOverhang = false;
            yield return new WaitForSeconds (0.2f); // Fade to hang pose
            nextPoint = hero.position - ((hero.up * -heightOffsetToEdge) - (hero.forward * offsetToWall)); //Current position
            curT = lastT;
            climbState = ClimbState.Climb; // To last position
        }
        isPreparing = false;
    }
    //=================================================================================================================o
    IEnumerator PreTop()
    {
        isPreparing = true;
        if (curT.name == "climbObjectTopOh")
        {
            if (doClimbDel != null) { doClimbDel("PreOh"); } // Overhang
        }
        else
        {
            if (doClimbDel != null) { doClimbDel("Prepare"); } // Normal
        }
        climbState = ClimbState.Prepare;

        yield return new WaitForSeconds (0.2f);//transition to top

        if (Input.GetAxis("Vertical") > .5 && climbState == ClimbState.Prepare) // Climb up
        {
            if (doClimbDel != null) { doClimbDel("Top"); }
                climbState = ClimbState.Top; // Out
        }
        else // Stay at position
        {
            yield return new WaitForSeconds (0.2f); // Fade to hang pose
            if (doClimbDel != null) { doClimbDel("Edge"); }
            climbState = ClimbState.Edge;
        }
        isPreparing = false;
    }
    //=================================================================================================================o
    // Reached the top, PullUp
    void PullUp()
    {
        Vector3 topVec = lastHeroPos + hero.up * 2.3f;
        Vector3 fwdVec = topVec + hero.forward * 1.5f;

        // Step uo
        if (Vector3.Distance (hero.position, lastHeroPos) <= 2.1f)
        {
            hero.position = Vector3.Lerp (hero.position, topVec, Time.deltaTime * climbSpeed *4.5f);
        }
        else // Step forward
        {
            hero.position = Vector3.Lerp (hero.position, fwdVec, Time.deltaTime * climbSpeed *4);

            // Exit
            if (Vector3.Distance (topVec, hero.position) >= 0.7f)
            {
                climbState = ClimbState.None;
            }
        }
        isPullUp = false;
    }
 //=================================================================================================================o
 void Start()
 {
     hero = transform;
     rb = rigidbody;
     climbState = ClimbState.None;
     Physics.IgnoreLayerCollision(8,9); // ignore player / climb collision
     hMove = GetComponent <HeroMotor> () as HeroMotor;
     hSwim = GetComponent <HeroSwim> () as HeroSwim;
     hKey = GetComponent <HeroKeymap> () as HeroKeymap;
     cacheDist = checkDistance;
 }
    //=================================================================================================================o
    // Look for objects to climb
    void CheckClimb()
    {
        if (!canClimb)
            return;
        if (doClimb && v > 0.2) // Up
        {
            // Reduce check distance/height while falling
            if (!grounded && baseState == BaseState.Base)
            {
                climbCheckDistance = 0.4f;
            }
            else
                climbCheckDistance = cacheDist;

            Vector3 p1 = hero.position - (hero.up * -heightOffsetToEdge) + hero.forward;
            Vector3 p2 = hero.position - (hero.up * -heightOffsetToEdge) - hero.forward;
            RaycastHit hit;

            // Hit nothing and not at edge -> Out
            if (!Physics.CapsuleCast(p1, p2, climbCheckRadius, hero.up, out hit, climbCheckDistance, climbLayers))
                return;
            // If not almost facing the edge cancel/Out
            if (Vector3.Angle(hero.right, hit.transform.right) >= 60.0f)
                return;

            if (isTop)
                return;

            if (curT != hit.transform)
            {
                curT = hit.transform;
                nextPoint = hit.point;
            }

            hero.rotation = Quaternion.Euler(curT.eulerAngles.x, curT.eulerAngles.y, 0);

            animator.SetInteger("RandomM", Random.Range(0, 3));

            if (curT.name == "climbObject")
            {
                rigidbody.isKinematic = true;
                climbState = ClimbState.Climb;
            }
            else if (curT.name == "climbObjectOh")
            {
                rigidbody.isKinematic = true;
                isOverhang = true;
                climbState = ClimbState.Climb;
            }
            else if (curT.name == "climbObjectTop")
            {
                rigidbody.isKinematic = true;
                isTop = true;
                climbState = ClimbState.Climb;
            }
            else if (curT.name == "climbObjectTopOh")
            {
                rigidbody.isKinematic = true;
                isTop = true;
                isOverhang = true;
                climbState = ClimbState.Climb;
            }
            else if (curT.name == "climbWall")
            {
                rigidbody.isKinematic = true;
                isTop = true;
                if (grounded)
                    climbState = ClimbState.Wall;
                else
                    climbState = ClimbState.Area;
            }
            else if (curT.name == "climbArea")
            {
                rigidbody.isKinematic = true;
                climbState = ClimbState.Area;
            }
            else
            {
                climbState = ClimbState.None;
            }

            isClimb = true;
            // UP
            climbUp = true;
            // Long or Short ?
            climbLong = hit.distance > 1 ? true : false;
        }
        else if (doClimb && v < -0.2) // Down
        {
            // Reduce check distance/height while falling
            if (!grounded && baseState == BaseState.Base)
            {
                climbCheckDistance = 0.4f;
            }
            else
                climbCheckDistance = cacheDist;

            Vector3 p1 = hero.position - (hero.up * -heightOffsetToEdge) + hero.forward;
            Vector3 p2 = hero.position - (hero.up * -heightOffsetToEdge) - hero.forward;
            RaycastHit hit;

            // Hit nothing and not at edge -> Out
            if (!Physics.CapsuleCast(p1, p2, climbCheckRadius, -hero.up, out hit, climbCheckDistance, climbLayers))
                return;
            // If not almost facing the edge cancel/Out
            if (Vector3.Angle(hero.right, hit.transform.right) >= 60.0f)
                return;

            if (curT != hit.transform)
            {
                curT = hit.transform;
                nextPoint = hit.point;
            }

            hero.rotation = Quaternion.Euler(0, curT.eulerAngles.y, 0);
            isTop = false; // RESET
            animator.SetBool("Top", false); // RESET
            animator.SetInteger("RandomM", Random.Range(0, 3));

            if (curT.name == "climbObject")
            {
                rigidbody.isKinematic = true;
                climbState = ClimbState.Climb;
            }
            else if (curT.name == "climbObjectOh")
            {
                rigidbody.isKinematic = true;
                isOverhang = true;
                climbState = ClimbState.Climb;
            }
            else if (curT.name == "climbObjectTop")
            {
                rigidbody.isKinematic = true;
                isTop = true;
                climbState = ClimbState.Climb;
            }
            else if (curT.name == "climbObjectTopOh")
            {
                rigidbody.isKinematic = true;
                isTop = true;
                isOverhang = true;
                climbState = ClimbState.Climb;
            }
            else if (curT.name == "climbWall")
            {
                climbState = ClimbState.None;
            }
            else if (curT.name == "climbArea")
            {
                rigidbody.isKinematic = true;
                climbState = ClimbState.Area;
            }
            else
            {
                climbState = ClimbState.None;
            }

            isClimb = true;
            // Down
            climbUp = false;
            // Long or Short ?
            climbLong = hit.distance > 1 ? true : false;
            //print ("Down");
        }
    }
    //=================================================================================================================o
    void ExitClimb()
    {
        // Base State
        if (animCtrl.climb)
        {
            rigidbody.isKinematic = false;

            isTop = false; // RESET
            isOverhang = false; // RESET
            hero.rotation = Quaternion.Euler(0, curT.eulerAngles.y, 0);
            curT = null;
            climbState = ClimbState.None;
            animator.runtimeAnimatorController = animCtrl.baseC;
            baseState = BaseState.Base;
            reset = true; // Out
        }
    }
    //=================================================================================================================o
    void ClimbTo()
    {
        // When entering Climb state
        if (isClimb)
        {
            if (climbUp)
            {
                if (climbLong)
                    animator.SetBool("Climb", true);
                else
                    animator.SetBool("ClimbShort", true);
                isClimb = false;
            }
            else
            {
                if (climbLong)
                    animator.SetBool("ClimbDown", true);
                else
                    animator.SetBool("ClimbDownShort", true);
                isClimb = false;
            }
        }

        if (grounded && v < 0) // On ground and going down
        {
            climbState = ClimbState.None;
        }

        if (!animatorStateInfo.IsTag("Pre"))
        {
            Vector3 edgePos = nextPoint + ((hero.up * -heightOffsetToEdge) - (hero.forward * climbOffsetToWall));
            // Apply lift up
            hero.position = Vector3.Lerp(hero.position, edgePos, Time.deltaTime * climbSpeed * 11);

            if (Vector3.Distance(hero.position, edgePos) <= 0.1f)
            {
                animator.SetBool("Climb", false); // RESET
                animator.SetBool("ClimbShort", false); // RESET
                animator.SetBool("ClimbDown", false); // RESET
                animator.SetBool("ClimbDownShort", false); // RESET

                if (isOverhang)
                    animator.SetBool("Overhang", true);

                if (curT.name == "climbArea" || curT.name == "climbWall")
                {
                    climbState = ClimbState.Wall; // Out
                }
                else
                    climbState = ClimbState.Edge; // Out
            }
        }
    }
    //=================================================================================================================o
    // At corner change climb handle
    void CornerLerp(float speed)
    {
        Vector3 v = nextPoint -
            (hero.right * cornerSideOffset) - (hero.forward * offsetToWall) - (hero.up * heightOffsetToEdge);

        float angleTo = Vector3.Angle (hero.right, curT.transform.right);

        // Faster if angle is rel small
        speed = angleTo <= 15.0f ?  speed *= 15 : speed *= 4;

        // Apply
        hero.position = Vector3.Lerp (hero.position, v, Time.deltaTime * speed);
        hero.rotation = Quaternion.Lerp (hero.rotation, curT.rotation, Time.deltaTime * speed);

        // Shift inward a bit
        if (angleTo <= 0.01f)
        {
            Vector3 relPoint = curT.InverseTransformPoint (hero.position);
            SmoothToSpot (Mathf.Abs(relPoint.z), offsetToWall, Vector3.forward, Vector3.back);

            if (doClimbDel != null) { doClimbDel("Edge"); }
            climbState = ClimbState.Edge; // Out

        } // Reset hang
        atHangR = false;
        atHangL = false;
    }
    //=================================================================================================================o
    void EdgeClimb()
    {
        Vector3 relPoint = curT.InverseTransformPoint(hero.position);
        MatchP(Mathf.Abs(relPoint.z), climbOffsetToWall, Vector3.forward, Vector3.back);
        MatchP(Mathf.Abs(relPoint.y), heightOffsetToEdge, Vector3.up, Vector3.down);

        if (isOverhang)
        {
            animator.SetBool("Overhang", true);
        }

        if (!animatorStateInfo.IsTag("Oh") && !animator.IsInTransition(0)) // not if overhanging
        {
            // Horizontal climbing
            if (h != 0.0f)
            {
                Vector3 origin = hero.position - (hero.forward * -climbOffsetToWall) - (hero.up * -heightOffsetToEdge);
                if (h > 0.0f) // Check right
                {
                    RaycastHit hit;
                    if (Physics.SphereCast(origin, 0.2f, hero.right, out hit, 0.4f, climbLayers))
                    {
                        nextPoint = hit.point;
                        curT = hit.transform;
                        animator.SetBool("CornerR", true);
                        cornerReach = 0.4f;
                        climbState = ClimbState.Corner; // Out
                    }
                    // Edge speed interval, min - max speed.
                    float edgeSpeed = animatorStateInfo.normalizedTime % 1 < 0.5f ? 0.9f : 0.3f;
                    // Apply
                    hero.Translate(1 * Time.deltaTime * edgeSpeed, 0, 0, curT);
                }
                else // Check left
                {
                    RaycastHit hit;
                    if (Physics.SphereCast(origin, 0.2f, -hero.right, out hit, 0.4f, climbLayers))
                    {
                        nextPoint = hit.point;
                        curT = hit.transform;
                        animator.SetBool("CornerL", true);
                        cornerReach = -0.4f;
                        climbState = ClimbState.Corner; // Out
                    }
                    // Edge speed interval, min - max speed.
                    float edgeSpeed = animatorStateInfo.normalizedTime % 1 < 0.5f ? 0.3f : 0.9f;
                    // Apply
                    hero.Translate(-1 * Time.deltaTime * edgeSpeed, 0, 0, curT);
                }
            }

            // Top
            if (isTop && doClimb)
            {
                animator.SetBool("Top", true);
                climbState = ClimbState.Top; // Out
            }
        }

        // Right End
        if (relPoint.x >= 0.44f)
        {
            animator.SetBool("HangR", true);

            if (relPoint.x >= 0.5f)
                climbState = ClimbState.None; // Out
        }
        // Left End
        else if (relPoint.x <= -0.44f)
        {
            animator.SetBool("HangL", true);

            if (relPoint.x <= -0.5f)
                climbState = ClimbState.None; // Out
        }
        else
        {
            animator.SetBool("HangL", false); // RESET
            animator.SetBool("HangR", false); // RESET

            // While not hanging, preparing or climbing
            if ((!animatorStateInfo.IsTag("Pre") || !animatorStateInfo.IsTag("Climb")) && !animator.IsInTransition(0))
                CheckClimb(); // Find next
        }
    }
    //=================================================================================================================o
    // Reset if leaving Climb modus
    public void ExitClimb()
    {
        rb.isKinematic = false;
        hMove.canMove = true;
        atHangR = false;
        atHangL = false;
        isWall = false;
        isPullUp = false;
        curT = null;
        lastT = null;

        rb.AddForce( Vector3.down * 2, ForceMode.VelocityChange);

        // Restore Rotation
        if (inClimbRot)
        {
            hero.rotation = Quaternion.Euler (0, rot.eulerAngles.y, 0);
            inClimbRot = false;
        }

        isClimbing = false;

        if (doClimbDel != null) { doClimbDel("None"); }
        climbState = ClimbState.None;

        // Out
        reset = true;
    }
    //=================================================================================================================o
    // Moving sideways on edge
    void EdgeMovement()
    {
        Vector3 relPoint = curT.InverseTransformPoint (hero.position);

        SmoothToSpot (Mathf.Abs(relPoint.z), offsetToWall, Vector3.forward, Vector3.back);
        SmoothToSpot (Mathf.Abs(relPoint.y), heightOffsetToEdge, Vector3.up, Vector3.down);

        // Drop down
        if (Input.GetAxis("Vertical") < -0.5f/* || relPoint.z > 5f*/)
        {
            climbState = ClimbState.None;
        }
        // One handed on edge, animation trigger
        else if (Mathf.Abs(relPoint.x) >= 0.44f)
        {
            // Right side
            if (relPoint.x >= 0.44f)
            {

                if (doClimbDel != null) { doClimbDel("HangR"); }
                atHangR = true; // Hang at right end

                if (relPoint.x >= 0.5f)
                {
                    climbState = ClimbState.None; // Out
                }
            }
            // Left side
            else if (relPoint.x <= -0.44f)
            {
                if (doClimbDel != null) { doClimbDel("HangL"); }
                atHangL = true; // Hang at left end

                if (relPoint.x <= -0.5f)
                {
                    climbState = ClimbState.None; // Out
                }
            }
        }

        // Early out
        if (Input.GetAxis ("Horizontal") == 0.0f)
            return;

        // Left / Right check for new spots
        else
        {
            Vector3 origin = hero.position - (hero.forward * -offsetToWall) - (hero.up * -heightOffsetToEdge);
            float xInpt = Input.GetAxis ("Horizontal") > 0.0f ? 1.0f : -1.0f;
            Vector3 dir = Input.GetAxis ("Horizontal") > 0.0f ? hero.right : -hero.right;
            cornerSideOffset = Input.GetAxis ("Horizontal") > 0.0f ? -0.4f : 0.4f;
            RaycastHit hit;

            if (Physics.SphereCast (origin, 0.2f, dir, out hit, 0.3f, climbLayers))
            {
                nextPoint = hit.point;
                lastT = curT;
                curT = hit.transform;

                inClimbRot = true;
                rot = hero.rotation;

                if (doClimbDel != null) { doClimbDel("Corner"); }
                climbState = ClimbState.Corner; // Out
            }

            // Speed interval
            if (!speedInterval)
            {
                StartCoroutine( SpeedInterval( 0.0f, climbSpeed)); // 0.2f, climbspeed
            }

            // Apply
            hero.Translate( xInpt * Time.deltaTime * edgeSpeed, 0, 0, curT );

            // If not close to end
            if ((Mathf.Abs(relPoint.x) < 0.44f) && (atHangR || atHangL))
            {
                if (doClimbDel != null) { doClimbDel("Edge"); }
                atHangR = false;
                atHangL = false;
            }
        }
    }
    //=================================================================================================================o
    // Check for ledge collider in front
    void CheckLedge()
    {
        if (hMove.Grounded)
        {
            RaycastHit hit;

            if (!Physics.Raycast (hero.position + hero.up, hero.forward, 1f, climbLayers))
                return;

            else if (Physics.Raycast (hero.position + hero.up, hero.forward, out hit, 1f, climbLayers))
            {
                if (hit.collider.name == "climbLedge")
                {
                    isClimbing = true;
                    rb.isKinematic = true;
                    hMove.canMove = false;

                    isLedgeEnd = false;

                    curT = hit.transform;
                    lastHeroPos = hero.position;

                    if (doClimbDel != null) { doClimbDel("Ledge"); }
                    climbState = ClimbState.LedgeJump;
                }
            }
        }
    }
示例#46
0
        static void Everything()
        {
            // creates a variable for the time(seconds)
            float time = stopwatch.Duration;

            // prevents unexpected behavior
            rightDriveTalon.ConfigFactoryDefault();
            leftDriveTalon.ConfigFactoryDefault();
            climbTalon.ConfigFactoryDefault();

            // not finished autonomous period
            if (time < 30)
            {
                Debug.Print("Auton is attempting to E");

                leftDriveTalon.Set(ControlMode.PercentOutput, 0.5);  //sets left drive talon to 50%
                rightDriveTalon.Set(ControlMode.PercentOutput, 0.5); //sets right drive talon to 50%

                Thread.Sleep(10);

                Debug.Print("Auton ending, E complete.");
                leftDriveTalon.Set(ControlMode.PercentOutput, 0.0);  //sets left drive talon to 0%
                rightDriveTalon.Set(ControlMode.PercentOutput, 0.0); //sets right drive talon to 0%
            }

            while (running)
            {
                // print axis value ???
                Debug.Print("axis:" + gamepad1.GetAxis(1));

                // allows motor control
                CTRE.Phoenix.Watchdog.Feed();

                // Teleoperated
                // determine inputs
                forwardAxis = gamepad1.GetAxis(1);
                turnAxis    = gamepad1.GetAxis(2);

                // accounting for forward and turn b4 Eing into the talons
                finalLeftTalonValue  = (forwardAxis * forwardGain) + (turnAxis * turnGain);
                finalRightTalonValue = (forwardAxis * forwardGain) - (turnAxis * turnGain);

                // pass motor value to Talons
                leftDriveTalon.Set(ControlMode.PercentOutput, finalLeftTalonValue);
                rightDriveTalon.Set(ControlMode.PercentOutput, finalRightTalonValue);

                // Elevator controls
                if (gamepad1.GetButton(elevatorRise))
                {
                    climbState = ClimbState.RISE;
                }
                else if (gamepad1.GetButton(elevatorLower))
                {
                    climbState = ClimbState.LOWER;
                }
                else
                {
                    climbState = ClimbState.IDLE;
                }

                // if the button is pressed the drivestate will switch
                if (gamepad1.GetButton(driveStateButton) && driveState == DriveState.PRECISE)
                {
                    driveState = DriveState.STRONGER;
                }
                else if (gamepad1.GetButton(driveStateButton) && driveState == DriveState.STRONGER)
                {
                    driveState = DriveState.PRECISE;
                }

                // elevator state machine
                switch (climbState)
                {
                case ClimbState.IDLE:
                    Debug.Print("nothing");
                    climbTalon.Set(ControlMode.PercentOutput, 0.0);     //sets the climber talon to 0%
                    break;

                case ClimbState.RISE:
                    Debug.Print("rising");
                    climbTalon.Set(ControlMode.PercentOutput, 1 * climbGain);     //sets the climber talon to 50%
                    break;

                case ClimbState.LOWER:
                    Debug.Print("lowering");
                    climbTalon.Set(ControlMode.PercentOutput, -1 * climbGain);      //sets the climber talon to -50%
                    break;

                case ClimbState.ERROR:
                    Debug.Print("ElevatorState error");
                    break;

                default:
                    Debug.Print("very bad error");
                    break;
                }

                // drive gain state machine
                switch (driveState)
                {
                case DriveState.PRECISE:
                    forwardGain = 0.3f;
                    turnGain    = 0.1f;
                    Debug.Print("precise");
                    break;

                case DriveState.STRONGER:
                    forwardGain = 0.5f;
                    turnGain    = 0.25f;
                    Debug.Print("stronger");
                    break;

                default:
                    Debug.Print("DriveState error");
                    break;
                }

                if (gamepad1.GetButton(emergencyStop))
                {
                    running = false;
                }
            }
        }
    //=================================================================================================================o
    // Wall climb handling
    void WallClimb()
    {
        Vector3 relV = curT.InverseTransformPoint(hero.position);

        float distY = Mathf.Abs(relV.y);
        float distZ = Mathf.Abs(relV.z);

        // Limit is almost the edge
        if (distY >= heightOffsetToEdge * 1.1f)
        {
            SmoothToSpot (distZ, offsetToWall, Vector3.forward, Vector3.back);

            // Input
            if (Input.GetAxis ("Vertical") != 0.0f)
            {
                if (Input.GetAxis ("Vertical") > 0.0f)
                {
                    inputVec = hero.TransformPoint( Vector3.up );
                }
                else
                {
                    inputVec = hero.TransformPoint( Vector3.down );

                    if (!Physics.Raycast(hero.position, hero.forward, offsetToWall, climbLayers) || hMove.Grounded)
                    {
                        climbState = ClimbState.None;
                    }
                }

                // Apply movement
                hero.position = Vector3.Lerp( hero.position, inputVec, Time.deltaTime * climbSpeed * 1.3f);
            }
            else // Stop if there's no input
            {
                inputVec = hero.TransformPoint( Vector3.zero );
            }
        }
        else // Reached the edge
        {
            if (doClimbDel != null) { doClimbDel("Edge"); }
            climbState = ClimbState.Edge; // Out
        }

        // Drop
        // Action key down to Exit
        if (Input.GetKeyDown (hKey.jumpKey) && !hMove.Grounded)
        {
            climbState = ClimbState.None; // Out
        }
    }
    //=================================================================================================================o
    void Climb()
    {
        Vector3 edgePos = nextPoint + ((hero.up * -heightOffsetToEdge) - (hero.forward * offsetToWall));

        // Apply lift up
        hero.position = Vector3.Lerp (hero.position, edgePos, Time.deltaTime * climbSpeed * 8 );

        // At edge
        if (Vector3.Distance ( hero.position, edgePos ) <=  0.1f)
        {
            if (isOverhang)
            {
                StartCoroutine( Overhang());
            }
            else
            {
                if (doClimbDel != null) { doClimbDel("Edge"); }
                climbState = ClimbState.Edge;
            }
        }
    }
示例#49
0
    void WallClimb()
    {
        Vector3 way = rigid.velocity;

        if (isGrounded)
        {
            wallClimb = ClimbState.None;
        }

        switch (wallClimb)
        {
        case ClimbState.Jumping:
        case ClimbState.None:
            if (way.y >= 0.0f || isGrounded || (wallClimb == ClimbState.Jumping && Mathf.Abs(transform.eulerAngles.y - LastWallAngle) < 100f))
            {
                return;
            }

            way.y = 0.0f;
            way.Normalize();

            bool foundWall = false;
            bool firstWall = false;                     // Did the raycast find a wall? (if not then climb to top)

            for (int i = 0; i < wallOffsets.Length && !foundWall; i++)
            {
                Vector3 pos = transform.forward * wallOffsets[i].z;
                pos.y     = wallOffsets[i].y;
                pos      += transform.position;
                foundWall = foundWall || Physics.Raycast(pos, transform.forward, wallDistance, wallLayers.value);
                if (i == 0)
                {
                    firstWall = foundWall;
                }
                Debug.DrawRay(pos, transform.forward * wallDistance, Color.green, 1.0f);
            }

            if (!foundWall)
            {
                return;
            }

            if (!firstWall)
            {
                // Jump up
            }

            wallClimb     = ClimbState.Climbing;
            climbStartY   = transform.position.y;
            LastWallAngle = transform.eulerAngles.y;

            break;

        case ClimbState.Climbing:

            rigid.velocity = Vector3.up * ClimbSpeed * Time.deltaTime;

            if (Mathf.Abs(transform.position.y - climbStartY) > ClimbDistance)
            {
                wallClimb = ClimbState.Sliding;
            }

            break;

        case ClimbState.Sliding:
            if (isGrounded)
            {
                wallClimb = ClimbState.None;
            }

            if (Input.GetButtonDown("Jump"))
            {
                WallJump();
                return;
            }

            rigid.velocity = Vector3.down * wallSlideSpeed * Time.deltaTime;

            break;

        default:
            break;
        }
    }
    //=================================================================================================================o
    // Find next spot and climb up
    void Check()
    {
        // Action button E to start climbing
        if (Input.GetAxis("Vertical") > .5 && (climbState == ClimbState.None || climbState == ClimbState.Edge)
            && hMove.isAfterTap)//Input.GetKey(hKey.climbOrStandKey)
        {
            Vector3 p1 = hero.position - (hero.up * -heightOffsetToEdge) + hero.forward;
            Vector3 p2 = hero.position - (hero.up * -heightOffsetToEdge) - hero.forward;
            RaycastHit hit;

            CheckLedge ();

            // Reduce check distance/height while falling
            if (!hMove.Grounded && climbState == ClimbState.None && !hSwim.isSwimming)
            {
                checkDistance = 0.4f;
            }
            else
                checkDistance = cacheDist;

            // Hit nothing and not at edge -> Out
            if (!Physics.CapsuleCast (p1, p2, checkRadius, hero.up, out hit, checkDistance, climbLayers)
                && (climbState != ClimbState.Edge))
                return;

            // Get next edge point location
            else if (Physics.CapsuleCast (p1, p2, checkRadius, hero.up, out hit, checkDistance, climbLayers)
                && !isPullUp)
            {
                if ((hit.collider.name == "climbObject" || hit.collider.name == "climbObjectTop"
                    || hit.collider.name == "climbObjectTopOh" || hit.collider.name == "climbObjectOh")
                    && hit.transform != curT)
                {
                    // If not almost facing the edge cancel/Out
                    if (Vector3.Angle (hero.right, hit.transform.right) >= 60.0f)
                        return;

                    isClimbing = true;
                    rb.isKinematic = true;
                    hMove.canMove = false;

                    nextPoint = hit.point;
                    lastT = curT;
                    curT = hit.transform;

                    // Hero rotation
                    hero.rotation = hit.transform.rotation;
                    inClimbRot = true;
                    rot = hero.rotation;

                    // Jump to edge if grounded or start climbing
                    if (hMove.Grounded)
                    {
                        if (doClimbDel != null) { doClimbDel("WallJump"); }
                        climbState = ClimbState.WallJump;

                        if ((hit.collider.name == "climbObjectTopOh") || (hit.collider.name == "climbObjectTop"))
                        {
                            isPullUp = true;
                            if ((hit.collider.name == "climbObjectTopOh"))
                                isOverhang = true;
                        }
                        else if ((hit.collider.name == "climbObjectOh"))
                        {
                            isOverhang = true;
                        }
                    }
                    else // Not grounded
                    {
                        // Standard climb
                        if (climbState == ClimbState.Edge) // Prepare & climb up
                        {
                            if (hit.distance > 1) // Distance is bigger than
                            {
                                if (!isPreparing) // if coroutine has finished
                                {
                                    StartCoroutine( Prepare());
                                }
                                if (hit.collider.name == "climbObjectOh")
                                    isOverhang = true;
                            }
                            else // Short climb action
                            {
                                if (!isPreShort) // if coroutine has finished
                                {
                                    StartCoroutine( PreShort( ClimbState.Climb ));
                                }
                            }
                            if ((hit.collider.name == "climbObjectTop") || (hit.collider.name == "climbObjectTopOh"))
                            {
                                isPullUp = true;
                                if (hit.collider.name == "climbObjectTopOh")
                                    isOverhang = true;
                            }
                        }
                        else if (climbState == ClimbState.None) // Falling
                        {
                            if (doClimbDel != null) { doClimbDel("Catch"); } // Trigger catch motion
                            climbState = ClimbState.Climb; // move to edge we hit

                            if ((hit.collider.name == "climbObjectTop") || (hit.collider.name == "climbObjectTopOh"))
                            {
                                isPullUp = true;
                                if (hit.collider.name == "climbObjectTopOh")
                                    isOverhang = true;
                            }
                        }
                    }
                }

                // Hit a climb wall collider
                else if (hit.collider.name == "climbWall" || hit.collider.name == "climbArea"
                    && climbState != ClimbState.WallClimb && climbState != ClimbState.WallJump)
                {
                    // If not almost facing the wall cancel/Out
                    if (Vector3.Angle (hero.right, hit.transform.right) >= 60.0f)
                        return;

                    isClimbing = true;
                    rb.isKinematic = true;
                    hMove.canMove = false;

                    nextPoint = hit.point;
                    lastT = curT;
                    curT = hit.transform;

                    // Hero rotation
                    hero.rotation = hit.transform.rotation;
                    inClimbRot = true;
                    rot = hero.rotation;

                    // Wall-climb-jump modus
                    if (curT.name == "climbWall")
                    {
                        isWall = true;
                        if (hMove.Grounded || hSwim.isSwimming)
                        {
                            if (doClimbDel != null) { doClimbDel("WallJump"); }
                            climbState = ClimbState.WallJump;
                        }
                        else
                        {
                            if (doClimbDel != null) { doClimbDel("WallClimb"); }
                            climbState = ClimbState.WallClimb;
                        }
                    }
                    else // Wall-climb area
                    {
                        /*if (doClimbDel != null) { doClimbDel("WallClimb"); }
                        climbState = ClimbState.WallJump;*/
                        if (!isPreShort && !hMove.Grounded) // if coroutine has finished
                        {
                            StartCoroutine( PreShort( ClimbState.WallJump ));
                        }
                        else // Grounded
                        {
                            if (doClimbDel != null) { doClimbDel("WallClimb"); }
                            climbState = ClimbState.WallJump;
                        }
                    }
                }
            }

            // End, climb on top
            else if (isPullUp || isWall)
            {
                isClimbing = true;
                lastHeroPos = hero.position;

                if (!isPreparing) // if coroutine has finished , PullUp()
                {
                    StartCoroutine( PreTop());
                }
            }
        }
    }
    //=================================================================================================================o
    // Jump over ledge
    void LedgeJump()
    {
        Vector3 topVec = new Vector3 (lastHeroPos.x, curT.position.y + 0.3f, lastHeroPos.z);
        Vector3 fwdVec = topVec + hero.forward * 2.0f;
        Vector3 dwnVec = hero.position - (hero.up * 3f);

        // Up
        if (((hero.position.y - curT.position.y) <=  0.0f) && !isLedgeEnd)
        {
            hero.position = Vector3.Lerp (hero.position, topVec, Time.deltaTime * climbSpeed * 5f);
        }
        else
        {
            // Forward
            if (!isLedgeEnd)
            {
                hero.position = Vector3.Lerp (hero.position, fwdVec, Time.deltaTime * climbSpeed * 9f);
            }

            // Down & Exit
            if (Vector3.Distance(topVec, hero.position) >= 1.8f) // Forward distance to go over the ledge
            {
                isLedgeEnd = true;
                hero.position = Vector3.Lerp (hero.position, dwnVec, Time.deltaTime * climbSpeed * 1.0f);
                if (hMove.Grounded)
                {
                    climbState = ClimbState.None;
                }
            }
        }
    }
示例#52
0
    void Update()
    {
        if (playerState == ClimbState.NONE)
        {
            if (isInTrigger)
            {
                if (Input.GetAxis(TAG_AXIS_V) > 0)                      // Player moving forward
                {
                    // Attach player to ladder
                    playerMotor.grounded = false;                           // (prevent jump if dropping off ladder)
                    playerMotor.enabled  = false;                           // disable normal movement
                    playerState          = ClimbState.CENTERING;            // center player with ladder
                }
            }
        }
        else if (playerState == ClimbState.CENTERING)
        {
            if (t_lerp == 0)
            {
                // initialize values
                start = player.position;
                end   = new Vector3(transform.position.x, player.position.y, transform.position.z);
            }

            if (t_lerp < 1)
            {
                // center player
                t_lerp         += Time.deltaTime / attachTime;
                player.position = Vector3.Lerp(start, end, t_lerp);
            }
            else
            {
                // finish centering
                t_lerp      = 0;
                playerState = ClimbState.CLIMBING;
            }
        }
        else if (playerState == ClimbState.CLIMBING)
        {
            CollisionFlags playerCol = CollisionFlags.None;

            if (Input.GetKey(KeyCode.W))             // Player climbing up
            {
                playerCol = playerCtrl.Move(new Vector3(0, Time.deltaTime * climbSpeed, 0));
            }
            else if (Input.GetKey(KeyCode.S))            // Player climbing down
            {
                playerCol = playerCtrl.Move(new Vector3(0, Time.deltaTime * -climbSpeed, 0));
            }

            if (Input.GetKeyDown(KeyCode.Space))            // Player "let go" of ladder
            {
                Detach(ClimbState.NONE);
            }

            if ((playerCol & CollisionFlags.CollidedBelow) != 0)            // player touched ground - release
            {
                Detach(ClimbState.NONE);
            }
        }
        else if (playerState == ClimbState.DISMOUNTING)
        {
            if (t_lerp < 1)
            {
                // Move player off ladder
                t_lerp += Time.deltaTime / detachTime;
                Vector3 diff = Vector3.Lerp(start, end, t_lerp) - player.position;
                playerCtrl.Move(diff);
            }
            else
            {
                // Enable player movement
                t_lerp = 0;

                Detach(ClimbState.NONE);
            }
        }
    }
    //=================================================================================================================o
    // Reached the top, PullUp
    void PullUp()
    {
        if (animatorStateInfo.IsTag("Top") && !animator.IsInTransition(0))
        {
            float nT = animatorStateInfo.normalizedTime;
            if (nT <= 1.0f)
            {
                if (nT <= 0.4f) // Step up
                {
                    hero.Translate(Vector3.up * Time.deltaTime * climbSpeed * 8.0f);
                }
                else // Step forward
                {
                    if (nT <= 0.6f)
                        hero.Translate(Vector3.forward * Time.deltaTime * climbSpeed * 2.5f);

                    else if (nT >= 0.6f && rigidbody.isKinematic) // fall early
                        rigidbody.isKinematic = false;
                    if (!rigidbody.isKinematic)
                        rigidbody.velocity = new Vector3(0, rigidbody.velocity.y, 0);
                }
            }
            else // Animation is finished
                climbState = ClimbState.None; // Out
        }
    }
示例#54
0
    //=================================================================================================================o
    void DoClimb(string s)
    {
        if (s == "None") { climbState = ClimbState.None; isShort = false; } // Shortclimb reset
        else if (s == "WallClimb") { climbState = ClimbState.WallClimb; }
        else if (s == "WallJump") { climbState = ClimbState.WallJump; }
        else if (s == "PreOh") { climbState = ClimbState.PreOh; }
        else if (s == "Overhang") { climbState = ClimbState.Overhang; isShort = false; }
        else if (s == "Prepare") { climbState = ClimbState.Prepare; }
        else if (s == "PreShort") { climbState = ClimbState.PreShort; }
        else if (s == "Ledge") { climbState = ClimbState.Ledge; }
        else if (s == "Catch") { climbState = ClimbState.Catch; }
        else if (s == "Corner") { climbState = ClimbState.Corner; }
        else if (s == "HangL") { climbState = ClimbState.HangL; }
        else if (s == "HangR") { climbState = ClimbState.HangR; }
        else if (s == "Climb") { climbState = ClimbState.Climb; isShort = false; }
        else if (s == "Short") { climbState = ClimbState.Short; isShort = true; }
        else if (s == "Edge") { climbState = ClimbState.Edge; climbMotion = false; } // XFadeRandom() is ready now
        else if (s == "Top") { climbState = ClimbState.Top; }

        mainState = MainState.Climbing;
    }
    //=================================================================================================================o
    void WallClimb()
    {
        if (grounded && v < 0) // On ground and going down
        {
            climbState = ClimbState.None;
        }

        Vector3 relV = curT.InverseTransformPoint(hero.position);
        Vector3 inputVec = hero.position;
        float distY = Mathf.Abs(relV.y);
        float distZ = Mathf.Abs(relV.z);

        animator.SetBool("WallClimb", true);

        // Limit is almost the edge
        if (distY >= heightOffsetToEdge * 1.1f)
        {
            MatchP(distZ, climbOffsetToWall, Vector3.forward, Vector3.back);

            // Input
            if (v != 0.0f)
            {
                if (v > 0.0f)
                {
                    inputVec = hero.TransformPoint(Vector3.up);
                }
                else
                {
                    inputVec = hero.TransformPoint(Vector3.down);

                    if (!Physics.Raycast(hero.position, hero.forward, climbOffsetToWall, climbLayers) || grounded)
                    {
                        climbState = ClimbState.None;
                    }
                }

                // Apply movement
                hero.position = Vector3.Lerp(hero.position, inputVec, Time.deltaTime * climbSpeed * 1.3f);
            }
            else // Stop if there's no input
            {
                inputVec = hero.TransformPoint(Vector3.zero);
            }
        }
        else // Reached the edge
        {
            animator.SetBool("WallClimb", false); // RESET
            climbState = ClimbState.Edge; // Out
        }
    }