- Home /
RigidBody2D trap inside a circle
I'm trying to trap objects (with RigidBody2D) inside a circle and use the object's physics material to calculate bouncing/friction with the circle's border.. Yet I can't figure out how to get less of a bouncy effect but something that transfers the velocity into velocity along the surface (that takes into account this friction/bounciness).
This is basically my current solution:
// offset = vector from center to current position
// distanceSqr = distance from center squared
// radius = radius of the sphere object is trapped in.
if (distanceSqr > radius * radius)
{
// Reflect only if velocity is outwards
float dot = Vector2.Dot(offset.normalized, m_rigidBody.velocity.normalized);
if (dot > 0.0f)
{
// Reflect (Bounce)
m_rigidBody.velocity = Vector3.Reflect(m_rigidBody.velocity, -offset.normalized);
// Drag
m_rigidBody.velocity = m_rigidBody.velocity * (1.0f - (drag));
}
// Trap Position inside
m_transform.position = center + (offset.normalized * radius); // maximum distance (trap inside)
}
Another thing I've tried is to remove all outwards velocity of the rigidBody. But as long as it moves slightly to the side it comes to a halt very quickly because then it removes the upwards vector in sublty different directions and rather soon it removed all of it. :)
Is there a way to figure out how to calculate a similar resulting velocity vector as it would've had if moved up against a point with a normal of an object (which is the information I have) of a regular RigidBody2D object?
I would love to be able to control the friction and bounciness just like with the Physics2d Material.
(Pointers on how this works in 3D space to calculate it nicely would - I think - also be good enough to point me in the direction of how to solve this)
Answer by BigRoy · Apr 09, 2014 at 08:49 PM
So I've found a workaround that works very nicely. :)
Instead of figuring out my own physics I wanted to rather rely mostly on the PhysX engine that is already implemented in Unity (so it works with basically all of rigidBody stuff I throw at it).
The solution I thought of was using the EdgeCollider2D that just has points laid out in a circular fashion! And it seems to work beautifully.
For anyone else that wants to do something similar and needs a high quality one here's a small script I quickly put together. It's an editor script that creates a small window that allows you to apply/set EdgeCollider2D to selected gameObjects where it lays out the points automatically in a circular fashion. :) The window allows you to set how many vertices you want to have in the final circle.
using UnityEditor;
using UnityEngine;
public class CircleEdgeCollider : EditorWindow
{
float radius = 1.0f;
int vertices = 30;
[MenuItem("Scripts/Colliders/CircleEdgeCollider")]
public static void ShowWindow()
{
//Show existing window instance. If one doesn't exist, make one.
EditorWindow.GetWindow(typeof(CircleEdgeCollider));
}
void OnGUI()
{
radius = EditorGUILayout.FloatField("Radius", radius);
vertices = EditorGUILayout.IntField("Vertices", vertices);
if (GUILayout.Button("Add CircleEdgeCollider")) this.AddCircleEdgeCollider();
}
void AddCircleEdgeCollider()
{
// Get selection
GameObject[] sel;
sel = Selection.gameObjects;
if (sel.Length == 0) return;
if (vertices < 2){
Debug.LogError("Can't create a circle edge collider with less than 2 points.");
return;
}
// Create list of points
Vector2[] pts = new Vector2[vertices];
for(int i=0; i<vertices; i++)
{
// Points on a circle
Vector2 pt;
pt.x = Mathf.Cos((i / ((float)vertices - 1.0f)) * (2f * Mathf.PI)) * radius;
pt.y = Mathf.Sin((i / ((float)vertices - 1.0f)) * (2f * Mathf.PI)) * radius;
pts[i] = pt;
}
GameObject obj;
for (int i = 0; i < sel.Length; i++)
{
obj = sel[i];
Debug.Log(obj.name);
EdgeCollider2D coll = obj.GetComponent<EdgeCollider2D>();
if (coll == null)
{
coll = obj.AddComponent<EdgeCollider2D>();
}
coll.points = pts;
}
}
}
Oh yeah, this is my first ever Editor script. ;) But I hope this workaround can be useful to someone else as well.
Your answer
Follow this Question
Related Questions
Re-Creating Unity's Friction and Bounce 0 Answers
Why Rigidbody collide with wall passes through partially? 0 Answers
How to have a sphere roll/be affected by friction 0 Answers
Disable bouncing effect 0 Answers