protected void FindSurface(Collider2D collider)
        {
            Vector3 forward = spriteOriginallyFacesLeft ? Vector3.left : Vector3.right;

            if (m_SpriteRenderer.flipX)
            {
                forward.x = -forward.x;
            }

            TileBase surfaceHit = PhysicsHelper.FindTileForOverride(collider, transform.position, forward);

            VFXController.Instance.Trigger(VFX_HASH, transform.position, 0, m_SpriteRenderer.flipX, null, surfaceHit);
        }
Example #2
0
        public bool MakePlatformFallthrough()
        {
            int colliderCount            = 0;
            int fallthroughColliderCount = 0;

            for (int i = 0; i < m_CharacterController2D.GroundColliders.Length; i++)
            {
                Collider2D col = m_CharacterController2D.GroundColliders[i];
                if (col == null)
                {
                    continue;
                }

                colliderCount++;

                if (PhysicsHelper.ColliderHasPlatformEffector(col))
                {
                    fallthroughColliderCount++;
                }
            }

            if (fallthroughColliderCount == colliderCount)
            {
                for (int i = 0; i < m_CharacterController2D.GroundColliders.Length; i++)
                {
                    Collider2D col = m_CharacterController2D.GroundColliders[i];
                    if (col == null)
                    {
                        continue;
                    }

                    PlatformEffector2D effector;
                    PhysicsHelper.TryGetPlatformEffector(col, out effector);
                    FallthroughReseter reseter = effector.gameObject.AddComponent <FallthroughReseter>();
                    reseter.StartFall(effector);
                    //set invincible for half a second when falling through a platform, as it will make the player "standup"
                    StartCoroutine(FallThroughtInvincibility());
                }
            }

            return(fallthroughColliderCount == colliderCount);
        }
Example #3
0
        public void FindCurrentSurface()
        {
            Collider2D groundCollider = m_CharacterController2D.GroundColliders[0];

            if (groundCollider == null)
            {
                groundCollider = m_CharacterController2D.GroundColliders[1];
            }

            if (groundCollider == null)
            {
                return;
            }

            TileBase b = PhysicsHelper.FindTileForOverride(groundCollider, transform.position, Vector2.down);

            if (b != null)
            {
                m_CurrentSurface = b;
            }
        }
        static void Create()
        {
            GameObject physicsHelperGameObject = new GameObject("PhysicsHelper");

            s_Instance = physicsHelperGameObject.AddComponent <PhysicsHelper> ();
        }
