Files
SHI-Cesium/Assets/Scripts/MeasureManager.cs
2025-09-17 15:57:26 +09:00

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;
}
}