public static void RegisterCollider(MyCollider collider)
 {
     if (!instance.registeredColliders.Contains(collider))
     {
         instance.registeredColliders.Add(collider);
     }
 }
    public void AddCollider(MyCollider newCollider)
    {
        if (newCollider == this)
        {
            return;
        }

        //STAY
        if (current_colliding_objs.Exists(a => a == newCollider))
        {
            if (eOnColliderStay != null)
            {
                eOnColliderStay(newCollider);
            }
        }
        //Enter
        else
        {
            if (eOnColliderEnter != null)
            {
                eOnColliderEnter(newCollider);
            }
            current_colliding_objs.Add(newCollider);
        }
    }
Exemple #3
0
 //檢查移動後的物體是否還在該group範圍內
 public void GroupCheck(MyCollider collider)
 {
     //移動距離不大時,跳過
     //if (CheckIsInsideBoundsCircle(collider.belongGroup.center, collider.belongGroup.bounds.extents * 0.5f, collider))return;
     //if (CheckIsInsideBoundsCircle(collider.belongGroup.center, (Vector2)collider.spr.bounds.size * 0.1f, collider)) return;
     //找到有沾到邊的其他群組加入
     for (int i = 0; i < colliderGroups.Count; i++)
     {
         if (collider.belongGroup == colliderGroups[i])
         {
             continue;
         }
         if (CheckIsInsideBoundsCircle(colliderGroups[i].center, colliderGroups[i].bounds.extents, collider))
         {
             //把目前碰撞中的物體也加進來
             ColliderGroup to = colliderGroups[i];
             //collider.current_colliding_objs.ForEach(a => MergeGroup(a.belongGroup, to));
             MergeGroup(collider.belongGroup, to);
             return;
         }
     }
     //離組的中心太遠
     if ((collider.belongGroup.center - (Vector2)collider.transform.position).magnitude > group_max_distance)
     {
         //創個組給自己
         ColliderGroup self_group = new ColliderGroup();
         //把目前碰撞中的物體也加進來
         collider.current_colliding_objs.ForEach(a => MergeGroup(self_group, a.belongGroup));
         TransferGroup(collider.belongGroup, self_group, collider);
         return;
     }
 }
Exemple #4
0
    //檢查碰撞
    public bool CheckCollision(MyCollider colliderA, MyCollider colliderB)
    {
        for (int i = 0; i < colliderA.vertices.Count; i++)
        {
            Vector2 current_normal = colliderA.normals[i];
            float[] AMinMax        = colliderA.GetMaxMinDot(current_normal, colliderA.vertices, colliderA.transform);
            float[] BMinMax        = colliderB.GetMaxMinDot(current_normal, colliderB.vertices, colliderB.transform);

            if (AMinMax[0] > BMinMax[1] || BMinMax[0] > AMinMax[1])
            {
                return(false);
            }
        }
        for (int i = 0; i < colliderB.vertices.Count; i++)
        {
            Vector2 current_normal = colliderB.normals[i];
            float[] AMinMax        = colliderA.GetMaxMinDot(current_normal, colliderA.vertices, colliderA.transform);
            float[] BMinMax        = colliderB.GetMaxMinDot(current_normal, colliderB.vertices, colliderB.transform);
            if (AMinMax[0] > BMinMax[1] || BMinMax[0] > AMinMax[1])
            {
                return(false);
            }
        }
        return(true);
    }
 /// <summary>
 /// Check for Cuboid and Sphere
 /// </summary>
 /// <param name="_coll1"></param>
 /// <param name="_coll2"></param>
 /// <returns></returns>
 private MyCollider CheckForCub_Sph(MyCollider _coll1, MyCollider _coll2)
 {
     if (_coll1 is MyBoxCollider && _coll2 is MySphereCollider)
     {
         if (Collisions.CuboidInSphere((Cuboid)_coll1.Get(), (Sphere)_coll2.Get()))
         {
             return(_coll1);
         }
         else
         {
             return(null);
         }
     }
     else
     if (_coll1 is MySphereCollider && _coll2 is MyBoxCollider)
     {
         if (Collisions.CuboidInSphere((Cuboid)_coll2.Get(), (Sphere)_coll1.Get()))
         {
             return(_coll1);
         }
         else
         {
             return(null);
         }
     }
     else
     {
         throw new System.Exception("Es müssen zwei verschiedene MyCollider in <CheckForCub_Sph> angewendet werden");
     }
 }
    public override bool isColliding(MyCollider _other)
    {
        if (_other == null)
        {
            return(false);
        }
        if (_other is MyBox2DCollider)
        {
            MyBox2DCollider other = (MyBox2DCollider)_other;
            if (this.minPosition.x > other.minPosition.x && this.minPosition.x < other.maxPosition.x && this.minPosition.y > other.minPosition.y && this.minPosition.y < other.maxPosition.y)
            {
                return(true);
            }
            if (this.maxPosition.x > other.minPosition.x && this.maxPosition.x < other.maxPosition.x && this.maxPosition.y > other.minPosition.y && this.maxPosition.x < other.maxPosition.x)
            {
                return(true);
            }
            return(false);
        }
        else if (_other is MyCircleCollider)
        {
            MyCircleCollider other        = (MyCircleCollider)_other;
            Vector3          closestPoint = GetClosestPoint(other.Position);
            float            distance     = Vector3.SqrMagnitude(closestPoint - other.Position);

            return(distance < (other.Radius * other.Radius));
        }
        return(base.isColliding(_other));
    }