Example #5
0
        /// <summary>
        /// This updates the state of IsGrounded.  It is called automatically in FixedUpdate but can be called more frequently if higher accurracy is required.
        /// </summary>
        public void CheckCapsuleEndCollisions(bool bottom = true)
        {
            Vector2 raycastDirection;
            Vector2 raycastStart;
            float   raycastDistance;

            //Si el componente CapsuleCollider2D no esta
            if (m_Capsule == null)
            {
                //inicio de rayo comienza con la posicion del rigid + la compensación
                raycastStart    = m_Rigidbody2D.position + Vector2.up;
                raycastDistance = 1f + groundedRaycastDistance;

                if (bottom)
                {
                    raycastDirection = Vector2.down;

                    m_RaycastPositions[0] = raycastStart + Vector2.left * 0.4f;
                    m_RaycastPositions[1] = raycastStart;
                    m_RaycastPositions[2] = raycastStart + Vector2.right * 0.4f;
                }
                else
                {
                    raycastDirection = Vector2.up;

                    m_RaycastPositions[0] = raycastStart + Vector2.left * 0.4f;
                    m_RaycastPositions[1] = raycastStart;
                    m_RaycastPositions[2] = raycastStart + Vector2.right * 0.4f;
                }
            }
            else//si hay componente CapsulaCollider 2D
            {
                //inicio de rayo comienza con la posicion del rigid + la compensación
                raycastStart    = m_Rigidbody2D.position + m_Capsule.offset;              //encuentre el centro del personaje
                raycastDistance = m_Capsule.size.x * 0.5f + groundedRaycastDistance * 2f; //valor de mitad del personaje en x + rayo a Piso= .1f *2f(supungo que para anticipar mas el rayo)

                if (bottom)
                {
                    //Calcule el inicio del rayo en el centro inferior, multiplico down(-) por la mitad Y y a Y le quita el valor de la mitad de X del tamaño del collider
                    raycastDirection = Vector2.down;
                    Vector2 raycastStartBottomCentre = raycastStart + Vector2.down * (m_Capsule.size.y * 0.5f - m_Capsule.size.x * 0.5f);
                    //Pondra los rayos justo antes de la curvatura de la capsula en la parte inferior
                    m_RaycastPositions[0] = raycastStartBottomCentre + Vector2.left * m_Capsule.size.x * 0.5f;
                    m_RaycastPositions[1] = raycastStartBottomCentre;
                    m_RaycastPositions[2] = raycastStartBottomCentre + Vector2.right * m_Capsule.size.x * 0.5f;
                }
                else
                {
                    raycastDirection = Vector2.up;
                    Vector2 raycastStartTopCentre = raycastStart + Vector2.up * (m_Capsule.size.y * 0.5f - m_Capsule.size.x * 0.5f);
                    //Igual que en el if pero arriba
                    m_RaycastPositions[0] = raycastStartTopCentre + Vector2.left * m_Capsule.size.x * 0.5f;
                    m_RaycastPositions[1] = raycastStartTopCentre;
                    m_RaycastPositions[2] = raycastStartTopCentre + Vector2.right * m_Capsule.size.x * 0.5f;
                }
            }

            //Emicion de Rayo y Colisionadores en el piso
            for (int i = 0; i < m_RaycastPositions.Length; i++)
            {
                //Cuenta la cantidad de objetos golpeados
                int count = Physics2D.Raycast(m_RaycastPositions[i], raycastDirection, m_ContactFilter, m_HitBuffer, raycastDistance);

                if (bottom)//Si es piso almacene lo encontrado colliders o no.
                {
                    //Encontro mas de un golpe? si si:almacene ese golpetemporal encontrado, sino:almacene un raycashit2d vacio
                    m_FoundHits[i]       = count > 0 ? m_HitBuffer[0] : new RaycastHit2D(); //almacene el primer objeto golpeado de cada uno de los 3 rayos
                    m_GroundColliders[i] = m_FoundHits[i].collider;                         //Almacene los collider de los primeros golpes encontrados (Se usa para plataformas mobiles mas abajo)
                }
                else//Es techo
                {
                    IsCeilinged = false;//si va en el aire y no ha golpeado nada
                    //hasta la cantidad de golpes
                    for (int j = 0; j < m_HitBuffer.Length; j++)
                    {
                        if (m_HitBuffer[j].collider != null)                                         //Si lo que golpeo tiene un collider
                        {                                                                            //Creo dice si es diferente a una plataforma mobil entonces es techo
                            if (!PhysicsHelper.ColliderHasPlatformEffector(m_HitBuffer[j].collider)) //Cache para plataformas
                            {
                                IsCeilinged = true;                                                  //Es techo
                            }
                        }
                    }
                }
            }
            //Determina normales para saber si esta en el piso
            if (bottom)
            {
                Vector2 groundNormal = Vector2.zero;
                int     hitCount     = 0;

                for (int i = 0; i < m_FoundHits.Length; i++)
                {
                    if (m_FoundHits[i].collider != null)       //Si hay colliders encontrados en el primer impacto de cada rayo
                    {
                        groundNormal += m_FoundHits[i].normal; //Acumule en el vector2 las normales de todos los golpes encontrados
                        hitCount++;
                    }
                }

                if (hitCount > 0)             //Si hay golpes
                {
                    groundNormal.Normalize(); // normalice el vector acumulador
                }
                //velocidad relativa a la plataforma mobil
                Vector2 relativeVelocity = Velocity;
                for (int i = 0; i < m_GroundColliders.Length; i++)
                {
                    if (m_GroundColliders[i] == null) //sino encuentra collider
                    {
                        continue;                     // salte al final del bucle evitando llamar a La clase de ayuda
                    }
                    MovingPlatform movingPlatform;

                    if (PhysicsHelper.TryGetMovingPlatform(m_GroundColliders[i], out movingPlatform))
                    {
                        relativeVelocity -= movingPlatform.Velocity / Time.deltaTime;
                        break;
                    }
                }
                //Piso. Debe determinar si esta en el piso
                //Si la normal en X e Y es 0 es porque esta en el aire no hay normales que rebotan de los colliders
                if (Mathf.Approximately(groundNormal.x, 0f) && Mathf.Approximately(groundNormal.y, 0f))
                {
                    IsGrounded = false;
                }
                else// Es piso
                {
                    IsGrounded = relativeVelocity.y <= 0f;//Es piso si hay normales rebotando y velocidad relativa en Y es menor o igual a cero, es decir si el personaje esta quieto o con gravedad ejerciendo

                    if (m_Capsule != null)                                                                                       //Si no tiene capsula
                    {
                        if (m_GroundColliders[1] != null)                                                                        //Pero encontro un golpe en la posicion 1, supungo que cero seria el mismo
                        {
                            float capsuleBottomHeight = m_Rigidbody2D.position.y + m_Capsule.offset.y - m_Capsule.size.y * 0.5f; //en la posicion del rigidbody + la compensacion de la cap en Y - la mitad de la cap
                            float middleHitHeight     = m_FoundHits[1].point.y;                                                  //punto Y del golpe 2 ( el 1 seria [0])
                            IsGrounded &= middleHitHeight < capsuleBottomHeight + groundedRaycastDistance;                       //si es menor de la posicion a la capsula + distancia de rayo entonces true
                            //el operador & evalúa ambos operandos, incluso aunque el izquierdo se evalúe como false, de modo que el resultado debe ser false con independencia del valor del operando derecho.
                            //el operador && no evalúa el operando derecho si el izquierdo se evalúa como false.
                        }
                    }
                }
            }
            //inicializa o limpia el bugger de goles en el array
            for (int i = 0; i < m_HitBuffer.Length; i++)
            {
                m_HitBuffer[i] = new RaycastHit2D();
            }
        }
