一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

unity3d學習筆記(十一)NGUI結(jié)合Shader制作小地圖

 3dC 2014-01-28

本系列文章由Aimar_Johnny編寫,歡迎轉(zhuǎn)載,轉(zhuǎn)載請標明出處,謝謝。

http://blog.csdn.net/lzhq1982/article/details/12783493


在做這個demo的過程中,制作小地圖著實刁難了我一把,百度了很多文章,花了好長的時間,需要的知識點實在太多了,尤其是shader語言,好在最后成功把它啃下來了,先聲明一下,本篇文章將會是這個系列中最難的,不過如果成功做出來成就感也是大大的,其實按照我的步驟一步一步來也沒那么復雜啦,接下來我把這個過程分享給大家,下面上一張截圖:


看右上角,那個就是小地圖,也許有點不太好看,沒辦法,誰讓我不是美術(shù)啊,需要的圖素都是自己用Photoshop做的,記得有人說過,不會美術(shù)的程序不是好策劃,所以自己來吧。


先說一下原理,我們做小地圖用的技術(shù)就是遮罩,玩過flash的對這個詞應(yīng)該不新鮮,何為遮罩呢,通俗一下講,你有兩張紙,一張紙上畫了漂亮的山川河流,另一張紙就是張白紙,中間挖個圓洞,然后你把白紙蓋在那張畫滿山川河流的紙上,只有中間圓洞的地方你能看到,其他地方都被蓋住了,保持白紙不動,移動后面的畫紙,你會看到連續(xù)的不同的地貌,我們的小地圖原理就是這樣的,時刻保持角色在中間,動的只是后面的背景罷了。只是這里需要多處理一下,就是除了那個圓洞,其他的部分我們要透明掉。


相信這么解釋應(yīng)該沒有不懂的了吧。如果還不清楚那要么是我的表達能力有問題,要么你的智商。。??瓤?,言歸正傳,按照上面的理論,我們都該準備些什么呢。最起碼的得有一張完整的地圖吧,得有個圓形的遮罩吧,再漂亮點圓形遮罩需要個圓框,地圖上得有個小標志顯示玩家的位置和方向。

地圖好搞,在unity中調(diào)到場景的頂視圖,然后截個圖就好了,縮放一下比例,我的地圖是512*512的,取名map,如下圖:


丑是丑了點,誰讓我的地形簡單呢,再一次聲明,我是個程序。

遮罩就需要你自己畫個了,要保證它和背景圖一樣大,我這里也是512*512的,中間是個白色的圓,其他地方alpha是透明的。如圖:


我這里并沒有截全部512的圖,不要以為只這么小啊,除了白圓,其他地方都是透明的,其實什么顏色的無所謂,只要是圓的就行。

然后做個圓框,也是512的,圓框和白圓大小一致,中間和其他地方都是透明的。


最后是角色的那個小標記

資源就這些,準備好就可以開干了。


關(guān)于NGUI我這里就不解釋了,看過我前面文章的童鞋應(yīng)該知道怎么用了,我們要把小地圖放在右上角的錨點上,不是簡單的放幾個sprite的事情,那我們需要做些什么呢。來,我們倒著說,先看結(jié)果,我希望我的右上角先有個Panel,然后Panel下有個Textrue,而我的小地圖就是繪制在這個Texture上;那小地圖是以什么方式繪制到這個Texture上的呢,當然是靠material(材質(zhì)),而且是一個能實現(xiàn)遮罩,透明,動態(tài)渲染的材質(zhì)。那只能靠材質(zhì)中的shader了;先不說遮罩和透明,先說動態(tài)渲染,我們以前用到的材質(zhì)都是靜態(tài)的,而現(xiàn)在我們要用到的是地圖可以移動的動態(tài)材質(zhì),所以要用動態(tài)渲染,要說動態(tài)渲染,那最先想到的就是Render Texture,要說什么是Render Texture,看這里好了:渲染紋理。由果推因,我們就知道都該做些什么了,一個一個攻克吧,現(xiàn)在我們由因及果。


1、繪制渲染紋理(Render Texture)

a、先在MainCamera下創(chuàng)建一個UI,選擇NGUI->Open the UI Wizard,保持設(shè)置,點Create Your UI,然后Anchor下的Panel改名為MiniMapRenderPanel。

b、創(chuàng)建一個Atlas,不知道什么是Atlas的可以看我前面的文章,選NGUI->Open the Atlas Maker,新彈出的界面上修改你的atlas名稱,點擊那個完整的地圖,就是我上面的那個map,然后點Create。


c、在MiniMapRenderPanel下建一個sprite,NGUI->Open the Widget Wizard,Atlas選剛建的那個Atlas,Template選sprite,Sprite選map,其他默認。最后建完了是這個結(jié)構(gòu)。