Exemple #7
0
    ColliderGroup MergeGroup(ColliderGroup groupA, MyCollider collider)//B融進A
    {
        ColliderGroup newGroup = new ColliderGroup();

        newGroup.colliders = groupA.colliders;
        newGroup.colliders.Add(collider);
        return(newGroup);
    }
    public override bool isColliding(MyCollider _other)
    {
        if (_other == null)
        {
            return(false);
        }
        if (_other is MySphereCollider)
        {
            MySphereCollider other    = (MySphereCollider)_other;
            float            distance = (this.Position - other.Position).sqrMagnitude;
            float            radii    = this.m_radius * transform.lossyScale.x + other.m_radius * other.transform.lossyScale.x;

            return(distance < (radii * radii));
        }
        else if (_other is MyBoxCollider)
        {
            MyBoxCollider other = (MyBoxCollider)_other;
            other.CalculateCubeCorners();
            Vector3 potentialAxis = this.Position - other.Position;
            potentialAxis = potentialAxis.normalized;

            float min1, max1, min2, max2;

            min1 = float.PositiveInfinity;
            max1 = float.NegativeInfinity;
            float tmp;
            for (int i = 0; i < other.CubeCorners.Length; i++)
            {
                tmp = Vector3.Dot(potentialAxis, other.cubeCorners[i]);
                if (tmp < min1)
                {
                    tmp = min1;
                }
                if (tmp > max1)
                {
                    max1 = tmp;
                }
            }

            min2 = float.PositiveInfinity;
            max2 = float.NegativeInfinity;

            tmp  = Vector3.Dot(potentialAxis, other.Position);
            min2 = tmp - this.ActualRadius;
            max2 = tmp + this.ActualRadius;

            if (min1 > min2 && min1 < max2)
            {
                return(true);
            }
            if (max1 > min2 && max1 < max2)
            {
                return(true);
            }
            return(false);
        }
        return(base.isColliding(_other));
    }
Exemple #9
0
    private bool CheckForIntersectionBetween(MyCollider c1, MyCollider c2)
    {
        if (c1 is MySphereCollider && c2 is MySphereCollider)
        {
            return(CheckForIntersectionBetweenSpherers((MySphereCollider)c1, (MySphereCollider)c2));
        }

        throw new System.NotImplementedException("Intersection between collider types unknown");
    }
