using UnityEngine; namespace RoadArchitect { public static class Construction { /// Creates a node and performs validation checks public static SplineN CreateNode(Road _road, bool _isSpecialEndNode = false, Vector3 _vectorSpecialLoc = default(Vector3), bool _isInterNode = false) { Object[] worldNodeCount = GameObject.FindObjectsOfType(); GameObject nodeObj = new GameObject("Node" + worldNodeCount.Length.ToString()); if (!_isInterNode) { EngineIntegration.RegisterUndo(nodeObj, "Created node"); } SplineN node = nodeObj.AddComponent(); if (_isSpecialEndNode) { node.isSpecialEndNode = true; nodeObj.transform.position = _vectorSpecialLoc; } else { nodeObj.transform.position = _road.editorMousePos; //This helps prevent double clicks: int nodeCount = _road.spline.GetNodeCount(); for (int index = 0; index < nodeCount; index++) { if (Vector3.Distance(_road.editorMousePos, _road.spline.nodes[index].pos) < 5f) { Object.DestroyImmediate(nodeObj); return null; } } //End double click prevention } Vector3 xVect = nodeObj.transform.position; if (xVect.y < 0.03f) { xVect.y = 0.03f; } nodeObj.transform.position = xVect; nodeObj.transform.parent = _road.splineObject.transform; node.idOnSpline = _road.spline.GetNodeCount() + 1; node.spline = _road.spline; //Enforce max road grade: if (_road.isMaxGradeEnabled && !_isSpecialEndNode) { node.EnsureGradeValidity(-1, true); } if (!_isInterNode && !_isSpecialEndNode) { _road.UpdateRoad(); } return node; } /// Insert /// Detect closest node (if end node, auto select other node) /// Determine which node is closest (up or down) on spline /// Place node, adjust all id on splines /// Setup spline public static SplineN InsertNode(Road _road, bool _isForcedLoc = false, Vector3 _forcedLoc = default(Vector3), bool _isPreNode = false, int _insertIndex = -1, bool _isSpecialEndNode = false, bool _isInterNode = false) { GameObject nodeObj; Object[] worldNodeCount = GameObject.FindObjectsOfType(); if (!_isForcedLoc) { nodeObj = new GameObject("Node" + worldNodeCount.Length.ToString()); } else if (_isForcedLoc && !_isSpecialEndNode) { nodeObj = new GameObject("Node" + worldNodeCount.Length.ToString() + "Ignore"); } else { nodeObj = new GameObject("Node" + worldNodeCount.Length.ToString()); } if (!_isInterNode) { EngineIntegration.RegisterUndo(nodeObj, "Inserted node"); } if (!_isForcedLoc) { nodeObj.transform.position = _road.editorMousePos; //This helps prevent double clicks: int nodeCount = _road.spline.GetNodeCount(); for (int index = 0; index < nodeCount; index++) { if (Vector3.Distance(_road.editorMousePos, _road.spline.nodes[index].pos) < 15f) { Object.DestroyImmediate(nodeObj); return null; } } //End double click prevention } else { nodeObj.transform.position = _forcedLoc; } Vector3 xVect = nodeObj.transform.position; if (xVect.y < 0.03f) { xVect.y = 0.03f; } nodeObj.transform.position = xVect; nodeObj.transform.parent = _road.splineObject.transform; int childCount = _road.spline.nodes.Count; //float mDistance = 50000f; //float tDistance = 0f; float param; if (!_isForcedLoc) { param = _road.spline.GetClosestParam(_road.editorMousePos, false, true); } else { param = _road.spline.GetClosestParam(_forcedLoc, false, true); } bool isEndInsert = false; bool isZeroInsert = false; int iStart = 0; if (RootUtils.IsApproximately(param, 0f, 0.0001f)) { isZeroInsert = true; iStart = 0; } else if (RootUtils.IsApproximately(param, 1f, 0.0001f)) { isEndInsert = true; } if (_isForcedLoc) { iStart = _insertIndex; } else { for (int index = 0; index < childCount; index++) { SplineN xNode = _road.spline.nodes[index]; if (!isZeroInsert && !isEndInsert) { if (param > xNode.time) { iStart = xNode.idOnSpline + 1; } } } } if (isEndInsert) { iStart = _road.spline.nodes.Count; } else { for (int i = iStart; i < childCount; i++) { _road.spline.nodes[i].idOnSpline += 1; } } // Create new node SplineN node = nodeObj.AddComponent(); if (_isForcedLoc && !_isSpecialEndNode) { node.isBridge = true; node.isIgnore = true; //tNode.bIsBridge_PreNode = bIsPreNode; //tNode.bIsBridge_PostNode = !bIsPreNode; } node.spline = _road.spline; node.idOnSpline = iStart; node.isSpecialEndNode = _isSpecialEndNode; if (!_isForcedLoc) { node.pos = _road.editorMousePos; } else { node.pos = _forcedLoc; } _road.spline.nodes.Insert(iStart, node); //Enforce maximum road grade: if (!_isForcedLoc && !_isSpecialEndNode && _road.isMaxGradeEnabled) { node.EnsureGradeValidity(iStart); } if (!_isInterNode && !_isSpecialEndNode) { if (!_isForcedLoc) { _road.UpdateRoad(); } } return node; } } }