最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

【Unity】工具類(lèi)系列教程——配置化和規(guī)范流程

2017-10-23 17:43 作者:皮皮關(guān)做游戲  | 我要投稿

前言:

程序員是看重效率的群體,如果凡事都事必躬親,一行一行的碼代碼,進(jìn)行重復(fù)的勞動(dòng),最后只會(huì)淪為碼農(nóng)(知乎很多大神都用這個(gè)自稱(chēng),這個(gè)詞不是褒義詞?。。?/p>


我們想象一下這個(gè)場(chǎng)景:

策劃:這個(gè)場(chǎng)景的出場(chǎng)位置太遠(yuǎn)了,調(diào)近一點(diǎn)點(diǎn)
程序:(臥槽,還有很多新需求還沒(méi)解決,這貨又來(lái)?。┖?,我等下就調(diào)。
過(guò)了一會(huì)……
策劃:角色位置還是不對(duì),你再調(diào)遠(yuǎn)一點(diǎn)點(diǎn)?
程序:……
反復(fù)幾次后,程序暴走
程序:還做不做新功能了???
(還是不敢不改啊)
還有這種場(chǎng)景:
程序:美術(shù)大爺,你這個(gè)角色的動(dòng)畫(huà)丟失了。
美術(shù):好的,我改一下
一會(huì)后……
程序:美術(shù)大爺,動(dòng)畫(huà)是沒(méi)丟失了,但是卻沒(méi)設(shè)置成循環(huán)……,您?您再改一下?
美術(shù):怎么會(huì)?!好的……
過(guò)了幾天,這個(gè)情況依然還會(huì)上演。
很多項(xiàng)目遇到的時(shí)間消耗,其實(shí)都在“舉手之勞”上,最后程序、美術(shù)、策劃三方互相都有怨氣。但是如果一個(gè)項(xiàng)目里面有規(guī)范流程化的工具。
比如程序策劃交流場(chǎng)景變成了這樣
程序:這個(gè)場(chǎng)景的出生點(diǎn)坐標(biāo)我已經(jīng)暴露在這個(gè)腳本上了,你直接在場(chǎng)景里面隨便調(diào),調(diào)好了點(diǎn)這個(gè)上傳就行,有BUG或者不懂的再問(wèn)我。
策劃:好的大爺。
程序美術(shù)交流的場(chǎng)景是這樣:
程序:你每次上傳美術(shù)資源的時(shí)候,點(diǎn)一下菜單欄的這個(gè)按鈕,它會(huì)把你丟失或者不對(duì)的都報(bào)錯(cuò)出來(lái)。
美術(shù)一查,就看到了所有美術(shù)資源出錯(cuò)的地方。

因此引出這篇教程的主題,配置化和規(guī)范流程。


ScriptableObject

做游戲配置有很多方法,有Excel保存,有導(dǎo)出Json、TXT,這里對(duì)Unity自帶ScriptableObject序列化方法配置做介紹。

(如果對(duì)配置有興趣的朋友可以去試試LitJson將類(lèi)導(dǎo)出成Json格式,或者自己試著寫(xiě)格式)

開(kāi)始具體使用前,我們普及幾個(gè)概念。

ScriptableObject 有什么好處?

1.Unity用于創(chuàng)建不需要綁定到物體的對(duì)象,即非繼承于Mono,該類(lèi)繼承于UnityEngine.Object

2.存放編輯器或數(shù)據(jù)配置文件

3.方便操作管理,可以可視化編輯

4.取數(shù)據(jù)方便,ScriptableObject已經(jīng)是可序列化的數(shù)據(jù),不用像讀取純文本或xml那樣還要繁瑣耗時(shí)的數(shù)據(jù)解析過(guò)程

(當(dāng)然也有壞處,如果不進(jìn)行Editor編寫(xiě)變量,可讀性其實(shí)很低,而且它和代碼綁定,如果配置類(lèi)的代碼修改,序列化的數(shù)據(jù)就會(huì)丟失,但是總的來(lái)說(shuō)不使用其他插件的情況下,用ScriptableObject 來(lái)學(xué)習(xí)游戲內(nèi)容配置是不錯(cuò)的)

序列化和反序列化的概念

把對(duì)象轉(zhuǎn)換為字節(jié)序列的過(guò)程稱(chēng)為對(duì)象的序列化;把字節(jié)序列恢復(fù)為對(duì)象的過(guò)程稱(chēng)為對(duì)象的反序列化。

/*強(qiáng)調(diào)一下,數(shù)據(jù)解析和序列化目的是一致的,就是將不可用轉(zhuǎn)換為可用,但是實(shí)際的方式方法不同*/


我們先做一個(gè)ScriptableObject的 數(shù)據(jù)類(lèi)


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class sceneConfigObject : ScriptableObject
{
   /// <summary>
   /// 配置名字
   /// </summary>
   public string mIndex;
   /// <summary>
   /// 出生點(diǎn)位置
   /// </summary>
   public Vector3 spawnPos;   
}

這個(gè)腳本是不能直接掛載到物體上的,只有繼承了mono類(lèi)的腳本才能夠。



然后為了我們直觀的修改數(shù)據(jù),我們用一個(gè)mono腳本做中間層。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SceneConfig : MonoBehaviour
{
   public sceneConfigObject mInfo;
}

現(xiàn)在我們可以將SceneConfig 掛載物體上,但是顯示并不是我們想要看到的數(shù)據(jù)。



我們?nèi)绻孶nity顯示出來(lái)我們要編輯的數(shù)據(jù),就比如去修改它顯示的內(nèi)容。而我們?nèi)绾稳プ远x化腳本的顯示內(nèi)容呢?

