{"id":1554,"date":"2016-07-25T04:14:01","date_gmt":"2016-07-24T20:14:01","guid":{"rendered":"http:\/\/www.clonefactor.com\/wordpress\/?p=1554"},"modified":"2016-08-09T00:35:07","modified_gmt":"2016-08-08T16:35:07","slug":"technical-artist-test-case-%e5%9c%a8%e9%a6%99%e6%b8%af%e5%a4%a7%e6%a6%82%e6%b2%92%e6%9c%89%e5%85%ac%e5%8f%b8%e9%9c%80%e8%a6%81%e6%88%91%e7%9a%84%e6%9d%90%e8%83%bd","status":"publish","type":"post","link":"https:\/\/www.clonefactor.com\/wordpress\/program\/unity3d\/1554\/","title":{"rendered":"Technical Artist : test case"},"content":{"rendered":"<p>\u6709\u6642\u6703\u60f3, \u6211\u5b78\u9019\u4e9b\u5e79\u751a\u9ebc?!<br \/>\n\u5728\u9999\u6e2f\u5927\u6982\u6c92\u6709\u516c\u53f8\u9700\u8981\u6211\u7684\u6750\u80fd.\u00a0\u53cd\u6b63\u6c92\u6709\u751f\u7522\u751a\u9ebc\u5927\u88fd\u4f5c\u7684\u904a\u6232\u516c\u53f8.<br \/>\nTechnical Artist \u7684\u540d\u982d\u597d\u50cf\u53ea\u80fd\u81ea\u5df1 FF \u4e00\u4e0b. \u53cd\u6b63\u5165\u8077\u5f8c\u90fd\u4e00\u6982\u53eb Programmer \u4e0d\u662f\u55ce?<br \/>\n\u9ad8\u7d1a\u6e05\u6f54\u5de5\u8ddf\u6e05\u6f54\u5de5\u57fa\u672c\u6c92\u5206\u5225\u7684.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1555\" src=\"http:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/tech_artist.jpg\" alt=\"tech_artist\" width=\"1919\" height=\"1156\" srcset=\"https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/tech_artist.jpg 1919w, https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/tech_artist-300x181.jpg 300w, https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/tech_artist-768x463.jpg 768w, https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/tech_artist-1024x617.jpg 1024w\" sizes=\"auto, (max-width: 1919px) 100vw, 1919px\" \/><\/p>\n<p>\u672c\u6b21\u5f88\u7c21\u55ae, \u7528\u4e00\u5806\u5c0f\u5f1f Photoshop \u81ea\u88fd\u7684\u7834\u5716\u628a\u754c\u9762\u5806\u5230\u76e1\u53ef\u80fd\u7684 Sci-fi.<br \/>\n\u7531\u65bc Photoshop \u7684\u529f\u529b\u4e0d\u6df1\u7684\u95dc\u4fc2\u672c\u6b21\u53ea\u7528 Pixel Art (\u6a94\u6848\u5c11)<br \/>\n\u4e5f\u9806\u9053\u6e2c\u8a66\u4e00\u4e0b\u958b\u767c\u4e2d\u7684 Panel Manager\u7684\u4f7f\u7528\u8005\u6d41\u7a0b.<br \/>\nMulti scene loader \u7684\u64cd\u4f5c\u4e5f\u611f\u89ba\u4e0d\u932f.<\/p>\n<div class=\"aio-button\"><div class=\"aio-pulse\"><a target=\"_blank\" href=\"http:\/\/www.clonefactor.com\/20160725_SpaceShip_Menu\" class=\"aio-orange-medium\" title=\"WebGL Demo\"><i class=\"glyphicons glyphicons-gamepad x2\"><\/i>WebGL Demo<\/a><\/div><\/div>\n<p>&nbsp;<\/p>\n<p>SceneLoader.cs<\/p>\n<pre class=\"brush:csharp\">using UnityEngine;\r\nusing UnityEngine.SceneManagement;\r\nusing System.Collections;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\n\r\nusing Kit.UI;\r\n\r\nnamespace Kit.SceneControl\r\n{\r\n\tpublic enum eLoadState\r\n\t{\r\n\t\tIdle = 0,\r\n\t\tLoading = 1, \/\/ start loading scene\r\n\t\tSceneLoaded = 2, \/\/ every scene loaded\r\n\t\tPostLoading = 3, \/\/ period will wait for program request.\r\n\t\tLoaded = 100 \/\/ back to Idle\r\n\t}\r\n\r\n\t\/\/\/ &lt;summary&gt;main progress can use Coroutine Start() to listen the eloadState, in order to align Start moment of scene.&lt;\/summary&gt;\r\n\tpublic class SceneLoader : Singleton&lt;SceneLoader&gt;\r\n\t{\r\n\t\t[SerializeField] Camera m_LoadingCamera;\r\n\t\t[SerializeField] Panel m_LoadingUi;\r\n\t\t[SerializeField] float m_MinPostLoadingSecond = 3f, m_MaxPostLoadingSecond = 7f;\r\n\r\n\t\tList&lt;AsyncSceneObj&gt; m_Loaders = new List&lt;AsyncSceneObj&gt;();\r\n\t\tIEnumerator m_Coroutine;\r\n\t\tUnityEngine.SceneManagement.Scene m_NextActiveScene;\r\n\t\teLoadState m_State = eLoadState.Idle;\r\n\t\tbool m_Dirty = false;\r\n\t\tHashSet&lt;int&gt; m_PostLock = new HashSet&lt;int&gt;();\r\n\t\tpublic eLoadState State { get { return m_State; } private set { m_State = value; m_Dirty = true; } }\r\n\t\tpublic event System.Action OnStateChange, OnLoadFinished;\r\n\r\n\t\tstruct AsyncSceneObj\r\n\t\t{\r\n\t\t\tpublic AsyncOperation operation;\r\n\t\t\tpublic string sceneName;\r\n\t\t}\r\n\r\n\t\tprotected override void Awake()\r\n\t\t{\r\n\t\t\tbase.Awake();\r\n\t\t\tDontDestroyOnLoad(this);\r\n\t\t\tm_LoadingUi.OpenStart += OnPanelOpenStart;\r\n\t\t\tm_LoadingUi.CloseEnd += OnPanelCloseEnd;\r\n\t\t\tState = eLoadState.Idle;\r\n\t\t}\r\n\r\n\t\tprotected void Update()\r\n\t\t{\r\n\t\t\tif(m_Dirty)\r\n\t\t\t{\r\n\t\t\t\tm_Dirty = false;\r\n\t\t\t\tif (OnStateChange != null)\r\n\t\t\t\t\tOnStateChange();\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tprotected override void OnDestroy()\r\n\t\t{\r\n\t\t\tbase.OnDestroy();\r\n\t\t\tm_LoadingUi.OpenStart -= OnPanelOpenStart;\r\n\t\t\tm_LoadingUi.CloseEnd -= OnPanelCloseEnd;\r\n\t\t}\r\n\t\t\r\n\t\tpublic void LoadScene(string[] sceneNames)\r\n\t\t{\r\n\t\t\tif (State &gt; eLoadState.Idle &amp;&amp; State &lt; eLoadState.Loaded)\r\n\t\t\t\tthrow new System.Exception(\"loader in use, LoadScene request Failed\");\r\n\t\t\tif (sceneNames.Length == 0)\r\n\t\t\t\treturn;\r\n\r\n\t\t\t\/\/ force reset lock\r\n\t\t\tm_PostLock.Clear();\r\n\t\t\tm_Loaders.Clear();\r\n\t\t\tState = eLoadState.Loading;\r\n\r\n\t\t\tm_LoadingUi.Open();\r\n\t\t\tm_LoadingCamera.enabled = true;\r\n\t\t\tforeach (string sceneName in sceneNames)\r\n\t\t\t{\r\n\t\t\t\tif (!string.IsNullOrEmpty(sceneName))\r\n\t\t\t\t{\r\n\t\t\t\t\tm_Loaders.Add(\r\n\t\t\t\t\t\tnew AsyncSceneObj()\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\toperation = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive),\r\n\t\t\t\t\t\t\tsceneName = sceneName\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\tm_Loaders[m_Loaders.Count - 1].operation.allowSceneActivation = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tm_NextActiveScene = SceneManager.GetSceneByName(sceneNames[0]);\r\n\r\n\t\t\tif (m_Coroutine != null)\r\n\t\t\t{\r\n\t\t\t\tStopCoroutine(m_Coroutine);\r\n\t\t\t\tm_Coroutine = null;\r\n\t\t\t}\r\n\t\t\tm_Coroutine = Loading();\r\n\t\t\tStartCoroutine(m_Coroutine);\r\n\t\t}\r\n\r\n\t\tIEnumerator Loading()\r\n\t\t{\r\n\t\t\twhile (m_Loaders.Count &gt; 0)\r\n\t\t\t{\r\n\t\t\t\tif (m_Loaders[0].operation.isDone)\r\n\t\t\t\t\tm_Loaders.RemoveAt(0);\r\n\t\t\t\tyield return null;\r\n\t\t\t}\r\n\r\n\t\t\tState = eLoadState.SceneLoaded;\r\n\t\t\tSceneManager.SetActiveScene(m_NextActiveScene);\r\n\t\t\tyield return new WaitForEndOfFrame();\r\n\t\t\t\r\n\t\t\t\/\/ min time to wait for register m_PostLock\r\n\t\t\tyield return new WaitForSeconds(m_MinPostLoadingSecond);\r\n\r\n\t\t\tfloat countdown = m_MaxPostLoadingSecond;\r\n\t\t\twhile (m_PostLock.Count &gt; 0 &amp;&amp; countdown &gt; 0)\r\n\t\t\t{\r\n\t\t\t\tyield return null;\r\n\t\t\t\tcountdown -= Time.deltaTime;\r\n\t\t\t}\r\n\t\t\tif(m_PostLock.Count &gt; 0)\r\n\t\t\t\tDebug.LogWarning(\"SceneLoader Instance locked timeout : Total = \" + m_PostLock.Count + \"\\n\" + string.Join(\", \", m_PostLock.Select(o =&gt; o.ToString()).ToArray()));\r\n\t\t\t\r\n\t\t\tm_LoadingUi.Close();\r\n\t\t\tState = eLoadState.Loaded;\r\n\t\t\tif (OnLoadFinished != null)\r\n\t\t\t\tOnLoadFinished();\r\n\t\t}\r\n\r\n\t\tprivate void OnPanelOpenStart(IPanel obj) { m_LoadingCamera.enabled = true; }\r\n\t\tprivate void OnPanelCloseEnd(IPanel obj) { m_LoadingCamera.enabled = false; }\r\n\r\n\t\tpublic void Lock(Object obj) { m_PostLock.Add(obj.GetInstanceID()); }\r\n\t\tpublic void Unlock(Object obj) { m_PostLock.Remove(obj.GetInstanceID()); }\r\n\t}\r\n}<\/pre>\n<p>SceneInitializer.cs<\/p>\n<pre class=\"brush:csharp\">using UnityEngine;\r\nusing UnityEngine.SceneManagement;\r\nusing System.Collections;\r\n\r\nnamespace Kit.SceneControl\r\n{\r\n\tpublic class SceneInitializer : MonoBehaviour\r\n\t{\r\n\t\t[SerializeField] string[] m_AutoLoadScene;\r\n\t\t[SerializeField] string m_LoaderScene = \"Loading\";\r\n\t\t[SerializeField] GameObject m_LoaderScreen;\r\n\t\tprivate string m_ActiveScene;\r\n\t\tstatic bool IsInited = false;\r\n\r\n\t\tvoid Awake()\r\n\t\t{\r\n\t\t\tif (IsInited)\r\n\t\t\t{\r\n\t\t\t\t\/\/ we only active once in entire game\r\n\t\t\t\tDestroyImmediate(gameObject);\r\n\t\t\t}\r\n\t\t\telse if (SceneLoader.Instance == null)\r\n\t\t\t{\r\n\t\t\t\tInstantiate(m_LoaderScreen, Vector3.up * 10f, Quaternion.LookRotation(Vector3.down, Vector3.forward));\r\n\t\t\t}\r\n\t\t\tIsInited = true;\r\n\t\t}\r\n\r\n\t\tIEnumerator Start()\r\n\t\t{\r\n\t\t\twhile (SceneLoader.Instance == null)\r\n\t\t\t\tyield return null;\r\n\t\t\tyield return 1;\r\n\t\t\tif (m_AutoLoadScene.Length &gt; 0)\r\n\t\t\t\tSceneLoader.Instance.LoadScene(m_AutoLoadScene);\r\n\r\n\t\t\tif (!string.IsNullOrEmpty(m_LoaderScene))\r\n\t\t\t{\r\n\t\t\t\twhile (SceneManager.GetActiveScene().name == m_LoaderScene)\r\n\t\t\t\t\tyield return null;\r\n\t\t\t\tyield return 1;\r\n\t\t\t\tSceneManager.UnloadScene(m_LoaderScene);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}<\/pre>\n<p>\u8a2d\u5b9a\u6982\u5ff5\u5f88\u7c21\u55ae, \u628a\u5834\u666f\u90fd\u7368\u7acb\u8a2d\u5b9a\u7136\u5f8c\u52d5\u614b\u8f09\u5165\u5230 active scene.<br \/>\n\u6b63\u5e38\u6d41\u7a0b\u662f\u7531\u958b\u59cb\u756b\u9762 -&gt; \u8f09\u5165 Menu UI, Menu Background -&gt; start game -&gt; destroy Background, destroy menu -&gt; In Game menu &amp; SceneA,<\/p>\n<p>\u958b\u767c\u6d41\u7a0b\u5247\u53ef\u80fd\u7531 SceneA \u958b\u59cb -&gt; load in game menu -&gt; end game -&gt; load Menu UI, Menu Background<\/p>\n<p>\u76ee\u7684\u5c31\u662f\u65b9\u4fbf\u958b\u767c\u6d41\u7a0b,\u4f7f\u904a\u6232\u53ef\u4ee5\u5728\u4efb\u4f55 scene \u4f5c\u70ba start point.<br \/>\n[1] \u5404\u5834\u666f\u7684\u8a2d\u5b9a, \u628a\u7f3a\u5931\u7684 Scene Name \u5beb\u5728\u88e1\u9762.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1583\" src=\"http:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/Init.jpg\" alt=\"Init\" width=\"650\" height=\"546\" srcset=\"https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/Init.jpg 650w, https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/Init-300x252.jpg 300w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>[2]\u00a0\u81ea\u5bb6\u5236\u919c\u919c\u7684 loading screen. \u5171\u7528\u7684 prefab.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1584\" src=\"http:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/loading_prefab.jpg\" alt=\"loading_prefab\" width=\"1138\" height=\"729\" srcset=\"https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/loading_prefab.jpg 1138w, https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/loading_prefab-300x192.jpg 300w, https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/loading_prefab-768x492.jpg 768w, https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/loading_prefab-1024x656.jpg 1024w\" sizes=\"auto, (max-width: 1138px) 100vw, 1138px\" \/><\/p>\n<p>Menu \u6574\u500b\u7368\u4f54\u4e00\u500b scene.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1585\" src=\"http:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/menu.jpg\" alt=\"menu\" width=\"1907\" height=\"1116\" srcset=\"https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/menu.jpg 1907w, https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/menu-300x176.jpg 300w, https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/menu-768x449.jpg 768w, https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/menu-1024x599.jpg 1024w\" sizes=\"auto, (max-width: 1907px) 100vw, 1907px\" \/><\/p>\n<p>\u904b\u4f5c\u4e2d\u5883\u6cc1. loading<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1586\" src=\"http:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/real_loading.jpg\" alt=\"real_loading\" width=\"1280\" height=\"801\" srcset=\"https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/real_loading.jpg 1280w, https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/real_loading-300x188.jpg 300w, https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/real_loading-768x481.jpg 768w, https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/07\/real_loading-1024x641.jpg 1024w\" sizes=\"auto, (max-width: 1280px) 100vw, 1280px\" \/><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u6709\u6642\u6703\u60f3, \u6211\u5b78\u9019\u4e9b\u5e79\u751a\u9ebc?! \u5728\u9999\u6e2f\u5927\u6982\u6c92\u6709\u516c\u53f8\u9700\u8981\u6211\u7684\u6750\u80fd.\u00a0\u53cd\u6b63\u6c92\u6709\u751f\u7522\u751a\u9ebc\u5927\u88fd\u4f5c\u7684\u904a\u6232\u516c\u53f8. &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[91,92,43],"class_list":["post-1554","post","type-post","status-publish","format-standard","hentry","category-unity3d","tag-photoshop","tag-scene","tag-unity3d-2"],"_links":{"self":[{"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/posts\/1554","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/comments?post=1554"}],"version-history":[{"count":0,"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/posts\/1554\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/media?parent=1554"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/categories?post=1554"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/tags?post=1554"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}