Exemple #10
0
    public static void Disable(MyCollider collider)
    {
        allColliders.Remove(collider);

        foreach (var other in collider.touching)
        {
            other.touching.Remove(collider);
        }
        collider.touching.Clear();
    }
Exemple #11
0
    public static void Enable(MyCollider collider)
    {
        allColliders.Add(collider);

        foreach (var(other, overlap) in Physics.AllOverlaps(collider))
        {
            collider.touching.Add(other);
            other.touching.Add(collider);
        }
    }
    private void UpdateBallColorOnColorGiverCollision(MyCollider colorGiverCollider)
    {
        MeshRenderer ballMeshRenderer       = GetComponent <MeshRenderer>();
        MeshRenderer colorGiverMeshRenderer = colorGiverCollider.GetComponent <MeshRenderer>();

        if (!MeshesAreSameColor(ballMeshRenderer, colorGiverMeshRenderer))
        {
            ballMeshRenderer.material.color = colorGiverMeshRenderer.material.color;
        }
    }
Exemple #13
0
 private void ResolveCollisionFor(MyCollider c1, MyCollider c2)
 {
     if (c1 is MySphereCollider && c2 is MySphereCollider)
     {
         ResolveCollisionForSphereres((MySphereCollider)c1, (MySphereCollider)c2);
     }
     else
     {
         throw new System.NotImplementedException("Collision resolution between collider types unknown");
     }
 }
Exemple #14
0
 public override bool DetectCollisionWithCollider(MyCollider other)
 {
     if (other is MySphereCollider)
     {
         return(PhysicsManager.OverlapSphereBox((MySphereCollider)other, this));
     }
     else
     {
         return(false);
     }
 }
Exemple #15
0
 private void Update()
 {
     if (MyCollider.IsTouching(PlayerM70.GroundCollider))
     {
         StartCoroutine(SplashWater());
     }
     else if (MyCollider.IsTouching(PlayerM70.BiteCollider))
     {
         StartCoroutine(HitPlayer());
     }
 }
Exemple #16
0
    public void RemoveCollider(MyCollider leavingCollider)
    {
        if (current_colliding_objs.Exists(a => a == leavingCollider) || !belongGroup.colliders.Exists(a => a == leavingCollider))
        {
            current_colliding_objs.Remove(leavingCollider);

            //Leave
            if (eOnColliderLeave != null)
            {
                eOnColliderLeave(leavingCollider);
            }
        }
    }
Exemple #17
0
    void AddCollider(MyCollider collider)
    {
        // add collider to collider list
        m_colliders.Add(collider);
        collider.m_body = this;

        // reset local centroid & mass
        m_localCentroid = Vector3.zero;
        m_mass          = 0.0f;

        // compute local centroid & mass
        foreach (var col in m_colliders)
        {
            // accumulate mass
            m_mass += col.m_mass;

            // accumulate weighted contribution
            m_localCentroid +=
                col.m_mass * col.m_localCentroid;
        }

        // compute inverse mass
        m_inverseMass = 1.0f / m_mass;

        // compute final local centroid
        m_localCentroid *= m_inverseMass;

        // compute local inertia tensor
        localInertiaTensor = Matrix4x4.zero;
        foreach (var col in m_colliders)
        {
            Vector3   r     = m_localCentroid - col.m_localCentroid;
            float     rDotR = Vector3.Dot(r, r);
            Matrix4x4 rOutR = OutProduct(r, r);

            // accumulate local inertia tensor contribution,
            // using Parallel Axis Theorem
            localInertiaTensor =
                Add(localInertiaTensor,
                    Add(col.m_localInertiaTensor,
                        Multiple(
                            Substract(
                                Multiple(Matrix4x4.identity, rDotR), rOutR), col.m_mass)));
        }

        // compute inverse inertia tensor
        m_localInverseInertiaTensor = localInertiaTensor.inverse;
    }