d、在資源里新建個Render Texture,Assets->Create->Render Texture,起名MiniMapRenderTexture。

e、設(shè)置camera,那個NGUI的camera設(shè)置如下:


Clear Flags設(shè)為Solid Color,Background設(shè)為黑色,這樣當你走到地圖的邊緣時,沒有地圖的地方會繪制成黑色。Projection設(shè)為平行投影Orthographic,不了解平行投影和透視投影的話需要補一下3d基礎(chǔ)了。Target Texture那里把之前做的那個Render Texture拖上去。這樣攝像機投影的地方就會繪制在這個Render Texture上,也就是地圖會繪制在它上面了,然后我們就可以做material了。

f、有一點差點忘了,Anchor那里的Side一定要選擇TopLeft,地圖的原點是從左下角開始的。



2、制作材質(zhì)(material)

這是本篇的難點,要用到shader語言,如果沒有3d基礎(chǔ)的可能理解起來有點費勁,不懂也沒關(guān)系,按著操作也能做出來。

a、創(chuàng)建一個Shader,Assets->Create->Shader。

b、打開shader,把下面的代碼覆蓋過去。


[csharp] view plaincopy

  1. Shader "Transparent/Mask"  

  2. {  

  3.    Properties  

  4.    {  

  5.       _MainTex ("Base (RGB)", 2D) = "white" {}  

  6.       _Mask ("Culling Mask", 2D) = "white" {}  

  7.       _Cutoff ("Alpha cutoff", Range (0,1)) = 0.1  

  8.    }  

  9.    SubShader  

  10.    {  

  11.       Tags {"Queue"="Transparent"}  

  12.       Lighting Off  

  13.       ZWrite Off  

  14.       Blend Off  

  15.       AlphaTest GEqual [_Cutoff]  

  16.       Pass  

  17.       {           

  18.          SetTexture [_Mask] {combine texture}  

  19.          SetTexture [_MainTex] {combine texture, previous}  

  20.       }  

  21.    }  

  22. }  

你百度遮罩shader的話會有很多,但基本沒有解釋的,我這里解釋一下,第一行是設(shè)置你的shader的路徑和名稱,比如上面的shader就建在了Transparent下,起名Mask,大括號里面有兩個部分,第一個部分是屬性Properties,第二部分是SubShader。


Properties里是設(shè)置渲染的屬性,比如這里設(shè)置了兩張圖片和一個滑動條,第一張圖片用來加載背景圖片,就是我們之前做的那個Render Texture,用來顯示地圖,第二張圖片就是遮罩圖片,用我們之前的那個白圓,滑動條范圍從0到1,初始值0.1,再看一下語法。


[csharp] view plaincopy

  1. _MainTex ("Base (RGB)", 2D) = "white" {}  


_MainTex是屬性名,會在SubShader中用到,Base (RGB)是在界面上顯示的名稱,你會在屬性面板上看到,2D是圖片維數(shù),white是默認值。
SubShader是處理渲染的主體,Tags是標簽,Queue標簽決定被渲染的次序,而Transparent是四個預定義的渲染隊列之一,任何有關(guān)alpha混合的對象都應(yīng)該在這里處理,看這里可以了解的更多:SubShader Tags,關(guān)閉光照,關(guān)閉z緩沖器的寫操作,關(guān)閉混合,Alpha測試是當Alpha大于等于你之前設(shè)定的_Cutoff時有效,也就是說這里當alpha大于等于0.1的圖素會被渲染出來,其他的就透明了。Pass通道里處理混合,先設(shè)置第一張圖片:SetTexture [_Mask] {combine texture},這里是遮罩圖片,然后第二張圖片和前一張混合:SetTexture [_MainTex] {combine texture, previous},而我們之前關(guān)閉了混合,所以第二張圖片只是純粹的顯示,但大括號里第二個參數(shù)表示alpha,這里previous表示我們用之前那張圖片的alpha,而第一張圖片的alpha除了白圓部分,其余部分都是0,所以這張圖片除了與白圓 重合的地方,其他地方alpha也是0,這樣就透明了,只剩下了圓的地方,想了解Pass看這里:著色器語法:Pass,想了解SetTexture看這里:著色器語法:Texturing。


寫了這么多,純粹手打,覺得好的麻煩支持一下,哈哈。Shader有一定難度,但據(jù)說會shader的程序員薪水都在2萬以上啊,望眼欲穿啊,所以大家努力學吧。

如果上面的沒看懂,你又不想學,那就跳過吧,反正把代碼粘過去就可以了。

c、創(chuàng)建一個material,Assets->Create->Material,然后Shader那里找到你建的那個shader,在Transparent下面。

d、這時界面上會出現(xiàn)Base(RGB)和Culling Mask,Base(RGB)里把你之前那個Render Texture拖上去,Culling Mask把那個白圓的圖片拖上去,如下圖:


