Search Unity

Multiplatform Runtime Level Editor

Discussion in 'Assets and Asset Store' started by FreebordMAD, Jun 10, 2014.

  1. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    The problem is that Unity does not allow to mix the forward and the deferrend camera modes with depth-only clear flags where deferred needs to be rendered on top of forward. The deferred and the forward rendering cameras seem to mix the depth and the background textures, which results in ghosting or black areas on the screen. Probably the problem is that deferred rendering must be completed before the forward rendering is done.
    However, having all cameras in deferred mode also does not work. I think that this is a Unity bug and I also don't see any chance to correct this.
    Finally, I don't think that you need to render the UI or the camera perspective gizmo in the deferred mode! Is there any reason for this?
    Everything works fine if you set the UI Camera and the gizmo camera to render in the forward mode, but the main camera to render in the deferred mode.
    Would it be a valid option for you to do the following?
    1. Set Player Settings to render Forward
    2. Set the Main Cameras in all your scenes to render Deferred
    3. Leave all UI Cameras in all your scenes with the Use Player Settings selection
    This way you should have the most performant version. Your world will be rendered deferred, with all the advantages concerning lighting that you need. The UI and the gizmo will be rendered forward, without the overhead of the deferred rendering.
     
    Last edited: Nov 15, 2016
  2. HakJak

    HakJak

    Joined:
    Dec 2, 2014
    Posts:
    192
    I'm slowly figuring out some of your GUI methods. However, I'm stuck on one area: How can I alter the horizontal selection menus, such as the one for selecting Terrain Texture or Paint Brushes (see screenshot below)? I want to show the icons vertically for these 2 menus, instead of horizontally... and preferably 2 or 3 wide.

     
  3. MrIconic

    MrIconic

    Joined:
    Apr 5, 2013
    Posts:
    239
    Are there any new versions coming or is MRLE in its final form?
     
  4. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    The texture selections are implemented in the uMyGUI_TexturePicker class. This script is attached to the child called ScrollRect of the object with the Unity ScrollRect component. I will show you what needs to be done by writing down the steps for the RightMenu_TerrainEdit_Texture object. This is the terrain paint texture selector.
    1. Select the RightMenu_TerrainEdit_Texture in the hierarchy
    2. Mark the Vertical check and disable the Horizontal check of the ScrollRect component
    3. Select the child object ScrollBar and change its Direction to Bottom To Top
    4. Adapt the RectTransform components of ScrollBar and SlidingArea children to make the scroll bar handle be visible vertically
    5. You should now be able to scroll by moving the scroll handle up and down
    6. Select again RightMenu_TerrainEdit_Texture object and set the ScrollBar child to be the Vertical Scrollbar instead of the Horizontal Scrollbar
    7. Now you will not be able to scroll anymore, because you will need to rearange the textures so that they are built from top to bottom instead from left to right
    8. To arrange the textures as you need them change the uMyGUI_TexturePicker.SetTextures method (calculate the positions of the elements e.g. 3 columns, then next row)

    Please ask if something is still unclear!



    The MRLE is my best Asset Store product and it will be further developed in the future. I have a list with things that I want to implement. I also fix bugs instantly if they arise. However, I don't have much time. I have a full time job now (I was a full time indie dev before) + I'm a young father since a few months. Therefore, it can take a long time for new features to be implemented.
     
    MrIconic likes this.
  5. MrIconic

    MrIconic

    Joined:
    Apr 5, 2013
    Posts:
    239
    No worries and congratulations :)
     
    FreebordMAD likes this.
  6. HakJak

    HakJak

    Joined:
    Dec 2, 2014
    Posts:
    192
    Congrats on becoming a father! Do you have a PayPal email address? I would like to send you a gift to help with your new family, and to say thanks for the awesome customer support. :D

    Also, I have some other issues with the level editor that I'm hoping you can help me with, rather urgently. I can usually figure out how to modify Unity store assets to whatever I need, but your coding skills are very advanced and some of the project setup is more complicated than I'm used to. (I still consider myself to be a programming noob.)

    1. How can I bypass the delete button pop-up? I just want to delete the object immediately when I press the delete button in the UI. It's a bit tedious otherwise....
    2. How can I bypass the save/load pop-ups when the user presses the Play button? I would like the level to just be saved to a temporary file and quickly loaded so the player can test it out and make adjustments rapidly while they build. Makes for a much more pleasant user experience.
    3. How can I add a way to Delete existing levels? For example, maybe just a red "X" next to file names in the Save/Load pop-up? I tried deleting levels manually from the save folder, but they still show up on the list and just give an error when trying to load. User needs a way to delete unwanted levels during runtime.
    4. Can't mouse-wheel-scroll over Objects list. Any ideas on how to fix this? Works fine when Categories are collapsed, or mouse pointer is in a gap on the sides, but no scrolling when mouse is over any Object buttons that are used to drag-n-drop items into the scene. (This is a lower priority issue than the others.)
    These could make good updates for the asset in general, or at least the last two.

    Sorry for the laundry list of issues. I'm launching the beta next month and the level editor is a super important part of that, so I'm under some serious crunch time here :confused:
     
  7. HakJak

    HakJak

    Joined:
    Dec 2, 2014
    Posts:
    192
    Also, how do I detect when an object has been deleted?

    I'm able to use LE_EventInterface.OnObjectPlaced to detect when an object has been placed, but I can't find something similar to detect when an object has been deleted. I need this to finish the "level complexity" meter. Please help
     
    Last edited: Nov 28, 2016
  8. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    I first want to explain you how you could search such things in general. This could make it a lot easier for you.
    If you are searching how any action is performed in the editor, then you can just go to LapinerTools/LevelEditor/Scripts/UndoRedoCommands folder. The classes there are representing single tasks performed by the editor. You could create such a task and run it from any of your own scripts.
    If you take a look at the LE_CmdDeleteObject class and search for references, then you will see that the only usage is in the Delete method of the LE_GUI3dObject class.
    Code (CSharp):
    1. UR_CommandMgr.Instance.Execute(new LE_CmdDeleteObject(this, m_selectedObject));
    2. // ... p.s. you could copy paste this to any of your scripts
    The LE_GUI3dObject.Delete method is called by the LE_LogicObjects.ConfirmDelete method. Change the method as below to skip the confirm popup:
    Code (CSharp):
    1.  
    2. // changed
    3.         private void ConfirmDelete()
    4.         {
    5.             m_GUI3dObject.Delete();
    6.         }
    7.  
    8. // original
    9. //     private void ConfirmDelete()
    10. //     {
    11. //       // save current object edit mode and deactivate it
    12. //       LE_EObjectEditMode editModeBK = m_GUI3dObject.ObjectEditMode;
    13. //       m_GUI3dObject.ObjectEditMode = LE_EObjectEditMode.NO_EDIT;
    14. //       // show confirm delete popup
    15. //       LE_GUIInterface.Instance.delegates.ShowPopupConfirmDeleteObject((bool p_isDeleteConfirmed)=>
    16. //       {
    17. //         // delte object if confirmed
    18. //         if (p_isDeleteConfirmed)
    19. //         {
    20. //           m_GUI3dObject.Delete();
    21. //         }
    22. //         // restore the saved edit mode
    23. //         m_GUI3dObject.ObjectEditMode = editModeBK;
    24. //       });
    25. //     }
    26.  


    First please add the following two properties to the FileSelectionExtensionLoader class (I will add them in the next version)
    Code (CSharp):
    1.             public string ReloadLevelName
    2.             {
    3.                 get{ return m_reloadLevelName; }
    4.                 set{ m_reloadLevelName = value; }
    5.             }
    6.  
    7.             public static FileSelectionExtensionLoader Instance { get{ return s_fileSelectionExtensionLoader; } }
    The ExampleGame_Editor.OnPlayButtonClick method is called when the Play button is clicked in the UI. Please change the method as described below:
    Code (CSharp):
    1. // changed
    2.         public void OnPlayButtonClick()
    3.         {
    4.             if (m_lastSaveFrame < LE_LevelEditorMain.Instance.LastChangeFrame)
    5.             {
    6.                 // there are unsaved changes -> save to a temporary file
    7.                 LE_TerrainTextureConfig terrainTextConf = LE_LevelEditorMain.Instance.GetComponentInChildren<LE_ConfigTerrain>().TerrainTextureConfig;
    8.                 byte[] levelData = LE_SaveLoad.SaveCurrentLevelDataToByteArray(terrainTextConf.TERRAIN_TEXTURES);
    9.                 byte[] levelMeta = LE_SaveLoad.SaveCurrentLevelMetaToByteArray(null, new System.Collections.Generic.KeyValuePair<string, string>[0]);
    10.                 ExampleGame_LoadSave.Save("tempLevel.txt", levelData, levelMeta);
    11.                 LE_LevelEditor.Extensions.LE_ExtensionInterface.FileSelectionExtensionLoader.Instance.ReloadLevelName = "tempLevel.txt";
    12.             }
    13.  
    14.             string errorMessage;
    15.             if (IsLevelPlayable(out errorMessage))
    16.             {
    17.                 uMyGUI_PopupManager.Instance.ShowPopup(POPUP_LOADING);
    18.                 StartCoroutine(LatePlay(1));
    19.             }
    20.             else
    21.             {
    22.                 ((uMyGUI_PopupText)uMyGUI_PopupManager.Instance.ShowPopup(POPUP_TEXT)).SetText("Game logic objects missing!", errorMessage).ShowButton("ok");
    23.             }
    24.         }
    25.  
    26. // original
    27. //        public void OnPlayButtonClick()
    28. //        {
    29. //            if (m_lastSaveFrame > LE_LevelEditorMain.Instance.LastChangeFrame)
    30. //            {
    31. //                string errorMessage;
    32. //                if (IsLevelPlayable(out errorMessage))
    33. //                {
    34. //                    uMyGUI_PopupManager.Instance.ShowPopup(POPUP_LOADING);
    35. //                    StartCoroutine(LatePlay(1));
    36. //        
    37. //                }
    38. //                else
    39. //                {
    40. //                    ((uMyGUI_PopupText)uMyGUI_PopupManager.Instance.ShowPopup(POPUP_TEXT)).SetText("Game logic objects missing!", errorMessage).ShowButton("ok");
    41. //                }
    42. //            }
    43. //            else
    44. //            {
    45. //                ((uMyGUI_PopupText)uMyGUI_PopupManager.Instance.ShowPopup(POPUP_TEXT)).SetText(
    46. //                    "Unsaved Changes!",
    47. //                    "There are unsaved changes. You need to save the level before you can play it!").ShowButton("ok");
    48. //            }
    49. //        }


    Find below an excerpt of the FileSelectionExtensionLoader.SaveFile method:
    Code (CSharp):
    1.                     // add new level file name to the list
    2.                     string[] levelFileNames = new string[p_levelFileNames.Length+1];
    3.                     System.Array.Copy(p_levelFileNames, levelFileNames, p_levelFileNames.Length);
    4.                     levelFileNames[levelFileNames.Length-1] = p_fileName;
    5.                     System.Array.Sort(levelFileNames);
    6.                     string levelFileNamesText = "";
    7.                     for (int i = 0; i < levelFileNames.Length; i++)
    8.                     {
    9.                         levelFileNamesText += levelFileNames[i] + "\n";
    10.                     }
    11.                     stringpath=Application.persistentDataPath+"/"+LEVEL_FILE_NAMES_PATH;
    12.                     UtilityPlatformIO.SaveToFile(path,levelFileNamesText);
    The code above will add your level name to an array with all known level names. This array is then saved a to text file where each line is a level name. You can find all known levels in the file at LEVEL_FILE_NAMES_PATH. When you delete a level, then you also need to delete it from this file. Please tell me if you need more guidance here. By the way this is already on the to-do list, but there are some other features with higher priority.



    This was introduced in one of the new Unity versions, I need to fix this. This post describes how you could do this.
    [EDIT:] Fixed, please find the changed LE_ObjectPrefabNode class below:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using UnityEngine.EventSystems;
    4. using System.Collections;
    5. using LE_LevelEditor.Core;
    6. using MyUtility;
    7.  
    8. namespace LE_LevelEditor.UI
    9. {
    10.     public class LE_ObjectPrefabNode : MonoBehaviour, IScrollHandler
    11.     {
    12.         public class SendMessageInitData
    13.         {
    14.             public readonly LE_Object m_object;
    15.             public readonly int m_indentLevel;
    16.             public SendMessageInitData(LE_Object p_object, int p_indentLevel) { m_object = p_object; m_indentLevel = p_indentLevel; }
    17.         }
    18.  
    19.         [SerializeField]
    20.         private Text m_text;
    21.  
    22.         [SerializeField]
    23.         private RawImage m_image;
    24.         public RawImage Image { get{ return m_image; } }
    25.  
    26.         [SerializeField]
    27.         private Image m_selectionImage;
    28.  
    29.         private ScrollRect m_parentScroller = null;
    30.  
    31.         public void uMyGUI_TreeBrowser_InitNode(object p_data)
    32.         {
    33.             if (m_text != null && m_image != null)
    34.             {
    35.                 if (p_data is SendMessageInitData)
    36.                 {
    37.                     SendMessageInitData data = (SendMessageInitData)p_data;
    38.                     // image
    39.                     Texture2D iconTex = (Texture2D)Resources.Load(data.m_object.IconPath);
    40.                     if (iconTex != null)
    41.                     {
    42.                         m_image.texture = iconTex;
    43.                     }
    44.                     else
    45.                     {
    46.                         Debug.LogError("LE_ObjectPrefabNode: uMyGUI_TreeBrowser_InitNode: object '" + data.m_object.name + "'" +
    47.                                        " has an invalid icon resource path! Path: '"+data.m_object.IconPath+"'");
    48.                     }
    49.                     // name
    50.                     m_text.text = UtilityStrings.InsertSpacesIntoCamelCase(data.m_object.name);
    51.                     // resize text due to indent
    52.                     Vector2 offsetMax = m_text.rectTransform.offsetMax;
    53.                     offsetMax.x -= data.m_indentLevel*10f;
    54.                     m_text.rectTransform.offsetMax = offsetMax;
    55.                 }
    56.                 else if (p_data is LE_ObjectCategoryNode.SendMessageInitData)
    57.                 {
    58.                     LE_ObjectCategoryNode.SendMessageInitData data = (LE_ObjectCategoryNode.SendMessageInitData)p_data;
    59.                     Debug.LogError("LE_ObjectPrefabNode: uMyGUI_TreeBrowser_InitNode: the category '" + data.m_categoryName + "' is empty and will not be shown correctly!");
    60.                     m_image.gameObject.SetActive(false);
    61.                     m_text.text = LE_ObjectCategoryNode.GetCleanCategoryName(data.m_categoryName);
    62.                 }
    63.                 else
    64.                 {
    65.                     Debug.LogError("LE_ObjectPrefabNode: uMyGUI_TreeBrowser_InitNode: expected p_data to be a LE_ObjectPrefabNode.SendMessageInitData! p_data: " + p_data);
    66.                 }
    67.             }
    68.             else
    69.             {
    70.                 Debug.LogError("LE_ObjectPrefabNode: uMyGUI_TreeBrowser_InitNode: m_text or m_image were not set via inspector!");
    71.             }
    72.         }
    73.  
    74.         public void OnSelected()
    75.         {
    76.             LE_ObjectDragDrop dragAndDrop = GetComponentInParent<LE_ObjectDragDrop>();
    77.             if (dragAndDrop != null)
    78.             {
    79.                 dragAndDrop.OnObjectSelected(this);
    80.             }
    81.             else
    82.             {
    83.                 Debug.LogError("LE_ObjectPrefabNode: OnSelected: could not find LE_ObjectDragDrop in parents!");
    84.             }
    85.             ShowSelection();
    86.         }
    87.  
    88.         public void ShowSelection()
    89.         {
    90.             if (m_selectionImage != null) { m_selectionImage.color = Color.green; }
    91.             if (m_text != null) { m_text.color = Color.green; }
    92.         }
    93.  
    94.         public void HideSelection()
    95.         {
    96.             if (m_selectionImage != null) { m_selectionImage.color = Color.white; }
    97.             if (m_text != null) { m_text.color = Color.white; }
    98.         }
    99.  
    100.         public void OnScroll(PointerEventData data)
    101.         {
    102.             // try to find the parent ScrollRect
    103.             if (m_parentScroller == null)
    104.             {
    105.                 m_parentScroller = GetComponentInParent<ScrollRect>();
    106.             }
    107.  
    108.             // cannot do anything without a parent ScrollRect -> return
    109.             if (m_parentScroller == null)
    110.             {
    111.                 return;
    112.             }
    113.  
    114.             // forward the scroll event data to the parent
    115.             m_parentScroller.OnScroll(data);
    116.         }
    117.     }
    118. }
    119.  


    LE_EventInterface.OnChangeLevelData will be called with event type LE_ELevelDataChangeType.OBJECT_DELETE.



    Thanks for the congrats. You would make my wife happy with that ;), I'll send you a private message.
     
    Last edited: Nov 28, 2016
    HakJak likes this.
  9. HakJak

    HakJak

    Joined:
    Dec 2, 2014
    Posts:
    192
    Thank you for the thorough response, and especially for pointing out where I can find more answers for myself. Very helpful and easy to implement.

    I'll try to wait until you have time to add the File Delete feature, since it's already on your to-do list and I don't want to screw it up... especially since it involves deleting stuff. I'll just let users know it's coming later and work on other things for now.
     
    Last edited: Nov 28, 2016
  10. montyfi

    montyfi

    Joined:
    Aug 3, 2012
    Posts:
    548
    @FreebordMAD I'm using RTP on custom terrain, it works fine in editor, but outside of editor it is always standard material, without any additional scripts. Could you please explain how to use custom material/script on terrain?

    FIXED: I don't know if there is more straightforward way, but I just replaced .CreateTerrainGameObject(p_terrainData) in your code with modifying terrain data of existing terrain.
     
    Last edited: Dec 6, 2016
    FreebordMAD likes this.
  11. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    I'm glad that you could fix this yourself! Unfortunately, I'm on holidays right now and I cannot test this myself. As far as I understand you have a prepared terrain in your editor scene. Do you also have the same prepared terrain object in your game scene? Doesn't the MRLE automatically use the prepared terrain in the game scene? Is a new terrain created?
     
  12. HakJak

    HakJak

    Joined:
    Dec 2, 2014
    Posts:
    192
    Heeeey! I'm working on integrating my game with Steamworks Workshop for level sharing. I'm just reading through the documentation right now and it looks pretty complicated. I'm also using Steamworks.NET wrapper.

    I saw that your game, Mad Snowboarding, is on Steam. How did you go about allowing player's to share levels with others? Do you have Workshop integration with any of your games? Any advice on how I should go about sharing levels with the community? Any help would be greatly appreciated!
     
  13. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    I have not integrated the Steam Workshop my self, but the RC Simulation 2.0 game does. As far as I know the levels are saved to a file and the uploaded automatically to the Steam Workshop. Maybe you can drop the RC Sim dev a mail...
     
    HakJak likes this.
  14. HakJak

    HakJak

    Joined:
    Dec 2, 2014
    Posts:
    192
    Well, the RC 2.0 dev never got back to me, but I managed to figure it out :cool:
    I can now upload custom levels to Steam Workshop and I'm working on integrating the downloads into the game. Woot!


    However, I really need your help with a couple issues preventing me from being ready for the Steam Early Access beta. I'm under a ton of pressure to get this ready asap, so I will be sure to show my appreciation for your help! ;)


    Issue #1: How do I load a level and it's metadata into a scene?

    When the user presses a level button, it will take them to a staging scene. I then need it to load the level data and metadata, according to the level name. I know this is super basic, but I'm just stuck.

    I tried using the example code in the documentation (see below), but it is incomplete, and I can't figure out how to get it to point to the external file and location it needs to load from. (Keep in mind, this will be a different location than the levels made by the user in the Level Editor... that part all works great!)

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using LE_LevelEditor.Core;
    4.  
    5.  
    6. public class CommunityLevelManager : MonoBehaviour
    7. {
    8.     // This serialized field should be defined in the top of this class. Its value should be
    9.     // assigned through the Unity editor's inspector.
    10.     [SerializeField]
    11.     private LE_TerrainTextureConfig TERRAIN_TEXTURE_CONFIG = null;
    12.  
    13.     public void LoadCommunityTrack()
    14.     {
    15.         // You will probably load your level's data from a file here
    16.         byte[] dataAsByteArray = ...;
    17.  
    18.         // Load the level from the byte array. Since there are no editor scripts in this scene the terrain
    19.         // texture configuration is not defined and needs to be passed to the LoadLevelDataFromByteArray method.
    20.         // In this example we expect TERRAIN_TEXTURE_CONFIG to be a serialized property of this class.
    21.         LE_SaveLoadData level = LE_SaveLoad.LoadLevelDataFromByteArray(
    22.             dataAsByteArray,
    23.             // pass '0' to put the terrain in the 'Default' layer. Something like LayerMask.NameToLayer("Terrain") is also possible
    24.             0,
    25.             TERRAIN_TEXTURE_CONFIG.TERRAIN_TEXTURES,
    26.             TERRAIN_TEXTURE_CONFIG.TERRAIN_TEXTURE_SIZES,
    27.             TERRAIN_TEXTURE_CONFIG.TERRAIN_TEXTURE_OFFSETS);
    28.  
    29.         // call this function to destroy level editing scripts and improve performance
    30.         LE_SaveLoad.DisableLevelEditing(level);
    31.  
    32.  
    33.         // You could make some default operations on the level, since it is fully loaded now
    34.         // For example you could move the player to the start position and make the camera look at him
    35.     }
    36. }

    Issue #2: In the Level Editor, how can I save the .txt and .png level files into sub-folders of the same name, instead of everything getting dumped into the same folder? For example: "MyLevelName" folder --> "MyLevelName.txt" and "MyLevelName.png" inside that folder.

    I need the levels saved in this manner in order to work properly with Steam Workshop, but the save/load functions of this asset confuse the hell outta me so I don't even know where to begin to customize them. I'm at my wits end and just need to resolve it :confused:

    Thank you so much for your time and expertise!
     
  15. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    I'm on holidays till mid of next week. I don't have access to my code.

    Issue #1: Load Community Levels.
    Take a look at the FileSelectionExtensionLoader there you should find save and load methods. You will probably need to change logic using the LEVEL_FILE_NAMES_PATH property. Use a different path if it is a community level. You should set the last loaded level name member in this class, then the example game scene would load this level.
    You could also completely rewrite this class. I think that it is more complex than you need it. The reason for the level names being saved in a list is that on some platforms you cannot scan a folder and get all file names, but for you it could be easier to just scan folders and collect all level names.
    You can also send me the classes of the save/load extension via e-mail, then I can tell you more precisely what needs to be done. However, I'm writing from a phone and cannot test or compile anything.

    Issue #2: This is again the same class of the extension package. This package simply sets the save and the load delegates which are then called by the level editor.

    I'm sorry that I cannot help you more. Please send me script files that you want me to explain via email for further help.
     
  16. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    Guts and Glory will soon be available on Steam! Checkout @HakJak's video showing his Multiplatform Runtime Level Editor integration.


    Read the whole article here:
    http://www.indiedb.com/games/guts-and-glory/news/guts-and-glory-level-editor-sneak-peek
     
    mfleurent likes this.
  17. HakJak

    HakJak

    Joined:
    Dec 2, 2014
    Posts:
    192
    Hey where can I edit the pop-up message that appears when a user saves a level? The one that shows the file path? I figured out the rest of the pop-ups, but can't find that one.
     
  18. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    Please take a look at the LE_FileSelectionHelpers.SaveLevel method.
    The code below defines the popup:
    Code (CSharp):
    1.             // info popup
    2.             System.Action<string> infoPopup = (string p_infoText)=>
    3.             {
    4.                 if (uMyGUI_PopupManager.Instance != null)
    5.                 {
    6.                     if (p_removedDuplicatesCount > 0)
    7.                     {
    8.                         p_infoText += "\n'" + p_removedDuplicatesCount + "' duplicate object(s) removed before saving\n(duplicate = same: object, position, rotation, scale).";
    9.                     }
    10.                     ((uMyGUI_PopupText)uMyGUI_PopupManager.Instance.ShowPopup(POPUP_TEXT)).SetText("Level Saved", p_infoText).ShowButton("ok");  
    11.                 }
    12.             };
    The code line below shows the popup and adds the level size and location information to it:
    Code (CSharp):
    1.             // save level
    2.             infoPopup(ExampleGame_LoadSave.Save(new FileInfo(p_levelDataFilePath), p_levelData, p_levelMeta));
     
    HakJak likes this.
  19. Banksy

    Banksy

    Joined:
    Mar 31, 2013
    Posts:
    376
    Does this Level Editor support Unity NavMesh ?
     
  20. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    Hi and sorry for the late reply!

    As far as I know this is unfortunately not possible, because Unity NavMesh data needs to be baked in the Editor before the game is compiled/built. Therefore, it is impossible to create NavMeshes at runtime.
     
  21. devotid

    devotid

    Joined:
    Nov 14, 2011
    Posts:
    445
    Hey @FreebordMAD I just finally got updated to the newest version and am working on some big changes and features.... I have one question.

    Whats the best way to get the transform position of the OnSelectedGameObject? I just need the Vector3 so I can update the camera position of my custom camera controller. It seems that when I use your "focus" on selected game object method in the LE GUIinterface, The focus "distant is always different for different size objects.

    What depicts the zoom distance? The size of the object on screen? The overall volume of the gameobject? Its seems to work good but on larger objects like a house it seems to not get close enough for my custom camera controller. So If I had the Transform vector3 Postion I could just use my own "zoom setup".

    I have been trying to get it with this code you gave me way long ago....

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using LE_LevelEditor.Events;
    4.  
    5. public class ObjectSelectionTest : MonoBehaviour
    6. {
    7.     public string SELECTED_OBJECT_RESOURCE_PATH = "";
    8.     public Vector3 SELECTED_OBJECT_POSITION ;
    9.  
    10.     private void Start()
    11.     {
    12.         LE_EventInterface.OnObjectSelectedInScene += OnObjectSelectedInScene;
    13.     }
    14.  
    15.     private void OnDestroy()
    16.     {
    17.         LE_EventInterface.OnObjectSelectedInScene -= OnObjectSelectedInScene;
    18.     }
    19.  
    20.     private void OnObjectSelectedInScene(object p_obj, LE_ObjectSelectedEvent p_args)
    21.     {
    22.         SELECTED_OBJECT_RESOURCE_PATH = p_args.SelectedObject!=null ? p_args.SelectedObject.name : "";
    23.         SELECTED_OBJECT_POSITION = p_args.SelectedObject.transform.position ; // NOTES: I tried this but it will act weird when I try to "unselect somthing in the scene. ie clicking off into space to hide the move, rotate or scale cursors.
    24.     }
    25. }
    Thanks very much for your help. :)
     
  22. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    The object's size is calculated in the LE_GUI3dObject.Focus method. All renderers are iterated and the average of their bounds is calculated. The final distance is size * 3:
    I think that the easiest solution for you would be to tweak the distance at this place.

    In your code you would need to check for p_args.SelectedObject not being null. Similar to the line above. Besides, you would not get the right position after the object being moved. If you want to go with OnObjectSelectedInScene, then you need to store the Transform instead of the Vector3 at time of selection.
     
    HakJak likes this.
  23. Banksy

    Banksy

    Joined:
    Mar 31, 2013
    Posts:
    376
    Hi ya... I bit the bullet and made the purchase.

    So just wanted to say HI :) & I'll be asking a few Qs in coming days to get up and running.

    p.s - I found out at Christmas time my wife is pregnant... (11 wks,)

    early days
     
    Last edited: Jan 9, 2017
  24. Banksy

    Banksy

    Joined:
    Mar 31, 2013
    Posts:
    376
    V.R camea

    I plan to run the editor in the normal single camera mode & then load the saved environment into a different scene which contains a VR camera attached to the character. (HTC Vive )

    [ Edit] I have managed to get a scene that I edited & saved running in V.R

    Q.
    How can save out multiple scenes ? ( the example scene only allows for one )
     
    Last edited: Jan 9, 2017
  25. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    This p.s. seems to be the most important news. Hence, congrats and all the best for your kid!
    I have a 9 month old son ;)

    Nice, feel free to post a screenshot if you want!

    There is an extension package that allows to save multiple scenes: http://u3d.as/nsD
    If you plan to release on Steam, I have a reworked version of this package that stores the levels in a folder structure that can be uploaded to Steam Workshop (the Workshop integration itself is not yet included).

    However, you can also implement your own save/load mechanics:
    http://www.freebord-game.com/index.php/multiplatform-runtime-level-editor/documentation/save
    http://www.freebord-game.com/index.php/multiplatform-runtime-level-editor/documentation/load
     
  26. VisualProdigy

    VisualProdigy

    Joined:
    Dec 17, 2016
    Posts:
    3
    Hello I`m new to Uniti and Runtime level editor is my first project. Can I say that you have don an excellent job with documentation and what is what. I stil have some questions.

    1.The bug when scrolling through the menu, camera moves to.
    2. Why are all (your) textures for terrain in bulded game blurred or lo rez
    3. When i load my texture it does not show in final game
    4.It would be cool if you could select multiple object at runtime
     
  27. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    Welcome to the Unity forum!

    If you mean that the camera moves when scrolling inside the object selection, then I can tell you that this is on the list already and should be fixed in the next release.

    Maybe the problem is that you have low quality settings. Take a look at the documentation below, try to set the default setting to Fantastic.
    https://docs.unity3d.com/Manual/class-QualitySettings.html
    If this does not help, then please post a screenshot of your problem here.

    Please give me more details for this. Where do you "load a texture"?

    This is on the list, but currently it does not have any priority. It could take some time until this feature is implemented. The MRLE is meant to be as easy as possible so that players can create levels (on all platforms) without having any developer background. Hence, there is no mass selection yet.

    Thank you, I'm glad to hear that you like what you see! If you would post this in a review on the Asset Store, then you would help me a lot!
     
  28. VisualProdigy

    VisualProdigy

    Joined:
    Dec 17, 2016
    Posts:
    3
    I have red the documentation did not help. The Quality setting are all ok, the rez was bad from the start when I downloaded it. This should be grass on the floor.

    Untitled-2.jpg
     
  29. VisualProdigy

    VisualProdigy

    Joined:
    Dec 17, 2016
    Posts:
    3
    I mean in TerrainTextureConfig. I make my own texture and put it in here but it does not show in bild game, only black color on my terrain.
     
  30. HakJak

    HakJak

    Joined:
    Dec 2, 2014
    Posts:
    192
    I doubt it's an issue with MRLE. Working perfectly for me
     
    FreebordMAD and VisualProdigy like this.
  31. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    Please try to play with the TerrainTextureConfig.TerrainTextureSizes property (e.g. try setting the sizes to 1).
    Also select the texture files and check in the inspector if the texture size is reduced for your platform or in the default settings.
    What is the size of your terrain?
    Do the textures look odd in the demo level?
    Which Unity version are you using?

    Please try to put your textures in a resources folder, this way they will be forced to be included in the built.
    Do I understand right that it works in the Unity Editor, but not in the built game (e.g. .exe file)?
    Which platform are you building for?
    Which Unity version are you using?
     
  32. HakJak

    HakJak

    Joined:
    Dec 2, 2014
    Posts:
    192
    FYI, some users are reporting that they see no green outline on selected objects. Maybe there is a problem with the LE_SelectionOutlineShader? Here are the computer specs of one user who reported the issue: http://i.imgur.com/MIGWpOZ.png

    Where can I edit the code to replace this shader with a different one to test?
     
  33. devotid

    devotid

    Joined:
    Nov 14, 2011
    Posts:
    445
    I dont think it is a shader prob. I found that the highlight prefab is just in the wrong order in the hierarchy... So I just wrote a small script to make sure it is placed in last in the parent and below all of the other generated prefabs in the list. To test this theory just run the game in the Unity editor and then after the objects are loaded in whatever list.... drag the highlight prefab to the bottom of the list. It should show the object as highlighted now. (as before it was hiding behind the images.)

    Hell, you may even be able to change its depth somehow.
     
    HakJak likes this.
  34. devotid

    devotid

    Joined:
    Nov 14, 2011
    Posts:
    445
    Im getting different icons generated somehow with the LE_Object script. Do the player settings change the icons generation? Ie; If I generate the icons in Forward Lighting as opposed to Deferred Lighting? Or in Gamma Lighting as opposed to Linear Lighting. I think when I switched to Linear lighting from the gamma mode I lost the Alpha layer on the Icons as they are not transparent anymore. I have some icons that are like a png with a transparent background and then some of them are JPG style where there is no Transparency at all. Im getting inconsistent results.

    Any tips? I plan on deleting them all and starting over but Im just trying to save myself some time to only do it once next time.

    Thanks again. :)

    devotid
     
  35. HakJak

    HakJak

    Joined:
    Dec 2, 2014
    Posts:
    192
    Had the same thing happen to me on a couple icons, but not sure why. I just made custom icons for those and updated the icon file path. Don't know the cause though.

    Thanks for the tip above. I'll give it a try.
     
  36. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    There are two outlines in the MRLE.
    1. The 3d outline. It is created with a very simple shader (LE_SelectionOutlineShader) that should work on all platforms on all machines. A copy of the object's mesh is created and the outline shader applied to it. The 3d outline is handled in the LE_Object.LateUpdate and the LE_Object.ApplySelectionState methods.

    2. The tree browser icon outline. It is a simple sprite that is colored green. It is handled in the LE_ObjectPrefabNode. ShowSelection and LE_ObjectPrefabNode. HideSelection methods.

    Which outline do you mean? Were you able to reproduce the problem?



    The icons are rendered by the LE_ObjectMapInspector. RenderPreviewIcons method. To render the icon I use the Unity AssetPreview.GetAssetPreview(go) method. This way I get the same image as you can see in the inspector's preview. Then I try to set the alpha of the background to transparent by checking for a certain color. However, this method does not always work and that is why I assume that the first and the last pixel must be the background color if they match. Please check if you see this warning:
    "LE_ObjectMapInspector: RenderPreviewIcons: internal error! The background of the generated icon is not completely cleared!" when generating your icon.
    [EDIT:] have you updated the MRLE? The fallback with the first and last pixel was added in one of the recent patches (Patch v1.22)...
     
    Last edited: Jan 17, 2017
  37. Banksy

    Banksy

    Joined:
    Mar 31, 2013
    Posts:
    376
    hi yas... I'm still here just getting things up and running.

    will post my Qs shortly
     
    FreebordMAD likes this.
  38. HakJak

    HakJak

    Joined:
    Dec 2, 2014
    Posts:
    192
    What is the proper way to go about adding additional keyboard shortcuts? Single key and key combos.

    I'm sure others will find this info useful as well.
     
  39. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    Unfortunately, this is something that I didn't find the time to refactor yet.
    The right way to do it would be:
    - add new methods to LE_IInputHandler interface
    - the LE_LevelEditorMain derives from the LE_IInputHandler interface, which would force you to implement it there
    - the LE_LevelEditorMain should not do any complex logic itself and forward the work to one of the logic classes like LE_GUI3dObject, LE_GUI3dTerrain, LE_LogicTerrain, LE_LogicLevel
    - the new key combos should be defined in the LE_InputDeviceKeyboard class
    Having it done as described above would keep all key combo logic in one place. Porting it to other platforms would be easier, because only one class is affected and there is no need to search for input logic. Besides, different devices, e.g. a touchscreen could define gestures without changing any logic, but by simply extending the touchscreen device class.

    However, you will see that the current key combos are scattered across the project...
     
  40. HakJak

    HakJak

    Joined:
    Dec 2, 2014
    Posts:
    192
    Hey no worries, that helped me figure it out. I just used LE_LevelEditorMain.Instance.EditMode to check mode, and then LE_GUIInterface.Instance.OnObjectEditModeBtn to switch tools based on keyboard input.
     
  41. nirvanajie

    nirvanajie

    Joined:
    Jan 7, 2016
    Posts:
    42
    I want to use your Camera Perspective Gizmo to rotate the camera . I check the demo on your web site (http://www.freebord-game.com/index.php/camera-perspective-gizmo). In this demo we can hold the left mouse button on Camera Perspective Gizmo to rotate the camera. How can I do the same thing in MRLE ?
     
  42. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    In the MRLE you can rotate the camera around an object by holding the left or right mouse key while you are holding alt.
    In the Camera Perspective Gizmo the camera is always rotated when holding the left mouse button, not only when the gizmo is hovered. See code below:
    Code (CSharp):
    1. // mouse look
    2.     private Vector3 m_mousePos = Vector3.zero;
    3.     private void Update ()
    4.     {
    5.         if (Input.GetMouseButton(0) && m_mousePos.sqrMagnitude > 0)
    6.         {
    7.             Camera.main.transform.RotateAround(m_gizmo.Pivot, Vector3.up, Input.mousePosition.x - m_mousePos.x);
    8.             Camera.main.transform.RotateAround(m_gizmo.Pivot, Camera.main.transform.right, m_mousePos.y - Input.mousePosition.y);
    9.         }
    10.         m_mousePos = Input.mousePosition;
    11.     }
    So do you still want to change something in the MRLE?
     
  43. nirvanajie

    nirvanajie

    Joined:
    Jan 7, 2016
    Posts:
    42
    Can I rotate the camera around an object by touch control on mobile?
     
  44. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    This is not yet implemented. If you want to do it yourself, then you can take a look at the LE_InputDeviceTouchscreen class. Define a new gesture and call m_inputHandler.RotateCameraAroundPivot in OnTouchGestureDetected method.
     
  45. nirvanajie

    nirvanajie

    Joined:
    Jan 7, 2016
    Posts:
    42
    That's great! I will try to figure it out.
     
  46. Banksy

    Banksy

    Joined:
    Mar 31, 2013
    Posts:
    376
    I've managed to get the demo MRLE running...
    What's the best method to add my project, I have one scene that I'd like to add

    is there a tutorial that walks through the process ?
     
  47. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    You can simply load the MRLE main scene from your game.
    In the menus you can change the exit button to "Go Back" to get back into your game.
     
  48. Banksy

    Banksy

    Joined:
    Mar 31, 2013
    Posts:
    376
    I'm not sure what you mean by " you can simply load the MRLE scene from your game " ?

    to date I've been able to run MRLE Demo scene by creating a new project..but am unsure as to setting up within my project.

    Is there a walkthrough of adding MRLE to a project ?
     
    Last edited: Feb 1, 2017
  49. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    There is no walkthrough. Please tell me in more details how you want to use the MRLE.
    Some of the things you probably would need to do:
    1. Import the MRLE package into your existing project.
    2. Add a "Level Editor" button to your main menu and load the LE_ExampleEditor scene.
    3. Remove the demo objects and add your objects to the object maps.
    folder: LapinerTools\LevelEditor\Example\ObjectMaps\
    docs: http://www.freebord-game.com/index....time-level-editor/documentation/level-objects
    4. Modify the TerrainTextureConfig to fit your game's terrain and style.
    docs: http://www.freebord-game.com/index....e-level-editor/documentation/terrain-textures

    Once you are through with these, we can work on the next steps, such as replacing the demo game scene with the your game's scene, adding a back to menu button to the MRLE menus, changing the terrain brushes, etc.
     
    devotid likes this.
  50. Banksy

    Banksy

    Joined:
    Mar 31, 2013
    Posts:
    376
    Ok I'll check it out over the weekend... I think i need to have good sit down and read over the docs.. but just want to say that your last message was really great as it has provided me much better comprehension of the initial setup.
     
    FreebordMAD likes this.