Search Unity

[RELEASE]Beast Helper! Don't lose old maps anymore!

Discussion in 'Made With Unity' started by Rbn_3D, Sep 30, 2010.

  1. Rbn_3D

    Rbn_3D

    Joined:
    Sep 30, 2010
    Posts:
    17
    I finished a tool that saves and loads files with beast lightmap index and tiling info, you can merge different beast sessions just loading and merging the maps, also allows to edit maps settings directly on screen.

    $Beast_Helper.jpg


    To install, just place the script in Assets/Editor folder. To use, just Go to Window > Beast Helper.

    How To Merge lightmaps??

    Easy.

    -Select objects and bake selected.

    -Move the lightmaps to another folder (using always the project view, not explorer!)

    -Open Beast Helper.

    -Click on Read current maps(The current Beast maps will be loaded).

    -Click on Store maps info to Disk (Select folder/filename and save).


    -Now select other objects and bake selected(Don't worry about old maps ;) ).

    -Reopen Beast helper and choose Read Current Maps again.

    -Click on Store maps info to Disk (Don't replace the other file).

    Now we have 2 files with beast info.

    -Click on Read maps info from disk,(Select one of our 2 files) click on replace.

    -Click on Read maps info from disk again, (Select the other file) click on Merge.

    Now, we only need to click Set acutal maps in Beast! click on Apply!

    Done ;)

    Enjoy!

    If you found bugs, please post here!

    Backup your project, and use at your own risk! Dual lightmaps not suppoerted for now!


    DOWNLOAD

    View attachment $BeastHelper.cs

    Also available here:

    http://www.unifycommunity.com/wiki/index.php?title=Beast_Helper


    MODERATORS: I´m a bit confused with the new categories, so if it isn't the best place for this trhead, you can move it.
     
    Last edited: Oct 2, 2010
    Pulov likes this.
  2. Rbn_3D

    Rbn_3D

    Joined:
    Sep 30, 2010
    Posts:
    17
    reserved 1
     
  3. Rbn_3D

    Rbn_3D

    Joined:
    Sep 30, 2010
    Posts:
    17
    and reserved 2 ;)
     
  4. nm8shun

    nm8shun

    Joined:
    Jul 14, 2007
    Posts:
    476
    Wow. This looks like an awesome tool, and one that I was preparing for Unity's wish list. I will definitely be trying this out today (got a huge project that crashes on every Beast bake - although all the areas bake fine if I bake them one at a time). This looks perfect. I'll report back. Cheers and Thanks!
     
  5. Rush-Rage-Games

    Rush-Rage-Games

    Joined:
    Sep 9, 2010
    Posts:
    1,997
    Looks like a great tool!
     
  6. Rbn_3D

    Rbn_3D

    Joined:
    Sep 30, 2010
    Posts:
    17
    Thanks for the replies!

    Waiting feedback!

    Cheers
     
  7. liverolA

    liverolA

    Joined:
    Feb 10, 2009
    Posts:
    347
    doesn't work though,would you please make a video tutorial to show how to use this?
     
  8. Rbn_3D

    Rbn_3D

    Joined:
    Sep 30, 2010
    Posts:
    17
    Are you using dual lightmaps??

    If you have +50 meshes in a lightmap it will fail...

    How is the error exactly??
     
  9. liverolA

    liverolA

    Joined:
    Feb 10, 2009
    Posts:
    347
    i am using single lightmaps,

    here is what i do:
    1.create a dir in project view named "lminfo"
    2.create a simple scene with 3 static objects:box,sphere,plane,with a point light(shadow on);
    3.open lmap window, set using single lightmaps

    4.select box,click bake selected,done,move the lmap into folder "lminfo",click read lmap info,and store the ini file in lminfo folder with name "info1"
    5.select spere,do as 4,save the ini file with name "info2"..
    6. select plane,bake it,done,and read current lmap,then i load ini file1,merge...nothing happend!!!

    what did i miss?
     
  10. Rbn_3D

    Rbn_3D

    Joined:
    Sep 30, 2010
    Posts:
    17
    Decrease array size to the real count of lightmaps before merge.

    If not works:

    Try to save two beast info files, clear all, and merge them. And click "Set acutal maps in Beast", of course.

    Works for me, but it's a very early release, can have bugs.

    Are you receiving console errors?? something like "array: out of index" or "NullReferenceException"??
     
  11. liverolA

    liverolA

    Joined:
    Feb 10, 2009
    Posts:
    347
    no bugs,just nothing happend
     
  12. DocSWAB

    DocSWAB

    Joined:
    Aug 28, 2006
    Posts:
    615
    Question about this -- I haven't tried using it yet, but was wondering if you could clarify that by "merging" you mean adding previously rendered lightmaps to the map array so you can swap them at runtime?

    That is exactly what I've been looking for, so I just want to make sure I understand that this is the tool for me.

    Thanks in advance!
     
  13. Rbn_3D

    Rbn_3D

    Joined:
    Sep 30, 2010
    Posts:
    17
    Is a editor window that allows to have different bakes at the same time, nothing to swap at runtime, but it should be easy, you can just create your own LightmapData array and set it in LightmapSettings.lightmaps at runtime.

    About the bugs... I will revise the script for find the bug this weekend...
     
  14. innercircus

    innercircus

    Joined:
    Aug 19, 2009
    Posts:
    15
    This tool looks awesome and I've given it a few tries now but I think I'm confusing it up a bit. I just want to make sure before I spend to much more time on it that it will do what I think it will do... :)

    So I have say 10 prefab's walls. These walls are combined to make up say 20 different rooms/hallways etc.

    The idea being that with minimal geometry/textures we can get the most bang for our buck. Ideally we would like to lightmap each room/hallway independently have them assigned in beast.

    then we can copy/paste, instantiate etc, the pieces into different combinations in the editor and they will keep their lightmapping states.

    Does this make sense? and if so, is this what the tool is supposed to allow us to do? :)
     
  15. Rbn_3D

    Rbn_3D

    Joined:
    Sep 30, 2010
    Posts:
    17
    It only allows to merge lightmap tiling and offset info, even if you do a new "Bake selected" in other objects, so you can bake certain area, bake other area after, and then, merge both lightmapings...

    But I think if you copy/paste an object after bake, it doesn't lose lightmap state by default...
     
  16. box01

    box01

    Joined:
    Apr 2, 2009
    Posts:
    62
    quick question before trying myself, doest it work across projects?
     
  17. jymmyt

    jymmyt

    Joined:
    Jun 18, 2008
    Posts:
    9
    This is a great idea, however, since it uses kernel32.dll to write ini files, it will not work in os x as far as i know.
     
  18. davebuchhofer

    davebuchhofer

    Joined:
    Nov 9, 2007
    Posts:
    126
    Awesome, I've been itching for something like this for weeks, it was in the 'Things to make life easier' todo-list, thanks for sharing!
     
  19. hatto

    hatto

    Joined:
    Nov 9, 2008
    Posts:
    31
    Is jymmyt correct here that it won't work on the Mac installed Unity?
     
  20. hatto

    hatto

    Joined:
    Nov 9, 2008
    Posts:
    31
    Just tried saving the info file on my Mac.. and I can't see it.. will try my PC version now
     
  21. NTDC-DEV

    NTDC-DEV

    Joined:
    Jul 22, 2010
    Posts:
    593
    Sorry for ressurecting an old thread...

    But I can't make it work either. Nothing happens when I click on "Set actual maps in Beast" after doing everything as per say.

    What is weird though, when I load the data, only the first index (1) object is actualy loaded for all lightmaps. Something is definitely not working, maybe it broke during the 3.3 upgrade?
     
  22. cemC

    cemC

    Joined:
    Dec 23, 2010
    Posts:
    214
    looks great :)
     
  23. minevr

    minevr

    Joined:
    Mar 4, 2008
    Posts:
    1,018
    Cool!Thanks for share.

    ps:Why Unity can't save it?
     
  24. obsidian1269

    obsidian1269

    Joined:
    May 12, 2011
    Posts:
    24
    Hey Rbn_3D!

    Thanks for putting together this awesome tool! I had a few issues with it and really needed this thing to work so I fixed it up a bit and thought I'd post it here for everyone to use.

    Download Here:
    BeastHelperPlus.cs

    Cheers!
     
    Pulov likes this.
  25. Kyuuji

    Kyuuji

    Joined:
    Aug 18, 2012
    Posts:
    1
    I hope Rbn_3D is still around.

    A problem came up for me. The maps only work for one and doesn't work for the other. Is there something I'm doing wrong, or it's the Unity version?

     
    Last edited: Aug 18, 2012
  26. Pulov

    Pulov

    Joined:
    Feb 20, 2010
    Posts:
    824
    Hope this still works in unity 4.6. I'll try the plus version. Deleting the existing maps is a MAJOR flaw that unity has no mercy for, having it keeped to the end of the cycle.
     
  27. Pulov

    Pulov

    Joined:
    Feb 20, 2010
    Posts:
    824
    No matter where I move the exr files that Beast will search for them in the end of next bake and delete them.
     
  28. Pulov

    Pulov

    Joined:
    Feb 20, 2010
    Posts:
    824
    THANK YOU FOR THIS TOOOL !!!! finally!!! woah. !!!
    I managed to bake objects individually, keeping the atlases etc.. this is superb.!!!!!!!!!
    I've a big scene and computing all was a no go. I had to hack a bit the procedure:

    Bake some selected objects.
    Within editor move them to desired folder, with Backer helper "read current maps" and "store maps info to disk". I save the info file with the maps. I recommend to have a folder that relates to the lightmaps such as "building 9" or whatever.

    So, now, unity wont let you steall the lightmaps so easily so in the lightmaps folder right click and "show in explorer" , if you go back to unity, unity will have moved the ligthmap back to when beast creates them... go there and open that folder in explorer, copy them in windows to where they should be, convert them to lightmapsin the inspector (they're imported as textures) and your'e done with this bake. Sounds more messy than it is, believe me.

    Then, clear the lightmaps by "clear all" in the beast helper and "clear" in lightmap tool. This is important because "clear" does not delete the asociations object/lightmap. Unity... once again you screwed....

    Bake new stuff and then once you've cleared everything after new bake, recall the bakes you need, merge them and send them to beast.

    If you backed dual lighmaps, you can reasign them manually in teh lightmap window, just select the existing map and the missing one will be by the side in the project explorer, just drag&drop.

    THANKS ALL FOR MAKING THIS POSSIBLE

    The only thing I missed in teh tool was a search tool to find an specific gameobject. This is interesting when you've many and looking for them in the Beast Helper can become a hell when trying to disable the lightmap of an especific object for a rebake withour rebaking their neighbours etc..

    If unity does not delete your lightmaps by simply moving from folder as initially was expected to be you can skip the windows copying but I bet this wont happen.

    With this technique you can have full control of the baking, update some scene parts, control the global resolution of the lightmaps easily, have different baking resolutions etc... pretty much the way it should have been from start.

    tested with 4.6.2

    [edit] this is crazy, I'm in a baking sesion now and I'm being able to bake the scene with "bake selected" without crushing the lightmaps, with aditive lightmaps, and when I modify already baked they update the lightmaps... I cant believe my eyes. All this with the regular beast implementation.
     
    Last edited: Mar 29, 2015
  29. Pulov

    Pulov

    Joined:
    Feb 20, 2010
    Posts:
    824
    I'm having some issues when loading the ini files. THese are ok created, I've checked the content and is ok, but sometimes when I import the ini file it assings incorrectly the game objects. It stuck with teh first gameobjects and replicates this for the rest etc. If someone could fix the code for a more robust object designation based on teh ini file would nail the tool.
     
  30. Pulov

    Pulov

    Joined:
    Feb 20, 2010
    Posts:
    824
    I'm getting a similar error
     
  31. NTDC-DEV

    NTDC-DEV

    Joined:
    Jul 22, 2010
    Posts:
    593
    You can lightmap individual objects since 4.3... this tool isn't required anymore.
     
  32. Pulov

    Pulov

    Joined:
    Feb 20, 2010
    Posts:
    824
    This is crazy. I've realised that already but I was loosing them when baking selected, started looking for info and found the issue and found miself trapped into this. They where getting overriden and when lightmaping lets say a building, the road did got screwed. I've been able to bake by parts but there is a major issue that is that if you've a big scene and you go baking by parts, the used ram goes up and up till a point where you can bake no more because it crashes. Hopefully for me I had all the baked selections saved with a tool i bought in the asset store so this morning by doing a crazy trick I was able to load the scene with a "low" memory footprint and launch a big bake and it has worked. This tool could allow to bake by parts (big parts) and merge later on not being affected by the 32 limit. Ideal for large environments with tons of stuff. I found that with 2GB free of RAM for unity to use is able to handle quite a large amount of lightmap stuff 85 dual lightmaps of about 500megs. Otherwise it always crashed when coming back from beast.
     
  33. Pulov

    Pulov

    Joined:
    Feb 20, 2010
    Posts:
    824
    By the way, the trick is simple.

    The scene you whant to bake you save it with the viewport not showing any of the objects.

    Close Unity and reopen it. (keep the task manager open to see the memory consumption variations).

    Select the objects you whant to bake without rendering them in teh viewport. You could use the hyerarchy or an specific tool to manage saved selections. Launch the bake.

    Minimize unity. If you move the viewport so that it renders the 3d geometry you're lost because it is loaded into memory and is not unloaded when going out of sight.

    Let the bake finish and when done, save and you're done.
     
  34. Pulov

    Pulov

    Joined:
    Feb 20, 2010
    Posts:
    824
  35. NTDC-DEV

    NTDC-DEV

    Joined:
    Jul 22, 2010
    Posts:
    593
    You can lower your number of lightmaps by increasing the atlas size to 2048. This is also helpful for baking big objects with high texel count as Beast isn't able to fit them on lower size atlas. That means that bake-selected is less efficient at finding a place in a small atlas vs big one.
     
  36. Pulov

    Pulov

    Joined:
    Feb 20, 2010
    Posts:
    824
    That would be awesome but I could not find any atlas size param. Only the resolution param witch I understand that if I increase it will increase the number of atlased at the fixed 1024 resolution.
     
  37. NTDC-DEV

    NTDC-DEV

    Joined:
    Jul 22, 2010
    Posts:
    593
  38. Pulov

    Pulov

    Joined:
    Feb 20, 2010
    Posts:
    824
    JAjaja, yes. But you know. When the Bake Selected started to work I told myself that may be it was getting screwed because I was messing params betwen bakes. My initial focus was to use diferent resolutions based on the probability of the player to see them from a close up. BUt as the things started to mess up I fosuced simply on getting it to work witch did happen this morning. But now, with teh full scene bake, if I want to rebake one part only it will crash for sure, no matter how tiny it is. This is where this soft could be usefull. Whatever, I'll rebake with bigger atlass.

    Thanks for the google it link, lol. I was searching already in unity answers without much luck
     
  39. Pulov

    Pulov

    Joined:
    Feb 20, 2010
    Posts:
    824
  40. Sondre-S

    Sondre-S

    Joined:
    Jun 29, 2013
    Posts:
    54

    I got this "bug" too, and after reading through the code a few times I found out what's causing it.

    In the part of the code where it loads from file, if you replace "counter2" with "i2" it works like expected.

    I also believe the original code got offset mixed up so I changed that aswell.

    This should be working correctly:
    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEditor;
    4. using System;
    5. using System.IO;
    6. using System.Text;
    7. using System.Runtime.InteropServices;
    8.  
    9. public class BeastHelper : EditorWindow
    10. {
    11.     int ArraySize = 10;
    12.     Vector2 scrollpos1;
    13.     static GameObject[] staticobjects; // Static Gameobjects Array
    14.     static object[,,] arrayobjects = new object[255,50,3];  // array relative to baketex array, contains gamobject(s) and tiling info for each lightmap
    15.     Texture2D[] baketex = new Texture2D[255]; //array of lightmaps
    16.  
    17.     //---------------------------------------------
    18.  
    19.     // Add menu named "My Window" to the Window menu
    20.     [MenuItem("Window/Beast Helper")]
    21.     static void Init()
    22.     {
    23.         // Get existing open window or if none, make a new one:
    24.         BeastHelper window = (BeastHelper)EditorWindow.GetWindow(typeof(BeastHelper));
    25.         window.autoRepaintOnSceneChange = true;
    26.         window.title = "Beast Helper";
    27.         window.Show();
    28.  
    29.         //-------------- Get Lightmapped geometry... ----------------
    30.  
    31.         GameObject[] gameobjects = (GameObject[])Resources.FindObjectsOfTypeAll(typeof(GameObject));
    32.  
    33.         int i1 = 0;
    34.         foreach (GameObject g in gameobjects)
    35.         {
    36.             if (g.isStatic)
    37.             {
    38.                 i1++;
    39.             }
    40.         }
    41.  
    42.         staticobjects = new GameObject[i1];
    43.  
    44.         int i2 = 0;
    45.         foreach (GameObject g in gameobjects)
    46.         {
    47.             if (g.isStatic)
    48.             {
    49.                 staticobjects.SetValue((GameObject)g, i2);
    50.                 i2++;
    51.             }
    52.         }
    53.  
    54.         Debug.Log("Static GameObjects count = " + i1);
    55.  
    56.         for (int i = 0; i < arrayobjects.GetLength(0); i++)
    57.         {
    58.             for (int i3 = 0; i3 < arrayobjects.GetLength(1); i3++)
    59.             {
    60.                 arrayobjects[i, i3, 0] = null;
    61.                 arrayobjects[i, i3, 1] = (Vector4)new Vector4();
    62.                 arrayobjects[i, i3, 2] = (bool)false;
    63.             }
    64.         }
    65.  
    66.         //----------------------------------------------------------
    67.  
    68.     }
    69.  
    70.     void OnGUI()
    71.     {
    72.  
    73.         GUILayout.Label("Stored Lightmaps", EditorStyles.boldLabel);
    74.  
    75.         ArraySize = EditorGUILayout.IntField("Array Size(" + ArraySize.ToString() + ")", ArraySize);
    76.  
    77.         GUILayoutOption[] layout1 = new GUILayoutOption[2];
    78.  
    79.         layout1[0] = (GUILayoutOption)GUILayout.Height(75);
    80.         layout1[1] = (GUILayoutOption)GUILayout.Width(75);
    81.  
    82.  
    83.         scrollpos1 = EditorGUILayout.BeginScrollView(scrollpos1);
    84.         for (int i = 0; i < ArraySize; i++)
    85.         {
    86.          
    87.             // Debug.Log("Loop1 i = " + i);
    88.             EditorGUILayout.BeginHorizontal();
    89.             EditorGUILayout.LabelField(i.ToString(),"", GUILayout.Width(20));
    90.             baketex[i] = (Texture2D)EditorGUILayout.ObjectField((Texture2D)baketex.GetValue(i), typeof(Texture2D), layout1);
    91.          
    92.             //----------- Each GameObject whit [i] lightmap index go here -----------
    93.  
    94.             for (int i2 = 0; i2 < arrayobjects.GetLength(1); i2++)
    95.             {
    96.  
    97.                     GUILayout.BeginVertical(GUILayout.Width(300));
    98.                     EditorGUILayout.LabelField("GameObject: " + i2.ToString(), "", GUILayout.Width(300));
    99.                     arrayobjects[i, i2, 0] = (GameObject)EditorGUILayout.ObjectField((GameObject)arrayobjects[i, i2, 0], typeof(GameObject), GUILayout.Width(300));
    100.                     arrayobjects[i, i2, 1] = (Vector4)EditorGUILayout.Vector4Field("Tiling (X-Y) / Offset (X-Y)", (Vector4)arrayobjects[i, i2, 1], GUILayout.Width(300));
    101.                     arrayobjects[i, i2, 2] = (bool)EditorGUILayout.Toggle("Use: ",(bool)arrayobjects[i, i2, 2], GUILayout.Width(300));
    102.                     GUILayout.EndVertical();
    103.  
    104.             }
    105.  
    106.  
    107.             //-------------------------------------------------------------------------
    108.  
    109.  
    110.             EditorGUILayout.EndHorizontal();
    111.         }
    112.         EditorGUILayout.EndScrollView();
    113.  
    114.         Repaint();
    115.  
    116.         EditorGUILayout.BeginHorizontal();
    117.         //-------------- Buttons -------------------
    118.  
    119.         if(GUILayout.Button("Read current maps"))
    120.         {
    121.             if (LightmapSettings.lightmaps.Length > ArraySize)
    122.                 ArraySize = LightmapSettings.lightmaps.Length;
    123.  
    124.             Repaint();
    125.  
    126.             for (int i = 0; i < LightmapSettings.lightmaps.Length; i++)
    127.             {
    128.                 // Debug.Log("Loop2 i = " + i);
    129.                 baketex.SetValue(LightmapSettings.lightmaps[i].lightmapFar,i);
    130.  
    131.                 //------------- Get objects with same lightmap index ---------
    132.                 if (baketex.GetValue(i) != null)
    133.                 {
    134.                     var i2 = 0;
    135.                     foreach (GameObject r in staticobjects)
    136.                     {
    137.                         if (r.renderer)
    138.                         {
    139.                             if (r.renderer.lightmapIndex == i)
    140.                             {
    141.                                 arrayobjects[i, i2, 0] = (GameObject)r; // The real GameObject
    142.                                 arrayobjects[i, i2, 1] = (Vector4)r.renderer.lightmapTilingOffset; // Tiling Lightmap properties
    143.                                 arrayobjects[i, i2, 2] = (bool)true; // use it??
    144.                                 i2++;
    145.                             }
    146.                         }
    147.  
    148.                     }
    149.                 }
    150.                 //------------------------------------------------------------
    151.             }
    152.  
    153.             Repaint();
    154.         }
    155.  
    156.         if (GUILayout.Button("Load Maps info from Disk"))
    157.         {
    158.             string path = EditorUtility.OpenFilePanel("Select beast maps info file", Application.dataPath, "ini");
    159.             if (path.Length > 0)
    160.             {
    161.                 //-------------- Loading .ini file -------------
    162.                 cIni inifile = new cIni(path);
    163.  
    164.                 string mapscountstr = inifile.ReadValue("MAPSCOUNT", "COUNT");
    165.  
    166.                 int mapscount = 0;
    167.                 if (mapscountstr.Length > 0)
    168.                 {
    169.                     mapscount = int.Parse(mapscountstr);
    170.                 }
    171.  
    172.                 if (ArraySize < mapscount)
    173.                 {
    174.                     ArraySize = mapscount;
    175.                     Repaint();
    176.                 }
    177.  
    178.                 int arrayofsset = 0;
    179.  
    180.                 bool cancel = false;
    181.  
    182.                 switch (EditorUtility.DisplayDialogComplex("Merge with current maps?", "If you choose merge, the loaded maps will be added after the current ones", "Merge", "Replace", "Cancel"))
    183.                 {
    184.                     case 0:
    185.                         {
    186.                             for (int i = 0; i < ArraySize; i++)
    187.                             {
    188.                                 if (baketex[i] != null)
    189.                                     arrayofsset = i;
    190.                             }
    191.  
    192.                             if (arrayofsset > 0)
    193.                                 arrayofsset++;
    194.  
    195.                             if ((arrayofsset + mapscount) > ArraySize)
    196.                             {
    197.                                 ArraySize = arrayofsset + mapscount;
    198.                             }
    199.                         }
    200.                         break;
    201.                     case 1:
    202.                         {
    203.                             for (int i = 0; i < ArraySize; i++)
    204.                             {
    205.                                  //Debug.Log("Loop2 i = " + i);
    206.                                 baketex.SetValue(null, i);
    207.                        //Debug.Log("arrayobjects.GetLength(1) = " + arrayobjects.GetLength(1));
    208.                                 for (int i2 = 0; i2 < arrayobjects.GetLength(1); i2++)
    209.                                 {
    210.                              
    211.                                     arrayobjects[i, i2, 0] = null;
    212.                                     arrayobjects[i, i2, 1] = (Vector4)new Vector4();
    213.                                     arrayobjects[i, i2, 2] = (bool)false;
    214.                                 }
    215.  
    216.                             }
    217.                             Repaint();
    218.                         }
    219.                         break;
    220.                     case 2:
    221.                         {
    222.                             cancel = true;
    223.                         }
    224.                         break;
    225.                 }
    226.  
    227.                 if (cancel == false)
    228.                 {
    229.                     int counter1 = 0;
    230.                     for (int i = arrayofsset; i < ArraySize; i++)
    231.                     {
    232.                         string texpath = inifile.ReadValue("MAPS", counter1.ToString());
    233.  
    234.                         if (texpath.Length > 0)
    235.                         {
    236.                             baketex.SetValue((Texture2D)AssetDatabase.LoadAssetAtPath(texpath, typeof(Texture2D)), i);
    237.                         }
    238.                         counter1++;
    239.                     }
    240.  
    241.                  
    242.                     for (int i2 = arrayofsset; i2 < ArraySize; i2++)
    243.                     {
    244.                         int counter2 = 0;
    245.                         for (int i3 = 0; i3 < arrayobjects.GetLength(1); i3++)
    246.                         {
    247.                          
    248.                          
    249.                          
    250.                             string gpath = inifile.ReadValue("MAP" + i2.ToString(), "GAMEOBJECT" + i3.ToString());
    251.                             string gtiling = inifile.ReadValue("MAP" + i2.ToString(), "TILING" + i3.ToString());
    252.                             string guse = inifile.ReadValue("MAP" + i2.ToString(), "USE" + i3.ToString());
    253.                          
    254.                          
    255.                          
    256.                             if (gpath.Length > 0)
    257.                             {
    258.                              
    259.                                 arrayobjects[i2, i3, 0] = (GameObject)GameObject.Find(gpath);
    260.  
    261.  
    262.                                 arrayobjects[i2, i3, 1] = (Vector4)vector4fromstring(gtiling);
    263.                                 arrayobjects[i2, i3, 2] = (bool)Convert.ToBoolean(guse);
    264.                             }
    265.                             counter2++;
    266.                            //Debug.Log("gpath="+gpath);
    267.                          
    268.                         }
    269.                      
    270.                    
    271.                     }
    272.                 }
    273.                 //-----------------------------------------------
    274.             }
    275.         }
    276.  
    277.         if(GUILayout.Button("Store Maps info to Disk"))
    278.         {
    279.             EditorUtility.DisplayDialog("Important!", "If you want to start a new bake operation whitout lose current maps, move them to another folder in the project view! Beast will remove old maps otherwise!", "Ok");
    280.  
    281.             string path = EditorUtility.SaveFilePanel("Save beast maps info to file", Application.dataPath, "beast_info", "ini");
    282.             if (path.Length > 0)
    283.             {
    284.                 //-------------- Creating .ini file -------------
    285.                 if (File.Exists(path))
    286.                     File.Delete(path); // Delete old ini file, otherwise files content will be merged.
    287.  
    288.                 cIni inifile = new cIni(path);
    289.  
    290.                 inifile.WriteValue("MAPSCOUNT", "COUNT", ArraySize.ToString());
    291.  
    292.                 for (int i = 0; i < ArraySize; i++)
    293.                 {
    294.                     inifile.WriteValue("MAPS",i.ToString(), AssetDatabase.GetAssetPath(baketex[i]));
    295.                 }
    296.  
    297.                 for (int i2 = 0; i2 < ArraySize; i2++)
    298.                 {
    299.                     for (int i3 = 0; i3 < arrayobjects.GetLength(1); i3++)
    300.                     {
    301.                         inifile.WriteValue("MAP" + i2.ToString(), "GAMEOBJECT" + i3.ToString(), GetHierarchy((GameObject)arrayobjects[i2,i3,0]));
    302.                         Vector4 tiling = (Vector4)arrayobjects[i2, i3, 1];
    303.                         inifile.WriteValue("MAP" + i2.ToString(), "TILING" + i3.ToString(), "(" + tiling.x.ToString() + "," + tiling.y.ToString() + "," + tiling.z.ToString() + "," + tiling.w.ToString() + ")");
    304.                         inifile.WriteValue("MAP" + i2.ToString(), "USE" + i3.ToString(), arrayobjects[i2, i3, 2].ToString().ToLower());
    305.                     }
    306.                      
    307.                 }
    308.  
    309.                 //-----------------------------------------------
    310.             }
    311.  
    312.  
    313.  
    314.         }
    315.  
    316.         if(GUILayout.Button("Set actual Maps in Beast"))
    317.         {
    318.             bool cancel = false;
    319.  
    320.  
    321.  
    322.             if(!cancel)
    323.             {
    324.                 if (EditorUtility.DisplayDialog("Do you want to apply these maps??", "If you have unsaved maps in beast, you will lose them", "Apply", "Cancel"))
    325.                 {
    326.  
    327.                     LightmapData[] maps = LightmapSettings.lightmaps;
    328.                     Array.Resize(ref maps, ArraySize);
    329.  
    330.  
    331.                     for (int c2 = 0; c2 < maps.Length; c2++)
    332.                     {
    333.                         maps.SetValue(new LightmapData(), c2);
    334.                     }
    335.  
    336.                     for (int c1 = 0; c1 < ArraySize; c1++)
    337.                     {
    338.                         maps[c1].lightmapFar = baketex[c1];
    339.                     }
    340.                     LightmapSettings.lightmaps = maps;
    341.  
    342.  
    343.                         for (int i2 = 0; i2 < ArraySize; i2++)
    344.                         {
    345.                             for (int i3 = 0; i3 < arrayobjects.GetLength(1); i3++)
    346.                             {
    347.                                 bool use = (bool)arrayobjects[i2, i3, 2];
    348.  
    349.                                 if (use == true)
    350.                                 {
    351.                                     GameObject g = (GameObject)arrayobjects[i2, i3, 0];
    352.                                     g.renderer.lightmapIndex = i2;
    353.                                     g.renderer.lightmapTilingOffset = (Vector4)arrayobjects[i2, i3, 1];
    354.                                 }
    355.                             }
    356.  
    357.  
    358.                         }
    359.    
    360.                 }
    361.             }
    362.         }
    363.  
    364.         //------------------------------------------
    365.         EditorGUILayout.EndHorizontal();
    366.  
    367.         //--------------- Down Buttons -------------
    368.  
    369.         EditorGUILayout.BeginHorizontal();
    370.  
    371.         if (GUILayout.Button("Clear All"))
    372.         {
    373.             for (int i = 0; i < ArraySize; i++)
    374.             {
    375.                 // Debug.Log("Loop2 i = " + i);
    376.                 baketex.SetValue(null, i);
    377.                 for (int i2 = 0; i2 < arrayobjects.GetLength(1); i2++)
    378.                 {
    379.                     arrayobjects[i, i2, 0] = null;
    380.                     arrayobjects[i, i2, 1] = (Vector4)new Vector4();
    381.                     arrayobjects[i, i2, 2] = (bool)false;
    382.                 }
    383.  
    384.             }
    385.             Repaint();
    386.         }
    387.  
    388.         //if (GUILayout.Button("Reload Gameobject List"))
    389.         //{
    390.  
    391.         //}
    392.  
    393.         if (GUILayout.Button("Close"))
    394.         {
    395.             Close();
    396.         }
    397.  
    398.         EditorGUILayout.EndHorizontal();
    399.  
    400.         if (GUI.changed)
    401.             Repaint();
    402.  
    403.     }
    404.  
    405.     // Class for handling .ini files...
    406.  
    407.     public class cIni
    408.     {
    409.  
    410.         [DllImport("kernel32", SetLastError = true)]
    411.         private static extern int WritePrivateProfileString(string pSection, string pKey, string pValue, string pFile);
    412.         [DllImport("kernel32", SetLastError = true)]
    413.         private static extern int WritePrivateProfileStruct(string pSection, string pKey, string pValue, int pValueLen, string pFile);
    414.         [DllImport("kernel32", SetLastError = true)]
    415.         private static extern int GetPrivateProfileString(string pSection, string pKey, string pDefault, byte[] prReturn, int pBufferLen, string pFile);
    416.         [DllImport("kernel32", SetLastError = true)]
    417.         private static extern int GetPrivateProfileStruct(string pSection, string pKey, byte[] prReturn, int pBufferLen, string pFile);
    418.  
    419.         private string ls_IniFilename;
    420.         private int li_BufferLen = 256;
    421.  
    422.         /// <summary>
    423.         /// cINI Constructor
    424.         /// </summary>
    425.         public cIni(string pIniFilename)
    426.         {
    427.             ls_IniFilename = pIniFilename;
    428.         }
    429.  
    430.         /// <summary>
    431.         /// INI filename (If no path is specifyed the function will look with-in the windows directory for the file)
    432.         /// </summary>
    433.         public string IniFile
    434.         {
    435.             get { return (ls_IniFilename); }
    436.             set { ls_IniFilename = value; }
    437.         }
    438.  
    439.         /// <summary>
    440.         /// Max return length when reading data (Max: 32767)
    441.         /// </summary>
    442.         public int BufferLen
    443.         {
    444.             get { return li_BufferLen; }
    445.             set
    446.             {
    447.                 if (value > 32767) { li_BufferLen = 32767; }
    448.                 else if (value < 1) { li_BufferLen = 1; }
    449.                 else { li_BufferLen = value; }
    450.             }
    451.         }
    452.  
    453.         /// <summary>
    454.         /// Read value from INI File
    455.         /// </summary>
    456.         public string ReadValue(string pSection, string pKey, string pDefault)
    457.         {
    458.  
    459.             return (z_GetString(pSection, pKey, pDefault));
    460.  
    461.         }
    462.  
    463.         /// <summary>
    464.         /// Read value from INI File, default = ""
    465.         /// </summary>
    466.         public string ReadValue(string pSection, string pKey)
    467.         {
    468.  
    469.             return (z_GetString(pSection, pKey, ""));
    470.  
    471.         }
    472.  
    473.         /// <summary>
    474.         /// Write value to INI File
    475.         /// </summary>
    476.         public void WriteValue(string pSection, string pKey, string pValue)
    477.         {
    478.  
    479.             WritePrivateProfileString(pSection, pKey, pValue, this.ls_IniFilename);
    480.  
    481.         }
    482.  
    483.         /// <summary>
    484.         /// Remove value from INI File
    485.         /// </summary>
    486.         public void RemoveValue(string pSection, string pKey)
    487.         {
    488.  
    489.             WritePrivateProfileString(pSection, pKey, null, this.ls_IniFilename);
    490.  
    491.         }
    492.  
    493.         /// <summary>
    494.         /// Read values in a section from INI File
    495.         /// </summary>
    496.         public void ReadValues(string pSection, ref Array pValues)
    497.         {
    498.  
    499.             pValues = z_GetString(pSection, null, null).Split((char)0);
    500.  
    501.         }
    502.  
    503.         /// <summary>
    504.         /// Read sections from INI File
    505.         /// </summary>
    506.         public void ReadSections(ref Array pSections)
    507.         {
    508.  
    509.             pSections = z_GetString(null, null, null).Split((char)0);
    510.  
    511.         }
    512.  
    513.         /// <summary>
    514.         /// Remove section from INI File
    515.         /// </summary>
    516.         public void RemoveSection(string pSection)
    517.         {
    518.  
    519.             WritePrivateProfileString(pSection, null, null, this.ls_IniFilename);
    520.  
    521.         }
    522.  
    523.         /// <summary>
    524.         /// Call GetPrivateProfileString / GetPrivateProfileStruct API
    525.         /// </summary>
    526.         private string z_GetString(string pSection, string pKey, string pDefault)
    527.         {
    528.  
    529.             string sRet = pDefault; byte[] bRet = new byte[li_BufferLen];
    530.             int i = GetPrivateProfileString(pSection, pKey, pDefault, bRet, li_BufferLen, ls_IniFilename);
    531.             sRet = System.Text.Encoding.GetEncoding(1252).GetString(bRet, 0, i).TrimEnd((char)0);
    532.             return (sRet);
    533.  
    534.         }
    535.  
    536.     }
    537.  
    538.     //Return the full hierarchy string of a gameObject, ready for use in GameObject.Find method later...
    539.     string GetHierarchy(GameObject g)
    540.     {
    541.         if (!g || g == null)
    542.         {
    543.             return "";
    544.         }
    545.  
    546.         string hierarchy = null;
    547.         string gname = g.name;
    548.  
    549.         Transform parent = g.transform.parent;
    550.  
    551.         while (parent)
    552.         {
    553.             hierarchy += "/" + parent.gameObject.name;
    554.             parent = parent.parent;
    555.         }
    556.         string inverse = gname + hierarchy;
    557.  
    558.         string[] arrayh = (string[])inverse.Split(new string[] { "/" }, StringSplitOptions.None);
    559.         Array.Reverse(arrayh);
    560.  
    561.         return "/" + string.Join("/", arrayh);
    562.  
    563.     }
    564.  
    565.     Vector4 vector4fromstring(string vectorstring)
    566.     {
    567.         if (vectorstring == null || vectorstring.Length == 0)
    568.             return new Vector4();
    569.  
    570.         vectorstring = vectorstring.Substring(1, vectorstring.Length - 2);
    571.  
    572.         string[] arrayvector = (string[])vectorstring.Split(new string[] { "," }, StringSplitOptions.None);
    573.  
    574.         Vector4 vectorfinal = new Vector4(float.Parse(arrayvector[0]), float.Parse(arrayvector[1]), float.Parse(arrayvector[2]), float.Parse(arrayvector[3]));
    575.  
    576.         return vectorfinal;
    577.     }
    578.  
    579. }
    580.  
     
    Last edited: Nov 27, 2017
  41. Sondre-S

    Sondre-S

    Joined:
    Jun 29, 2013
    Posts:
    54
    I almost got this working now.

    For some reason, when merging for the 2nd map when merging, the tiling is messed up and I can't figure out why...
     
  42. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    Good Job