- Home /
Given a position, how do I figure out Pixel's Per Unit?
I have a custom editor for my scene which demonstrates the playable radius (how close my game ships will get to an object before slowing. The problem is that the circle draws a single line, and I want it a little thicker, say 3 pixels wide.
I can set that with this for now:
Handles.DrawWireDisc(transform.position, Vector3.up, Radius);
Handles.DrawWireDisc(transform.position, Vector3.up, Radius-.05f);
Handles.DrawWireDisc(transform.position, Vector3.up, Radius-.1f);
But if I zoom in or out, then the lines become just 1 line, or spread apart, loosing the effect. I'm looking for away to guarantee the next radius will be 1 pixel out.
Answer by andrew-lukasik · Oct 20, 2018 at 12:00 AM
Not pixel perfect but does the job (keeps constant size):
using System.Collections.Generic;
using UnityEngine;
public class GlGizmo : MonoBehaviour
{
[SerializeField][Range(3,32)] int _lineCount = 12;
[SerializeField][Range(0.001f,100f)] float _radius = 1.5f;
[SerializeField][Range(0.001f,1f)] float _unitWidth = 0.1f;//width when distance to camera is 1.0
void OnDrawGizmos ()
{
System.Func<int,int,Vector3> CalcPoint = ( i , max ) =>
{
float f = i / (float)max;
float angle = f * Mathf.PI * 2;
return new Vector3( Mathf.Cos(angle)*_radius , Mathf.Sin(angle)*_radius );
};
float dist = Vector3.Distance( Camera.current.transform.position , transform.position );
GL.PushMatrix();
GL.MultMatrix( transform.localToWorldMatrix );
( new Material( Shader.Find("Sprites/Default") ) ).SetPass(0);//replace material to customize render style
GL.Begin( GL.QUADS );
{
//set color:
GL.Color( Color.white );
//warm up:
{
Vector3 A0 = CalcPoint( 0 , _lineCount );
Vector3 B0 = A0 + A0.normalized*_unitWidth*dist;
GL.Vertex( A0 );
GL.Vertex( B0 );
}
//segments:
for( int i=1 ; i<=_lineCount ; i++ )
{
Vector3 A = CalcPoint( i , _lineCount );
Vector3 B = A + A.normalized*_unitWidth*dist;
if( i%2==0 )//even
{
//end started quad:
GL.Vertex( A );
GL.Vertex( B );
//start new quad
GL.Vertex( A );
GL.Vertex( B );
}
else//odd
{
//end started quad:
GL.Vertex( B );
GL.Vertex( A );
//start new quad
GL.Vertex( B );
GL.Vertex( A );
}
}
}
GL.End();
GL.PopMatrix();
}
}
As a bonus, you can customize it more, for example, adding gradients and what not
Whatever drawing concept one uses, core of this consists of just linear proportion:
unit value * distance to camera
Note: To add precision, distance can be calculated not once (for circle center) but for every vertex pair A-B.
Your answer
![](https://koobas.hobune.stream/wayback/20220612180544im_/https://answers.unity.com/themes/thub/images/avi.jpg)