163 lines
4.4 KiB
C#
163 lines
4.4 KiB
C#
using System.Collections.Generic;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
|
|
public enum MeasureMode
|
|
{
|
|
None,
|
|
Line,
|
|
Rectangle,
|
|
Polygon,
|
|
Circle
|
|
}
|
|
|
|
public class MeasureManager : MonoBehaviour
|
|
{
|
|
private Camera cam;
|
|
|
|
[SerializeField] private GameObject distanceLabelPrefab;
|
|
[SerializeField] private GameObject deleteButtonPrefab;
|
|
[SerializeField] private GameObject lineInfoPrefab;
|
|
[SerializeField] private GameObject polygonInfoPrefab;
|
|
[SerializeField] private GameObject circleInfoPrefab;
|
|
|
|
[SerializeField] private RectTransform labelRoot;
|
|
[SerializeField] private RectTransform infoPopupRoot;
|
|
[SerializeField] private Transform measureGroupRoot;
|
|
|
|
[SerializeField] private Material lineMaterial;
|
|
|
|
private MeasureGroup currentGroup;
|
|
private List<MeasureGroup> groups = new List<MeasureGroup>();
|
|
|
|
private float scaleMultiplier = 0.1f;
|
|
private float lineWidth = 0.02f;
|
|
public bool isMeasuring = false;
|
|
|
|
public MeasureMode currentMeasureMode = MeasureMode.None;
|
|
|
|
private void Awake()
|
|
{
|
|
cam = Camera.main;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (Input.GetMouseButtonDown(0) && TryGetClickPosition(out Vector3 hitPos))
|
|
{
|
|
if (EventSystem.current != null && EventSystem.current.IsPointerOverGameObject())
|
|
return;
|
|
|
|
if (!isMeasuring)
|
|
{
|
|
CreateMeasureGroup();
|
|
}
|
|
currentGroup.AddPoint(hitPos);
|
|
}
|
|
|
|
if (Input.GetMouseButtonDown(1))
|
|
{
|
|
if (isMeasuring)
|
|
{
|
|
currentGroup.EndMeasure();
|
|
isMeasuring = false;
|
|
}
|
|
}
|
|
|
|
if (Input.GetKeyDown(KeyCode.Escape)) // Test
|
|
{
|
|
ResetAll();
|
|
}
|
|
|
|
if (isMeasuring && currentGroup != null)
|
|
{
|
|
if (TryGetClickPosition(out Vector3 mousePos))
|
|
{
|
|
currentGroup.UpdatePreviewLine(mousePos);
|
|
if (currentGroup is LineMeasureGroup lineGroup)
|
|
{
|
|
lineGroup.UpdateInfoPopupPos(mousePos);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void CreateMeasureGroup()
|
|
{
|
|
MeasureGroup group = null;
|
|
Color color = Color.white;
|
|
|
|
switch (currentMeasureMode)
|
|
{
|
|
case MeasureMode.Line:
|
|
group = new GameObject("LineMeasureGroup").AddComponent<LineMeasureGroup>();
|
|
color = Color.white;
|
|
break;
|
|
case MeasureMode.Rectangle:
|
|
group = new GameObject("RectangleMeasureGroup").AddComponent<RectangleMeasureGroup>();
|
|
color = Color.red;
|
|
break;
|
|
case MeasureMode.Polygon:
|
|
group = new GameObject("PolygonMeasureGroup").AddComponent<PolygonMeasureGroup>();
|
|
color = Color.yellow;
|
|
break;
|
|
case MeasureMode.Circle:
|
|
group = new GameObject("CircleMeasureGroup").AddComponent<CircleMeasureGroup>();
|
|
color = Color.green;
|
|
break;
|
|
case MeasureMode.None:
|
|
return;
|
|
}
|
|
|
|
LineRenderer line = group.gameObject.AddComponent<LineRenderer>();
|
|
line.material = lineMaterial;
|
|
line.widthMultiplier = lineWidth;
|
|
line.positionCount = 0;
|
|
line.useWorldSpace = true;
|
|
line.startColor = color;
|
|
line.endColor = color;
|
|
|
|
group.Init(
|
|
line,
|
|
distanceLabelPrefab,
|
|
deleteButtonPrefab,
|
|
lineInfoPrefab,
|
|
polygonInfoPrefab,
|
|
circleInfoPrefab,
|
|
labelRoot,
|
|
infoPopupRoot,
|
|
scaleMultiplier,
|
|
lineWidth,
|
|
lineMaterial);
|
|
|
|
currentGroup = group;
|
|
groups.Add(group);
|
|
group.transform.SetParent(measureGroupRoot);
|
|
isMeasuring = true;
|
|
}
|
|
|
|
private void ResetAll()
|
|
{
|
|
foreach (LineMeasureGroup g in groups)
|
|
{
|
|
g.DestroyAll();
|
|
}
|
|
|
|
groups.Clear();
|
|
isMeasuring = false;
|
|
}
|
|
|
|
private bool TryGetClickPosition(out Vector3 hitPos)
|
|
{
|
|
hitPos = Vector3.zero;
|
|
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
|
|
if (Physics.Raycast(ray, out RaycastHit hit))
|
|
{
|
|
hitPos = hit.point;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|