using UnityEngine; using UnityEngine.UI; using System.Collections.Generic; using System; using ZIM.Unity; using System.Linq; using o0InfraredLocate.ZIM; public class PointMarker : MonoBehaviour { //public Text instructionText; // 用于显示提示文字 [Tooltip("标记页面标题提示")] [SerializeField] TextAutoLanguage2 instructionText; public Button undoButton; // 撤回按钮 public Button completeButton; // 完成按钮 public bool bComplete = false;// 是否完成 public GameObject markerPrefab; // 用于表示标记的UI元素,可能是一个小图标(如枪) // 新增父对象,用于存放标记的物体 public Transform markerParent; // 标记物体的父对象(例如Canvas中的一个空物体) public Image[] hintImages; // 依次存放左上、右上、右下、左下四个提示图片 Vector2 oldPoint = Vector2.zero; private List markedPoints = new List(); // { "左上", "右上", "右下", "左下" } private string[] directions = { "TipTopLeft", "TipTopRight", "TipBottomRight", "TipBottomLeft" }; private int currentPointIndex = 0; // 当前需要标记的点的索引 private List markerObjects = new List(); // 记录标记物体 [SerializeField] InfraredScreenPositioningView infraredScreenPositioningView; [Tooltip("存在校准数据时候显示")] [SerializeField] ZIM.LineGenerator line;//开始显示屏幕线条 void Start() { if (AimHandler.ins) AimHandler.ins.OnCrossBtnEvent += OnRecordInfrared; UpdateInstruction(); undoButton.onClick.AddListener(UndoLastPoint); completeButton.onClick.AddListener(CompletePoint); // 初始化时隐藏完成按钮 bComplete = false; // 初始化时,显示第一个提示图片,其余隐藏 ShowHintImage(0); } void OnDestroy() { if (AimHandler.ins) AimHandler.ins.OnCrossBtnEvent -= OnRecordInfrared; } private float lastClickTime = 0f; private float doubleClickThreshold = 0.3f; // 双击间隔时间,单位:秒 void Update() { if (Input.GetMouseButtonDown(0)) // 检测左键按下 { float currentTime = Time.time; if (currentTime - lastClickTime <= doubleClickThreshold) { // 双击检测成功,执行触发逻辑 if (currentPointIndex >= 4) return; var mouse = Input.mousePosition; var u = mouse.x / Screen.width; var v = mouse.y / Screen.height; u = Math.Clamp(u, 0, 1); v = Math.Clamp(v, 0, 1); Vector2 pos = new Vector2(u * ScreenLocate.Main.getUVCTexture.width, v * ScreenLocate.Main.getUVCTexture.height); //markedPoints.Add(pos); oldPoint = new Vector2(u, v); // 设置标记的位置 MarkPoint(new Vector2(u, v).pixelToLocalPosition_AnchorCenter(new Vector2(1, 1), markerParent.GetComponent().rect)); } lastClickTime = currentTime; // 更新上一次点击时间 } //#if UNITY_EDITOR //if (Input.GetKeyDown(KeyCode.Alpha6) || Input.GetMouseButtonDown(1)) //{ // //Vector2 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); // //MarkPoint(mousePosition); // // OnRecordInfrared(); // if (currentPointIndex >= 4) return; // var mouse = Input.mousePosition; // var u = mouse.x / Screen.width; // var v = mouse.y / Screen.height; // u = Math.Clamp(u, 0, 1); // v = Math.Clamp(v, 0, 1); // Vector2 pos = new Vector2(u * ScreenLocate.Main.getUVCTexture.width, v * ScreenLocate.Main.getUVCTexture.height); // markedPoints.Add(pos); // // 设置标记的位置 // MarkPoint(new Vector2(u, v).pixelToLocalPosition_AnchorCenter(new Vector2(1, 1), markerParent.GetComponent().rect)); //} //#endif } /// /// 记录红外点 /// public void OnRecordInfrared() { if (currentPointIndex >= 4) return; var location = ScreenLocate.Main.infraredSpotBuffer.FirstOrDefault()?.CameraLocation; if (location != null) { oldPoint = location.Value; Vector2 localPosition = location.Value.pixelToLocalPosition_AnchorCenter(ScreenLocate.Main.CameraSize, infraredScreenPositioningView.Bg.rectTransform.rect); //markedPoints.Add(localPosition); MarkPoint(localPosition); } } void MarkPoint(Vector2 point) { if (!infraredScreenPositioningView.IsPointInMaskLine(point)) { Debug.Log("不在梯形内部!"); instructionText.SetTextKey("TipMarkerError"); return; } // 创建标记物体,并将其作为markerParent的子对象 GameObject marker = Instantiate(markerPrefab, markerParent); marker.SetActive(true); marker.transform.localPosition = point; markerObjects.Add(marker); //绘制连线 markedPoints.Add(point); UpdateLine(); // 隐藏当前的提示图片,显示下一个提示图片 currentPointIndex++; ShowHintImage(currentPointIndex); UpdateInstruction(); // 如果已经标记了四个点,显示完成按钮 if (currentPointIndex == 4) { Vector2[] points = { markerObjects[0].transform.localPosition, markerObjects[1].transform.localPosition, markerObjects[2].transform.localPosition, markerObjects[3].transform.localPosition, }; bool result = infraredScreenPositioningView.IsValidQuadrilateral(points); Debug.Log(result ? "是有效的四边形" : "不是有效的四边形"); if (result) { instructionText.SetTextKey("TipMarkComplete"); //PopupMgr.ins.ShowTipTop(TextAutoLanguage2.GetTextByKey("TipMarkComplete")); bComplete = true; } else { //不是有效是四边形时候,回退 一个 //instructionText.SetTextKey("TipMarkerError"); PopupMgr.ins.ShowTipTop(TextAutoLanguage2.GetTextByKey("TipQuadError")); UndoLastPoint(); } } } void UndoLastPoint() { if (currentPointIndex > 0) { // 移除最后一个标记的点 markedPoints.RemoveAt(markedPoints.Count - 1); UpdateLine(); // 删除最后一个标记的物体 Destroy(markerObjects[markerObjects.Count - 1]); markerObjects.RemoveAt(markerObjects.Count - 1); // 回退到上一个提示图片 currentPointIndex--; ShowHintImage(currentPointIndex); UpdateInstruction(); } // 隐藏完成按钮 bComplete = false; } /// /// 移除全部标记,选择自动和半自动数据界面返回时候调用 /// public void UndoAllPoints() { // 移除所有标记物体 foreach (var marker in markerObjects) { Destroy(marker); } markerObjects.Clear(); markedPoints.Clear(); UpdateLine(); // 重置索引 currentPointIndex = 0; // 更新提示图片和说明 ShowHintImage(currentPointIndex); UpdateInstruction(); // 隐藏完成按钮 bComplete = false; } void UpdateLine() { if (line.gameObject.activeSelf) { RectTransform rectTransform = markerParent as RectTransform; Vector2 pivot = rectTransform.pivot; // 获取父物体的 pivot 值 Vector2 texSize = rectTransform.rect.size; line.Points = InfraredDemo._ins.ConvertPointsToCoordinates(markedPoints.ToArray(), texSize, pivot); } } void UpdateInstruction() { if (currentPointIndex < 4) { instructionText.textFormatArgs = new object[] { TextAutoLanguage2.GetTextByKey(directions[currentPointIndex]) }; instructionText.SetTextKey("TipMiddle"); } } // 显示当前需要的提示图片,并隐藏其余提示图片 void ShowHintImage(int index) { for (int i = 0; i < hintImages.Length; i++) { if (i == index) hintImages[i].gameObject.SetActive(true); else hintImages[i].gameObject.SetActive(false); } } /// /// 如果没有数据时候,可能需要隐藏渲染 /// /// public void ShowHintImageParent(bool bShow) { for (int i = 0; i < hintImages.Length; i++) { hintImages[i].transform.parent.gameObject.SetActive(bShow); } } void CompletePoint() { if (!bComplete) { //Debug.Log("未完成"); //todo,加提示 PopupMgr.ins.ShowTipTop(TextAutoLanguage2.GetTextByKey("Incomplete")); return; } //完成,下一步 for (int i = 0; i < 4; i++) { int index = i; infraredScreenPositioningView.onManualNewPos(3 - index, markerObjects[index].transform.localPosition); } infraredScreenPositioningView.onFinishManualToAutomatic(); ////清空数据 //currentPointIndex = 0; ////清空生成的数据 //markerObjects.Clear(); //foreach (Transform i in markerParent.transform) // Destroy(i.gameObject); } }