void GenerateColls(Collision col, bool resetCount)
        {
            if (resetCount)
            {
                mCollCount = 0;
            }

            Vector3 up = dirHolder.up;

            for (int i = 0, max = col.contacts.Length; i < max; i++)
            {
                if (mCollCount >= maxColls)
                {
                    Debug.LogWarning("Ran out of collideInfo");
                    break;
                }

                ContactPoint contact = col.contacts[i];

                Collider whichColl = col.collider;// contact.thisCollider != collider ? contact.thisCollider : contact.otherCollider;

                Vector3        n  = contact.normal;
                Vector3        p  = contact.point;
                CollisionFlags cf = GenCollFlag(up, contact);

                //check if already exists
                int ind = -1;
                for (int j = 0; j < mCollCount; j++)
                {
                    CollideInfo inf = mColls[j];
                    if (inf.collider == whichColl)
                    {
                        //if(cf == CollisionFlags.None)
                        //cf = GenCollFlag(up, contact);

                        if (inf.flag == cf)
                        {
                            ind = j;
                            break;
                        }
                    }
                }

                CollideInfo newInfo;
                if (ind == -1)
                {
                    newInfo = mColls[mCollCount];
                    mCollCount++;
                }
                else
                {
                    newInfo = mColls[ind];
                }

                newInfo.collider     = whichColl;
                newInfo.contactPoint = p;
                newInfo.normal       = n;
                newInfo.flag         = cf;
            }
        }
        protected virtual void Awake()
        {
            mBody = GetComponent <Rigidbody>();

            mColls = new CollideInfo[maxColls];
            for (int i = 0; i < maxColls; i++)
            {
                mColls[i] = new CollideInfo();
            }

            mGravCtrl = GetComponent <GravityController>();

            //mTopBottomColCos = Mathf.Cos(sphereCollisionAngle * Mathf.Deg2Rad);
            mSlopLimitCos  = Mathf.Cos(slopLimit * Mathf.Deg2Rad);
            mAboveLimitCos = Mathf.Cos(aboveLimit * Mathf.Deg2Rad);

            mColl = GetComponent <Collider>();
            if (mColl != null)
            {
                if (mColl is SphereCollider)
                {
                    mRadius = ((SphereCollider)mColl).radius;
                }
                else if (mColl is CapsuleCollider)
                {
                    mCapsuleColl = mColl as CapsuleCollider;
                    mRadius      = mCapsuleColl.radius;
                }
            }

            mDefaultSpeedCap = speedCap;
        }
Example #3
0
    void OnCollisionStay2D(Collision2D col)
    {
        //remove existing information with given collider
        for (int j = 0; j < mColls.Count; j++)
        {
            CollideInfo inf = mColls[j];
            if (inf.collider == col.collider)
            {
                RemoveColl(j);
                j--;
            }
        }

        GenerateColls(col, false);

        //recalculate flags
        RefreshCollInfo();

        if (collisionStayCallback != null)
        {
            collisionStayCallback(this, col);
        }

        /*if(pc != mCollCount)
         *  Debug.Log("scount: " + mCollCount);*/
    }