這里就需要UnityEditor擴(kuò)展編輯器功能。


編寫(xiě)Editor代碼:


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

[CustomEditor(typeof(SceneConfig))]
public class SceneConfigEditor : Editor
{

   SceneConfig mScript;

   /// <summary>
   /// 腳本激活的時(shí)候進(jìn)入,target就是對(duì)應(yīng)[CustomEditor(typeof(SceneConfig))]的SceneConfig類(lèi)
   /// </summary>
   public void OnEnable()
   {
       mScript = target as SceneConfig;
       if (mScript.mInfo == null)
       {
           mScript.mInfo = new sceneConfigObject();
       }
   }

   /// <summary>
   /// 重載腳本的界面
   /// </summary>
   public override void OnInspectorGUI()
   {
       mScript.mInfo.mIndex = EditorGUILayout.TextField("場(chǎng)景配置名", mScript.mInfo.mIndex);

       mScript.mInfo.spawnPos = EditorGUILayout.Vector3Field("出生點(diǎn)位置", mScript.mInfo.spawnPos);
   }

}

此時(shí)我們的數(shù)據(jù)就顯示出來(lái)了:



但是我們不可能就這樣存儲(chǔ)數(shù)據(jù),所以最后我們加上載入配置和導(dǎo)出配置的功能



/// <summary>
   /// 重載腳本的界面
   /// </summary>
   public override void OnInspectorGUI()
   {
   ……

       if (GUILayout.Button("導(dǎo)入"))
       {
           if (string.IsNullOrEmpty(mScript.mInfo.mIndex))
           {
               Debug.LogError("未輸入配置名");
               return;
           }

           string path = "config/" + mScript.mInfo.mIndex;

           var configObj = Resources.Load(path) as sceneConfigObject;
           if (configObj != null)
           {
               configObj = Instantiate(configObj);
               configObj.name = mScript.mInfo.mIndex;
           }
           mScript.mInfo = configObj;
       }

       if (GUILayout.Button("導(dǎo)出"))
       {
           if (string.IsNullOrEmpty(mScript.mInfo.mIndex))
           {
               Debug.LogError("未輸入配置名");
               return;
           }

           string path = "Assets/Resources/config/" + mScript.mInfo.mIndex + ".asset";

           if (File.Exists(path))
           {
               AssetDatabase.DeleteAsset(path);
               AssetDatabase.SaveAssets();
           }


           AssetDatabase.CreateAsset(Instantiate(mScript.mInfo), "Assets/Resources/config/" + mScript.mInfo.mIndex + ".asset");
           AssetDatabase.SaveAssets();
           AssetDatabase.Refresh();
       }
   }

這樣我們導(dǎo)出的ScriptableObject類(lèi)就存放到硬盤(pán)上。

/*AssetDatabase類(lèi)是Unity專(zhuān)門(mén)針對(duì)編輯模式下的數(shù)據(jù)存儲(chǔ)基類(lèi)*/



如果要使用,我們就將它當(dāng)成資源加載,轉(zhuǎn)換成對(duì)應(yīng)的腳本類(lèi)型,就可以實(shí)現(xiàn)調(diào)用



public void LoadScriptableObject()
   {
       var configObj = Instantiate(Resources.Load("config/test01") as sceneConfigObject);
       Debug.Log(configObj.mIndex);
       Debug.Log(configObj.spawnPos);
   }

[查錯(cuò)工具]

游戲中的查錯(cuò)工具很多,因?yàn)閳F(tuán)隊(duì)項(xiàng)目在工作中合并資源出錯(cuò)會(huì)導(dǎo)致資源丟失,如果一個(gè)一個(gè)去尋找是非?;〞r(shí)間的。這里以檢測(cè)動(dòng)畫(huà)文件狀態(tài)為例。

