I have a very simple code that draws the shape of a pre-defined capsule. It handles everything well, except the case when the GameObject
to which the CapsuleCollider2D
is attached or any parent GameObject
up the chain have scale set different than 1. The pre-computed matrix with lossyScale
supposedly should take that into account but it does not:
var cap = GetComponent<CapsuleCollider2D>();
// -- basics
var radius = cap.size.x * 0.5f;
var halfH = cap.size.y * 0.5f;
var center = cap.bounds.center;
// -- hemispehre offsets
var upperDiff = Mathf.Clamp(halfH - radius, 0, 999);
var lowerDiff = upperDiff * -1;
// -- matrix that supposedly hould take into account lossy scale
var mtx = Matrix4x4.TRS(cap.bounds.center, cap.transform.rotation, cap.transform.lossyScale);
// -- upper and lower hemisphere "centers"
var upper = mtx.MultiplyPoint3x4(new Vector3(0, upperDiff, 0));
var lower = mtx.MultiplyPoint3x4(new Vector3(0, lowerDiff, 0));
// -- drawing setup
int pts = 80;
float step = 360f / pts;
// -- central shape of the capsule essentially a box, so we find the "box" vertices
var topLeft = mtx.MultiplyPoint3x4(new Vector3(-radius, upperDiff, 0));
var topRight = mtx.MultiplyPoint3x4(new Vector3(radius, upperDiff, 0));
var lowLeft = mtx.MultiplyPoint3x4(new Vector3(-radius, lowerDiff, 0));
var lowRight = mtx.MultiplyPoint3x4(new Vector3(radius, lowerDiff, 0));
// drawing
for (int i = 0; i < pts / 2; i++)
{
// first point
float cx = Mathf.Cos(Mathf.Deg2Rad * step * i) * radius;
float cy = Mathf.Sin(Mathf.Deg2Rad * step * i) * radius;
Vector3 cur = new Vector3(cx, cy);
// next point
float nx = Mathf.Cos(Mathf.Deg2Rad * step * (i + 1)) * radius;
float ny = Mathf.Sin(Mathf.Deg2Rad * step * (i + 1)) * radius;
Vector3 next = new Vector3(nx, ny);
// upper hemisphere
var curUP = mtx.MultiplyPoint3x4(cur + new Vector3(0, upperDiff, 0));
var nextUP = mtx.MultiplyPoint3x4(next + new Vector3(0, upperDiff, 0));
// lower hemisphere
var curDOWN = mtx.MultiplyPoint3x4(new Vector3(0, lowerDiff, 0) - cur);
var nextDOWN = mtx.MultiplyPoint3x4(new Vector3(0, lowerDiff, 0) - next);
// triangle in upper hemisphere
GL.Vertex3(curUP.x, curUP.y, 0);
GL.Vertex3(nextUP.x, nextUP.y, 0);
GL.Vertex3(center.x, center.y, 0);
// triangle in lower
GL.Vertex3(curDOWN.x, curDOWN.y, 0);
GL.Vertex3(nextDOWN.x, nextDOWN.y, 0);
GL.Vertex3(center.x, center.y, 0);
}
GL.Vertex3(topLeft.x, topLeft.y, 0);
GL.Vertex3(lowLeft.x, lowLeft.y, 0);
GL.Vertex3(center.x, center.y, 0);
// --
GL.Vertex3(topRight.x, topRight.y, 0);
GL.Vertex3(lowRight.x, lowRight.y, 0);
GL.Vertex3(center.x, center.y, 0);
Any ideas how can I account for scaling?
https://docs.unity3d.com/ScriptReference/Transform-localToWorldMatrix.html
then yes,TransformPoint
exhibits the same issue). \$\endgroup\$