Example #4
0
    void OnCollisionExit2D(Collision2D col)
    {
        //foreach(ContactPoint cp in col.contacts) {
        //Debug.Log("out: " + cp.otherCollider.name + " n: " + cp.normal);
        //}
        //mCollCount = 0;
        //remove existing information with given collider
        for (int j = 0; j < mColls.Count; j++)
        {
            CollideInfo inf = mColls[j];
            if (inf.collider == col.collider)
            {
                RemoveColl(j);
                j--;
            }
        }

        RefreshCollInfo();

        if (collisionExitCallback != null)
        {
            collisionExitCallback(this, col);
        }

        //Debug.Log("exit count: " + mCollCount);
    }
        protected virtual void RefreshCollInfo()
        {
            mCollFlags     = CollisionFlags.None;
            mCollLayerMask = 0;
            mIsSlopSlide   = false;

            bool groundNoSlope = false; //prevent slope slide if we are also touching a non-slidable ground (standing on the corner base of slope)

            Vector3 up = dirHolder.up;

            //

            for (int i = 0; i < mCollCount; i++)
            {
                CollideInfo inf = mColls[i];
                if (inf.collider == null || inf.collider.gameObject == null || !inf.collider.gameObject.activeInHierarchy)
                {
                    RemoveColl(i);
                    i--;
                    continue;
                }

                Vector3        n    = inf.normal;
                CollisionFlags flag = inf.flag;

                mCollFlags |= inf.flag;

                if (flag == CollisionFlags.Below || flag == CollisionFlags.Sides)
                {
                    //sliding
                    if (!(slideDisable || groundNoSlope))
                    {
                        float a = Vector3.Angle(up, n);
                        mIsSlopSlide = a > slopLimit && a <= slideLimit;
                        if (mIsSlopSlide)
                        {
                            //Debug.Log("a: " + a);
                            mSlopNormal = n;
                        }
                        else if (flag == CollisionFlags.Below)
                        {
                            mIsSlopSlide  = false;
                            groundNoSlope = true;
                        }
                    }

                    mCollLayerMask |= 1 << inf.collider.gameObject.layer;
                }
            }

            //no longer standing?
            if (!isGrounded)
            {
                mStanding = false;
            }
        }
        void OnCollisionExit(Collision col)
        {
            //foreach(ContactPoint cp in col.contacts) {
            //Debug.Log("out: " + cp.otherCollider.name + " n: " + cp.normal);
            //}
            //mCollCount = 0;
            //remove existing information with given collider
            for (int j = 0; j < mCollCount; j++)
            {
                CollideInfo inf = mColls[j];
                if (inf.collider == col.collider)
                {
                    RemoveColl(j);
                    j--;
                }
            }

            /*foreach(ContactPoint cp in col.contacts) {
             *  Debug.Log("out: " + cp.otherCollider.name + " n: " + cp.normal);
             * }*/

            //Debug.Log("exit: " + col.gameObject.name);

            //Vector3 up = dirHolder.up;

            /*foreach(ContactPoint contact in col.contacts) {
             *  Collider whichColl = contact.thisCollider != collider ? contact.thisCollider : contact.otherCollider;
             *  //Vector3 n = contact.normal;
             *  //Vector3 p = contact.point;
             *  //CollisionFlags cf = CollisionFlags.None;
             *
             *  for(int i = 0; i < mCollCount; i++) {
             *      CollideInfo inf = mColls[i];
             *      if(inf.collider == whichColl) {
             *          //if(cf == CollisionFlags.None)
             *          //cf = GenCollFlag(up, contact);
             *
             *          //if(inf.flag == cf)
             *          RemoveColl(i);
             *      }
             *  }
             * }*/

            RefreshCollInfo();

            if (collisionExitCallback != null)
            {
                collisionExitCallback(this, col);
            }

            //Debug.Log("exit count: " + mCollCount);
        }
        /// <summary>
        /// Get the first occurence of CollideInfo based on given flags
        /// </summary>
        public CollideInfo GetCollideInfo(CollisionFlags flags)
        {
            for (int i = 0; i < mCollCount; i++)
            {
                CollideInfo inf = mColls[i];
                if ((inf.flag & flags) != 0)
                {
                    return(inf);
                }
            }

            return(null);
        }
Example #8
0
    //return true if we moved
    public bool Move(Vector2 axis, float force)
    {
        //compute move direction
        Vector2 moveDelta = axis;

        mCurMoveDir = moveDelta.normalized;

        float maxSpeed = 0.0f;

        //allow for moving diagonally downwards
        //TODO: test for non-platformer
        if (isGrounded)
        {
            for (int i = 0; i < mColls.Count; i++)
            {
                CollideInfo inf = mColls[i];
                if (inf.flag == CollisionFlags.Below)
                {
                    Vector2 moveDeltaX = new Vector2(moveDelta.x, 0f);
                    moveDeltaX = M8.MathUtil.Slide(moveDeltaX, inf.normal);

                    moveDelta = new Vector2(moveDeltaX.x, moveDeltaX.y + moveDelta.y);

                    mCurMoveDir = moveDelta.normalized;
                    break;
                }
            }

            maxSpeed = moveMaxSpeed;
        }
        else
        {
            maxSpeed = airMaxSpeed;
        }

#if MATE_PHYSICS_DEBUG
        M8.DebugUtil.DrawArrow(transform.position, mCurMoveDir);
#endif

        //check if we can move based on speed or if going against new direction
        bool canMove = CanMove(mCurMoveDir, maxSpeed * moveScale);

        if (canMove)
        {
            //M8.Debug.
            mBody.AddForce(moveDelta * force * moveScale);
            return(true);
        }

        return(false);
    }
Example #9
0
    public bool TryGetCollideInfo(Collider col, out CollideInfo inf)
    {
        for (int i = 0; i < mColls.Count; i++)
        {
            if (mColls[i].collider == col)
            {
                inf = mColls[i];
                return(true);
            }
        }

        inf = new CollideInfo();
        return(false);
    }
Example #10
0
    /// <summary>
    /// Get the first occurence of CollideInfo based on given flags
    /// </summary>
    public bool TryGetCollideInfo(CollisionFlags flags, out CollideInfo inf)
    {
        for (int i = 0; i < mColls.Count; i++)
        {
            CollideInfo _inf = mColls[i];
            if ((_inf.flag & flags) != 0)
            {
                inf = _inf;
                return(true);
            }
        }

        inf = new CollideInfo();
        return(false);
    }
