[Unity] Unity5中自动烘焙光照(转载)

查看:7403 |回复:57 | 2015-11-27 10:01:25

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 成林 于 2018-5-22 21:39 编辑

36.jpg
大家好,咱一起聊聊unity5的光照烘焙和烘焙自动化。

有时候万事俱备,只欠烘焙了。你盯着进度条总觉得它马上就好,但常常是离结束遥遥无期。不如省下这点等待的时间去睡个美容觉吧。

光照烘焙相当耗时,一般的过程都由多台计算机分担或者单台彻夜工作即可。但烘焙过程却需要人工交互,你得时不时的点点按钮才能继续。为了减少烘焙管理的手动操作,我创建了一个简单的脚本,用于管理你交给它的任意数量场景的烘焙。

想法很简单,告诉Unity哪些场景需要烘焙让它干活,下面是实例。



脚本会为列表中的每个场景自动点击烘焙按钮,并在进行下一场景的烘焙前保存结果。同时,脚本会报告当前进度,包括各场景烘焙的耗时以及每次烘焙完成的时间。
1) 在Unity工程根目录下创建Editor文件夹,创建一个C# 脚本,命名为 BakeScenes。

2) 将下面的代码拷贝并粘贴到BakeScenes文件中。


using System.IO;
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;

public class BakeScenes : EditorWindow
{
// 存放场景对象的数组
    public Object[] scenes;

// Lists and string array for easier management
// 为便于管理用的列表和字符串
    List sceneList = new List();
    private int sceneIndex = 0;
    private string[] scenePath;

// Editor text
// 编辑器文本
    string bakeButton = "Bake";
    string status = "Idle...";
    System.DateTime timeStamp;

// 菜单项
    [MenuItem("Tools/Bake Scenes")]
    public static void ShowWindow()
    {
        EditorWindow window = GetWindow(typeof(BakeScenes), false, "Bake Scenes");
        window.autoRepaintOnSceneChange = true;
    }

// 获取焦点时更新编辑器文本信息
    void OnFocus()
    {
        status = "Idle...";
        if (!Lightmapping.isRunning)
        {
            bakeButton = "Bake";
        }
    }

    void OnGUI()
    {
        // "target" can be any class derrived from ScriptableObject
        // (could be EditorWindow, MonoBehaviour, etc)
            // target可以是任何由ScriptableObject派生的类(如EditorWindow, MonoBehaviour等)
        ScriptableObject target = this;
        SerializedObject so = new SerializedObject(target);
        SerializedProperty scenesProperty = so.FindProperty("scenes");

        EditorGUILayout.PropertyField(scenesProperty, true); // True means show children
        so.ApplyModifiedProperties(); // Remember to apply modified properties

        if (GUILayout.Button(bakeButton)) // Button to start bake process
        {
            InitializeBake();
        }
        EditorGUILayout.LabelField("Status: ", status);
        so.Update();
    }

// 若当前没有烘焙任务,则设置代理、场景,并开始烘焙,
// 否则,停止光照贴图并更新编辑器文本
    void InitializeBake()
    {
        if (!Lightmapping.isRunning)
        {
            Lightmapping.completed = null;
            Lightmapping.completed = SaveScene;
            Lightmapping.completed += BakeNewScene;
            SetScenes();
            BakeNewScene();
        }
        else
        {
            Lightmapping.Cancel();
            UpdateBakeProgress();
        }
    }

// 创建要烘焙场景的字符串数组
    private bool SetScenes()
    {
        // Reset values
        sceneList.Clear();
        sceneIndex = 0;

            // 获取场景路径并存储在列表中                  
        if (scenes.Length == 0)
        {
            status = "No scenes found";
            bakeButton = "Bake";
            return false;
        }
        else
        {
            for (int i = 0; i < scenes.Length; i++)
            {
                sceneList.Add(AssetDatabase.GetAssetPath(scenes));
            }

            // Sort and put scene paths in array
                   // 排序并将场景路径放进数组
            scenePath = sceneList.ToArray();
            return true;
        }
    }

// 循环进行场景烘焙,并更新进度
    private void BakeNewScene()
    {
        if (sceneIndex < scenes.Length)
        {
            EditorApplication.OpenScene(scenePath[sceneIndex]);
            timeStamp = System.DateTime.Now;
            Lightmapping.BakeAsync();
            UpdateBakeProgress();
            sceneIndex++;
        }
        else
        {
            DoneBaking("done");
        }
    }

// 更新烘焙进度
    private void UpdateBakeProgress()
    {
        if (Lightmapping.isRunning)
        {
            status = "Baking " + (sceneIndex + 1).ToString() +
            " of " + scenes.Length.ToString();
            bakeButton = "Cancel";
        }
        else if (!Lightmapping.isRunning)
        {
            DoneBaking("cancel");
        }
    }

// 开始新的烘焙前保存当前场景
    private void SaveScene()
    {
        System.TimeSpan bakeSpan = System.DateTime.Now - timeStamp;
        string bakeTime = string.Format("{0:D2}:{1:D2}:{2:D2}",
            bakeSpan.Hours, bakeSpan.Minutes, bakeSpan.Seconds);
        Debug.Log("(" + sceneIndex.ToString() + "/" +
            scenes.Length.ToString() + ") " + "Done baking: " +
            EditorApplication.currentScene + " after " + bakeTime +
            " on " + System.DateTime.Now.ToString());
        EditorApplication.SaveScene();
    }

// 完成烘焙后,更新编辑器文本
    private void DoneBaking(string reason)
    {
        Lightmapping.completed = null;
        sceneList.Clear();
        sceneIndex = 0;

        if (reason == "done")
        {
            status = "Bake is done";
            bakeButton = "Bake";
        }
        else if (reason == "cancel")
        {
            status = "Canceled";
            bakeButton = "Bake";
        }
    }
}
现在你的Unity菜单条上有了一个Tools菜单项,正如在第一个动画中显示的那样,点击菜单项,打开Bake Scenes窗口,添加场景,点击烘焙,然后….