Exemple #18
0
 private void FixedUpdate()
 {
     //iterate through every possible collider pair and check (and then resolve) collision
     for (int i1 = 0; i1 < activeColliders.Length; i1++)
     {
         MyCollider c1 = activeColliders[i1];
         for (int i2 = i1 + 1; i2 < activeColliders.Length; i2++)
         {
             MyCollider c2 = activeColliders[i2];
             if (CheckForIntersectionBetween(c1, c2))
             {
                 Debug.Log(c1 + " is intersecting with " + c2);
                 ResolveCollisionFor(c1, c2);
             }
         }
     }
 }
    private void Update()
    {
        MyCollider groundCollider = PhysicsManager.DetectCollisionFromLayer(sphereCollider, GROUND_LAYER);

        if (groundCollider)
        {
            if (speed.y < 0)// Prevents the ball from sticking to the ground
            {
                NotifyCollisionBetweenObjects(gameObject, groundCollider.gameObject);
                UpdateBallSpeedOnGroundCollision();
            }

            MyCollider colorGiverCollider = PhysicsManager.DetectCollisionFromLayer(sphereCollider, COLOR_GIVER_LAYER);
            if (colorGiverCollider)
            {
                NotifyCollisionBetweenObjects(gameObject, colorGiverCollider.gameObject);
                UpdateBallColorOnColorGiverCollision(colorGiverCollider);
            }
        }

        UpdateBallSpeed();
    }
Exemple #20
0
    public static MyCollider DetectCollisionFromLayer(MyCollider collider, int layerMask)
    {
        if (collider == null || instance == null)
        {
            return(null);
        }

        foreach (MyCollider otherCollider in instance.registeredColliders)
        {
            if (otherCollider.gameObject.layer != layerMask || otherCollider == collider)
            {
                continue;
            }

            if (collider.DetectCollisionWithCollider(otherCollider))
            {
                return(otherCollider);
            }
        }

        return(null);
    }
Exemple #21
0
    public bool CheckIsInsideBoundsCircle(Vector2 center, Vector2 radious, MyCollider c)
    {
        //AABB檢測
        // Rect1
        float minX1 = center.x - radious.x;
        float maxX1 = center.x + radious.x;
        float minY1 = center.y - radious.y;
        float maxY1 = center.y + radious.y;
        // Rect2
        float minX2 = c.spr.bounds.center.x - c.spr.bounds.extents.x;
        float maxX2 = c.spr.bounds.center.x + c.spr.bounds.extents.x;
        float minY2 = c.spr.bounds.center.y - c.spr.bounds.extents.y;
        float maxY2 = c.spr.bounds.center.y + c.spr.bounds.extents.y;

        if (maxX1 > minX2 && maxX2 > minX1 &&
            maxY1 > minY2 && maxY2 > minY1)
        {
            return(true);
        }
        else
        {
            return(false);
        }
    }
Exemple #22
0
    public override bool isColliding(MyCollider _other)
    {
        if (_other == null)
        {
            return(false);
        }
        if (_other is MyCircleCollider)
        {
            MyCircleCollider other    = (MyCircleCollider)_other;
            float            distance = (other.Position - this.Position).sqrMagnitude;
            float            radii    = other.m_radius * other.transform.lossyScale.x + this.m_radius * other.transform.lossyScale.x;

            return(distance < (radii * radii));
        }
        else if (_other is MyBox2DCollider)
        {
            MyBox2DCollider other        = (MyBox2DCollider)_other;
            Vector3         closestPoint = other.GetClosestPoint(Position);
            float           distance     = Vector3.SqrMagnitude(closestPoint - Position);

            return(distance < (Radius * Radius));
        }
        return(base.isColliding(_other));
    }