Example #11
0
        void Rule_Shot()
        {
            if (newRule)
            {
                SFX("Rayman2/Rayman/shoot/simple").SetVolume(0.625f);
                SFX("Rayman2/Rayman/shoot/simple").Play(0.05f);
                SpawnParticle(true, "FistTrail1", LumType.Yellow);
                bounces = 0;
            }

            if (DistTo(rayman) > 40)
            {
                SetRule("Fizzle");
                return;
            }

            r = Raycast(vel, 1);
            if (r.Any)
            {
                if (++bounces >= 3)
                {
                    Kill();
                }
                else
                {
                    if (r.hitPerso != null)
                    {
                        r.hitPerso.Damage(damage);
                        Remove();
                        return;
                    }

                    Bounce3D(r.hit.normal);
                    FaceVel2D(false);
                    BounceFX();

                    var t = FindTarget(20, 45);
                    if (t != null)
                    {
                        vel = vel.magnitude * Vec(t);
                    }
                }
            }
        }
        protected void RemoveColl(int ind)
        {
            if (mCollCount > 0)
            {
                int lastInd = mCollCount - 1;
                if (ind == lastInd)
                {
                    mColls[ind].collider = null;
                    mColls[ind].flag     = CollisionFlags.None;
                }
                else
                {
                    CollideInfo removeInf = mColls[ind];
                    removeInf.collider = null;
                    removeInf.flag     = CollisionFlags.None;

                    CollideInfo lastInf = mColls[lastInd];
                    mColls[ind]     = lastInf;
                    mColls[lastInd] = removeInf;
                }
                mCollCount--;
            }
        }
Example #13
0
    //bool allowTest = false;
    void testPath()
    {
        //    if (allowTest == false)
        //        return;
        if (nextNode == null)
        {
            return;
        }


        Vector3 distVec       = nextNode.goal.point - transform.position;
        float   awayOrNearDot = Vector3.Dot(speedVec, distVec.normalized);

        if (awayOrNearDot < 0) //is away
        {
            return;
        }

        float collideTime = distVec.magnitude / speed;

        CollideInfo info = CollideManager.collideInfo;

        if (info.minCollideTime == -1 || collideTime < info.minCollideTime)
        {
            info.minCollideTime   = collideTime;
            info.node             = nextNode;
            info.reachGoalobj     = this;
            info.collidePoint     = Vector3.zero;
            info.collideSurfaceP0 = Vector3.zero;
            info.collideSurfaceP1 = Vector3.zero;
            info.intersectPoint   = Vector3.zero;
            info.vertex           = null;
            info.surface          = null;
        }
        //Debug.Log ( collideTime );
    }
Example #14
0
    //collide will ocur after this time
    public void vertexContactSurface(VERTEX vertex, SURFACE surface)
    {
        //ignore vertexs which is back to surface
        bool isFacing = false;

        for (int i = 0; i < vertex.normals.Count; i++)
        {
            Vector3 vertexNormal = vertex.normals[i].direct;
            float   facingDot    = Vector3.Dot(vertexNormal, surface.normal.direct);
            float   threshold    = 0.000001f;
            if (facingDot > -threshold && facingDot < threshold)
            {
                facingDot = 0;
            }
            if (facingDot < 0)
            {
                isFacing = true;
                break;
            }
        }
        if (!isFacing)
        {
            return;
        }
        //check if under surface
        Vector3 beginVec = surface.points[0].pos - vertex.pos;
        float   dist     = Vector3.Dot(beginVec, surface.normal.direct);

        if (dist > 0)//ignore the surfaces which is back to vertex
        {
            return;
        }

        // relateVec intersect surface
        Vector3 perpendicularVec = surface.normal.direct * dist;
        float   angle            = Vector3.Angle(-relateVec, perpendicularVec);

        if (angle >= 90)//parallel
        {
            return;
        }
        float length = Mathf.Abs(dist) / Mathf.Cos(Mathf.Deg2Rad * angle);

        Vector3 intersectPoint = vertex.pos - relateVec.normalized * length;
        //contactsurface
        float collideTime = length / relateVec.magnitude;

        surface.belongToObj.computeGlobalSpeed();
        Vector3 surfaceGlobalSpeedVec = surface.belongToObj.globalSpeedVec;
        Vector3 collideSurfaceP0      = surface.points[0].pos + surfaceGlobalSpeedVec * collideTime;
        Vector3 collideSurfaceP1      = surface.points[1].pos + surfaceGlobalSpeedVec * collideTime;
        //Vector3 collideSurfaceNormal = surface.normal.direct;
        //check if in contact surface
        Vector3 collidePoint = vertex.pos + globalSpeedVec * collideTime;

        if (Math3D.isProjectInSurface(collidePoint, collideSurfaceP0, collideSurfaceP1))   //will contact in future
        {
            CollideInfo info = CollideManager.collideInfo;
            if (info.minCollideTime == -1 || collideTime < info.minCollideTime)
            {
                info.minCollideTime   = collideTime;
                info.collidePoint     = collidePoint;
                info.collideSurfaceP0 = collideSurfaceP0;
                info.collideSurfaceP1 = collideSurfaceP1;
                info.intersectPoint   = intersectPoint;
                info.vertex           = vertex;
                info.surface          = surface;
                info.node             = null;
                info.reachGoalobj     = null;
            }
        }
    }
