/// <summary> /// Create and initialise a location of a manual group in the scene. /// </summary> /// <param name="landscape"></param> /// <param name="lbGroupLocation"></param> /// <param name="locationMaterial"></param> /// <param name="locationPos"></param> /// <param name="locationYRotation"></param> /// <param name="locationNumber"></param> /// <param name="showErrors"></param> /// <returns></returns> private static LBGroupLocationItem CreateLocationItemInScene(LBLandscape landscape, LBGroup lbGroupLocation, Material locationMaterial, Vector3 locationPos, float locationYRotation, int locationNumber, bool showErrors) { LBGroupLocationItem lbGroupLocationItem = null; string methodName = "LBGroupLocationItem.CreateLocationItemInScene"; GameObject cylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder); if (cylinder != null) { lbGroupLocationItem = cylinder.AddComponent <LBGroupLocationItem>(); if (lbGroupLocationItem == null) { DestroyImmediate(cylinder); if (showErrors) { Debug.LogWarning("ERROR: " + methodName + " could not add LBGroupLocationItem to location gameobject. Please Report."); } } else { lbGroupLocationItem.lbGroup = lbGroupLocation; cylinder.name = lbGroupLocation.groupName + "_loc" + locationNumber.ToString("0000"); cylinder.transform.SetPositionAndRotation(locationPos, Quaternion.Euler(0f, locationYRotation, 0f)); cylinder.transform.localScale = new Vector3(lbGroupLocation.maxClearingRadius * 2f, 0.1f, lbGroupLocation.maxClearingRadius * 2f); MeshRenderer mRen = cylinder.GetComponent(typeof(MeshRenderer)) as MeshRenderer; if (mRen != null) { // Disable casting and receive shadows mRen.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; mRen.receiveShadows = false; if (locationMaterial != null) { mRen.sharedMaterial = locationMaterial; } } // Remove capsule collider Component collider = cylinder.GetComponent(typeof(Collider)); if (collider != null) { DestroyImmediate(collider); } cylinder.transform.SetParent(landscape.transform); lbGroupLocationItem.rotationY = locationYRotation; // Get the number of zones so that they can be shown in OnDrawGizmos lbGroupLocationItem.numZones = lbGroupLocation.zoneList == null ? 0 : lbGroupLocation.zoneList.Count; lbGroupLocationItem.isInitialised = true; } } return(lbGroupLocationItem); }
private void OnEnable() { lbGroupLocationItem = (LBGroupLocationItem)target; landscape = lbGroupLocationItem.transform.GetComponentInParent <LBLandscape>(); landscapeBounds = landscape.GetLandscapeWorldBoundsFast(); prevPosition = lbGroupLocationItem.transform.position; if (lbGroupLocationItem.lbGroup != null && lbGroupLocationItem.lbGroup.isFixedRotation) { lbGroupLocationItem.rotationY = lbGroupLocationItem.transform.rotation.eulerAngles.y; // When first selected, update the rotation in the LB editor LBEditorHelper.RepaintEditorWindow(typeof(LandscapeBuilderWindow)); } //Debug.Log("WorldBounds: " + landscapeBounds.xMin + "," + landscapeBounds.yMin + " - " + landscapeBounds.xMax + "," + landscapeBounds.yMax); }
/// <summary> /// Add a new Location object and script to the scene. Append the location /// </summary> /// <param name="landscape"></param> /// <param name="lbGroupLocation"></param> /// <param name="showErrors"></param> /// <returns></returns> public static LBGroupLocationItem AddNewLocationToScene(LBLandscape landscape, LBGroup lbGroupLocation, Vector2 mousePosition, Camera svCamera, bool showErrors) { LBGroupLocationItem lbGroupLocationItem = null; string methodName = "LBGroupLocationItem.AddNewLocationToScene"; // Basic validation if (landscape == null) { if (showErrors) { Debug.LogWarning("ERROR: " + methodName + " landscape is null"); } } else if (lbGroupLocation == null) { if (showErrors) { Debug.LogWarning("ERROR: " + methodName + " lbGroupLocation is null"); } } else { Vector3 locationPoint = Vector3.zero; locationPoint = LBEditorHelper.GetLandscapePositionFromMouse(landscape, mousePosition, false, true); if (locationPoint.x != 0 && locationPoint.z != 0) { //Debug.Log("[DEBUG] locationPoint " + locationPoint + " mousePos: " + mousePosition); Material locationMaterial = null; locationMaterial = LBEditorHelper.GetMaterialFromAssets(LBSetup.materialsFolder, "LBLocation.mat"); lbGroupLocationItem = CreateLocationItemInScene(landscape, lbGroupLocation, locationMaterial, locationPoint, 0f, lbGroupLocation.positionList.Count + 1, showErrors); if (lbGroupLocationItem != null) { lbGroupLocationItem.lbGroup.positionList.Add(locationPoint - landscape.start); if (lbGroupLocationItem.lbGroup.isFixedRotation) { lbGroupLocationItem.lbGroup.rotationYList.Add(0f); } LBEditorHelper.RepaintLBW(); } } } return(lbGroupLocationItem); }
private void DeleteAll() { if (lbGroup != null && lbGroupLocationItem != null) { if (lbGroup.positionList != null) { lbGroup.positionList.Clear(); if (lbGroup.isFixedRotation && lbGroup.rotationYList != null) { lbGroup.rotationYList.Clear(); } LBGroupLocationItem.RemoveLocationsFromScene(landscape, true); LBEditorHelper.RepaintEditorWindow(typeof(LandscapeBuilderWindow)); } } }
/// <summary> /// Refresh the number of zones in all location items in the scene for this a group. /// Typically called when manual clearing groups are being edited, and the number of zones is changed. /// </summary> /// <param name="landscape"></param> /// <param name="lbGroupLocation"></param> /// <param name="showErrors"></param> public static void RefreshLocationZonesInScene(LBLandscape landscape, LBGroup lbGroupLocation, bool showErrors) { string methodName = "LBGroupLocationItem.RefreshLocationZonesInScene"; // Basic validation if (landscape == null) { if (showErrors) { Debug.LogWarning("ERROR: " + methodName + " landscape is null"); } } else { if (lbGroupLocation == null) { if (showErrors) { Debug.LogWarning("ERROR: " + methodName + " lbGroupLocation is null"); } } else { List <LBGroupLocationItem> lbGroupLocationItemList = new List <LBGroupLocationItem>(); landscape.GetComponentsInChildren(lbGroupLocationItemList); // Update the zone count for all the current location items in the scene for this group if (lbGroupLocationItemList != null) { lbGroupLocationItemList.RemoveAll(locItem => locItem.lbGroup.GUID != lbGroupLocation.GUID); int numItems = lbGroupLocationItemList.Count; for (int i = 0; i < numItems; i++) { LBGroupLocationItem lbGroupLocationItem = lbGroupLocationItemList[i]; lbGroupLocationItem.numZones = lbGroupLocation.zoneList == null ? 0 : lbGroupLocation.zoneList.Count; } } } } }
/// <summary> /// Find all the manual clearing location objects in the scene, filter them by a group, and set their size. /// </summary> /// <param name="landscape"></param> /// <param name="lbGroupLocation"></param> /// <param name="showErrors"></param> public static void RefreshLocationSizesInScene(LBLandscape landscape, LBGroup lbGroupLocation, bool showErrors) { string methodName = "LBGroupLocationItem.RefreshLocationSizesInScene"; // Basic validation if (landscape == null) { if (showErrors) { Debug.LogWarning("ERROR: " + methodName + " landscape is null"); } } else { if (lbGroupLocation == null) { if (showErrors) { Debug.LogWarning("ERROR: " + methodName + " lbGroupLocation is null"); } } else { List <LBGroupLocationItem> lbGroupLocationItemList = new List <LBGroupLocationItem>(); landscape.GetComponentsInChildren(lbGroupLocationItemList); // Update the size of all the current location items in the scene for this landscape if (lbGroupLocationItemList != null) { lbGroupLocationItemList.RemoveAll(locItem => locItem.lbGroup.groupName != lbGroupLocation.groupName); int numItems = lbGroupLocationItemList.Count; for (int i = 0; i < numItems; i++) { LBGroupLocationItem lbGroupLocationItem = lbGroupLocationItemList[i]; lbGroupLocationItem.transform.localScale = new Vector3(lbGroupLocation.maxClearingRadius * 2f, 0.1f, lbGroupLocation.maxClearingRadius * 2f); } } } } }
private void OnSceneGUI() { if (EditorApplication.isPlayingOrWillChangePlaymode) { return; } Event current = Event.current; if (current != null) { if (lbGroupLocationItem == null) { return; } else if (lbGroup == null) { lbGroup = lbGroupLocationItem.lbGroup; if (lbGroup == null) { return; } } bool isLeftButton = (current.button == 0); bool isRightButton = (current.button == 1); tryPosition = lbGroupLocationItem.transform.position; // Clamp position of clearing if (tryPosition.x < landscapeBounds.xMin || tryPosition.x > landscapeBounds.xMax || tryPosition.z < landscapeBounds.yMin || tryPosition.z > landscapeBounds.yMax) { lbGroupLocationItem.transform.position = prevPosition; } // Update prevPostion with the current position prevPosition = lbGroupLocationItem.transform.position; prevPosition.y = LBLandscapeTerrain.GetHeight(landscape, new Vector2(prevPosition.x, prevPosition.z), false) + landscape.start.y; // Snap the clearing location to the terrain height at this point lbGroupLocationItem.transform.position = prevPosition; if (current.type == EventType.MouseDown && isRightButton) { #region Display the Context-sensitive menu // NOTE: The Context Menu that is display when a location is NOT selected, can be found // in LandscapeBuilderWindow.SceneGUI(SceneView sv) GenericMenu menu = new GenericMenu(); menu.AddItem(new GUIContent("Delete Postion"), false, DeleteLocation); menu.AddSeparator(""); menu.AddItem(new GUIContent("Delete ALL"), false, DeleteAll); menu.AddSeparator(""); menu.AddItem(new GUIContent("Unselect"), false, () => { Selection.activeObject = null; }); // The Cancel option is not really necessary as use can just click anywhere else. However, it may help some users. menu.AddItem(new GUIContent("Cancel"), false, () => { }); menu.ShowAsContext(); current.Use(); #endregion } // Record the starting positions else if (current.type == EventType.MouseDown && isLeftButton && landscape != null) { lbGroupLocationItem.position = lbGroupLocationItem.transform.position - landscape.start; lbGroupLocationItem.rotationY = lbGroupLocationItem.transform.rotation.eulerAngles.y; } else if (current.type == EventType.MouseUp && isLeftButton) { if (lbGroup.isFixedRotation) { #if UNITY_2017_3_OR_NEWER if (Tools.current == Tool.Rotate || Tools.current == Tool.Transform) #else if (Tools.current == Tool.Rotate) #endif { // Locate the first matching clearing position // Only check x,z axis as the y-axis may be slightly wrong int idx = lbGroup.positionList.FindIndex(pos => pos.x == lbGroupLocationItem.position.x && pos.z == lbGroupLocationItem.position.z); if (idx > -1) { // update with the new rotation lbGroupLocationItem.rotationY = lbGroupLocationItem.transform.rotation.eulerAngles.y; lbGroup.rotationYList[idx] = lbGroupLocationItem.rotationY; lbGroupLocationItem.transform.rotation = Quaternion.Euler(0f, lbGroupLocationItem.rotationY, 0f); // Update the LB Editor Windows LBEditorHelper.RepaintEditorWindow(typeof(LandscapeBuilderWindow)); } } } #if UNITY_2017_3_OR_NEWER if ((Tools.current == Tool.Move || Tools.current == Tool.Transform) && landscape != null) #else if (Tools.current == Tool.Move && landscape != null) #endif { // Locate the first matching clearing position // Only check x,z axis as the y-axis may be slightly wrong int idx = lbGroup.positionList.FindIndex(pos => pos.x == lbGroupLocationItem.position.x && pos.z == lbGroupLocationItem.position.z); if (idx > -1) { // update it with the new position lbGroup.positionList[idx] = lbGroupLocationItem.transform.position - landscape.start; } } #if UNITY_2017_3_OR_NEWER if (Tools.current == Tool.Scale || Tools.current == Tool.Transform) #else if (Tools.current == Tool.Scale) #endif { lbGroup.minClearingRadius = lbGroupLocationItem.transform.localScale.x / 2f; lbGroup.maxClearingRadius = lbGroup.minClearingRadius; // Update the LB Editor Windows LBEditorHelper.RepaintEditorWindow(typeof(LandscapeBuilderWindow)); // Resize all the locations in the scene LBGroupLocationItem.RefreshLocationSizesInScene(landscape, lbGroup, true); } } #region Changed Rotation // Clamp rotation if (!lbGroup.isFixedRotation) { lbGroupLocationItem.transform.rotation = Quaternion.identity; } //else //{ // Vector3 eulerAngles = lbGroupLocationItem.transform.rotation.eulerAngles; // if (eulerAngles.x != 0f || eulerAngles.z != 0f) // { // //lbGroupLocationItem.transform.rotation = Quaternion.Euler(0f, lbGroupLocationItem.rotationY, 0f); // } //} #endregion #region Changed Radius #if UNITY_2017_3_OR_NEWER if (Tools.current == Tool.Scale || Tools.current == Tool.Transform) #else if (Tools.current == Tool.Scale) #endif { // Equally scale x-z axis float currentScale = lbGroup.minClearingRadius * 2f; float maxScale = -currentScale; Vector3 localScale = lbGroupLocationItem.transform.localScale; // Delta = Abs(localScale.) - currentScale float deltaX = (localScale.x < 0f ? -localScale.x : localScale.x); float deltaY = (localScale.y < 0f ? -localScale.y : localScale.y); float deltaZ = (localScale.z < 0f ? -localScale.z : localScale.z); // Get the max scale amount of any of the axis if (deltaX != currentScale && deltaX > maxScale) { maxScale = localScale.x; } if (deltaZ != currentScale && deltaZ > maxScale) { maxScale = localScale.z; } // Did the user change the scale? if (maxScale != -currentScale) { // Clamp scaling to 0.2 if (maxScale < 0.2f) { maxScale = 0.2f; } localScale.x = maxScale; // Make x-z axis the same localScale.z = localScale.x; // Don't change y-axis localScale.y = 0.1f; lbGroupLocationItem.transform.localScale = localScale; } else if (deltaY > 0f) { // Local Y axis scaling localScale.y = 0.1f; lbGroupLocationItem.transform.localScale = localScale; } } #endregion } }