Всем привет. Хочу сделать окно в котором можно было бы рисовать. Это gameobject который лежит под канвасом и имеет определенную высоту и ширину. Проблема в методе GetConvertedClampedValue. Линия ресуется выше справа от точки соприкосновения. Изначально я пробовал никак не конвертировать eventdata.position, так как она в пикселях, что и нужно для DrawLineVertices. Но получается то же самое. Как это фиксануть ?
[RequireComponent(typeof(CanvasRenderer))]
public class NewDrawCanvas : Graphic, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler, IDragHandler
{
[SerializeField] private bool _isActiveDrawLine = true;
[SerializeField] private float _lineWidth = 20f;
[SerializeField] private float _vertDistanceScale = 0.25f;
[SerializeField] private float _minVertDistance = 0.15f;
private bool _isDrawLine;
private bool _isInsideDrawPanel;
private List<Vector2> _linePointPositions;
private RectTransform _rectTransform;
private Canvas _canvas;
private Rect _canvasRect;
public event Action StartDraw;
public event Action EndDrawLine;
protected override void Awake()
{
base.Awake();
_linePointPositions = new List<Vector2>();
_rectTransform = GetComponent<RectTransform>();
_canvas = GetComponentInParent<Canvas>();
_canvasRect = RectTransformUtility.PixelAdjustRect(_canvas.GetComponent<RectTransform>(), _canvas);
}
public void OnPointerDown(PointerEventData eventData)
{
_isDrawLine = true;
}
public void OnPointerUp(PointerEventData eventData)
{
_isDrawLine = false;
EndLine();
}
public void OnPointerEnter(PointerEventData eventData)
{
_isInsideDrawPanel = true;
}
public void OnPointerExit(PointerEventData eventData)
{
_isInsideDrawPanel = false;
}
public void OnDrag(PointerEventData eventData)
{
var input = eventData.position;
if (!_isDrawLine && !_isInsideDrawPanel)
{
return;
}
if (_linePointPositions.Count == 0)
{
StartDraw?.Invoke();
AddLineVert(input);
}
var lastPoint = GetConvertedClampedValue(_linePointPositions[^1]);
var currentPoint = GetConvertedClampedValue(input);
lastPoint *= _vertDistanceScale;
currentPoint *= _vertDistanceScale;
if ((lastPoint - currentPoint).magnitude >= _minVertDistance * _vertDistanceScale)
{
AddLineVert(input);
}
}
private void AddLineVert(Vector2 pos)
{
_linePointPositions.Add(pos);
SetVerticesDirty();
}
private Vector2 GetConvertedClampedValue (Vector3 posPassed)
{
return new Vector2((((posPassed.x - _rectTransform.position.x) / Screen.width) * _canvasRect.width),
(((posPassed.y - _rectTransform.position.y) / Screen.height) * _canvasRect.height));
}
private void EndLine()
{
_linePointPositions.Clear();
SetVerticesDirty();
}
private float GetRelativeAngle (Vector2 v , Vector2 vt)
{
return Mathf.Atan2(vt.y - v.y , vt.x - v.x) * (180.0f/Mathf.PI) + 45.0f;
}
private void DrawLineVertices (Vector2 point , VertexHelper vh , float angle)
{
UIVertex vertex = UIVertex.simpleVert;
vertex.color = color;
//Right
vertex.position = Quaternion.Euler(0,0,angle) * new Vector3(-_lineWidth/2.0f , 0.0f);
vertex.position += new Vector3(point.x , point.y);
vh.AddVert(vertex);
//Left
vertex.position = Quaternion.Euler(0,0,angle) * new Vector3(_lineWidth/2.0f , 0.0f);
vertex.position += new Vector3(point.x , point.y);
vh.AddVert(vertex);
}
protected override void OnPopulateMesh(VertexHelper vh)
{
vh.Clear();
if (_linePointPositions.Count < 2)
{
return;
}
//Draw verticies
float gotAngle = 0;
for (var i =0; i < _linePointPositions.Count; i++)
{
if (i < _linePointPositions.Count -1)
{
gotAngle = GetRelativeAngle(_linePointPositions[i],_linePointPositions[i+1]);
}
DrawLineVertices(_linePointPositions[i] , vh , gotAngle);
}
//Draw triangles
for (var i = 0; i < _linePointPositions.Count -1; i++)
{
var index = i * 2;
vh.AddTriangle(index,index+1,index+3);
vh.AddTriangle(index +3,index+2,index);
}
}
}