Example #15
0
    void GenerateColls(Collision2D col, bool resetCount)
    {
        if (resetCount)
        {
            mColls.Clear();
        }

        Vector2 up = dirHolder.up;

        int contactCount = col.GetContacts(mContactPoints);

        for (int i = 0; i < contactCount; i++)
        {
            ContactPoint2D contact = mContactPoints[i];

            Collider2D whichColl = col.collider;// contact.thisCollider != collider ? contact.thisCollider : contact.otherCollider;

            Vector2        n  = contact.normal;
            Vector2        p  = contact.point;
            CollisionFlags cf = GenCollFlag(up, contact);

            //check if already exists
            int ind = -1;
            for (int j = 0; j < mColls.Count; j++)
            {
                CollideInfo inf = mColls[j];
                if (inf.collider == whichColl)
                {
                    //if(cf == CollisionFlags.None)
                    //cf = GenCollFlag(up, contact);

                    if (inf.flag == cf)
                    {
                        ind = j;
                        break;
                    }
                }
            }

            var newCollInf = new CollideInfo()
            {
                collider     = whichColl,
                contactPoint = p,
                normal       = n,
                flag         = cf,
            };

            if (ind == -1)  //add new
            {
                if (mColls.Count == mColls.Capacity)
                {
                    mColls.Expand();
                }

                mColls.Add(newCollInf);
            }
            else //update info
            {
                mColls[ind] = newCollInf;
            }
        }
    }