這樣你的材質(zhì)就做完了。堅持到這步的為自己鼓個掌吧,你離成功不遠了。


3、在界面的右上角用NGUI建地圖

終于到了最后一步了,剩下的工作就簡單多了,回到你的界面布局那里,有關(guān)NGUI界面布局不了解的看我前面的文章,在右上角的Anchor下建個Panel,起名MiniMapPanel,然后下面加兩個sprite和一個Texture,一個sprite是圓框,一個sprite是小箭頭,表示地圖上的玩家,Texture用來接收之前的材質(zhì)顯示地圖,如下圖:



Texture那里大小調(diào)成512*512的,Material那里把之前做的材質(zhì)拖上去就ok了,如果顯示順序有問題別忘了調(diào)Depth或Z值。

現(xiàn)在你應(yīng)該可以看到東西了,但小箭頭位置不對,當然,還沒上代碼呢。

創(chuàng)建一個MiniMap的腳本,我把全部代碼貼上來。


[csharp] view plaincopy

  1. public class MiniMap : MonoBehaviour {  

  2.   

  3.     // Use this for initialization  

  4.     public GameObject point;  

  5.     public GameObject map;  

  6.     private GameObject hero;  

  7.     private float miniMapScaleRatio;  

  8.       

  9.     void Start () {  

  10.         map.transform.localScale = new Vector3(Screen.height, Screen.height, 1);  

  11.         hero = GameObject.Find("/Blade_Girl_Prefab");  

  12.         GameObject terrain = GameObject.Find("Terrain");  

  13.         Terrain script = terrain.GetComponent<Terrain>();  

  14.         miniMapScaleRatio = (float)map.transform.localScale.x / script.terrainData.size.x;  

  15.     }  

  16.       

  17.     // Update is called once per frame  

  18.     void Update () {  

  19.           

  20.         if (hero && point && map) {  

  21.             point.transform.rotation = Quaternion.Euler(0, 0, -hero.transform.rotation.eulerAngles.y);  

  22.             map.transform.localPosition = new Vector3()  

  23.             {  

  24.                 x = -hero.transform.position.x * miniMapScaleRatio,  

  25.                 y = -hero.transform.position.z * miniMapScaleRatio,  

  26.                 z = 0,  

  27.             };  

  28.         }  

  29.     }  

  30. }  

代碼不多吧,point是玩家標志小箭頭,map是地圖面板,就是1里面那個MiniMapRenderPanel,public屬性的,自己拖上去吧。hero是我們的主角,miniMapScaleRatio是地圖和真實地形尺寸比例,start里的第一句是在干嗎呢,雖然我們的地圖是512*512的,但經(jīng)過實測,發(fā)現(xiàn)這個尺寸會隨著屏幕的高度而有誤差,需要設(shè)置成屏幕的高度這種尺寸,好吧,我也需要有人幫我解釋下,Update里時刻獲得主角的轉(zhuǎn)向,主角在世界中是繞y軸旋轉(zhuǎn)的,小標志是繞z軸旋轉(zhuǎn)的,并且方向相反,這里要注意一下。然后按照角色在地形上的位置乘以地圖與地形的比例獲得小標志在地圖上的位置,噢啦,大功告成,打完收工。


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    日韩欧美国产亚洲一区| 亚洲欧美日本成人在线| 老司机精品国产在线视频| 高清不卡视频在线观看| 在线观看中文字幕91| 成人精品国产亚洲av久久| 国产传媒高清视频在线| 我的性感妹妹在线观看| 不卡在线播放一区二区三区| 国产日本欧美特黄在线观看| 国产传媒欧美日韩成人精品| 国产又粗又猛又大爽又黄| 久久99国产精品果冻传媒| 亚洲一级在线免费观看| 欧美一区二区三区五月婷婷| 国产亚洲不卡一区二区| 日韩精品一区二区不卡| 国产日韩欧美专区一区| 日韩人妻有码一区二区| 欧美成人免费一级特黄| 欧美午夜国产在线观看| 中文字字幕在线中文乱码二区| 国产精品99一区二区三区| 丰满少妇被猛烈插入在线观看| 色一情一乱一区二区三区码| 日韩欧美一区二区久久婷婷| 日韩欧美国产三级在线观看| 黄色片一区二区在线观看| 99久久精品国产日本| 这里只有九九热精品视频| 欧洲精品一区二区三区四区| 欧美极品欧美精品欧美| 亚洲妇女作爱一区二区三区| 扒开腿狂躁女人爽出白浆av| 欧美日不卡无在线一区| 五月激情综合在线视频| 免费国产成人性生活生活片| 98精品永久免费视频| 久久亚洲午夜精品毛片| 日韩欧美一区二区不卡视频| 日韩欧美综合中文字幕|