依然是Editor擴(kuò)展編輯器功能,它有一個(gè)屬性可以修改菜單欄。

[MenuItem("Tools/動(dòng)畫(huà)查錯(cuò)", priority = 0)]

MenuItem后跟上的路徑,為選項(xiàng)的父子目錄關(guān)系。

priority為優(yōu)先級(jí),可以調(diào)整選項(xiàng)顯示的順序。

效果圖:



EditorUtility.DisplayDialog

提供彈窗功能



以下為源碼:



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

public class AnimtorTool : Editor {


   public static string modePrefabsPath = "Assets/Resources/animator/";

   [MenuItem("Tools/動(dòng)畫(huà)查錯(cuò)", priority = 0)]
   public static void FreshAnimtor()
   {
       FileInfo[] modeDirect = new DirectoryInfo(modePrefabsPath).GetFiles();

       for (int i = 0; i < modeDirect.Length; i++)
       {
           if (modeDirect[i].Name.Contains("meta"))
           {
               continue;
           }
           string modelName = modeDirect[i].Name;

           string animtorPath = modePrefabsPath + modelName;

           //設(shè)置動(dòng)畫(huà)控制器內(nèi)參數(shù)
           AnimatorController AnimatorTemplate = AssetDatabase.LoadAssetAtPath(animtorPath, typeof(AnimatorController)) as AnimatorController;

           if (AnimatorTemplate == null)
           {
               if (EditorUtility.DisplayDialog("錯(cuò)誤的路徑", "尋找動(dòng)畫(huà)路徑失?。?quot; + animtorPath + ",檢查動(dòng)畫(huà)控制器名字是否和模型名字匹配", "繼續(xù)"))
               {
                   return;
               }
           }

           foreach (var obj in AnimatorTemplate.layers[0].stateMachine.states)
           {
               if (obj.state.motion == null)
               {
                   if (EditorUtility.DisplayDialog("存在空的動(dòng)畫(huà)Clip", "動(dòng)畫(huà)" + animtorPath + "的狀態(tài)" + obj.state.name + "為空", "繼續(xù)"))
                   {
                       continue;
                   }
               }
           }

       }
   }
}


最后注意,Editor代碼一定要放在Editor目錄中,目錄中的代碼不參與打包。


總結(jié)

我個(gè)人理解的程序員職責(zé)應(yīng)當(dāng)是除了解決項(xiàng)目實(shí)際問(wèn)題外,還要致力于優(yōu)化項(xiàng)目流程。畢竟修改自己的代碼容易,修改項(xiàng)目的BUG難。如果不以團(tuán)隊(duì)合作為目的,僅僅想著自身單方面能力的提高,是不能將個(gè)人價(jià)值發(fā)揮到最大,IT行業(yè)不比傳統(tǒng)行業(yè),更注重的是一個(gè)人的整體能力,有經(jīng)驗(yàn)的程序員一個(gè)能打十個(gè)就是因?yàn)槟芨纳祈?xiàng)目工作流程。

回到正題,Editor代碼因?yàn)椴粎⑴c打包,完全是游戲項(xiàng)目的擴(kuò)展工具,因此普適性很強(qiáng),能混用很多個(gè)項(xiàng)目中去,之后幾篇文章會(huì)針對(duì)工具類(lèi)腳本進(jìn)行教學(xué),盡請(qǐng)期待。


對(duì)游戲開(kāi)發(fā)感興趣的同學(xué),歡迎圍觀我們:【皮皮關(guān)游戲開(kāi)發(fā)教育】 ,會(huì)定期更新各種教程干貨,更有別具一格的線(xiàn)下小班教育。

我們的官網(wǎng)地址:levelpp.com/

我們的游戲開(kāi)發(fā)技術(shù)交流群:610475807

我們的微信公眾號(hào):皮皮關(guān)


【Unity】工具類(lèi)系列教程——配置化和規(guī)范流程的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
崇义县| 绍兴县| 古浪县| 象州县| 板桥市| 曲麻莱县| 育儿| 淅川县| 望都县| 灵石县| 大兴区| 尚义县| 策勒县| 达日县| 榆林市| 共和县| 隆德县| 时尚| 红河县| 石棉县| 加查县| 邻水| 南召县| 浪卡子县| 五指山市| 上饶市| 松潘县| 邢台市| 上林县| 周宁县| 石城县| 万载县| 临邑县| 抚宁县| 揭阳市| 东丰县| 天全县| 东光县| 禹州市| 岗巴县| 巴彦淖尔市|