Example #16
0
    protected override void RefreshCollInfo()
    {
        //plank check, see if we need to ignore it
        if (plankLayer != 0 && !mPlankIsIgnore)
        {
            //check if there's a coll that is a plank
            bool           plankFound    = false;
            CollisionFlags plankCollFlag = CollisionFlags.None;

            for (int i = 0; i < mCollCount; i++)
            {
                CollideInfo inf = mColls[i];
                if (inf.collider == null || inf.collider.gameObject == null || !inf.collider.gameObject.activeInHierarchy)
                {
                    RemoveColl(i);
                    i--;
                }
                else if (((1 << inf.collider.gameObject.layer) & plankLayer) != 0)
                {
                    plankFound    = true;
                    plankCollFlag = inf.flag;
                    if (plankCollFlag != CollisionFlags.Below)
                    {
                        RemoveColl(i);
                        i--;
                    }
                }
            }

            if (plankFound)
            {
                if (plankCollFlag == CollisionFlags.Below)
                {
                    //check if we are ready to drop
                    if (plankEnableDrop && mMoveYGround < 0.0f && Time.fixedTime - mMoveYGroundDownLastTime >= plankDropDelay)
                    {
                        SetPlankingIgnore(true);
                    }
                }
                else
                {
                    SetLocalVelocityToBody(); //revert rigidbody's velocity :P
                    SetPlankingIgnore(true);
                }
            }
            else if (isGrounded && mMoveYGround < 0.0f)
            {
                mMoveYGround = 0.0f;
            }
        }

        base.RefreshCollInfo();

        //bool isGroundColl = (mCollFlags & CollisionFlags.Below) != 0;

        if (mIsOnPlatform)
        {
            mCollFlags           |= CollisionFlags.Below;
            mCollGroundLayerMask |= mIsOnPlatformLayerMask;
        }

        bool lastWallStick = mWallSticking;

        mWallSticking = false;

        if (isSlopSlide)
        {
            //Debug.Log("sliding");
            mLastGround  = false;
            mJumpCounter = jumpCounter;
        }
        //refresh wallstick
        else if (wallStick && !mJumpingWall && collisionFlags == CollisionFlags.Sides)
        {
            //check if we are going up
            if (!wallStickDownOnly || localVelocity.y <= 0.0f)
            {
                Vector3 up = dirHolder.up;

                if (collisionFlags == CollisionFlags.Sides)
                {
                    for (int i = 0; i < mCollCount; i++)
                    {
                        CollideInfo inf = mColls[i];
                        if (inf.flag == CollisionFlags.Sides && (wallStickInvalidMask == 0 || ((1 << inf.collider.gameObject.layer) & wallStickInvalidMask) == 0))
                        {
                            float a = Vector3.Angle(up, inf.normal);
                            if (a >= 90.0f - wallStickAngleOfs && a <= 90.0f + wallStickAngleOfs)
                            {
                                //wallStickForce
                                mWallStickCollInfo = inf;
                                mWallStickSide     = M8.MathUtil.CheckSide(mWallStickCollInfo.normal, dirHolder.up);
                                mWallSticking      = true;
                                break;
                            }
                        }
                    }
                }
            }

            if (mWallSticking)
            {
                if (wallStickPush)
                {
                    if (CheckWallStickIn(moveSide))
                    {
                        if (!mWallStickWaitInput)
                        {
                            //cancel horizontal movement
                            Vector3 newVel = localVelocity;
                            newVel.x = 0.0f;

                            //reduce downward speed
                            if (newVel.y < -wallStickDownSpeedCap)
                            {
                                newVel.y = -wallStickDownSpeedCap;
                            }

                            rigidbody.velocity = dirHolder.rotation * newVel;

                            mWallStickLastTime = Time.fixedTime;

                            mWallStickWaitInput = true;
                        }

                        mWallStickLastInputTime = Time.fixedTime;
                    }
                    else
                    {
                        bool wallStickExpired = Time.fixedTime - mWallStickLastInputTime > wallStickDelay;

                        if (wallStickExpired)
                        {
                            mWallStickWaitInput = false;
                            mWallSticking       = false;
                        }
                    }
                }
                else
                {
                    bool wallStickExpired = Time.fixedTime - mWallStickLastTime > wallStickDelay;

                    //see if we are moving away
                    if ((wallStickExpired && CheckWallStickMoveAway(moveSide)))
                    {
                        if (!mWallStickWaitInput)
                        {
                            mWallSticking = false;
                        }
                    }
                    else if (!lastWallStick)
                    {
                        mWallStickWaitInput = true;
                        mWallStickLastTime  = Time.fixedTime;

                        //cancel horizontal movement
                        Vector3 newVel = localVelocity;
                        newVel.x = 0.0f;

                        //reduce downward speed
                        if (newVel.y < -wallStickDownSpeedCap)
                        {
                            newVel.y = -wallStickDownSpeedCap;
                        }

                        rigidbody.velocity = dirHolder.rotation * newVel;
                    }
                }
            }

            if (mWallSticking != lastWallStick)
            {
                if (mWallSticking)
                {
                    mJump    = false;
                    lockDrag = false;
                }
                else
                {
                    if (wallStickPush)
                    {
                        mWallStickWaitInput = false;
                    }
                }
            }
        }

        if (mLastGround != isGrounded)
        {
            if (!mLastGround)
            {
                //Debug.Log("landed");
                //mJump = false;
                //mJumpingWall = false;
                mJumpCounter = 0;

                if (localVelocity.y <= 0.0f)
                {
                    if (landCallback != null)
                    {
                        landCallback(this);
                    }
                }
            }
            else
            {
                //falling down?

                /*if(mJumpCounter <= 0)
                 *  mJumpCounter = 1;*/

                mJumpLastTime   = Time.fixedTime;
                mLastGroundTime = Time.fixedTime;
            }

            mLastGround = isGrounded;
        }
    }
        //return true if we moved
        public bool Move(Quaternion dirRot, Vector3 forward, Vector3 right, Vector2 axis, float force)
        {
            //compute move direction
            Vector3 moveDelta = axis.y != 0.0f ? dirRot * forward * axis.y : Vector3.zero;

            if (axis.x != 0.0f)
            {
                moveDelta += dirRot * right * axis.x;
            }

            mCurMoveDir = moveDelta.normalized;

            float maxSpeed = 0.0f;

            //allow for moving diagonally downwards
            //TODO: test for non-platformer
            if (isGrounded)
            {
                for (int i = 0; i < mCollCount; i++)
                {
                    CollideInfo inf = mColls[i];
                    if (inf.flag == CollisionFlags.Below)
                    {
                        moveDelta   = M8.MathUtil.Slide(moveDelta, inf.normal);
                        mCurMoveDir = moveDelta.normalized;
                        break;
                    }
                }

                maxSpeed = moveMaxSpeed;
            }
            else
            {
                maxSpeed = airMaxSpeed;
            }

            //check if we need to slide off walls

            /*foreach(KeyValuePair<Collider, CollideInfo> pair in mColls) {
             *  if(pair.Value.flag == CollisionFlags.Sides) {
             *      Vector3 colN = pair.Value.normal;
             *      if(Vector3.Dot(mCurMoveDir, colN) < 0.0f) {
             *          moveDelta = M8.MathUtil.Slide(mCurMoveDir, colN);
             *          moveDelta.Normalize();
             *          mCurMoveDir = moveDelta;
             *      }
             *  }
             * }*/

#if MATE_PHYSICS_DEBUG
            M8.DebugUtil.DrawArrow(transform.position, mCurMoveDir);
#endif

            //check if we can move based on speed or if going against new direction
            bool canMove = CanMove(mCurMoveDir, maxSpeed * moveScale);

            if (canMove)
            {
                //M8.Debug.
                mBody.AddForce(moveDelta * force * moveScale);
                return(true);
            }

            return(false);
        }
