Search Unity

Multiplatform Runtime Level Editor

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

  1. PLLART

    PLLART

    Joined:
    Jan 9, 2016
    Posts:
    2
    Hi Denis, thank you for your anwser! Yes, I get errors telling me that the object cannot be found. I am not a coder as you are, but I am familiar with it and will try something. I think that if I use
    Code (CSharp):
    1. transform.GetChild
    In the LE_Object script, then I could simply save its values(position,rotation,scale) with the LE_SaveLoad script.

    Also, do you have any piece of code lying around that you could share to make your editor to save/load terrain details(grass and detail meshes)? I tried something already, but it didnt work :(

    Thank you for your excellent support! :D
     
    Last edited: Jan 10, 2016
  2. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    Ok, tell me if you will run into problems with that. If hacking LE_SaveLoad will not work, then you can also take a look at LE_EventInterface.OnCollectMetaDataBeforeSave. You could search for all LE_Objects with child LE_Objects, then identify them by the position of the parent and save the data in p_args.LevelMetaData.


    Have you made some code to change the grass and details of the terrain? I'm asking, because the MRLE does not provide any built-in functionality to do this. Take a look at the pure terrain editor instead of saving the grass and details data a default terrain with grass and details is provided.
    [EDIT:] here is a post of another MRLE user who has worked on grass and details:
    http://forum.unity3d.com/threads/multiplatform-runtime-level-editor.250920/page-5#post-2406783

    You are welcome! I'm sorry that right now I have not more time to post you some scripts...
     
    Last edited: Jan 10, 2016
  3. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    I have finished the File Selection feature. You will be now able to save and load files. However, it will take a week or two until this patch is out in the Asset Store. If you want to get it earlier you could send me your e-mail address.
    MRLE_FileSelection_Load00.png MRLE_FileSelection_Save00.png MRLE_FileSelection_ConfirmOverwrite00.png
     
    FaberVi, musou0, PLLART and 1 other person like this.
  4. musou0

    musou0

    Joined:
    Dec 2, 2015
    Posts:
    16
    Thanks very much! I'm not in a hurry, so I'll be waiting for the upgrade on the store.
     
  5. Der_Kevin

    Der_Kevin

    Joined:
    Jan 2, 2013
    Posts:
    517
    nono, totally fine. wont have anything releaseable/playable anytime soon. was just interested in the status since it just appeared here :)
    ah, got it. thanks ;)
    awesome! just as a side note or feedback: a thumbnail of the level would be nice :) so actually just using the rendered level icon
     
  6. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    This is a very good idea! I will add it in the next patch. I don't want to cancel the submission process for the version that I have now.
     
    Der_Kevin likes this.
  7. Der_Kevin

    Der_Kevin

    Joined:
    Jan 2, 2013
    Posts:
    517
    awesome :)
    i am currently trying to solve the following problem: i have 4 spawnpoints objects in my leveleditor (just a colored cube with the names spawn1-4) and i want to force the player to use all of them. otherwise you can not play the level.
    i know it works with the PlayerSpehere that is in the example but i can not find the place where i can set the minimum requirements for a level?

    edit:
    ah, i think i got it. its in the ExampleGame_Editor.cs right?
    is this the right way to do it?

    Code (CSharp):
    1. private bool IsLevelPlayable(out string o_errorMessage)
    2.         {
    3.             // check if player position is defined
    4.             GameObject goSpawnpoint1 = GameObject.Find("GameLogic/Spawn_Player1");
    5.             GameObject goSpawnpoint2 = GameObject.Find("GameLogic/Spawn_Player2");
    6.             GameObject goSpawnpoint3 = GameObject.Find("GameLogic/Spawn_Player3");
    7.             GameObject goSpawnpoint4 = GameObject.Find("GameLogic/Spawn_Player4");
    8.             if (goSpawnpoint1 == null && goSpawnpoint2 == null && goSpawnpoint3 == null && goSpawnpoint4 == null)
    9.             {
    10.                 o_errorMessage = "You must define the\n<b>player start position</b>\nfor this level!\n" +
    11.                     "1. Go to Objects->GameLogic in the right window.\n" +
    12.                     "2. Drag and drop the player capsule into the level.";
    13.                 return false;
    14.             }
    15.             o_errorMessage = "";
    16.             return true;
    17.         }
    edit2:
    no, that seams to be wrong. i can also test the level even if i just have 1 spawnpoint in my level.

    also another question: is it somehow possible to move the level objects freely? so not with the handles, just normal dragging?

    thanks!
     
    Last edited: Jan 13, 2016
    FreebordMAD likes this.
  8. Der_Kevin

    Der_Kevin

    Joined:
    Jan 2, 2013
    Posts:
    517
    i have another question :)
    how can i determinate in the ExampleGame scene if all objects are loaded?
    I wanted to set some arrays with a specific tag in an array like this:

    Code (CSharp):
    1. private void Awake ()
    2.         {
    3.  
    4.         GameObject[] m_TargetsGO = GameObject.FindGameObjectsWithTag("Player");
    5.        
    6.         m_Targets = new Transform[m_TargetsGO.Length];
    7.        
    8.         for(int i = 0; i < m_TargetsGO.Length; ++i)
    9.         {
    10.             m_Targets[i] = m_TargetsGO[i].transform;
    11.             numberOfTargets = m_TargetsGO.Length;
    12.         }
    13.         }
    14.  
    but when i call it on Awake, it wont find anything because the objects are not there at frame 1. it works perfect when i change Awake to Update but i dont want to call it the whole time?
     
  9. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    You have to use || instead of &&. You want to check if one of the spawn points is not defined and not if all of them are not defined ;)
    Code (CSharp):
    1. if (goSpawnpoint1 == null || goSpawnpoint2 == null || goSpawnpoint3 == null || goSpawnpoint4 == null)
    Do we speak about drag&dropping them as if you would drag&drop a new object?

    In the example game script (ExampleGame_Game) you will find this code:
    Code (CSharp):
    1.  
    2. // load level data (we do not need p_levelData[1], since it contains only meta data for example the level icon)
    3. // however, you might want to load it as well when you add other information to it for example the level time
    4. LE_SaveLoadData level = LE_SaveLoad.LoadLevelDataFromByteArray(
    5.     p_levelData[0],
    6.     TERRAIN_LAYER,
    7.     TERRAIN_TEXTURE_CONFIG.TERRAIN_TEXTURES,
    8.     TERRAIN_TEXTURE_CONFIG.TERRAIN_TEXTURE_SIZES,
    9.     TERRAIN_TEXTURE_CONFIG.TERRAIN_TEXTURE_OFFSETS);
    10. // call this function to destroy level editing scripts and improve performance
    11. LE_SaveLoad.DisableLevelEditing(level);
    This code loads the level. After executing LoadLevelDataFromByteArray your level is fully loaded. You could use the returned level object to iterate over all loaded objects or you can execute your FindGameObjectsWithTag code here.
     
  10. Der_Kevin

    Der_Kevin

    Joined:
    Jan 2, 2013
    Posts:
    517
    ah, thanks. beginner mistake :)

    yeah, now as you mentioned it, exactly this behavior :)

    i think i need more help with this :(
    so, i want to call a function SpawnStuff. my idea was to do it like this:

    Code (CSharp):
    1. if (p_levelData != null && p_levelData.Length > 0 && p_levelData[0] != null)
    2.                 {
    3.                     // load level data (we do not need p_levelData[1], since it contains only meta data for example the level icon)
    4.                     // however, you might want to load it as well when you add other information to it for example the level time
    5.                     LE_SaveLoadData level = LE_SaveLoad.LoadLevelDataFromByteArray(
    6.                         p_levelData[0],
    7.                         GameObject.Find("GameManager").GetComponent<Game>().SpawnStuff();
    8.                         TERRAIN_LAYER,
    9.                         TERRAIN_TEXTURE_CONFIG.TERRAIN_TEXTURES,
    10.                         TERRAIN_TEXTURE_CONFIG.TERRAIN_TEXTURE_SIZES,
    11.                         TERRAIN_TEXTURE_CONFIG.TERRAIN_TEXTURE_OFFSETS);
    12.                     // call this function to destroy level editing scripts and improve performance
    13.                     LE_SaveLoad.DisableLevelEditing(level);
    14.                 }
    15.                 else
    16.                 {
    17.                     Debug.LogError("ExampleGame_Game: No saved level found!");
    18.                 }
    this is calling this stuff:

    Code (CSharp):
    1. public void SpawnStuff () {
    2.         Debug.Log ("Spawn");
    3.         Spawnpoint2 = GameObject.Find("CameraRig").GetComponent<SpawnManager>().m_Spawn[1];
    4.  (Instantiate (SpawnObjects[nav1Position], Spawnpoint1.transform.position, Quaternion.identity) asGameObject).transform.parent = Spawnpoint1.transform;
    5.  
    what i want to do with this behavior is spawning a prefab at a defined point which will be defined by the user in the leveleditor. everything works fine when i exectute the SpawnStuff on keypress (if Key go down SpwnStuff and so on...) but it doesent work when i execute the Spawn Stuff after the LoadLevelDataFromByteArray
     
  11. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    I fear your coding skills will not be enough to do this, but I agree that this is a useful feature. I will put it on the list. However, I'm working full time right now. Unfortunately, I have almost no time for development of my own products. Therefore, I cannot tell you when I will be able to implement this.



    The problem that you have now is that you are searching for "CameraRig", but the object will be called something like "Objects/CameraRig". The name of each loaded object is its full resource path. In ExampleGame_Game you will find the code line:
    Code (CSharp):
    1. GameObject goPlayerStart = GameObject.Find("Objects/PlayerStartPosition");
    This line find the object just after LoadLevelDataFromByteArray. You just need to use the right object name. You can look how your object is called in the hierarchy of the loaded scene on runtime.
     
  12. Der_Kevin

    Der_Kevin

    Joined:
    Jan 2, 2013
    Posts:
    517
    nope,CameraRig is right, its nothing that you have place in the level editor. its already in the ExampleGameScene. Like the GameLogic Object for example. but i just added a delay of 0.5f before i call the SpwanStuff function and now it works. so:

    Code (CSharp):
    1. private void Start ()
    2.         {
    3.             StartCoroutine(ExampleGame_LoadSave.LoadRoutine(LEVEL_FILE_NAME, (byte[][] p_levelData)=>
    4.             {
    5.                 if (p_levelData != null && p_levelData.Length > 0 && p_levelData[0] != null)
    6.                 {
    7.                    ...
    8.                 }
    9.                 else
    10.                 {
    11.                     Debug.LogError("ExampleGame_Game: No saved level found!");
    12.                 }
    13.  
    14.                 // here is the important line:
    15.               GameObject.Find("GameManager").GetComponent<Game>().SpawnStuff();
    16.                 GameObject goPlayerStart = GameObject.Find("Objects/PlayerStartPosition");
    17.                 if (goPlayerStart != null)
    and then:
    Code (CSharp):
    1.     public void SpawnStuff () {
    2.         StartCoroutine(DelayedKick());
    3.                 }
    then:
    Code (CSharp):
    1. private IEnumerator DelayedKick()
    2.     {
    3.         yield return new WaitForSeconds(0.5f);
    4.          (Instantiate (SpawnObjects[nav1Position], Spawnpoint1.transform.position, Quaternion.identity) as GameObject).transform.parent = Spawnpoint1.transform;
    5.        
    it works for now but maybe it wont if the loading time is more then 0.5f. but its okay for now

    its okay, i can wait. not really important, was just something realized but wont break anything if its not there :)
    thanks!
     
    FreebordMAD likes this.
  13. Der_Kevin

    Der_Kevin

    Joined:
    Jan 2, 2013
    Posts:
    517
    so, i am almost done with all my customizations :)
    there is just one little bug left which i dont understand somehow. so iam using a default terrain. its in my scene and i dragged it into the LE_LevelEditorMain -> LE_ConfigTerrain -> Custom Default Terrain. its also there when i start the Editor and everything else works also fine

    but when i test the level (LE_ExampleGame.unity) the terrain is on a wrong X and Z position. also when i load the level again in the LE_ExampleEditor the Terrain is at the wrong position. i just saw that it is related to the terrain size where the Terrain appears:

    when i have a 500x500 Terrain it spans at X:-250 Y:0 Z:-250
    when its 250x250 its at X:-150 Y:0 Z:-150
    100x100 is at X:-50 Y:0 Z:-50

    had anybody something like this before?
     
  14. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    Hey, this is rather a feature than a bug :rolleyes:
    The terrain is always centered on load, therefore you need to rearrange the level so that it is centered from the beginning in your saved scene. Is this possible or is there any reason for the terrain to be on a certain position?
     
  15. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    The file picker extension is now available in the asset store! Some first reviews would be super awesome!
    https://www.assetstore.unity3d.com/en/#!/content/53530

    The icons for the file selection will be the next implemented feature.

    When I will have finished the icons for the level file picker, then I will start a file upload extension package. I hope that you still have some time to wait for it.
     
  16. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    The next patch for the file picker extension is in approval now ;)

    Take a look at the updated screens with the level icons added to the list: MRLE_FileSelection_Load00.png MRLE_FileSelection_Load01.png MRLE_FileSelection_Save00.png
    MRLE_FileSelection_ConfirmOverwrite00.png
     
    mfleurent likes this.
  17. eelbaz

    eelbaz

    Joined:
    Feb 21, 2015
    Posts:
    19
    Hello and sorry if this question has already been answered!

    How easy it is additional fields to LE_Object? For example, it currently has a color which can be saved against it.

    As a simple example, how easy would it be to add a "name" String to an LE_Object and have it saved as part of the saved data of the level and then loaded again?

    Many thanks!
     
  18. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    Did I get it right that you want the player to be able to give names to the level objects?
    If yes, then these are the steps that you would need to do:
    1.) Add a property called Name to the LE_Object script
    (The name is saved in this property)​
    2.) Add a the new property Name to the OnInspectorGUI method of the LE_ObjectInspector script
    (The default name for each LE_Object can be set in the inspector)​
    3.) Add some UI with a text InputField similiar to the UI objects RightMenu_Object_Variation_BG and RightMenu_Object_Color_BG
    (In the text field the players will enter the object name)​
    4.) Take a look at the LE_GUIInterface_uGUIimpl and LE_GUIInterface (doc) classes
    (These classes build the interface between UI and Level Editor)​
    5.) Add new methods to the LE_GUIInterface which will be used by the Level Editor to work with the name property
    (Similar to OnSelectedObjectColorChanged and SetSelectedObjectColorPropertyValue)​
    6.) Assign the handlers of your new methods in LE_LogicObjects
    (Similar to OnSelectedObjectColorChanged and SetSelectedObjectColorPropertyValue)
    (Think about using the UR_CommandMgr this will automatically allow undo/redo)​
    7.) Save/Load the changed Name properties of all LE_Object
    (You can do it directly in the LE_SaveLoad class or you can use the LE_EventInterface.OnCollectMetaDataBeforeSave (doc) event)​
     
    Bauschen likes this.
  19. Donny_Crash

    Donny_Crash

    Joined:
    Feb 2, 2016
    Posts:
    1
    Hey there, I've had Multiplatform Runtime Level Editor for a while now and wanted to know if there is a viable way to 'not' use the tree browser and switch it out for a custom tabbed interface? I've been hacking away but it seems as if the 'core' is quite tightly coupled. Any help would be appreciated.
     
  20. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    The tree browser is used only in the LE_GUIInterface_uGUIimpl class. Take a look at the references and you will see that the core is separated from the UI with the LE_GUIInterface. Please ask again if it is still unclear how you could replace the tree browser.
     
  21. MrIconic

    MrIconic

    Joined:
    Apr 5, 2013
    Posts:
    239
    First of all in the few minutes I used this asset I'm already glad I found it. I do have a question though.

    For my game I want to be able to have developers modify the map in realtime. Placing vehicles, changing the environment etc. Therefore, I have a question.

    How does this plugin save the map? Does it save everything regardless of Multiplatform Runtime Level Editor creating it?

    The reason this is important is since I use Forge Networking my assumption is that after the modifications are made I can save the entire map hierarchy.
     
  22. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    I'm not quite sure if I understand your question. The level editor saves the level to a binary array. This array contains the resource paths of all objects along with other attributes like position, color, variation... The terrain is saved as a height map and the terrain painting as color arrays. The terrain textures themselves are not saved.

    Do you mean that your players will work on the same level simultaneously? So that changes will be visible for all players? Like editing a Google Docs file at the same time from two devices?
    If yes, then it will be surely possible to do this (without using the built in save to byte array functionality). However, this feature is not included in MRLE and you will need to implement it using your network library. It should be possible to attach a network script to all LE_Objects so that these objects are visible for all players.
     
  23. MrIconic

    MrIconic

    Joined:
    Apr 5, 2013
    Posts:
    239
    [QUOTE="FreebordMAD, post: 2496355, member: 224082This array contains the resource paths of all objects along with other attributes like position, color, variation... [/QUOTE]

    Is it all objects in the scene or all objects that have LE_Objects attached to it?
     
  24. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    All objects that habe LE_Object attached
     
  25. shwa

    shwa

    Joined:
    Apr 9, 2012
    Posts:
    461
    Just spent a bit of time checking this out. (Bought it quite a long time ago.)

    It's pretty darn cool!

    Kudos to FreebordMAD for making this.

    - shwa
     
    FreebordMAD likes this.
  26. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    Glad to hear that ;)
     
  27. shwa

    shwa

    Joined:
    Apr 9, 2012
    Posts:
    461
    1. This will be a very useful asset for an upcoming project that i'll be starting soon.

    2. In the short run, i'm looking for a very simple solution for player to move 3d models in an existing project i have that doesn't use this asset.

    Would it be relatively straightforward and simple to use some of the code in this asset so a player could move an object in an existing scene during runtime?
    My scene consists of a terrain, a living room, and a chair.
    I want the player to be able to move the chair by clicking on it and then being able to drag it in x/y/z space.

    thanks!
     
  28. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    I'm very sorry for the late reply, I was ill and have slept for the last 50h :/

    Great to hear ;)

    Ok, this should work for sure.

    I have just made a quick test. I have created a new scene, then I have created three cubes. I have dropped the edit handle prefabs inside those cubes (ObjectEditHandleMOVE, ObjectEditHandleROTATE, ObjectEditHandleSCALE). I have started the scene and I was able to move, rotate and scale the objects. However, everything works fine, but there is a harmless error in the console "SendMessage SolveCollisionAndDeactivateRigidbody has no receiver!". There are two solutions either comment out the line that triggers this error or add a script (to the moved object) that implements a SolveCollisionAndDeactivateRigidbody method (see LE_Object).

    The simplest solution is to add the right edit handle prefab from the resources (see handle names above) as a child of the chair when the edit mode is enabled.
     
  29. musou0

    musou0

    Joined:
    Dec 2, 2015
    Posts:
    16

    @FreebordMADHi, I just upgraded the package, but I found that all the brushes and the "add new" image goes pure white in GUI. I don't know what's going on. Got a way to fix this?
     
  30. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    Thanks for the feedback. I have changed the shader used in the TexturePickerPrefab prafab. Please can you confirm that after your update the RawImage component of your TexturePickerPrefab (please search in the project) has the TexturePickerMaterial assigned and that the TexturePickerMaterial has the UI/No Alpha (MRLE) shader assigned. If yes, then please check if the LE_UINoAlpha shader asset exists and compiles. If yes, then please remove the TexturePickerMaterial reference from the RawImage of the TexturePickerPrefab (this will be the behaviour before the patch).

    EDIT: I was able to reproduce this. I will make a fix. In the meantime just remove the TexturePickerMaterial reference from the RawImage of the TexturePickerPrefab (this will be the behaviour before the patch).

    EDIT 2: patch is in approval now, please tell me if the fix described above does not work for you in the meantime.
     
    Last edited: Feb 14, 2016
  31. max00007

    max00007

    Joined:
    Feb 13, 2016
    Posts:
    19
    First of all: Great work! And worth every cent. And I hope you keep on working on updates.
    But I have a lot of questions. Sorry for beeing new to all of this. And sorry I did not read through all of the posts, so maybe I missed the answers to my questions.

    But here I go:

    1.) How do I include another camera and FPS system into the level. Meaning leaving the camera in the "editor mode" as it is just changin the camera and FPS controls when starting the level (I have a different camera Prefab I want to use to also beeing abel to fly etc.)
    2.) Is there any way to make this a multiplayer experience? Meaning upto 8 people on the same map?

    Thx & Again: Great Work
     
  32. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    Thanks, I'm glad to hear that. Right now I'm uploading a package with a little bug fix (the issue in the posts above).

    Take a look at this conversation:
    http://forum.unity3d.com/threads/multiplatform-runtime-level-editor.250920/page-6#post-2408867

    Please tell me more about your plans. Do you want to make the level editor work in multiplayer or do you speak about the demo game?

    If you speak about the demo game, then you should take a look at the existing third party multiplayer solutions in the Unity Asset Store. This will save you a lot of time!

    If you speak about the level editor, then take a look at this conversation:
    http://forum.unity3d.com/threads/multiplatform-runtime-level-editor.250920/page-7#post-2496355
     
  33. max00007

    max00007

    Joined:
    Feb 13, 2016
    Posts:
    19
    Thanks for the hint onthe FPS/camera topic.

    Regarding the multiplayer issue: I would like to create a level and then invite other people to join in and take a walk around together. Sound simpel. It propably is... but not when you are a total beginner.
     
  34. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    If you want the multiplayer part to be in the game and not the editor, then everything should be very easy. Just get a full starter kit for a multiplayer game from the Asset Store and add it to the demo fame scene. Here is the first hit that I found searching on my phone (it requires an additional package to work)
    https://www.assetstore.unity3d.com/en/#!/content/38333

    The only complicated part will be to transfer the saved level to the other players, but I'm sure that you will find a way!

    Ask again if you have specific questions about your multiplayer integration.
     
  35. musou0

    musou0

    Joined:
    Dec 2, 2015
    Posts:
    16
    It works. Thanks for the answer.
     
    FreebordMAD likes this.
  36. Aizat-Musa

    Aizat-Musa

    Joined:
    Feb 25, 2016
    Posts:
    8
    EDITED:

    hi...

    right now what I am trying to do was a tab that list all of the objects that was dropped into the scene using the tree browser. my idea was every object dropped into the scene are inserted into an object map and that object map will be display using tree browser.

    I am thinking of changing the root object map when i click on new tab.

    3) when I instantiate the LE_ObjectMap in another script, it push the new objectmap into the one that was instantiate in LE_LevelEditorMain and display both the old and new objectmap in the tree browser. is there a way to clear the objects in LE_ObjectMap before inserting new one?
    4)how to add objects into empty object map in the script?
     
    Last edited: Feb 26, 2016
  37. Der_Kevin

    Der_Kevin

    Joined:
    Jan 2, 2013
    Posts:
    517
    i really have to admit: a paint object function would be nice, like this:

    drag and drop is nice, but when you want to place for example several boxes its realy a pain :D
     
    FaberVi likes this.
  38. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    The uMyGUI_TreeBrowser has a Clear method, simply call this Clear method before calling BuildTree to remove all objects from the tree browser before adding the updated objects. You should take a look at LE_GUIInterface_uGUIimpl.SetObjects, this is a good place to call the Clear method.
    [Edit:] if you need to clear an LE_ObjectMap, then you can simply set the ObjectPrefabs, ObjectPrefabResourcePaths and SubObjectMaps to empty arrays.
    I'm not exactly sure what you are doing, if you are still uncertain how to achieve it, then please explain how you have changed the LE_ObjectMap to make the old and the new objects appear.

    LE_ObjectMap was designed to be a simple data holder class. Therefore, to add an object you need to replace the ObjectPrefabs, ObjectPrefabResourcePaths and SubObjectMaps arrays. To get the resource paths you can use the AssetDatabase.GetAssetPath method like it is used in LE_ObjectMapInspector.SynchronizePrefabsAndPathes of the Unity Editor (will not work in build, but in editor only). Are you trying to add the objects at runtime or in the editor? If you need the object at runtime, then you could place the resource paths in the object names, like it is done when a level is loaded.

    I'm not completely sure if I understand what you are working at. Please ask again if something is still unclear!



    Actually the "grid object placement improvement" is already on the list. I have added your example video to the feature request. Nevertheless, since I'm not a full-time indie dev anymore, it will take some time for this feature to be included. There are a lot of other features with higher priority.
    By the way, you have posted some really nice gifs of your game here. Is it already available somewhere? I would like to include your game to the "Games using the MRLE" section of the store description ;)
     
    Last edited: Feb 28, 2016
  39. Aizat-Musa

    Aizat-Musa

    Joined:
    Feb 25, 2016
    Posts:
    8
    Okay what i am working at is two tabs named Scene & Template. Template tab is the drag & drop objects into the level, while Scene tab list all of the objects dropped into level during the runtime with its properties such as positions & id number.

    1)still figuring out how to list all of the objects dropped into the level during runtime.
     
    Last edited: Mar 1, 2016
  40. musou0

    musou0

    Joined:
    Dec 2, 2015
    Posts:
    16
    @FreebordMAD Hi, I have some questions about save & load.
    1. Can I use the save method to save game in "ExampleGame" scene?(save when playing, continue playing)
    2.Can I use the load method in other sceces?(I want to make a main menu and there needs a "continue to edit"button & function).
    3. If can't, any suggestions?
     
  41. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    In your LE_GUIInterface_uGUIimplScene you should remove this line:
    Code (CSharp):
    1. LE_GUIInterface.Instance.delegates.SetObjects += SetObjects;
    You don't want to set the objects from an Object Map which is loaded by the LE_LevelEditorMain, therefore you should not register for the SetObjects event.

    Instead, listen to the LE_EventInterface.OnObjectPlaced event. Every time a new object is placed you should search all LE_Object instances (do the same after level load). For example, you can use Object.FindObjectsOfType<LE_Object>() to get all LE_Objects in the scene. From this list/array containing all objects of the scene you need to create a tree hierarchy of type uMyGUI_TreeBrowser.Node[] (see LE_GUIInterface_uGUIimpl.SetObjectsRecursive). To do this you should iterate all level objects and compare their resource paths (the resource path is the name of the LE_Object). Add all distinct objects to the node list. Then pass the nodes to the BuildTree method of the tree browser.



    You will need to make some changes to do that. You can get the saved level with LE_SaveLoad.SaveCurrentLevelDataToByteArray. However, to save the terrain you will need to create a LE_GUI3dTerrain instance and call LE_GUI3dTerrain.SetTerrain passing the terrain object that you want to save. You can destroy LE_GUI3dTerrain after saving. Or you can change the code of LE_SaveLoad.SaveCurrentLevelDataToByteArray by replacing:
    Code (CSharp):
    1. Terrain terrain = gui3dTerrain!=null ? gui3dTerrain.TerrainInstance : null;
    with the terrain object that you need e.g. Terrain.activeTerrain.
    The other problem will be that if you have used the object to object snapping feature, then you will loose the snapped references, which will make all snap point available for snapping.
    What exactly are your plans?

    I'm not sure what you mean here. You can load levels in any scene, the editor is not needed to load a level. The example game has no editor objects in the scene.

    Does the information above solve your problem. If not, then please give me more details about your plans and the problems that you have.
     
    Last edited: Mar 1, 2016
  42. Aizat-Musa

    Aizat-Musa

    Joined:
    Feb 25, 2016
    Posts:
    8
    1) I am having trouble creating tree hierarchy. how do you iterate all level objects without using LE_ObjectMap p_objectMap?(refering to setObjectRecursive method). what do you mean by "compare their resource path"? can you elaborate more?
     
    Last edited: Mar 3, 2016
  43. musou0

    musou0

    Joined:
    Dec 2, 2015
    Posts:
    16
    Thanks for the reply. Looks like I didn't describe my problems clearly.
    So let me describe like this.
    Red words are the problems I need to solve.
    Players will play the game by these steps:
    Step1: Open the game, and there's the main menu.

    Step2: Click "Builder Mode", and the game switch to the editor scene.

    Step3: Build something in the editor, but it's not finish yet, so click "save" in the editor scene, exit the game and find another time to continue editing.

    Step4. Back to the game, the player needs to continue editing the scene, so click the" continue builder mode", select the scene and the game switch to the editor scene with the selected level loaded( Let the player to continue editing directly, no need to click the" load " button in the editor scene).

    Step4 = Shortcut of "Load Level" in the editor scene.

    Step5. After the player complete the level, it's time to play. Click the "Explore mode", select the level and start to play directly, not by the "play" button in the editor scene.

    Step5 = Shortcut of "Load level + play" in the editor scene.


    Step6. After playing some time, the player need to save the progress of play mode, so click "Save explore progress" button to save. This function will save, and only need to save the player's status(Some scripts to let the player have HP,MP,ATK...) and transform.

    Step7,Open the game by another time, Click "continue explore mode" button in the main menu, and the game loads the progress of the play mode to let player to continue playing.
    Step7 = Short cut of " Load level + play + load step6".
    I hope this should help me to explain my problems more clearly.
     
  44. chrisabranch

    chrisabranch

    Joined:
    Aug 15, 2014
    Posts:
    146
    hi, on android the terrain turns black, anyone have a fix for this?
     
  45. Aizat-Musa

    Aizat-Musa

    Joined:
    Feb 25, 2016
    Posts:
    8
    @FreebordMAD

    I think I am getting near to what you suggest. this is part of my LE_GUIInterface_uGUIimpl.SetObjectsRecursive code

    Code (CSharp):
    1.  for (int i = 0; i < allObject.Length; i++)
    2.             {
    3.                 if (allObject[i] != null)
    4.                 {
    5.                
    6.                     if (p_objectMap.SubObjectMaps[i].name == "Main Role_ObjectMap")
    7.                     {
    8.                         if (allObject[i].name == "Objects/ICSObjects/primeMover_chassi40ft" || allObject[i].name == "Objects/ICSObjects/primeMover_chassi45ft")
    9.                         {
    10.                             LE_ObjectPrefabNode.SendMessageInitData data = new LE_ObjectPrefabNode.SendMessageInitData(allObject[i], p_indentLevel);
    11.                             uMyGUI_TreeBrowser.Node node = new uMyGUI_TreeBrowser.Node(data, null);
    12.                             nodes.Add(node);
    13.                             m_nodeToObject.Add(node, allObject[i]);
    14.                             m_nodeToResourcePath.Add(node, allObject[i].name);
    15.                         }
    16.                     }
    17.                 }
    and down here is my OnObjectPlaced method

    Code (CSharp):
    1.  private void OnObjectPlaced(object p_obj, LE_ObjectPlacedEvent p_args)
    2.         {
    3.  
    4.             allObject = Object.FindObjectsOfType<LE_Object>();
    5.  
    6.             OBJECT_BROWSER.BuildTree(SetObjectsRecursive(p_objectMap, 0));
    7.  
    8.         }
    my question is how do i call OBJECT_BROWSER.BuildTree(SetObjectsRecursive(p_objectMap, 0)); . as there is no reference of p_objectMap in OnObjectPlaced method??

    EDIT:
    Code (CSharp):
    1. private void SetObjects(LE_ObjectMap p_objectMap)
    2.        {
    3.            OBJECT_BROWSER.Clear();
    4.            OBJECT_BROWSER.BuildTree(SetObjectsRecursive(p_objectMap, 0));
    5.        }
    tried to add this then i realized SetObjects only work when the script start.
     
    Last edited: Mar 4, 2016
  46. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    The code below will load a level in the editor scene. Execute this code in the editor scene in the Start method of your scripts or in the first Update loop of your scripts to continue the builder mode.
    Code (CSharp):
    1. // doc: http://www.freebord-game.com/index.php/multiplatform-runtime-level-editor/documentation/load
    2.                 string levelFileName = "level.txt";
    3.                 StartCoroutine(ExampleGame_LoadSave.LoadRoutine(levelFileName, (byte[][] p_loadedLevelData)=>
    4.                 {
    5.                     // tell the editor that you want to load a level and get the load level event
    6.                     LE_LevelEditor.Events.LE_LoadEvent editorLoadEvent = LE_LevelEditorMain.Instance.GetLoadEvent();
    7.                     // load level
    8.                     editorLoadEvent.LoadLevelDataFromBytesCallback(p_loadedLevelData[0]);
    9.                     editorLoadEvent.LoadLevelMetaFromBytesCallback(p_loadedLevelData[1]);
    10.                 }));

    The code below will load a level in the game scene. Execute this code in your game scene in the Start method of your scripts or in the first Update loop of your scripts to continue explore a level.
    Code (CSharp):
    1. // doc: http://www.freebord-game.com/index.php/multiplatform-runtime-level-editor/documentation/load
    2.                 string levelFileName = "level.txt";
    3.                 StartCoroutine(ExampleGame_LoadSave.LoadRoutine(levelFileName, (byte[][] p_loadedLevelData)=>
    4.                 {
    5.                     // load level data
    6.                     LE_SaveLoadData level = LE_SaveLoad.LoadLevelDataFromByteArray(
    7.                         p_loadedLevelData[0],
    8.                         TERRAIN_LAYER,
    9.                         TERRAIN_TEXTURE_CONFIG.TERRAIN_TEXTURES,
    10.                         TERRAIN_TEXTURE_CONFIG.TERRAIN_TEXTURE_SIZES,
    11.                         TERRAIN_TEXTURE_CONFIG.TERRAIN_TEXTURE_OFFSETS);
    12.                     // call this function to destroy level editing scripts and improve performance
    13.                     LE_SaveLoad.DisableLevelEditing(level);
    14.                 }));
    This does not sound like something that should be done by the level editor. You should create a script for this and save the data in the PlayerPrefs.

    Load the level as described for step 5, then load the player position and status data from the PlayerPrefs.
     
  47. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    Please give me some more details.
    Does this also happen in the example scenes?
    Does it work when played in the Unity Editor?
    Which Unity version are you using?
    Which Android device are you using?
    What are the lighting settings of your scene?
     
  48. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    I'm still not sure what you are tying to achieve. Maybe you can post some screenshots. Actually, you don't need two instances of LE_GUIInterface_uGUIimpl. This script is just an example of how you could implement your UI. The script below (also attached to this post) shows a very simple implementation that will list objects that are added to the scene. Before I invest too much time, please confirm that we are going in the right direction with this script. This script could be optimized in performance (I have written it to be easily understandable not performant) and also the names of the objects are shown as full resource paths in this simple version.
    Clipboard01MRLE.png

    SCRIPT INSTALLATION:
    1. Open the unchanged example editor scene LE_ExampleEditor.
    2. Find the RightMenu_Objects_BG object in the hierarchy.
    3. Duplicate the RightMenu_Objects_BG object and move it so that it is visible and does not overlap other UI.
    4. Attach the ListSceneObjects to it.
    5. Assign the ScrollRect object of the duplicated RightMenu_Objects_BG object with the attached uMyGUI_TreeBrowser script to the OBJECT_BROWSER property of the ListSceneObjects script.
    6. Start the scene and see how each newly added object is shown in the duplicated RightMenu_Objects_BG object tree.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Linq;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. using LE_LevelEditor.Events;
    7. using LE_LevelEditor.Core;
    8. using LE_LevelEditor.UI;
    9.  
    10. using uMyGUI;
    11.  
    12. public class ListSceneObjects : MonoBehaviour
    13. {
    14.     [SerializeField]
    15.     private uMyGUI_TreeBrowser OBJECT_BROWSER = null;
    16.  
    17.     private void Start()
    18.     {
    19.         LE_EventInterface.OnObjectPlaced += OnObjectPlaced;
    20.     }
    21.  
    22.     private void OnDestroy()
    23.     {
    24.         LE_EventInterface.OnObjectPlaced -= OnObjectPlaced;
    25.     }
    26.  
    27.     private void OnObjectPlaced(object p_sender, LE_ObjectPlacedEvent p_args)
    28.     {
    29.         OBJECT_BROWSER.Clear();
    30.         OBJECT_BROWSER.BuildTree(GetListWithAllLevelObjects());
    31.     }
    32.  
    33.     private uMyGUI_TreeBrowser.Node[] GetListWithAllLevelObjects()
    34.     {
    35.         LE_Object[] allLevelObjects = FindObjectsOfType<LE_Object>();
    36.         Dictionary<string, uMyGUI_TreeBrowser.Node> allDistinctLevelObjects = new Dictionary<string, uMyGUI_TreeBrowser.Node>();
    37.         for (int i = 0; i < allLevelObjects.Length; i++)
    38.         {
    39.             LE_Object lvlObj = allLevelObjects[i];
    40.             if (lvlObj.name != "LE_GUI3dObject Preview Instance") // this is the dragged object instance which is used only for preview -> remove it
    41.             {
    42.                 string lvlObjResourcePath = lvlObj.name;
    43.                 if (!allDistinctLevelObjects.ContainsKey(lvlObjResourcePath))
    44.                 {
    45.                     LE_ObjectPrefabNode.SendMessageInitData nodeRenderData = new LE_ObjectPrefabNode.SendMessageInitData(lvlObj, 0);
    46.                     allDistinctLevelObjects.Add(lvlObjResourcePath, new uMyGUI_TreeBrowser.Node(nodeRenderData, null));
    47.                 }
    48.             }
    49.         }
    50.         return allDistinctLevelObjects.Values.ToArray();
    51.     }
    52. }
    53.  
     

    Attached Files:

  49. musou0

    musou0

    Joined:
    Dec 2, 2015
    Posts:
    16
    Thanks for the reply. I'm now working with the "continue builder mode".

    As what your said, now I know I should make something in the editor scene. But first, The main menu needs a File selection UI to know which level should be loaded.

    So I have to make a File selection UI to load the level names just like yours, but this UI, of course, it's in the main menu scene, not the level editor scene. So I can't just make a copy of your file selection UI and throw it into the main menu. It's not working.

    How should I make some changes to let this UI works in the main menu scene like this picture below?

    In a word, Let this UI works in main menu.
    (let it get all level file names in main menu scene, and the level buttons are clickable)

    Thanks very much.

     
    Last edited: Mar 9, 2016
  50. FreebordMAD

    FreebordMAD

    Joined:
    Mar 15, 2013
    Posts:
    633
    I'm very sorry for the late reply! Here are the steps that need to be done in order to let the uMyGUI_PopupManager work in another scene:
    1. Go to the LE_ExampleEditor scene and select the following objects: PopupManager, Popup_Loading_Root, Popup_Text_Root (you can also select all popups if you need them)
    2. Copy and paste them into the canvas object of your menu scene
    3. Select the copied PopupManager object and remove the null entries in the Popups and the Popup Names arrays (set their Size to 2). Set the Size of Deactivated Elements When Popup Is Shown to 0.
    3. Open the FileSelectionExtensionLoader script
    4. Rewrite the private declaration of the FileSelectionExtensionLoader class to be public (will be included in the next version)
    5. Rewrite the private declaration of the LoadLevelFileNames method to be public static (will be included in the next version)
    6. Call the code below from one of your MonoBehaviour scripts:
    Code (CSharp):
    1.             // init file selection UI
    2.             LE_FileSelectionHelpers.AddFileSelectionPopup();
    3.        
    4.             // load file with the level file names
    5.             StartCoroutine(LE_ExtensionInterface.FileSelectionExtensionLoader.LoadLevelFileNames((string[] p_levelFileNames)=>
    6.             {
    7.                 if (uMyGUI_PopupManager.Instance != null)
    8.                 {
    9.                     // show file selection UI
    10.                     ((LE_PopupFileSelection)uMyGUI_PopupManager.Instance.ShowPopup(LE_FileSelectionHelpers.POPUP_NAME))
    11.                         .SetFiles(p_levelFileNames, (int p_selectedLevelIndex)=>
    12.                           {
    13.                             Debug.LogError("Load some other scene, the file that you want to load is: " + p_levelFileNames[p_selectedLevelIndex] + ".txt");
    14.                         })
    15.                         .SetText("Load Level", "Which level do you want to load?")
    16.                         .ShowButton("close");
    17.                 }
    18.             }));
    Attached a Test script with the code above.
     

    Attached Files:

    • Test.cs
      File size:
      991 bytes
      Views:
      1,085
    Last edited: Mar 18, 2016