可劲儿造吧~
原文作者:Tino van der Kraan



评分

参与人数 1元素币 +10 活跃度 +10 展开 理由
狼之独步 + 10 + 10 阅贴无数,楼主最强!

查看全部评分

2015-11-27 10:01:25  
 赞 赞 1

使用道具 登录

57个回答,把该问题分享到群,邀请大神一起回答。
2#
谢谢分享
回复 收起回复
2015-11-27 10:05:25   回复
 赞 赞 1

使用道具 登录

3#
虽然看不懂,不过牛掰
回复 收起回复
2015-11-27 10:12:41   回复
 赞 赞 1

使用道具 登录

4#

谢谢分享
回复 收起回复
2015-11-27 11:18:35   回复
 赞 赞 1

使用道具 登录

5#
{:1_144:}
回复 收起回复
2015-11-27 11:56:10   回复
 赞 赞 1

使用道具 登录

6#
黑板报吗
回复 收起回复
2015-11-27 12:32:47   回复
 赞 赞 1

使用道具 登录

8#
{:1_144:}
回复 收起回复
2015-11-28 09:39:15   回复
 赞 赞 1

使用道具 登录

9#
很不錯的分享
回复 收起回复
2018-5-20 07:23:26   回复
 赞 赞 1

使用道具 登录

10#
感谢分享
回复 收起回复
2018-6-13 17:46:49   回复
 赞 赞 1

使用道具 登录

11#

资源甚好,发帖艰辛,且阅且珍惜!
回复 收起回复
2018-10-15 10:05:40   回复
 赞 赞 1

使用道具 登录

12#


资源甚好,发帖艰辛,且阅且珍惜
回复 收起回复
2018-10-15 10:16:14   回复
 赞 赞 1

使用道具 登录

13#
感谢分享~棒棒哒
回复 收起回复
2018-10-15 10:18:58   回复
 赞 赞 1

使用道具 登录

14#
元素帖子强,满满正能量!
回复 收起回复
2018-10-15 10:30:15   回复
 赞 赞 1

使用道具 登录

15#
元素帖子强,满满正能量!
回复 收起回复
2018-10-15 10:30:58   回复
 赞 赞 1

使用道具 登录

16#
回复 收起回复
2018-10-15 10:31:38   回复
 赞 赞 1

使用道具 登录

17#
厉害了
回复 收起回复
2018-10-15 11:50:02   回复
 赞 赞 1

使用道具 登录

18#
感谢分享感谢分享感谢分享感谢分享感谢分享
回复 收起回复
2018-10-15 12:57:45   回复
 赞 赞 1

使用道具 登录

19#
有了它,特效这行业更没有技术含量了!
回复 收起回复
2018-10-15 13:06:08   回复
 赞 赞 1

使用道具 登录

20#
元素帖子强,满满正能量!
回复 收起回复
2018-10-15 13:14:54   回复
 赞 赞 1

使用道具 登录

CG 游戏行业专业问题

Unity3D技术手机游戏引擎手游引擎
123下一页
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表