Example #6
0
        /// <summary>
        /// This updates the state of IsGrounded.  It is called automatically in FixedUpdate but can be called more frequently if higher accurracy is required.
        /// </summary>
        public new void CheckCapsuleEndCollisions(bool bottom = true)
        {
            Vector2 raycastDirection;
            Vector2 raycastStart;
            float   raycastDistance;

            if (m_Capsule == null)
            {
                raycastStart    = m_Rigidbody2D.position + Vector2.up;
                raycastDistance = 1f + groundedRaycastDistance;

                if (bottom)
                {
                    raycastDirection = Vector2.down;

                    m_RaycastPositions[0] = raycastStart + Vector2.left * 0.4f;
                    m_RaycastPositions[1] = raycastStart;
                    m_RaycastPositions[2] = raycastStart + Vector2.right * 0.4f;
                }
                else
                {
                    raycastDirection = Vector2.up;

                    m_RaycastPositions[0] = raycastStart + Vector2.left * 0.4f;
                    m_RaycastPositions[1] = raycastStart;
                    m_RaycastPositions[2] = raycastStart + Vector2.right * 0.4f;
                }
            }
            else
            {
                raycastStart    = m_Rigidbody2D.position + m_Capsule.offset;
                raycastDistance = m_Capsule.size.x * 0.5f + groundedRaycastDistance * 2f;

                if (bottom)
                {
                    raycastDirection = Vector2.down;
                    Vector2 raycastStartBottomCentre = raycastStart + Vector2.down * (m_Capsule.size.y * 0.5f - m_Capsule.size.x * 0.5f);

                    m_RaycastPositions[0] = raycastStartBottomCentre + Vector2.left * m_Capsule.size.x * 0.5f;
                    m_RaycastPositions[1] = raycastStartBottomCentre;
                    m_RaycastPositions[2] = raycastStartBottomCentre + Vector2.right * m_Capsule.size.x * 0.5f;
                }
                else
                {
                    raycastDirection = Vector2.up;
                    Vector2 raycastStartTopCentre = raycastStart + Vector2.up * (m_Capsule.size.y * 0.5f - m_Capsule.size.x * 0.5f);

                    m_RaycastPositions[0] = raycastStartTopCentre + Vector2.left * m_Capsule.size.x * 0.5f;
                    m_RaycastPositions[1] = raycastStartTopCentre;
                    m_RaycastPositions[2] = raycastStartTopCentre + Vector2.right * m_Capsule.size.x * 0.5f;
                }
            }

            for (int i = 0; i < m_RaycastPositions.Length; i++)
            {
                int count = Physics2D.Raycast(m_RaycastPositions[i], raycastDirection, m_ContactFilter, m_HitBuffer, raycastDistance);

                if (bottom)
                {
                    m_FoundHits[i]       = count > 0 ? m_HitBuffer[0] : new RaycastHit2D();
                    m_GroundColliders[i] = m_FoundHits[i].collider;
                }
                else
                {
                    IsCeilinged = false;

                    for (int j = 0; j < m_HitBuffer.Length; j++)
                    {
                        if (m_HitBuffer[j].collider != null)
                        {
                            if (!PhysicsHelper.ColliderHasPlatformEffector(m_HitBuffer[j].collider))
                            {
                                IsCeilinged = true;
                            }
                        }
                    }
                }
            }

            if (bottom)
            {
                Vector2 groundNormal = Vector2.zero;
                int     hitCount     = 0;

                for (int i = 0; i < m_FoundHits.Length; i++)
                {
                    if (m_FoundHits[i].collider != null)
                    {
                        groundNormal += m_FoundHits[i].normal;
                        hitCount++;
                    }
                }

                if (hitCount > 0)
                {
                    groundNormal.Normalize();
                }

                Vector2 relativeVelocity = Velocity;
                for (int i = 0; i < m_GroundColliders.Length; i++)
                {
                    if (m_GroundColliders[i] == null)
                    {
                        continue;
                    }

                    MovingPlatform movingPlatform;

                    if (PhysicsHelper.TryGetMovingPlatform(m_GroundColliders[i], out movingPlatform))
                    {
                        relativeVelocity -= movingPlatform.Velocity / Time.deltaTime;
                        break;
                    }
                }

                if (Mathf.Approximately(groundNormal.x, 0f) && Mathf.Approximately(groundNormal.y, 0f))
                {
                    IsGrounded = false;
                }
                else
                {
                    IsGrounded = relativeVelocity.y <= 0f;

                    if (m_Capsule != null)
                    {
                        if (m_GroundColliders[1] != null)
                        {
                            float capsuleBottomHeight = m_Rigidbody2D.position.y + m_Capsule.offset.y - m_Capsule.size.y * 0.5f;
                            float middleHitHeight     = m_FoundHits[1].point.y;
                            IsGrounded &= middleHitHeight < capsuleBottomHeight + groundedRaycastDistance;
                        }
                    }
                }
            }

            for (int i = 0; i < m_HitBuffer.Length; i++)
            {
                m_HitBuffer[i] = new RaycastHit2D();
            }
        }