Example #18
0
        void Rule_Air()
        {
            #region Rule
            col.groundDepth = 0;
            col.UpdateGroundCollision();

            if (newRule)
            {
                liftOffVel = velXZ.magnitude;
            }

            if (col.ground.AnyGround && velY <= 0)
            {
                velY = 0;
                SetRule("Ground");
                return;
            }
            else if (col.ground.Slide)
            {
                SetRule("Sliding");
                return;
            }
            else if (col.ground.Water && velY < 0 && !col.waterIsShallow)
            {
                SetRule("Swimming");
                return;
            }
            else if (!t_blockHang.active && col.ceiling.HangableCeiling)
            {
                SetRule("Hanging");
                return;
            }

            if (jumping)
            {
                gravity = -20;
                if (velY < jumpCutoff)
                {
                    jumping = false;
                }
            }
            else
            {
                gravity = -30;
            }


            // Ledgegrab
            var lh = Raycast(forward * 2 + upward * 3, -upward, 1);
            if (lh.AnyGround)
            {
                float       dist  = DistTo(lh);
                CollideInfo ledge = new CollideInfo();
                for (float d = dist; d > 0; d -= 0.05f)
                {
                    var lh2 = RayCollider.Raycast(pos + d * Vec2D(pos, lh.hit.point), -upward, 2);
                    if (!lh2.AnyGround)
                    {
                        ledge = lh2;
                        break;
                    }
                }
                if (ledge.AnyGround)
                {
                    this.ledge = ledge;
                    SetRule("Ledgegrab");
                    return;
                }
            }


            ApplyGravity();

            if (helic)
            {
                if (superHelicAscend)
                {
                    superHelicRev = Mathf.Lerp(superHelicRev, 42, dt * 45);
                }
                else
                {
                    superHelicRev = Mathf.Lerp(superHelicRev, 0, dt * 1);
                }

                SFX("Rayman2/Rayman/helic").asrc.pitch = 1 + superHelicRev / 300;
                anim.SetSpeed(30 + superHelicRev / 7);

                SetFriction(6.5f, hasSuperHelic ? 2.6f : 7.5f);
                velY    += dt * superHelicRev;
                velY     = Mathf.Clamp(velY, hasSuperHelic ? -25 : -5, 5);
                selfJump = false;
            }
            else
            {
                if (slideJump)
                {
                    SetFriction(0.1f, 0);
                }
                else
                {
                    SetFriction(5, 0);
                }
                moveSpeed = 10;
            }


            MoveOrStrafe(6, helic ? 5 : -1);
            AlignY(10);

            if (pos.y < startPos.y - 1100)
            {
                SetRule("Falling");
            }
            #endregion
            #region Animation
            if (helic)
            {
                anim.Set(Anim.HelicEnable, 1);
            }
            else if (liftOffVel < 5 || !selfJump)
            {
                if (velY > 5 + jumpLiftOffVelY)
                {
                    anim.Set(Anim.JumpIdleLoop, 0);
                }
                else
                {
                    if (newRule)
                    {
                        anim.Set(Anim.FallIdleLoop, 0);
                    }
                    else
                    {
                        anim.Set(Anim.FallIdleStart, 1);
                    }
                }
            }
            else
            {
                if (velY > 5 + jumpLiftOffVelY)
                {
                    anim.Set(Anim.JumpRunLoop, 0);
                }
                else
                {
                    if (newRule)
                    {
                        anim.Set(Anim.FallRunLoop, 0);
                    }
                    else
                    {
                        anim.Set(Anim.FallRunStart, 1);
                    }
                }
            }
            #endregion
        }
