using System.Collections.Generic; using UnityEngine; using UnityEngine.UI.Extensions; using UnityEngine.UI; using System.Globalization; public class DRAW : MonoBehaviour { GameObject PNL; public Texture2D cursorPoint; Vector2 hotSpot = new Vector2(64, 64); float xpos; float ypos; Vector2 XY; void StartPNL() { // Activate the drawing panel Get.o2("Canvas", "Panel_DRAWPlan").SetActive(true); _G.NW = 1; PNL = Get.o2("Panel_DRAWPlan", "Plan"); PNL.SetActive(true); // Disable the 3D panel Get.o2("Panel_DRAWPlan", "3D").SetActive(false); _G.Down = false; _G.Open = true; // Clear any existing drawing lines UILineRenderer pr = PNL.transform.GetComponent(); var pointlist = new List(); pr.Points = pointlist.ToArray(); // Delete any child objects in the "Plan" container DOIT.DELETEAllChild("Plan"); // Initialize the array for storing drawing points _G.WallsPointStart = new(new Vector2[24]); } void Update() { // Update the XY position based on local mouse position XY = new Vector2(GetLocalPosition("x"), GetLocalPosition("y")); // Handle left mouse button down event if (Input.GetMouseButtonDown(0) && _G.Open == true && _G.Down == true) { // Check if the mouse position is within the valid drawing area if (XY.x > -500f && XY.x < 500f && XY.y > -300 && XY.y < 300) { if (_G.NW == 1) { _G.WallsPointStart [_G.NW - 1] = new Vector2(XY.x, XY.y); } if (_G.NW >= 1) { int sens = CalculateSense(_G.WallsPointStart [_G.NW - 2], XY); if (sens != 0) { _G.WallsPointStart [_G.NW - 1] = new Vector2(XY.x, XY.y); } } } else { Restart(); } } // Handle right mouse button down event if (Input.GetMouseButtonDown(1) && _G.Open == true && _G.Down == true && _G.NW >= 4) { _G.deleteLastWall = true; _G.closingWall = 0; _G.Down = false; _G.Open = true; _G.NW -= 1; DOIT.DELETEAllChild("Plan"); AddLinesAndMeasurements(_G.NW); AddMeasures(_G.NW); CalculateRoomSize(); Cursor.SetCursor(null, Vector2.zero, CursorMode.ForceSoftware); } // Handle left mouse button down event to start drawing if (Input.GetMouseButtonDown(0) && _G.Down == false && _G.Open == true) { if (XY.x < -192 && XY.x > -292 && XY.y < 245 && XY.y > 145) { _G.Down = true; _G.WallsPointStart [_G.NW - 1] = new Vector2(XY.x, XY.y); } } // Handle left mouse button up event to stop drawing if (Input.GetMouseButtonUp(0) && _G.Open == true && _G.Down) { if (_G.NW > 3 && XY.x < -210 && XY.x > -310 && XY.y < 236 && XY.y > 136) { _G.Down = false; _G.Open = false; _G.NW -= 1; int sense = CalculateSense(_G.WallsPointStart [_G.NW - 1], XY); if (sense == 7) { _G.WallsPointStart [_G.NW - 1] = new Vector2(_G.WallsPointStart [1 - 1].x, _G.WallsPointStart [_G.NW - 1].y); } else if (sense == 8) { float disx = Mathf.Abs(_G.WallsPointStart [_G.NW - 1].x - _G.WallsPointStart [1 - 1].x); _G.WallsPointStart [_G.NW - 1] = new Vector2(_G.WallsPointStart [_G.NW - 1].x, _G.WallsPointStart [1 - 1].y - disx); } DOIT.DELETEAllChild("Plan"); AddLinesAndMeasurements(_G.NW); AddMeasures(_G.NW); CalculateRoomSize(); Cursor.SetCursor(null, Vector2.zero, CursorMode.ForceSoftware); } else { _G.NW += 1; } } } void LateUpdate() { // Check if drawing mode is active and conditions are met if (_G.Down && _G.NW > 1 && _G.Open) { // Calculate distance and sensitivity float dis = Vector2.Distance(XY, _G.WallsPointStart [_G.NW - 2]); Cursor.SetCursor(cursorPoint, hotSpot, CursorMode.ForceSoftware); int sens = CalculateSense(_G.WallsPointStart [_G.NW - 2], XY); // Handle different cases based on sensitivity switch (sens) { case 1: _G.WallsPointStart [_G.NW - 1] = new Vector2(GetLocalPosition("x"), _G.WallsPointStart [_G.NW - 2].y); break; case 2: _G.WallsPointStart [_G.NW - 1] = new Vector2(_G.WallsPointStart [_G.NW - 2].x + dis * 0.707f, _G.WallsPointStart [_G.NW - 2].y - dis * 0.707f); break; case 3: _G.WallsPointStart [_G.NW - 1] = new Vector2(_G.WallsPointStart [_G.NW - 2].x, GetLocalPosition("y")); break; case 4: _G.WallsPointStart [_G.NW - 1] = new Vector2(_G.WallsPointStart [_G.NW - 2].x - dis * 0.707f, _G.WallsPointStart [_G.NW - 2].y - dis * 0.707f); break; case 5: _G.WallsPointStart [_G.NW - 1] = new Vector2(GetLocalPosition("x"), _G.WallsPointStart [_G.NW - 2].y); break; case 6: _G.WallsPointStart [_G.NW - 1] = new Vector2(_G.WallsPointStart [_G.NW - 2].x - dis * 0.707f, _G.WallsPointStart [_G.NW - 2].y + dis * 0.707f); break; case 7: _G.WallsPointStart [_G.NW - 1] = new Vector2(_G.WallsPointStart [_G.NW - 2].x, GetLocalPosition("y")); break; case 8: _G.WallsPointStart [_G.NW - 1] = new Vector2(_G.WallsPointStart [_G.NW - 2].x + dis * 0.707f, _G.WallsPointStart [_G.NW - 2].y + dis * 0.707f); break; } // Check if sensitivity is not zero, then add lines and measurements if (sens != 0) { AddLinesAndMeasurements(_G.NW); AddMeasures(_G.NW); _G.endPoint = _G.WallsPointStart [_G.NW - 1]; } // Update the text for StartHere Get.o3("Panel_DRAWPlan", "StartHere", "T_Start").GetComponent().text = TRANS.This("T_FinishHere"); } else { // Reset cursor when not in drawing mode Cursor.SetCursor(null, Vector2.zero, CursorMode.ForceSoftware); } } public void Restart() { // Reset variables and print debug information _G.NW = 1; print("RESTART"); _G.closingWall = 1; _G.Down = false; _G.Open = true; // Get the Plan object and clear its points GameObject plan = Get.o2("Panel_DRAWPlan", "Plan"); plan.SetActive(true); UILineRenderer pr = plan.GetComponent(); var pointList = new List(); pr.Points = pointList.ToArray(); // Delete all child objects of Plan DOIT.DELETEAllChild("Plan"); // Reset the wP array _G.WallsPointStart = new(new Vector2[24]); // Set the text for StartHere Get.o3("Panel_DRAWPlan", "StartHere", "T_Start").GetComponent().text = TRANS.This("T_StartHere"); } public static void RedrawRoom(string Ms, float Value) { // Print debug information print("--------pass redraw----------"); print("_G.NW===== " + _G.NW); // Parse the measurement ID to determine which wall to update int Mi = int.Parse(Ms.Substring(1, 3)) - 100; // Calculate wall senses for (int i = 0; i < _G.NW - 1; i++) { _G. WallsDirection[i] = CalculateSense(_G.WallsPointStart [i], _G.WallsPointStart [i + 1]); } _G. WallsDirection[_G.NW - 1] = CalculateSense(_G.WallsPointStart [_G.NW - 1], _G.WallsPointStart [0]); // Update the width of the specified wall _G.WallsWidth[Mi - 1] = Value; // Set the initial position of the first point _G.WallsPointStart [0] = new Vector2(-242, 195); float dis = _G.WallsWidth[0] * 2; for (int i = 0; i < _G.NW + 1; i++) { dis = _G.WallsWidth[i] * 2; // Calculate new positions for points based on wall senses switch (_G. WallsDirection[i]) { case 1: _G.WallsPointStart [i + 1] = new Vector2(_G.WallsPointStart [i].x + dis, _G.WallsPointStart [i].y); break; case 2: _G.WallsPointStart [i + 1] = new Vector2(_G.WallsPointStart [i].x + dis * 0.707f, _G.WallsPointStart [i].y - dis * 0.707f); break; case 3: _G.WallsPointStart [i + 1] = new Vector2(_G.WallsPointStart [i].x, _G.WallsPointStart [i].y - dis); break; case 4: _G.WallsPointStart [i + 1] = new Vector2(_G.WallsPointStart [i].x - dis * 0.707f, -_G.WallsPointStart [i].y - dis * 0.707f); break; case 5: _G.WallsPointStart [i + 1] = new Vector2(_G.WallsPointStart [i].x - dis, _G.WallsPointStart [i].y); break; case 6: _G.WallsPointStart [i + 1] = new Vector2(_G.WallsPointStart [i].x - dis * 0.707f, _G.WallsPointStart [i].y + dis * 0.707f); break; case 7: _G.WallsPointStart [i + 1] = new Vector2(_G.WallsPointStart [i].x, _G.WallsPointStart [i].y + dis); break; case 8: _G.WallsPointStart [i + 1] = new Vector2(_G.WallsPointStart [i].x + dis * 0.707f, _G.WallsPointStart [i].y + dis * 0.707f); break; } } // Update the position of the closing wall endpoint based on conditions if (_G.closingWall == 1) { _G.endPoint = _G.WallsPointStart [0]; } else { _G.endPoint = new Vector3(_G.WallsPointStart [_G.NW - 1].x + 50, _G.WallsPointStart [_G.NW - 1].y, 1); } // Activate the plan and line renderer GameObject plan = Get.o2("Panel_DRAWPlan", "Plan"); plan.SetActive(true); UILineRenderer pr = plan.GetComponent(); // Create a list of points for the line renderer var pointList = new List(); for (int i = 0; i < _G.NW; i++) { pointList.Add(_G.WallsPointStart [i]); // Add measurements and update control points and widths SetMeasurementLine("M" + (100 + i + 1).ToString(), _G.WallsPointStart [i], _G.WallsPointStart [i + 1]); _G. WallsPointCenter[i] = (_G.WallsPointStart [i] + _G.WallsPointStart [i + 1]) / 2; _G.WallsWidth[i] = Vector2.Distance(_G.WallsPointStart [i], _G.WallsPointStart [i + 1]) / 2; } // Update the width and control point of the closing wall _G.WallsWidth[_G.NW - 1] = Vector2.Distance(_G.WallsPointStart [_G.NW - 1], _G.WallsPointStart [0]) / 2; _G. WallsPointCenter[_G.NW - 1] = (_G.WallsPointStart [_G.NW - 1] + _G.WallsPointStart [0]) / 2; // Set the points in the line renderer pointList.Add(_G.endPoint); pr.Points = pointList.ToArray(); // Add measurements for all segments for (int i = 0; i < _G.NW; i++) { Create3D.SetMeasureNew(Mathf.Abs(_G.WallsWidth[i]), "m" + (100 + i + 1).ToString()); } // Calculate the room size CalculateRoomSize(); } public static void RedrawRoomFromScene() { Get.o2("Panel_DRAWPlan", "Plan").SetActive(true); for (int i = 0; i < _G.NW; i++) { _G.WallsPointStart [i] *= 2; } CalculateRoomSize(); // Add measurements for all segments for (int i = 0; i < _G.NW; i++) { SetMeasurementLine("M" + (100 + i + 1).ToString(), _G.WallsPointStart [i], _G.WallsPointStart [(i + 1) % _G.NW]); Create3D.SetMeasureNew(Mathf.Abs(_G.WallsWidth[i]), "m" + (100 + i + 1).ToString()); } return; } public static int CalculateSense(Vector2 P1, Vector2 P2) { int senseValue = 0; Vector2 direction = (P2 - P1).normalized; // Define directional thresholds float threshold1 = 0.8f; float threshold2 = 0.3f; float threshold3 = 0.8f; // Check various directional conditions and assign the corresponding sense value if (direction.x >= threshold1 && direction.y >= -threshold2 && direction.y <= threshold2) { senseValue = 1; } else if (direction.x >= threshold2 && direction.x <= threshold1 && direction.y >= -threshold3 && direction.y <= -threshold2) { senseValue = 2; } else if (direction.x >= -threshold2 && direction.x <= threshold2 && direction.y <= -threshold3) { senseValue = 3; } else if (direction.x >= -threshold3 && direction.x <= -threshold2 && direction.y >= -threshold3 && direction.y <= -threshold2) { senseValue = 4; } else if (direction.x <= -threshold1 && direction.y >= -threshold2 && direction.y <= threshold2) { senseValue = 5; } else if (direction.x >= -threshold3 && direction.x <= -threshold2 && direction.y >= threshold2 && direction.y <= threshold3) { senseValue = 6; } else if (direction.x >= -threshold2 && direction.x <= threshold2 && direction.y >= threshold3) { senseValue = 7; } else if (direction.x >= threshold2 && direction.x <= threshold1 && direction.y >= threshold2 && direction.y <= threshold1) { senseValue = 8; } return senseValue; } float GetLocalPosition(string axis) { // Initialize the XY vector with mouse cursor position Vector2 XY = new Vector2(Input.mousePosition.x, Input.mousePosition.y); // Define a Vector2 to store the local cursor position Vector2 localCursor; // Get the RectTransform for the "Planboard" within "Panel_DRAWPlan" var rect1 = Get.o2("Panel_DRAWPlan", "Planboard").GetComponent(); // Convert screen coordinates to local coordinates within "Planboard" RectTransformUtility.ScreenPointToLocalPointInRectangle(rect1, XY, null, out localCursor); // Extract the x and y positions float xpos = localCursor.x; float ypos = localCursor.y; // Adjust xpos and ypos based on the rect1 dimensions and center xpos += rect1.rect.width / 2; ypos += rect1.rect.height / 2; xpos -= 1000 / 2; ypos -= 300; // Round the positions to integers xpos = Mathf.RoundToInt(xpos); ypos = Mathf.RoundToInt(ypos); // Depending on the specified axis ("x" or "y"), return the corresponding value return (axis == "x") ? xpos : ypos; } #if false void AddLinesAndMeasurements(int Q) { print("addlinesaddlinesaddlinesaddlinesaddlinesaddlines"); GameObject p = Get.o2("Panel_DRAWPlan", "Plan"); p.SetActive(true); UILineRenderer pr = p.transform.GetComponent(); var pointlist = new List(); var pointAngle = new List(); int i = 1; for (i = 1; i < Q + 1; i++) { pointlist.Add(_G.WallsPointStart [i - 1]); } if (_G.Open == false) { pointlist.Add(_G.WallsPointStart [1 - 1]); } pr.Points = pointlist.ToArray(); //Calculate the angle between the each two line's points if (pointlist.Count > 1) { for (int j = 1; j < pointlist.Count; j++) { float AngleRad = Mathf.Atan2(pointlist[j - 1].y - pointlist[j].y, pointlist[j - 1].x - pointlist[j].x); float AngleDeg = (180 / Mathf.PI) * AngleRad; pointAngle.Add(AngleDeg); pr.PointAngle = pointAngle.ToArray(); } } for (i = 1; i < Q; i++) { SetMeasurementLine("M" + (100 + i).ToString(), _G.WallsPointStart [i - 1], _G.WallsPointStart [i]); //if open cp of last wall will be _G. WallsPointCenter[i - 1] = (_G.WallsPointStart [i - 1] + _G.WallsPointStart [i]) / 2; _G. WallsAngle[i - 1] = GetAngleFromVector((_G.WallsPointStart [i] - _G.WallsPointStart [i - 1]).normalized); _G.WallsWidth[i - 1] = Vector2.Distance(_G.WallsPointStart [i - 1], _G.WallsPointStart [i]) / 2; } if (_G.Open == false) { SetMeasurementLine("M" + (100 + Q).ToString(), _G.WallsPointStart [Q - 1], _G.WallsPointStart [1 - 1] * 1); _G. WallsPointCenter[Q - 1] = (_G.WallsPointStart [Q - 1] + _G.WallsPointStart [1 - 1]) / 2; _G. WallsAngle[Q - 1] = GetAngleFromVector((_G.WallsPointStart [1 - 1] - _G.WallsPointStart [Q - 1]).normalized); _G.WallsWidth[Q - 1] = Vector2.Distance(_G.WallsPointStart [Q - 1], _G.WallsPointStart [1 - 1]) / 2; } if (_G.Open == true) { pointlist.Remove(_G.WallsPointStart [pointlist.Count - 1]); } } #else void AddLinesAndMeasurements(int Q) { // Print a debug message //print("addlines in draw"); // Get the parent GameObject for the plan GameObject planParent = Get.o2("Panel_DRAWPlan", "Plan"); planParent.SetActive(true); // Get the UILineRenderer component from the plan UILineRenderer lineRenderer = planParent.GetComponent(); // Create lists to store points and angles var pointList = new List(); var pointAngles = new List(); // Iterate through the points and add them to the point list for (int i = 0; i < Q; i++) { pointList.Add(_G.WallsPointStart [i]); } // Add the first point again if the room is not open if (!_G.Open) { pointList.Add(_G.WallsPointStart [0]); } // Set the points in the line renderer lineRenderer.Points = pointList.ToArray(); // Calculate angles between consecutive points if (pointList.Count > 1) { for (int j = 1; j < pointList.Count; j++) { float angleRad = Mathf.Atan2(pointList[j - 1].y - pointList[j].y, pointList[j - 1].x - pointList[j].x); float angleDeg = (180 / Mathf.PI) * angleRad; pointAngles.Add(angleDeg); } // Set the point angles in the line renderer lineRenderer.PointAngle = pointAngles.ToArray(); } // Add measurements and update properties for (int i = 0; i < Q - 1; i++) { SetMeasurementLine("M" + (100 + i + 1).ToString(), _G.WallsPointStart [i], _G.WallsPointStart [i + 1]); // Calculate control point, angle, and width _G. WallsPointCenter[i] = (_G.WallsPointStart [i] + _G.WallsPointStart [i + 1]) / 2; _G. WallsAngle[i] = GetAngleFromVector((_G.WallsPointStart [i + 1] - _G.WallsPointStart [i]).normalized); _G.WallsWidth[i] = Vector2.Distance(_G.WallsPointStart [i], _G.WallsPointStart [i + 1]) / 2; } // Add measurement for the last segment if the room is not open if (!_G.Open) { SetMeasurementLine("M" + (100 + Q).ToString(), _G.WallsPointStart [Q - 1], _G.WallsPointStart [0]); // Calculate control point, angle, and width for the last segment _G. WallsPointCenter[Q - 1] = (_G.WallsPointStart [Q - 1] + _G.WallsPointStart [0]) / 2; _G. WallsAngle[Q - 1] = GetAngleFromVector((_G.WallsPointStart [0] - _G.WallsPointStart [Q - 1]).normalized); _G.WallsWidth[Q - 1] = Vector2.Distance(_G.WallsPointStart [Q - 1], _G.WallsPointStart [0]) / 2; } // Remove the last point if the room is open if (_G.Open) { pointList.RemoveAt(pointList.Count - 1); } } #endif static void SetMeasurementLine(string measurementName, Vector2 point1, Vector2 point2) { // Check if a GameObject with the given measurement name exists and destroy it if found GameObject existingMeasurement = GameObject.Find(measurementName); if (existingMeasurement != null) { GameObject.DestroyImmediate(existingMeasurement); } // Create a new measurement GameObject from a template (assuming "Mesure" is a prefab) GameObject measurementObject = Instantiate(Get.o2("HIDER", "Mesure")) as GameObject; // Set the name of the measurement GameObject measurementObject.name = measurementName; // Activate the measurement GameObject measurementObject.SetActive(true); // Rename the "m" child object to match the measurement name measurementObject.transform.Find("m").name = measurementName.Replace("M", "m"); // Set the parent of the measurement GameObject to the "Panel_DRAWPlan" in the "Plan" object Transform parentTransform = Get.o2("Panel_DRAWPlan", "Plan").transform; measurementObject.transform.SetParent(parentTransform); // Set the position of the measurement GameObject to the midpoint between p1 and p2 measurementObject.transform.localPosition = (point1 + point2) / 2; // Extract the measurement index (assuming the name format is "Mx" where x is a number) int measurementIndex = int.Parse(measurementName.Substring(1)); // Set the text of the "no" component to the measurement index (adjusted by subtracting 100) Text measurementText = measurementObject.transform.Find("no").gameObject.GetComponent(); measurementText.text = (measurementIndex - 100).ToString(); } void AddMeasures(int Q) { // Check if the room is not open and increment Q if (!_G.Open) { Q += 1; } // Loop through and create measures for (int i = 0; i < Q - 1; i++) { // Calculate the measure value (assuming it's the absolute width) float measureValue = Mathf.Abs(_G.WallsWidth[i]); // Create a measure with a unique name using the index string measureName = "m" + (100 + i + 1).ToString(); // Call a function to create the measure (assuming Create3D.SetMeasureNew exists) Create3D.SetMeasureNew(measureValue, measureName); } } float GetAngleFromVector(Vector2 direction) { // Round the x and y components of the input vector to handle floating-point imprecision float roundedX = Mathf.Round(direction.x * 10f) / 10f; float roundedY = Mathf.Round(direction.y * 10f) / 10f; // Calculate the angle based on the rounded values float angle = 0; Vector2 roundedDir = new Vector2(roundedX, roundedY); //angle = -Vector2.SignedAngle(Vector2.right, roundedDir); angle = (-Vector2.SignedAngle(Vector2.right, direction) + 360.0f) % 360.0f; Debug.Log("wall angle = " + angle); return angle; } public static void CalculateRoomSize() { _G.WIDE = 0; float Xmax = _G.WallsPointStart [0].x; float Xmin = _G.WallsPointStart [0].x; float Ymax = _G.WallsPointStart [0].y; float Ymin = _G.WallsPointStart [0].y; // Find the maximum and minimum X and Y coordinates for (int i = 0; i < _G.NW; i++) { float x = _G.WallsPointStart [i].x; float y = _G.WallsPointStart [i].y; if (x < Xmin) Xmin = x; if (x > Xmax) Xmax = x; if (y < Ymin) Ymin = y; if (y > Ymax) Ymax = y; } // Update the WIDE and DEPTH properties _G.WIDE = (Xmax - Xmin) / 2.0f; _G.DEPTH = (Ymax - Ymin) / 2.0f; // Calculate the room's center (RC) and offset //Vector2 RC = new Vector2(Xmin, Ymax); Vector2 offset = new Vector2((Xmax + Xmin) / 2, (Ymax + Ymin) / 2); // Apply the offset and scale down the points for (int i = 0; i < _G.NW; i++) { //Debug.Log($"before DRAW wall width of {i + 1} : {_G.WallsWidth[i]}"); _G.WallsPointStart [i] = (_G.WallsPointStart [i] - offset) / 2.0f; } // Calculate control points, widths, and directions for (int i = 0; i < _G.NW; i++) { int nextIndex = (i + 1) % _G.NW; _G. WallsPointCenter[i] = (_G.WallsPointStart [i] + _G.WallsPointStart [nextIndex]) / 2; _G.WallsWidth[i] = Vector2.Distance(_G.WallsPointStart [i], _G.WallsPointStart [nextIndex]); _G. WallsDirection[i] = CalculateSense(_G.WallsPointStart [i], _G.WallsPointStart [nextIndex]); //Debug.Log($"after DRAW wall width of {i + 1} : {_G.WallsWidth[i]}"); } } }