Exemple #1
0
    public void recursiveStepBack(GameObject objectCollidingWith, Collision_System objectCollision, Vector3 collidingPositionMinus, Vector3 myPositionMinus)
    {
        objectCollidingWith.transform.Translate(collidingPositionMinus);
        this.transform.Translate(myPositionMinus);

        if (objectCollidingWith.GetComponent <Collision_System>().colType == CollisionType.Sphere && colType == CollisionType.Sphere)
        {
            if (Vector3.Distance(objectCollidingWith.transform.position, transform.position) < (objectCollision.sphereRadius + sphereRadius))
            {
                recursiveStepBack(objectCollidingWith, objectCollision, collidingPositionMinus, myPositionMinus);
            }
            else
            {
                return;
            }
        }

        //Boxes aren't always cubes

        if (objectCollidingWith.GetComponent <Collision_System>().colType == CollisionType.AABB && colType == CollisionType.AABB)
        {
            //if (Vector3.Distance(objectCollidingWith.transform.position, transform.position) < (objectCollision.sphereRadius + sphereRadius))
            //    recursiveStepBack(objectCollidingWith, objectCollision, collidingPositionMinus, myPositionMinus);
            //else
            return;
        }

        if (objectCollidingWith.GetComponent <Collision_System>().colType == CollisionType.Sphere && colType == CollisionType.AABB)
        {
            //if (Vector3.Distance(objectCollidingWith.transform.position, transform.position) < (objectCollision.sphereRadius + sphereRadius))
            //    recursiveStepBack(objectCollidingWith, objectCollision, collidingPositionMinus, myPositionMinus);
            //else
            return;
        }

        if (objectCollidingWith.GetComponent <Collision_System>().colType == CollisionType.AABB && colType == CollisionType.Sphere)
        {
            //if (Vector3.Distance(objectCollidingWith.transform.position, transform.position) < (objectCollision.sphereRadius + sphereRadius))
            //    recursiveStepBack(objectCollidingWith, objectCollision, collidingPositionMinus, myPositionMinus);
            //else
            return;
        }
    }