Exemple #23
0
    ///<summary>若from組轉移後剩0個collider會自動刪掉</summary>
    public void TransferGroup(ColliderGroup from, ColliderGroup to, MyCollider collider)
    {
        if (!colliderGroups.Contains(to))
        {
            colliderGroups.Add(to);
        }
        if (to.colliders.Contains(collider))
        {
            return;
        }

        //若轉移目標group太多物件了 就踢掉一個叫它自創
        if (to.colliders.Count > group_max_colliders)
        {
            ColliderGroup newto = new ColliderGroup();
            TransferGroup(to, newto, to.colliders[0]);

            return;
        }

        //轉移
        from.colliders.Remove(collider);
        collider.belongGroup = to;
        to.colliders.Add(collider);


        to.UpdateCenter();
        if (from.colliders.Count < 1)
        {
            colliderGroups.Remove(from);
        }
        else
        {
            from.UpdateCenter();
        }
    }
        public void WriteXml(System.Xml.XmlWriter writer)
        {
            writer.WriteElementString("UniqueID", UniqueID.ToString());
            writer.WriteElementString("Name", Name);
            writer.WriteElementString("DrawLast", XmlConvert.ToString(DrawLast));

            writer.WriteStartElement("Tags");
            if (Tags != null && Tags.Count > 0)
            {
                foreach (string tag in Tags)
                {
                    writer.WriteElementString("Tag", tag);
                }
            }
            else if (Tags == null || Tags.Count == 0)
            {
                writer.WriteElementString("Tag", "null");
            }
            writer.WriteEndElement();

            writer.WriteElementString("Dynamic", XmlConvert.ToString(Dynamic));

            if (MyTransform != null)
            {
                writer.WriteStartElement("MyTransform");
                (MyTransform as IXmlSerializable).WriteXml(writer);
                writer.WriteEndElement();
            }

            if (MyPhysicalObject != null)
            {
                writer.WriteStartElement("MyPhysicalObject");
                (MyPhysicalObject as IXmlSerializable).WriteXml(writer);
                writer.WriteEndElement();
            }

            if (MyAnimator != null)
            {
                writer.WriteStartElement("MyAnimator");
                writer.WriteElementString("BaseAnim", ResourceManager.Instance.Models.FirstOrDefault(x => x.Value == MyAnimator.BaseAnim).Key);
                (MyAnimator as IXmlSerializable).WriteXml(writer);
                foreach (KeyValuePair <string, SkinningModelLibrary.AnimationPlayer> pair in MyAnimator.animationPlayers)
                {
                    writer.WriteElementString("AnimatorClip", pair.Key);
                }
                writer.WriteEndElement();
            }

            if (Components.Count != 0)
            {
                writer.WriteStartElement("Components");
                foreach (ObjectComponent comp in Components)
                {
                    if (comp != null)
                    {
                        writer.WriteStartElement(comp.GetType().ToString());
                        (comp as IXmlSerializable).WriteXml(writer);
                        writer.WriteEndElement();
                    }
                }
                writer.WriteEndElement();
            }

            if (MyCollider != null)
            {
                writer.WriteStartElement("MyCollider");
                writer.WriteElementString("Type", MyCollider.GetType().ToString());
                (MyCollider as IXmlSerializable).WriteXml(writer);
                writer.WriteEndElement();
            }
        }
