/// <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);
        }
예제 #2
0
 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);
        }
예제 #4
0
 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);
                        }
                    }
                }
            }
        }
예제 #7
0
        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
            }
        }