Exemple #2
0
    // Update is called once per frame
    void Update()
    {
        collidingWith.Clear();
        collisionNormals.Clear();


        if (colType == CollisionType.AABB)
        {
            minAABBx = this.transform.position.x - (this.transform.localScale.x / 2f);
            maxAABBx = this.transform.position.x + (this.transform.localScale.x / 2f);
            minAABBy = this.transform.position.y - (this.transform.localScale.y / 2f);
            maxAABBy = this.transform.position.y + (this.transform.localScale.y / 2f);
            minAABBz = this.transform.position.z - (this.transform.localScale.z / 2f);
            maxAABBz = this.transform.position.z + (this.transform.localScale.z / 2f);
        }



        //Checking through all the collidable objects in the scene (may get expensive, could limit to things within range
        foreach (GameObject collider in collidableObjects)
        {
            Collision_System thisCollider = collider.GetComponent <Collision_System>();

            #region Sphere_Collision_Test

            if (this.colType == CollisionType.Sphere && thisCollider.colType == CollisionType.Sphere)
            {
                if (Vector3.Distance(collider.transform.position, transform.position) < (thisCollider.sphereRadius + sphereRadius))
                {
                    Debug.Log("Collision between " + name + " and " + thisCollider.name);

                    collidingWith.Add(collider);

                    collisionNormals.Add(Vector3.Normalize(collider.transform.position - transform.position));

                    if (collider.GetComponent <Object_Movement>().previousPosition != collider.GetComponent <Object_Movement>().currentPosition&&
                        GetComponent <Object_Movement>().previousPosition != GetComponent <Object_Movement>().currentPosition)
                    {
                        Vector3 thisPositionMinus = collider.GetComponent <Object_Movement>().previousPosition - collider.GetComponent <Object_Movement>().currentPosition;
                        Vector3 myPositionMinus   = GetComponent <Object_Movement>().previousPosition - GetComponent <Object_Movement>().currentPosition;
                        recursiveStepBack(collider, thisCollider, thisPositionMinus, myPositionMinus);
                    }
                }
            }

            #endregion

            #region AABB_Collision_Tests

            if (this.colType == CollisionType.AABB && thisCollider.colType == CollisionType.AABB)
            {
                if ((minAABBx > thisCollider.maxAABBx) || (thisCollider.minAABBx > maxAABBx) ||
                    (minAABBy > thisCollider.maxAABBy) || (thisCollider.minAABBy > maxAABBy) ||
                    (minAABBz > thisCollider.maxAABBz) || (thisCollider.minAABBz > maxAABBz))
                {
                    //Check closest plane and store locally
                    //float centresDistance = Vector3.Distance(this.transform.position, thisCollider.transform.position);

                    separatingPlane = SeparatingPlane.NULL;

                    if (Mathf.Abs((minAABBx - thisCollider.maxAABBx)) > Mathf.Abs((thisCollider.minAABBx - maxAABBx)) ||
                        Mathf.Abs((minAABBx - thisCollider.maxAABBx)) > Mathf.Abs((minAABBy - thisCollider.maxAABBy)) ||
                        Mathf.Abs((minAABBx - thisCollider.maxAABBx)) > Mathf.Abs((thisCollider.minAABBy - maxAABBy)) ||
                        Mathf.Abs((minAABBx - thisCollider.maxAABBx)) > Mathf.Abs((minAABBz - thisCollider.maxAABBz)) ||
                        Mathf.Abs((minAABBx - thisCollider.maxAABBx)) > Mathf.Abs((thisCollider.minAABBz - maxAABBz)))
                    {
                        separatingPlane = SeparatingPlane.Right;
                    }
                    else if (Mathf.Abs((thisCollider.minAABBx - maxAABBx)) > Mathf.Abs((minAABBx - thisCollider.maxAABBx)) ||
                             Mathf.Abs((thisCollider.minAABBx - maxAABBx)) > Mathf.Abs((minAABBy - thisCollider.maxAABBy)) ||
                             Mathf.Abs((thisCollider.minAABBx - maxAABBx)) > Mathf.Abs((thisCollider.minAABBy - maxAABBy)) ||
                             Mathf.Abs((thisCollider.minAABBx - maxAABBx)) > Mathf.Abs((minAABBz - thisCollider.maxAABBz)) ||
                             Mathf.Abs((thisCollider.minAABBx - maxAABBx)) > Mathf.Abs((thisCollider.minAABBz - maxAABBz)))
                    {
                        separatingPlane = SeparatingPlane.Left;
                    }
                    else if (Mathf.Abs((minAABBy - thisCollider.maxAABBy)) > Mathf.Abs((minAABBx - thisCollider.maxAABBx)) ||
                             Mathf.Abs((minAABBy - thisCollider.maxAABBy)) > Mathf.Abs((thisCollider.minAABBx - maxAABBx)) ||
                             Mathf.Abs((minAABBy - thisCollider.maxAABBy)) > Mathf.Abs((thisCollider.minAABBy - maxAABBy)) ||
                             Mathf.Abs((minAABBy - thisCollider.maxAABBy)) > Mathf.Abs((minAABBz - thisCollider.maxAABBz)) ||
                             Mathf.Abs((minAABBy - thisCollider.maxAABBy)) > Mathf.Abs((thisCollider.minAABBz - maxAABBz)))
                    {
                        separatingPlane = SeparatingPlane.Bottom;
                    }
                    else if (Mathf.Abs((thisCollider.minAABBy - maxAABBy)) > Mathf.Abs((minAABBx - thisCollider.maxAABBx)) ||
                             Mathf.Abs((thisCollider.minAABBy - maxAABBy)) > Mathf.Abs((thisCollider.minAABBx - maxAABBx)) ||
                             Mathf.Abs((thisCollider.minAABBy - maxAABBy)) > Mathf.Abs((minAABBy - thisCollider.maxAABBy)) ||
                             Mathf.Abs((thisCollider.minAABBy - maxAABBy)) > Mathf.Abs((minAABBz - thisCollider.maxAABBz)) ||
                             Mathf.Abs((thisCollider.minAABBy - maxAABBy)) > Mathf.Abs((thisCollider.minAABBz - maxAABBz)))
                    {
                        separatingPlane = SeparatingPlane.Top;
                    }
                    else if (Mathf.Abs((minAABBz - thisCollider.maxAABBz)) > Mathf.Abs((minAABBx - thisCollider.maxAABBx)) ||
                             Mathf.Abs((minAABBz - thisCollider.maxAABBz)) > Mathf.Abs((thisCollider.minAABBx - maxAABBx)) ||
                             Mathf.Abs((minAABBz - thisCollider.maxAABBz)) > Mathf.Abs((minAABBy - thisCollider.maxAABBy)) ||
                             Mathf.Abs((minAABBz - thisCollider.maxAABBz)) > Mathf.Abs((thisCollider.minAABBy - maxAABBy)) ||
                             Mathf.Abs((minAABBz - thisCollider.maxAABBz)) > Mathf.Abs((thisCollider.minAABBz - maxAABBz)))
                    {
                        separatingPlane = SeparatingPlane.Front;
                    }
                    else
                    {
                        separatingPlane = SeparatingPlane.Back;
                    }
                }

                if ((minAABBx <= thisCollider.maxAABBx) && (thisCollider.minAABBx <= maxAABBx) &&
                    (minAABBy <= thisCollider.maxAABBy) && (thisCollider.minAABBy <= maxAABBy) &&
                    (minAABBz <= thisCollider.maxAABBz) && (thisCollider.minAABBz <= maxAABBz))
                {
                    //Is intersecting
                    collidingWith.Add(collider);
                    collisionNormals.Add(Vector3.Normalize(collider.transform.position - transform.position));

                    Debug.Log("Collision between " + name + " and " + thisCollider.name);

                    Vector3 thisPositionMinus = collider.GetComponent <Object_Movement>().previousPosition - collider.GetComponent <Object_Movement>().currentPosition;
                    Vector3 myPositionMinus   = GetComponent <Object_Movement>().previousPosition - GetComponent <Object_Movement>().currentPosition;

                    recursiveStepBack(collider, thisCollider, thisPositionMinus, myPositionMinus);
                }
            }

            #endregion

            #region Sphere-AABB_Collision_Tests

            if (this.colType == CollisionType.Sphere && thisCollider.colType == CollisionType.AABB)
            {
                Vector3 normanL       = Vector3.Normalize(collider.transform.position - transform.position);
                Vector3 sphereChecker = this.transform.position + (normanL * this.sphereRadius);

                if ((sphereChecker.x <= thisCollider.maxAABBx) && (thisCollider.minAABBx <= sphereChecker.x) &&
                    (sphereChecker.y <= thisCollider.maxAABBy) && (thisCollider.minAABBy <= sphereChecker.y) &&
                    (sphereChecker.z <= thisCollider.maxAABBz) && (thisCollider.minAABBz <= sphereChecker.z))
                {
                    collidingWith.Add(collider);

                    collisionNormals.Add(Vector3.Normalize(collider.transform.position - transform.position));

                    Debug.Log("Collision between " + name + " and " + thisCollider.name);

                    Vector3 thisPositionMinus = collider.GetComponent <Object_Movement>().previousPosition - collider.GetComponent <Object_Movement>().currentPosition;
                    Vector3 myPositionMinus   = GetComponent <Object_Movement>().previousPosition - GetComponent <Object_Movement>().currentPosition;

                    recursiveStepBack(collider, thisCollider, thisPositionMinus, myPositionMinus);
                }
            }

            #endregion

            #region AABB-Sphere_Collision_Tests

            if (this.colType == CollisionType.AABB && thisCollider.colType == CollisionType.Sphere)
            {
                Vector3 normanL       = Vector3.Normalize(collider.transform.position - transform.position);
                Vector3 sphereChecker = thisCollider.transform.position + (normanL * thisCollider.sphereRadius);

                if ((minAABBx <= sphereChecker.x) && (sphereChecker.x <= maxAABBx) &&
                    (minAABBy <= sphereChecker.y) && (sphereChecker.y <= maxAABBy) &&
                    (minAABBz <= sphereChecker.z) && (sphereChecker.z <= maxAABBz))
                {
                    collidingWith.Add(collider);

                    collisionNormals.Add(Vector3.Normalize(collider.transform.position - transform.position));

                    Debug.Log("Collision between " + name + " and " + thisCollider.name);

                    Vector3 thisPositionMinus = collider.GetComponent <Object_Movement>().previousPosition - collider.GetComponent <Object_Movement>().currentPosition;
                    Vector3 myPositionMinus   = GetComponent <Object_Movement>().previousPosition - GetComponent <Object_Movement>().currentPosition;

                    recursiveStepBack(collider, thisCollider, thisPositionMinus, myPositionMinus);
                }
            }

            #endregion
        }

        #region Impulse_Method

        //If any object collided with this object, it will switch the boolean to true
        if (collidingWith.Count > 0)
        {
            isColliding = true;
        }
        else
        {
            isColliding = false;
        }

        if (isColliding)
        {
            foreach (GameObject collider in collidingWith)
            {
                if (!this.hasImpulsed && !collider.GetComponent <Collision_System>().hasImpulsed)
                {
                    //Finds the normal that was stored between the two objects
                    Vector3 norm = collisionNormals[collidingWith.IndexOf(collider)];

                    //Find impulse J
                    float imp1    = Vector3.Dot((-(this.GetComponent <Object_Movement>().velocity - collider.GetComponent <Object_Movement>().velocity) * (coefficientOfRestitution + 1)), norm);
                    float imp2    = ((1 / this.GetComponent <Object_Movement>().mass) + (1 / collider.GetComponent <Object_Movement>().mass));
                    float impulse = imp1 / imp2;

                    //This new velocity for each object
                    this.GetComponent <Object_Movement>().velocity     = ((impulse / this.GetComponent <Object_Movement>().mass) * norm) + this.GetComponent <Object_Movement>().velocity;
                    collider.GetComponent <Object_Movement>().velocity = ((-impulse / collider.GetComponent <Object_Movement>().mass) * norm) + collider.GetComponent <Object_Movement>().velocity;

                    hasImpulsed = true;
                    collider.GetComponent <Collision_System>().hasImpulsed = true;
                }
            }
        }

        hasImpulsed = false;

        #endregion

        //Rebounds off of the ground to prevent falling through the "ground"
        #region Ground_Plane_Impulse

        if (transform.position.y < transform.localScale.y)
        {
            var imp1    = (-(this.GetComponent <Object_Movement>().velocity.y) * (coefficientOfRestitution + 1));
            var imp2    = (1 / this.GetComponent <Object_Movement>().mass);
            var impulse = imp1 / imp2;

            this.GetComponent <Object_Movement>().velocity.y = (impulse / this.GetComponent <Object_Movement>().mass) + this.GetComponent <Object_Movement>().velocity.y;
        }

        #endregion

        //These checks are just to keep the objects within the area, as regular bounding boxes surrounding it were breaking the entirety of scene
        #region Containment_Box_Impulses

        if (transform.position.x < (transform.localScale.x - 50))
        {
            transform.position = new Vector3(transform.position.x + 0.2f, transform.position.y, transform.position.z);

            var imp1    = (-(this.GetComponent <Object_Movement>().velocity.x) * (coefficientOfRestitution + 1));
            var imp2    = (1 / this.GetComponent <Object_Movement>().mass);
            var impulse = imp1 / imp2;

            this.GetComponent <Object_Movement>().velocity.x = (impulse / this.GetComponent <Object_Movement>().mass) + this.GetComponent <Object_Movement>().velocity.x;
        }

        if (transform.position.x > (50 - transform.localScale.x))
        {
            transform.position = new Vector3(transform.position.x - 0.2f, transform.position.y, transform.position.z);

            var imp1    = (-(this.GetComponent <Object_Movement>().velocity.x) * (coefficientOfRestitution + 1));
            var imp2    = (1 / this.GetComponent <Object_Movement>().mass);
            var impulse = imp1 / imp2;

            this.GetComponent <Object_Movement>().velocity.x = (impulse / this.GetComponent <Object_Movement>().mass) + this.GetComponent <Object_Movement>().velocity.x;
        }

        if (transform.position.z < (transform.localScale.z - 25))
        {
            transform.position = new Vector3(transform.position.x, transform.position.y, transform.position.z + 0.2f);

            var imp1    = (-(this.GetComponent <Object_Movement>().velocity.z) * (coefficientOfRestitution + 1));
            var imp2    = (1 / this.GetComponent <Object_Movement>().mass);
            var impulse = imp1 / imp2;

            this.GetComponent <Object_Movement>().velocity.z = (impulse / this.GetComponent <Object_Movement>().mass) + this.GetComponent <Object_Movement>().velocity.z;
        }

        if (transform.position.z > (25 - transform.localScale.z))
        {
            transform.position = new Vector3(transform.position.x, transform.position.y, transform.position.z - 0.2f);

            var imp1    = (-(this.GetComponent <Object_Movement>().velocity.z) * (coefficientOfRestitution + 1));
            var imp2    = (1 / this.GetComponent <Object_Movement>().mass);
            var impulse = imp1 / imp2;

            this.GetComponent <Object_Movement>().velocity.z = (impulse / this.GetComponent <Object_Movement>().mass) + this.GetComponent <Object_Movement>().velocity.z;
        }

        #endregion
    }