示例#1
0
        /// <summary>
        /// Move the character without going through things
        /// </summary>
        /// <param name="movement">offset to move the character</param>
        void CharacterMove(Vector3 movement)
        {
            Vector3 nTotal = Vector3.zero;

            // reset all collision flags
            Collisions = CC_Collision.None;

            Vector3 movNormalized = movement.normalized;
            float   distance      = movement.magnitude;

#if STAIRS
            StepDelta = Mathf.Clamp(StepDelta - Time.fixedDeltaTime * 1.5f, 0, Mathf.Infinity);
            if (IsGrounded && !CPMSettings.FlyingCharacter)
            {
                MoveOnSteps1(movNormalized);
            }
#endif
            //const float minimumStepDistance = 0.1f; // Greater than 0 to prevent infinite loop
            //float stepDistance = Math.Min((ownCollider as CapsuleCollider).radius, minimumStepDistance);
            float stepDistance = 0.05f;

            Vector3 nResult;
            if (distance > 0)
            {
                for (float curDist = 0; curDist < distance; curDist += stepDistance)
                {
                    float   curMagnitude = Math.Min(stepDistance, distance - curDist);
                    Vector3 start        = transform.position;
                    Vector3 end          = start + movNormalized * curMagnitude;
                    transform.position = FixOverlaps(end, movNormalized * curMagnitude, out nResult);
                    nTotal            += nResult;
                }
            }
            else
            {
                // when character doesn't move
                transform.position = FixOverlaps(transform.position, Vector3.zero, out nResult);
                nTotal            += nResult;
            }

            // handles collision
            OnCCHit(nTotal.normalized);
        }
示例#2
0
        /// <summary>
        /// Move the transform trying to stop being overlaping other colliders
        /// </summary>
        /// <param name="position">start position. Bottom of the collider</param>
        /// <returns>Final position</returns>
        Vector3 FixOverlaps(Vector3 position, Vector3 offset, out Vector3 nResult)
        {
            Vector3 nTemp = Vector3.zero;

            // what if you sum all the penetration directions to give the final result
            // and with each collision, add a CollisionFlag accordingly with the axis collided?

            CapsuleCollider coll = ownCollider as CapsuleCollider;
            //Vector3 p = position - (position - coll.transform.position) + (coll.bounds.center - new Vector3(0, coll.bounds.extents.y, 0));
            //int nColls = Physics.OverlapCapsuleNonAlloc(p, new Vector3(p.x, p.y + coll.height, p.z), coll.radius, overlapingColliders, GroundLayer, QueryTriggerInteraction.Ignore);

            // when dead, collide onlly with the world
            LayerMask overlapMask;

            if (IsAlive)
            {
                overlapMask = m_SolidLayer | m_EnemyLayer;
            }
            else
            {
                overlapMask = m_SolidLayer;
            }

            int nColls = PhysicsExtensions.OverlapCapsuleNonAlloc(coll, offset, overlapingColliders, overlapMask, QueryTriggerInteraction.Ignore);

            for (int i = 0; i < nColls; i++)
            {
                Collider c = overlapingColliders[i];
                if (c == ownCollider)
                {
                    continue;                   // ignore itself
                }
                Vector3 normal;
                float   dist;
                float   dot;
                if (Physics.ComputePenetration(ownCollider, position, transform.rotation,
                                               c, c.transform.position, c.transform.rotation, out normal, out dist))
                {
                    // TODO: report bug
                    if (float.IsNaN(normal.x) || float.IsNaN(normal.y) || float.IsNaN(normal.y))
                    {
                        continue;
                    }

                    // depenetration value for preventing doors
                    // from overlapping with player when it shouldn't
                    dist += Depenetration;

                    dot = Vector3.Dot(normal, Vector3.up);
                    if (dot > m_Settings.SlopeLimit && dot <= 1)
                    {
                        Collisions = Collisions | CC_Collision.CollisionBelow;
                        position  += normal * dist;

                        State &= ~CC_State.OnPlatform;
                    }

                    if (dot >= 0 && dot < m_Settings.SlopeLimit)
                    {
                        Collisions = Collisions | CC_Collision.CollisionSides;
                    }

                    if (dot < 0)
                    {
                        Collisions = Collisions | CC_Collision.CollisionAbove;
                    }

                    nTemp += normal;
                }
            }
            nResult = nTemp;
            return(position);
        }