Example #19
0
        void OnInputJump(InputManager.Info dat)
        {
            //jumpWall
            if (dat.state == InputManager.State.Pressed)
            {
                if (isUnderWater || isOnLadder)
                {
                    mJump = true;
                }
                else if (jumpWall && collisionFlags == CollisionFlags.Sides)
                {
                    bool        found = false;
                    CollideInfo inf   = new CollideInfo();

                    for (int i = 0; i < mCollCount; i++)
                    {
                        CollideInfo cInf = mColls[i];
                        if (cInf.flag == CollisionFlags.Sides)
                        {
                            if (Vector3.Angle(dirHolder.forward, cInf.normal) > 120.0f)
                            {
                                inf   = cInf;
                                found = true;
                                break;
                            }
                        }
                    }

                    if (found)
                    {
                        Vector3 jumpDir = inf.normal + dirHolder.up;

                        if (jumpImpulse > 0.0f)
                        {
                            ClearCollFlags();
                            mBody.drag = airDrag;
                            mBody.AddForce(jumpDir * jumpImpulse, ForceMode.Impulse);
                        }

                        mJump         = true;
                        mJumpLastTime = Time.fixedTime;

                        float a = M8.MathUtil.AngleForwardAxisDir(dirHolder.worldToLocalMatrix, Vector3.forward, inf.normal);
                        dirHolder.rotation *= Quaternion.AngleAxis(a, Vector3.up);
                        EyeOrient();
                        //TurnTo(inf.normal);
                    }
                }
                else if (!mJump)
                {
                    if (isUnderWater || isOnLadder)
                    {
                        mJump = true;
                    }
                    else if (!isSlopSlide)
                    {
                        if (isGrounded)
                        {
                            if (jumpImpulse > 0.0f)
                            {
                                ClearCollFlags();
                                mBody.drag = airDrag;
                                mBody.AddForce(dirHolder.up * jumpImpulse, ForceMode.Impulse);
                            }

                            mJump         = true;
                            mJumpLastTime = Time.fixedTime;
                        }
                    }
                }
            }
            else if (dat.state == InputManager.State.Released)
            {
                mJump = false;
            }
        }
    protected override void RefreshCollInfo() {
        //plank check, see if we need to ignore it
        if(plankLayer != 0 && !mPlankIsIgnore) {
            //check if there's a coll that is a plank
            bool plankFound = false;
            CollisionFlags plankCollFlag = CollisionFlags.None;

            for(int i = 0; i < mCollCount; i++) {
                CollideInfo inf = mColls[i];
                if(inf.collider == null || inf.collider.gameObject == null || !inf.collider.gameObject.activeInHierarchy) {
                    RemoveColl(i);
                    i--;
                }
                else if(((1 << inf.collider.gameObject.layer) & plankLayer) != 0) {
                    plankFound = true;
                    plankCollFlag = inf.flag;
                    if(plankCollFlag != CollisionFlags.Below) {
                        RemoveColl(i);
                        i--;
                    }
                }
            }

            if(plankFound) {
                if(plankCollFlag == CollisionFlags.Below) {
                    //check if we are ready to drop
                    if(plankEnableDrop && mMoveYGround < 0.0f && Time.fixedTime - mMoveYGroundDownLastTime >= plankDropDelay) {
                        SetPlankingIgnore(true);
                    }
                }
                else {
                    SetLocalVelocityToBody(); //revert rigidbody's velocity :P
                    SetPlankingIgnore(true);
                }
            }
            else if(isGrounded && mMoveYGround < 0.0f) {
                mMoveYGround = 0.0f;
            }
        }

        base.RefreshCollInfo();

        //bool isGroundColl = (mCollFlags & CollisionFlags.Below) != 0;

        if(mIsOnPlatform) {
            mCollFlags |= CollisionFlags.Below;
            mCollGroundLayerMask |= mIsOnPlatformLayerMask;
        }

        bool lastWallStick = mWallSticking;
        mWallSticking = false;

        if(isSlopSlide) {
            //Debug.Log("sliding");
            mLastGround = false;
            mJumpCounter = jumpCounter;
        }
        //refresh wallstick
        else if(wallStick && !mJumpingWall && collisionFlags == CollisionFlags.Sides) {
            //check if we are going up
            if(!wallStickDownOnly || localVelocity.y <= 0.0f) {
                Vector3 up = dirHolder.up;

                if(collisionFlags == CollisionFlags.Sides) {
                    for(int i = 0; i < mCollCount; i++) {
                        CollideInfo inf = mColls[i];
                        if(inf.flag == CollisionFlags.Sides && (wallStickInvalidMask == 0 || ((1<<inf.collider.gameObject.layer) & wallStickInvalidMask) == 0)) {
                            float a = Vector3.Angle(up, inf.normal);
                            if(a >= 90.0f - wallStickAngleOfs && a <= 90.0f + wallStickAngleOfs) {
                                //wallStickForce
                                mWallStickCollInfo = inf;
                                mWallStickSide = M8.MathUtil.CheckSide(mWallStickCollInfo.normal, dirHolder.up);
                                mWallSticking = true;
                                break;
                            }
                        }
                    }
                }
            }

            if(mWallSticking) {
                if(wallStickPush) {
                    if(CheckWallStickIn(moveSide)) {
                        if(!mWallStickWaitInput) {
                            //cancel horizontal movement
                            Vector3 newVel = localVelocity;
                            newVel.x = 0.0f;

                            //reduce downward speed
                            if(newVel.y < -wallStickDownSpeedCap)
                                newVel.y = -wallStickDownSpeedCap;

                            rigidbody.velocity = dirHolder.rotation * newVel;

                            mWallStickLastTime = Time.fixedTime;

                            mWallStickWaitInput = true;
                        }

                        mWallStickLastInputTime = Time.fixedTime;
                    }
                    else {
                        bool wallStickExpired = Time.fixedTime - mWallStickLastInputTime > wallStickDelay;

                        if(wallStickExpired) {
                            mWallStickWaitInput = false;
                            mWallSticking = false;
                        }
                    }
                }
                else {
                    bool wallStickExpired = Time.fixedTime - mWallStickLastTime > wallStickDelay;

                    //see if we are moving away
                    if((wallStickExpired && CheckWallStickMoveAway(moveSide))) {
                        if(!mWallStickWaitInput) {
                            mWallSticking = false;
                        }
                    }
                    else if(!lastWallStick) {
                        mWallStickWaitInput = true;
                        mWallStickLastTime = Time.fixedTime;

                        //cancel horizontal movement
                        Vector3 newVel = localVelocity;
                        newVel.x = 0.0f;

                        //reduce downward speed
                        if(newVel.y < -wallStickDownSpeedCap)
                            newVel.y = -wallStickDownSpeedCap;

                        rigidbody.velocity = dirHolder.rotation * newVel;
                    }
                }
            }

            if(mWallSticking != lastWallStick) {
                if(mWallSticking) {
                    mJump = false;
                    lockDrag = false;
                }
                else {
                    if(wallStickPush)
                        mWallStickWaitInput = false;
                }
            }
        }

        if(mLastGround != isGrounded) {
            if(!mLastGround) {
                //Debug.Log("landed");
                //mJump = false;
                //mJumpingWall = false;
                mJumpCounter = 0;

                if(localVelocity.y <= 0.0f) {
                    if(landCallback != null)
                        landCallback(this);
                }
            }
            else {
                //falling down?
                /*if(mJumpCounter <= 0)
                    mJumpCounter = 1;*/

                mJumpLastTime = Time.fixedTime;
                mLastGroundTime = Time.fixedTime;
            }

            mLastGround = isGrounded;
        }
    }
