- Home /
Best solution for making arc collider
I'm making a game where I need to have multiple "arc" colliders on a parent ring that has a rigidbody, if the ring is rotated all the arcs should move as well, but the arcs can also be destroyed separately (in fact they are only deactivated for efficiency reasons).
I tried using edge collider 2d for making the arc but it seems to be problematic since points of the edge need to be reasonably big to cover the whole arc and this will cause the points on the outer edge of the arc to also cover a bit of area outside the arc, making the collider somewhat inaccurate.
It's easy to make a pretty accurate arc by having one arc object as a child of the ring, and having multiple children of this arc that only have a box collider. There seems to be some problems with this too, though. Sometimes when player object (a ball) hits the arc, arc gets deactivated as it's supposed to be, but player continues through it instead of bouncing. I'm not sure what exactly causes this behaviour but I suspect it might be the player hitting multiple colliders on same frame. Does anyone have a better theory?
Is there a way to have collider that's similar to multiple box colliders, but using only one collider? I considered mesh, but for certain reasons the rigidbody on the ring shouldn't be kinematic, and there's a problem with that and non-convex mesh collider. Can anyone suggest a smarter way for making accurate arc collider?
Did you find any solution? I created an editor script that creates box colliders in circle which approximates arch colliders. Here I can share it:
using UnityEditor;
using UnityEngine;
public class ArcColliderCreatorWindow : EditorWindow
{
public float Radius;
public float SegSize = .25f;
public int Layer;
public string Tag;
public Physic$$anonymous$$aterial Physic$$anonymous$$aterial;
[$$anonymous$$enuItem("Tools/ArcColliderCreator")]
public static void ShowWindow()
{
EditorWindow.GetWindow(typeof(ArcColliderCreatorWindow));
}
void OnGUI()
{
if (!Selection.activeGameObject)
return;
var selectedTransform = Selection.activeGameObject.transform;
Radius = EditorGUILayout.FloatField("CircleRadius", Radius);
SegSize = EditorGUILayout.FloatField("SegmentSize", SegSize);
Layer = EditorGUILayout.LayerField("Layer", Layer);
Tag = EditorGUILayout.TagField("Tag", Tag);
Physic$$anonymous$$aterial = (Physic$$anonymous$$aterial)EditorGUILayout.ObjectField("Physic$$anonymous$$aterial", Physic$$anonymous$$aterial, typeof(Physic$$anonymous$$aterial), false);
if (GUILayout.Button("Create"))
{
int created = 0;
var c = Radius * 2 * $$anonymous$$athf.PI;
float angleChange = 90 / ((c / 4) / SegSize);
float angle = 0;
float x = 0;
float z = 0;
do
{
var go = GameObject.CreatePrimitive(PrimitiveType.Cube);
created++;
go.GetComponent<$$anonymous$$eshRenderer>().enabled = false;
go.name = "ArcSeg";
go.transform.SetParent(selectedTransform);
go.transform.localScale = new Vector3(SegSize, 1, SegSize);
x = Radius * $$anonymous$$athf.Cos(angle);
z = Radius * $$anonymous$$athf.Sin(angle);
go.layer = Layer;
go.tag = Tag;
go.GetComponent<BoxCollider>().material = Physic$$anonymous$$aterial;
go.transform.localPosition = new Vector3(x, 0, z);
go.transform.LookAt(selectedTransform.position);
angle += angleChange * $$anonymous$$athf.Deg2Rad;
}
while (angle < 90 * $$anonymous$$athf.Deg2Rad);
Debug.Log("Created " + created);
}
if (GUILayout.Button("Delete"))
{
for (int i = selectedTransform.childCount - 1; i >= 0; i--)
{
DestroyImmediate(selectedTransform.GetChild(i).gameObject);
}
}
}
}
Your answer
Follow this Question
Related Questions
Can I make mass and density constant independent of Collider 2D size? 1 Answer
How do I get collisions between Tilemap Collider 2d and a Kinematic Rigidbody 2d? 1 Answer
Detect onMouseDown() on children colliders of a rigidbody parent 2 Answers
(2D) Can't use colliders when I have a kinematic rigidbody? 1 Answer