Exemple #25
0
 public override MyContactPoint GenerateContactPoint(MyCollider _other)
 {
     if (_other == null)
     {
         return(default);
    public override bool isColliding(MyCollider _other)
    {
        if (_other == null)
        {
            return(false);
        }
        if (_other is MyBoxCollider)
        {
            MyBoxCollider other = (MyBoxCollider)_other;

            Vector3[] mySegment = new Vector3[]
            {
                m_cubeCorners[4] - m_cubeCorners[0],
                m_cubeCorners[3] - m_cubeCorners[0],
                m_cubeCorners[1] - m_cubeCorners[0],
            };

            Vector3[] otherSegments = new Vector3[]
            {
                other.m_cubeCorners[4] - other.m_cubeCorners[0],
                other.m_cubeCorners[3] - other.m_cubeCorners[0],
                other.m_cubeCorners[1] - other.m_cubeCorners[0],
            };

            Vector3[] potentialSeperatingAxis = new Vector3[]
            {
                Vector3.Cross(mySegment[0], mySegment[1]),
                Vector3.Cross(mySegment[0], mySegment[2]),
                Vector3.Cross(mySegment[1], mySegment[2]),

                Vector3.Cross(mySegment[0], mySegment[1]),
                Vector3.Cross(mySegment[0], mySegment[2]),
                Vector3.Cross(mySegment[1], mySegment[2]),

                Vector3.Cross(mySegment[0], mySegment[0]),
                Vector3.Cross(mySegment[0], mySegment[1]),
                Vector3.Cross(mySegment[0], mySegment[2]),
                Vector3.Cross(mySegment[1], mySegment[0]),
                Vector3.Cross(mySegment[1], mySegment[1]),
                Vector3.Cross(mySegment[1], mySegment[2]),
                Vector3.Cross(mySegment[1], mySegment[0]),
                Vector3.Cross(mySegment[1], mySegment[1]),
                Vector3.Cross(mySegment[1], mySegment[2]),
            };

            Vector3 normalizedAxis;
            float   min1, max1, min2, max2;
            float   tmp;
            foreach (Vector3 axis in potentialSeperatingAxis)
            {
                if (axis.sqrMagnitude == 0)
                {
                    continue;
                }
                normalizedAxis = axis.normalized;

                min1 = float.PositiveInfinity;
                max1 = float.NegativeInfinity;

                for (int i = 0; i < this.m_cubeCorners.Length; i++)
                {
                    tmp = Vector3.Dot(normalizedAxis, this.m_cubeCorners[i]);
                    if (tmp < min1)
                    {
                        min1 = tmp;
                    }
                    if (tmp > max1)
                    {
                        max1 = tmp;
                    }
                }
                min2 = float.PositiveInfinity;
                max2 = float.NegativeInfinity;

                for (int i = 0; i < other.m_cubeCorners.Length; i++)
                {
                    tmp = Vector3.Dot(normalizedAxis, this.m_cubeCorners[i]);
                    if (tmp < min2)
                    {
                        min2 = tmp;
                    }
                    if (tmp > max2)
                    {
                        max2 = tmp;
                    }
                }

                if (min1 > min2 && min1 < max2)
                {
                    continue;
                }
                if (max1 > min1 && max1 < max2)
                {
                    continue;
                }

                return(false);
            }

            return(true);
        }
        else if (_other is MySphereCollider)
        {
            this.CalculateCubeCorners();
            MySphereCollider other         = (MySphereCollider)_other;
            Vector3          potentialAxis = this.Position - other.Position;
            potentialAxis = potentialAxis.normalized;

            float min1, max1, min2, max2;

            min1 = float.PositiveInfinity;
            max1 = float.NegativeInfinity;
            float tmp;
            for (int i = 0; i < cubeCorners.Length; i++)
            {
                tmp = Vector3.Dot(potentialAxis, this.m_cubeCorners[i]);
                if (tmp < min1)
                {
                    tmp = min1;
                }
                if (tmp > max1)
                {
                    max1 = tmp;
                }
            }

            min2 = float.PositiveInfinity;
            max2 = float.NegativeInfinity;

            tmp  = Vector3.Dot(potentialAxis, other.Position);
            min2 = tmp - other.ActualRadius;
            max2 = tmp + other.ActualRadius;
            if (min1 > min2 && min1 < max2)
            {
                return(true);
            }
            if (max1 > min2 && max1 < max2)
            {
                return(true);
            }
            return(false);
        }
        return(base.isColliding(_other));
    }
Exemple #27
0
 public static IEnumerable <(MyCollider, Rect)> AllCollisions(MyCollider collider)
 {
     return(AllOverlaps(collider)
            .Where(c => c.Item1 is MyDynamic || c.Item1 is MyStatic));
 }
 private void Start()
 {
     myCollider = GetComponent <MyCollider>();
 }
Exemple #29
0
 public static void RemoveCollider(MyCollider collider)
 {
     instance.registeredColliders.Remove(collider);
 }
Exemple #30
0
 public abstract bool DetectCollisionWithCollider(MyCollider other);