Example #21
0
    protected override void RefreshCollInfo()
    {
        base.RefreshCollInfo();

        //bool isGroundColl = (mCollFlags & CollisionFlags.Below) != 0;

        if (mIsOnPlatform)
        {
            mCollFlags           |= CollisionFlags.Below;
            mCollGroundLayerMask |= mIsOnPlatformLayerMask;
        }

        bool lastWallStick = mWallSticking;

        mWallSticking = false;

        if (isSlopSlide)
        {
            //Debug.Log("sliding");
            mLastGround  = false;
            mJumpCounter = jumpCounter;
        }
        //refresh wallstick
        else if (wallStick && !mJumpingWall && collisionFlags == CollisionFlags.Sides)
        {
            Vector3 up = dirHolder.up;

            if (collisionFlags == CollisionFlags.Sides)
            {
                for (int i = 0; i < mCollCount; i++)
                {
                    CollideInfo inf = mColls[i];
                    if (inf.flag == CollisionFlags.Sides)
                    {
                        float a = Vector3.Angle(up, inf.normal);
                        if (a >= 90.0f - wallStickAngleOfs && a <= 90.0f + wallStickAngleOfs)
                        {
                            //wallStickForce
                            mWallStickCollInfo = inf;
                            mWallStickSide     = M8.MathUtil.CheckSide(mWallStickCollInfo.normal, dirHolder.up);
                            mWallSticking      = true;
                            mJump    = false;
                            lockDrag = false;
                            break;
                        }
                    }
                }
            }

            if (mWallSticking)
            {
                bool wallStickExpired = Time.fixedTime - mWallStickLastTime > wallStickDelay;

                //see if we are moving away
                if (wallStickExpired && CheckWallStickMoveAway(moveSide))
                {
                    if (!mWallStickWaitInput)
                    {
                        mWallSticking = false;
                    }
                }
                else if (!lastWallStick)
                {
                    mWallStickWaitInput = true;
                    mWallStickLastTime  = Time.fixedTime;

                    //cancel horizontal movement
                    Vector3 newVel = localVelocity;
                    newVel.x = 0.0f;

                    //reduce downward speed
                    if (newVel.y < -wallStickDownSpeedCap)
                    {
                        newVel.y = -wallStickDownSpeedCap;
                    }

                    rigidbody.velocity = dirHolder.rotation * newVel;
                }
            }
        }

        if (mLastGround != isGrounded)
        {
            if (!mLastGround)
            {
                //Debug.Log("landed");
                //mJump = false;
                //mJumpingWall = false;
                mJumpCounter = 0;

                if (landCallback != null)
                {
                    landCallback(this);
                }
            }
            else
            {
                //falling down?

                /*if(mJumpCounter <= 0)
                 *  mJumpCounter = 1;*/

                mJumpLastTime = Time.fixedTime;
            }

            mLastGround = isGrounded;
        }
    }