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); } }
//檢查移動後的物體是否還在該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; } }
//檢查碰撞 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)); }
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)); }
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"); }
public static void Disable(MyCollider collider) { allColliders.Remove(collider); foreach (var other in collider.touching) { other.touching.Remove(collider); } collider.touching.Clear(); }
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; } }
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"); } }
public override bool DetectCollisionWithCollider(MyCollider other) { if (other is MySphereCollider) { return(PhysicsManager.OverlapSphereBox((MySphereCollider)other, this)); } else { return(false); } }
private void Update() { if (MyCollider.IsTouching(PlayerM70.GroundCollider)) { StartCoroutine(SplashWater()); } else if (MyCollider.IsTouching(PlayerM70.BiteCollider)) { StartCoroutine(HitPlayer()); } }
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); } } }
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; }
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(); }
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); }
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); } }
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)); }
///<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(); } }
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)); }
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>(); }
public static void RemoveCollider(MyCollider collider) { instance.registeredColliders.Remove(collider); }
public abstract bool DetectCollisionWithCollider(MyCollider other);