示例#3
0
        /// <summary>
        /// Move the character without going through things
        /// </summary>
        /// <param name="movement">offset to move the character</param>
        void CharacterMove(Vector3 movement)
        {
            Vector3 nTotal = Vector3.zero;

            // reset all collision flags
            Collisions = CC_Collision.None;

            Vector3 totalMovNorm = movement.normalized;
            float   distance     = movement.magnitude;

#if STAIRS
            StepDelta = Mathf.Clamp(StepDelta - Time.fixedDeltaTime * 1.5f, 0, Mathf.Infinity);
            if (IsGrounded && !CPMSettings.FlyingCharacter)
            {
                MoveOnSteps1(movNormalized);
            }
#endif
            //const float minimumStepDistance = 0.1f; // Greater than 0 to prevent infinite loop
            //float stepDistance = Math.Min((ownCollider as CapsuleCollider).radius, minimumStepDistance);
            float stepDistance = 0.05f;

            int nHits = 0;

            for (int i = 0; i < 3; i++)
            {
                Vector3 movNormalized = Vector3.zero;
                switch (i)
                {
                case 0:
                    movNormalized = Vector3.right;
                    break;

                case 1:
                    movNormalized = Vector3.up;
                    break;

                case 2:
                    movNormalized = Vector3.forward;
                    break;
                }
                movNormalized *= totalMovNorm[i];

                Vector3 normal;
                if (distance > 0)
                {
                    for (float curDist = 0; curDist < distance; curDist += stepDistance)
                    {
                        float   curMagnitude = Mathf.Min(stepDistance, distance - curDist);
                        Vector3 start        = transform.position;
                        Vector3 end          = start + movNormalized * curMagnitude;
                        transform.position = FixOverlaps(end, movNormalized * curMagnitude, out normal);

                        if (nHits < hitNormals.Length)
                        {
                            hitNormals[nHits] = normal;
                            nHits++;
                        }
                    }
                }
                else
                {
                    // when character doesn't move
                    transform.position = FixOverlaps(transform.position, Vector3.zero, out normal);

                    if (nHits < hitNormals.Length)
                    {
                        hitNormals[nHits] = normal;
                        nHits++;
                    }
                }
            }

            Vector3 resultNormal = Vector3.zero;
            for (int n = 0; n < nHits; n++)
            {
                // handles collision
                OnCCHit(hitNormals[n]);
                resultNormal += hitNormals[n];
            }

            // align with planes
            var copyVelocity = Velocity;
            var newDir       = Vector3.ProjectOnPlane(copyVelocity.normalized, resultNormal.normalized);
            Velocity = (newDir * copyVelocity.magnitude);

            //FloorAlign();
        }
示例#4
0
        //Vector2 GetKeyInput()
        //{
        //    WalkForward = (InputManager.GetButton("Forward") ? 1 : 0) - (InputManager.GetButton("Backwards") ? 1 : 0);
        //    Strafe = (InputManager.GetButton("Strafe_Right") ? 1 : 0) - (InputManager.GetButton("Strafe_Left") ? 1 : 0);

        //    SwimUp = InputManager.GetAxisRaw("SwimUp");
        //    JumpInput = InputManager.GetButtonDown("Jump");

        //    if (JumpInput && triedJumping == 0)
        //        triedJumping = jumpInputWindow;

        //    return new Vector2(Strafe, WalkForward);
        //}

        /// <summary> Check if the player view is under water layer </summary>
        private bool HasCollisionFlag(CC_Collision flag)
        {
            return((Collisions & flag) != 0);
        }
示例#5
0
        void MoveOnSteps1(Vector3 movNormalized)
        {
            Vector3 p0, p1; // capsule point 0 and 1
            float   radius; // capsule radius

            // ignore gravity pull
            stepDir   = movNormalized;
            stepDir.y = 0;
            stepDist  = stepDir.magnitude; // for debug purposes


            ownCollider.ToWorldSpaceCapsule(out p0, out p1, out radius);
            p0 += (stepDir * stepDist) + (Vector3.up * CPMSettings.StepOffset);
            p1 += (stepDir * stepDist) + (Vector3.up * CPMSettings.StepOffset);

            if (stepDist <= Mathf.Epsilon)
            {
                return;
            }

            // check if collides in the next step
            if (Physics.CheckCapsule(p0, p1, radius, m_SolidLayer, QueryTriggerInteraction.Ignore))
            {
                // collided with a solid object, probably a wall
                return; // doesn't do anything
            }
            else
            {
                // didn't found a collision, so there is a step
                // try to find the step point
                stepCenter = ((p0 + p1) / 2) + stepDir * radius;
                Vector3 size = new Vector3(ownCollider.radius * 2, ownCollider.height, ownCollider.radius * 2);

                //if (Physics.Raycast(stepCenter, Vector3.down, out stepHit, Mathf.Infinity, Game.Settings.SOLID_LAYER, QueryTriggerInteraction.Ignore))
                //{
                //    var bottom = ownCollider.center + transform.position + (Vector3.down * ownCollider.height / 2);
                //    var dot = Vector3.Dot(stepHit.normal, Vector3.up);
                //    if (stepHit.point.y > bottom.y && dot > 0.95f)
                //    {
                //        float upDist = Mathf.Abs(stepHit.point.y - bottom.y);
                //        transform.position += Vector3.up * upDist; //raise the player on the step size
                //    }
                //}

                if (Physics.CapsuleCast(p0 + stepDir * radius, p1 + stepDir * radius, radius, Vector3.down, out stepHit, Mathf.Infinity, m_SolidLayer, QueryTriggerInteraction.Ignore))
                {
                    var bottom = ownCollider.center + transform.position + (Vector3.down * ownCollider.height / 2);

                    if (Physics.Raycast(stepHit.point + Vector3.up * CPMSettings.StepOffset,
                                        Vector3.down, out cornerHit, Mathf.Infinity, m_SolidLayer, QueryTriggerInteraction.Ignore))
                    {
                        var dot = Vector3.Dot(cornerHit.normal, Vector3.up);
                        if (stepHit.point.y > bottom.y && dot >= 0.98999999f)
                        {
                            float upDist = Mathf.Abs(stepHit.point.y - bottom.y);
                            transform.position += Vector3.up * upDist; //raise the player on the step size

                            if (upDist > StepDelta)
                            {
                                StepDelta = upDist;
                            }

                            Collisions |= CC_Collision.CollisionBelow;
                        }
                    }
                }
            }
        }
示例#6
0
 public void RemoveCollision(CC_Collision collision)
 {
     Collisions &= ~collision;
 }
示例#7
0
 public void AddCollision(CC_Collision collision)
 {
     Collisions |= collision;
 }
示例#8
0
 public bool HasCollision(CC_Collision collision)
 {
     return((Collisions & collision) != 0);
 }
示例#9
0
 public bool HasCollisionFlag(CC_Collision flag)
 {
     return(HasCollision(flag));
     //return (Collisions & flag) != 0;
 }