using Newtonsoft.Json; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.UI.Extensions; public class WallPoint : MonoBehaviour, IWallSelection { private List _wallLines = new(); private RectTransform _rectTransform; private bool _isDragging; private bool _startedDragging; [SerializeField] private Color _defaultColor; [SerializeField] private Color _hoverColor; [SerializeField] private Color _selectionColor; public float _PointHeight; public bool HasAwaken { get; private set; } public void Awake() { if (HasAwaken) { return; } HasAwaken = true; _rectTransform = GetComponent(); } public List GetWalls() { return _wallLines; } public void SetPositionAtPointer() // TODO : use state machine to disable drag when not appropriate { if (_isDragging) { Debug.Log($"{this.name} is moving"); WallSnap.TrySnap(WallCreationManager.GetMousePositionOnScreen(), _rectTransform, out Vector2 toPosition, out RectTransform onSnapTransform); SetAnchoredPosition(toPosition); //SetColorOnEvent(Color.green); UpdateWalls(); WallCreationManager.AddMeasure(); } } public Vector2 GetAnchoredPosition() { return _rectTransform.anchoredPosition; } public Vector2 GetWorldPosition() { return GetAnchoredPosition() / WallLine.RatioWorldToScreen; } public Vector3 GetWorldPositionFlat() { Vector2 worldPositon = GetWorldPosition(); return new(worldPositon.x, 0, worldPositon.y); } public void SetAnchoredPosition(Vector2 position) { _rectTransform.anchoredPosition = position; } public void TryAddWall(WallLine wallLine) { if (_wallLines.Contains(wallLine)) { return; } _wallLines.Add(wallLine); } public void TryRemoveWall(WallLine wallLine) { if (!_wallLines.Contains(wallLine)) { return; } _wallLines.Remove(wallLine); if (_wallLines.Count == 0) { DestroyPoint(); } } public void DestroyPoint() { _wallLines.Clear(); //transform.SetParent(WallCreationManager.GetDeletionContainer()); Destroy(gameObject); WallCreationManager.HideMeasureInteriorWall(); } public void MergeWithPointInRange() { if (_startedDragging) { _startedDragging = false; if (WallSnap.TrySnap(WallCreationManager.GetMousePositionOnScreen(), _rectTransform, out Vector2 toPosition, out RectTransform onSnapTransform) && onSnapTransform != null) { if (onSnapTransform.TryGetComponent(out WallPoint snappedWallPoint)) { MergeWithPoint(snappedWallPoint); } else if (onSnapTransform.TryGetComponent(out WallLine snappedWallLine)) { MergeWithWall(snappedWallLine); } } } } public void MergeWithPoint(WallPoint wallPoint) { // replace all reference of THIS in for the new one in walls (and other places) // update/dirty them foreach (WallLine wallLine in _wallLines) { if (wallLine._pointStart == this) { wallLine.InitPoints(wallPoint, wallLine._pointEnd); } else { wallLine.InitPoints(wallLine._pointStart, wallPoint); } wallLine.ValidateWall(); } // check for unique walls after all walls changed List uniqueWallKeys = new(); List mergePointWalls = wallPoint.GetWalls().GetRange(0, wallPoint.GetWalls().Count); foreach (WallLine item in mergePointWalls) { int idStart = item._pointStart.GetInstanceID(); int idEnd = item._pointEnd.GetInstanceID(); string key = idStart > idEnd ? $"{idStart},{idEnd}" : $"{idEnd},{idStart}"; if (uniqueWallKeys.Contains(key)) { item.DestroyWall(); } else { uniqueWallKeys.Add(key); } } // destroy point and clean up DestroyPoint(); uniqueWallKeys.Clear(); mergePointWalls.Clear(); } public void UpdateWalls() { UpdateWalls(null); } public void UpdateWalls(WallLine ignoreWall) { foreach (WallLine item in _wallLines) { if (item == ignoreWall) { continue; } item.UpdateValuesFromPoints(); } } public void MergeWithWall(WallLine wallLine) { WallLine wallA = WallCreationManager.CreateLine(wallLine._pointStart, this, wallLine.GetCopy()); WallLine wallB = WallCreationManager.CreateLine(this, wallLine._pointEnd, wallLine.GetCopy()); #if true // TODO : temporary ordering of walls in hierarchy for sequential walls, check if still needed int wallIndex = wallLine.transform.GetSiblingIndex(); wallA.transform.SetSiblingIndex(wallIndex); wallB.transform.SetSiblingIndex(wallIndex + 1); #endif wallLine.DestroyWall(); wallA.ValidateWall(); wallB.ValidateWall(); WallCreationManager.ReorderNumberWalls(); } public void SetColorOnEvent(Color color) { GetComponent().color = color; } public void PointerEnterColor(bool isEntered) { if (WallSelection.IsDragging || WallSelection.CompareSelection(this)) { return; } if (WallSelection.TryGetCurrentSelection(out IWallSelection selection)) { WallLine selectedWallLine = selection.GetGameObject().GetComponent(); WallPoint selectedWallPoint = selection.GetGameObject().GetComponent(); if (selectedWallLine != null) { selectedWallLine.ShowAdjacentInputFields(this, isEntered); } else if (selectedWallPoint != null) { List adjacentWalls = _wallLines.FindAll(x => !selectedWallPoint.GetWalls().Contains(x)); foreach (WallLine item in adjacentWalls) { item.ShowInputField(isEntered); } } } SelectionModePlan2D mode = isEntered ? SelectionModePlan2D.Hover : SelectionModePlan2D.Default; SetSelectionColor(mode); } public void OnClickDestroyEvent() { if (Input.GetMouseButtonDown(1)) { DestroySelected(); WallCreationManager.ReorderNumberWalls(); WallCreationManager.HideMeasureInteriorWall(); } } public void OnClickSelectEvent() { print("OnClickSelectEvent()===wp="); _isDragging = true; SetAsSelection(true); string Category="Exterior"; foreach (WallLine wallLine in _wallLines) { if (wallLine._pointStart == this || wallLine._pointEnd == this){ Category= wallLine._category;} } Get.o2("Panel_DRAWPlan_NEW","Selection Panel").SetActive(true); Get.o2("Panel_DRAWPlan_NEW/Selection Panel","Panel_Setting").SetActive(true); // if(SceneModeManager.CompareSceneMode(SceneModes.Cathedral)) // { if(Category=="Interior") { // SetAsSelection(true); // string Title=TRANS.This("T_INTERIOR WALL"); // Color ColorHeader = Color.blue; // float Height=transform.GetComponent()._PointHeight; // WallSelection.AddInputOption(ColorHeader,Title,"InputHeight",false,Height,0); } else{ //Set if Ceiling mode SetAsSelection(true); Color ColorHeader = Color.red; string Title=TRANS.This("T_EXTERIOR POINT"); float Height=transform.GetComponent()._PointHeight; WallSelection.AddInputOption(ColorHeader,Title,"InputHeight",false,Height,0); } //} print("Point Selected" +name); _G.SelectedPoint2D=this; // WallCreationManager.AddMeasure(); } public void DestroySelected() { #if true // TODO : temporary wall rebuilding after point deletion if (_wallLines.Count > 0) { MergeWithPoint(_wallLines[_wallLines.Count - 1].GetOtherPoint(this)); } else { DestroyPoint(); } #endif } public void SetAsSelection(bool isSelected) { WallSelection.SetSelection(this, isSelected); } public void HandleSelection(bool isSelected) { bool areInputFieldsEnabled = isSelected || !WallSelection.TryGetCurrentSelection(out IWallSelection selection); foreach (var line in _wallLines) { line.ShowInputField(areInputFieldsEnabled); } SelectionModePlan2D mode = isSelected ? SelectionModePlan2D.Select : SelectionModePlan2D.Default; SetSelectionColor(mode); } public void SetSelectionColor(SelectionModePlan2D mode) { Color color = _defaultColor; switch (mode) { case SelectionModePlan2D.Default: color = _defaultColor; break; case SelectionModePlan2D.Hover: color = _hoverColor; break; case SelectionModePlan2D.Select: color = _selectionColor; break; default: break; } SetColorOnEvent(color); } public void SetDragState(bool isDragging) { //print("FOLOW DRAG"); bool isAddingWallState = WallCreationManager._instance.IsAddingWallState(); if (isDragging) { if (isAddingWallState) { isDragging = WallCreationManager._instance.GetCurrentWallPoint() == this; } } if (isDragging) { _startedDragging = isDragging; } _isDragging = isDragging; WallSelection.IsDragging = isDragging; WallSelection.SetAllToDefaultColor(this); } public bool GetDragState() { return _isDragging; } public void InsertWall() // TODO : temporary? { Debug.Assert(_wallLines.Count <= 2, "Rework or remove wall insertion feature on points"); WallLine wallLineA = null; WallLine wallLineB = null; for (int i = 0; i < _wallLines.Count; i++) { if (i == 0) { wallLineA = _wallLines[0]; } else if (i == 1) { wallLineB = _wallLines[1]; } } wallLineA.SplitWall(); if (wallLineB != null) { wallLineB.SplitWall(); DestroySelected(); } } public GameObject GetGameObject() { return gameObject; } internal void Copy(WallPointData pointsData) { //_wallLines = points._wallLines; _PointHeight = pointsData._PointHeight; } public WallPointData GetCopy() { WallPointData copy = new WallPointData(this); return copy; } internal string SaveToJson() { return JsonConvert.SerializeObject(GetCopy()); } } [Serializable] public class WallPointData { public float _PointHeight; public Vector2 _Position; public WallPointData(WallPoint point) { _PointHeight = point._PointHeight; _Position = point.GetAnchoredPosition(); } public WallPointData(float pointHeight, Vector2 position) { _PointHeight = pointHeight; _Position = position; } }