[Unity3D]Unity3D再敘NGUI之血條及技能冷卻效果,unity3dngui
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
喜歡我的部落格請記住我的名字:秦元培,我的部落格地址是blog.csdn.net/qinyuanpei。
轉載請註明出處,本文作者:秦元培, 本文出處:http://blog.csdn.net/qinyuanpei/article/details/40744781
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
各位朋友,大家好,我是秦元培,歡迎大家關注我的部落格,我的部落格地址是blog.csdn.net/qinyuanpei。在11月份結束了全部的課程後,就意味著博主要開始找工作了,因為博主是非電腦專業出身,所以首先要完成本專業的實習,因此博主這段時間都在忙著尋找實習單位。在尋找實習單位的過程中,或多或少的接觸了些從傳統行業轉型到互連網行業的企業,博主在感慨互連網行業深刻地影響到各行各業的同時對這個行業的本質進行了思考。互連網行業是一種具有技術屬性、媒體屬性和社會屬性的服務行業,它通過為人們提供各種各樣的服務來串連人和人、人和資訊、資訊和資訊。互連網行業現在越來越不像是一個行業,相反它越來越像是一個社會,成功的互連網商業模式最終會在某一個環節實現與真實世界的接軌,因此互連網行業並不是以技術取勝,而是在於它找到了一種更好的方式來將虛擬世界和真實世界連結起來。可能因為長期研究技術形成的固定思維模式吧,博主此前一直認為技術才是互連網行業的核心,所以曾經在讀李彥宏的《矽谷商戰》這本書時,對於李彥宏在這本書中提出的"技術本身不是唯一的決定性策略,商戰策略才是決勝千裡的關鍵"這個觀點並不是很認同,而此時此刻博主卻深刻地認識到這一點,有信仰、有情懷、有技術固然可以讓你將一件事情做好,可是如果想要將一件事情做成則需要考慮各種各樣的因素。因為互連網行業面對的終端使用者是人,只要是人,那麼在傳統行業裡出現的問題都會遇到,即使你再喜歡宅在家裡、即使你再不喜歡和人打交道,該面對的問題總是要去面對的。好了,這個問題我們先說到這裡吧,我們今天的內容是使用NGUI來實現血條和技能冷卻效果。首先我們來看看今天要實現的效果:
從這個示範中我們可以找到今天要實現的具體內容是遊戲介面中的GUI血條和怪物頭頂上的血條以及技能冷卻效果的實現,我們這裡將其分成血條和技能冷卻兩部分來為大家講解,希望能對大家學習NGUI有所協助,如果有不足之處,希望大家能夠諒解啊。
一、血條
在前面的文章中博主曾經和大家分享過在Unity3D中使用NGUI的相關內容,那麼今天我們就來繼續學習如何利用NGUI在Unity3D中實現血條吧!在Unity3D中要實現一個血條是十分簡單的。在博主之前的文章《Unity3D遊戲開發之2D貼圖實現血條組件》中博主介紹了並且實現了基於2D貼圖的血條組件,這種方法的原理是前後疊加顯示兩張不同的貼圖前景貼圖和背景貼圖,通過改變前景貼圖的寬度就可以實現血條的效果了。在NGUI中,Slider就是這樣的一種控制項,因此我們可以使用Slider實現血條效果。首先我們在情境中建立一個Slider控制項,
這樣我們就可以利用NGUI做出一個漂亮的血條效果了。接下來,我們重複這樣的工作3次,最終可以設計出這樣的效果出來:
整個UI介面是由一個背景圖片(Sprite)和三個Slider組成,這樣我們就實現了遊戲中的介面搭建。Slider控制項有一個最為重要的屬性值叫做SliderValue,它是一個介於0到1之間的數值,表示Slider中滑塊滑過的長度與總長度的百分比,我們這裡正是使用這個屬性值來顯示血條中的血量。比如我們將玩家的總血量為100,則玩家血量的百分比就是玩家的當前血量與總血量的比值,我們只要將這個值賦給Slide控制項的SliderValue就可以了。比如,我們可以用下面的代碼來表示玩家受傷掉血:
this.HPValue=this.HPValue-10;HPTrans.GetComponent<UISlider>().sliderValue=(float)this.HPValue/100;
這裡HPValue顧名思義就是怪物的當前血量,HPTrans是血條(Slider)所在的Transform。在實際的設計中,怪物的總血量會根據怪物等級的不同而不同,因此我們最好將總血量儲存到封存檔案或者資料庫中,這樣我們就可以讓血條根據玩家的血量的不同而變化了。大家可以注意到在前面的示範中,玩家受到怪物攻擊時血量會減少。既然提到了血量的減少,那麼我們就順便說一下在某些遊戲中設計的自動回血、自動回藍。比如在《古劍奇譚2》遊戲中,由於戰鬥模式被改成了即時制,所以玩家在遊戲中的"氣"不再依賴於通過在戰鬥中攻擊敵人來獲得,而是當玩家處於Idle狀態時慢慢恢複。既然玩家受到掉血是將血量減少,那麼自動回復自然是將血量增加了,這一點我們不再說了。
下面我們來說說遊戲中怪物頭頂的血條是如何?的吧?和GUI中的血條不同的是怪物頭頂的血條會跟隨著玩家的移動而移動。這裡我們首先要引入兩個概念,即布告板(BillBoard)和HUD(抬頭顯示裝置)。
布告板簡單的來講就是情境中的一個四邊形或者平面,它始終與相機的視線方向對其。布告板技術可以用來做什麼呢?從遊戲中的GUI到遊戲中提示訊息、情境中樹木渲染等等,都會用到布告板技術。比如我們在玩經典的CS遊戲時,當玩家按下E鍵時可以進行炸彈的拆除,此時遊戲介面中會提示玩家相關操作,這就是布告板技術的一個應用情境。此外,在早期的3D遊戲中,情境中的樹木通常都是以平面的形式(紙片)來實現的,這樣可以有效地減少遊戲中渲染的數目,不過這樣會降低遊戲的表現力,這在博主玩過的《仙劍奇俠傳三》等遊戲中使較為常見的。
而抬頭顯示裝置則是一個從軍事領域引申過來的遊戲術語,它可以把遊戲相關的資訊以直觀的方式顯示在遊戲畫面上,同時不會影響玩家的正常視野內容,以便玩家可以隨時瞭解那些最重要最直接相關的內容。抬頭顯示裝置常見的應用情境有:RPG遊戲裡的生命、魔法、狀態、行動力等,ACT遊戲中的戰鬥統計、得分、精彩鏡頭、連擊等。這裡之所以要提到這兩個概念主要是因為它們的技術實現具有相似性,基本上都會涉及2D座標和3D座標的轉化等。這裡怪物頭頂的血條需要將Unity3D中的3D座標轉化為2D座標,然後再將2D座標轉換成NGUI下使用的3D座標。具體大家可以參考宣雨松的文章NGUI研究院之3D模型座標轉2D螢幕座標-血條。那麼,我們這裡怎麼實現呢?我們這裡可以先利用NGUI製作一個血條的預製件,然後將其掛到怪物頭頂的某個位置,然後保證怪物頭頂的血條始終面向主攝像機即可。這在Unity3D中是相當的簡單:
HPTrans.LookAt(Camera.main.transform.position);
這樣做出來的怪物血條會根據與攝像機距離的遠近而顯示不同的比例大小,博主覺得效果還是蠻不錯的啊,呵呵。好吧,萌妹子再次被一群小怪給圍攻了,我好殘忍啊.......
二、技能冷卻
技能冷卻是在即時制遊戲尤其是魔獸世界類遊戲興起以後出現的概念。所謂技能冷卻是指從上一次使用完技能到本次技能使用開始的這段時間,即技能cd。我們舉一個直觀的例子就是在遊戲介面中如果一個技能的表徵圖被完全點亮,則表示該技能冷卻結束,否則表示該技能正處於冷卻狀態,而只有技能冷卻結束後我們才能再次使用該技能。我們以《古劍奇譚2》為例來講解技能冷卻,是該遊戲實際的戰鬥畫面
《古劍奇譚2》從遊戲的製作理念上首次突破了國產單機遊戲回合制的格局,不能不說是國產單機遊戲製作史上的一次重大突破。大家可以注意到畫面下方的技能欄,在這個技能欄中的技能此時都是處於冷卻狀態的,所以玩家此時是無法使用這些技能的,只有等技能冷卻結束後才能使用。提及《古劍奇譚2》的戰鬥,博主還是忍不住要吐槽下,首先技能過於拖遝,玩家不得不停下來等待遊戲中的主角將一套動作打完,而且更加讓人無語的是玩家無法通過打斷技能來中止技能,所以在玩這個遊戲的時候博主大部分時間都處在一種亂按的狀態(偷笑),不過聽著武器和敵人攪在一起劈裡啪啦的聲音博主覺得玩勁舞團同樣是種不錯的選擇啊,哈哈。好了,不開玩笑了。下面我們就以在Unity3D中實現技能冷卻效果為例來深入地探索技能冷卻,首先我們先來瞭解下原理,技能冷卻效果的實現需要兩個NGUI控制項來實現,即Sprite和FilledSprite兩個控制項。其中Sprite控制項負責顯示技能圖片,FilledSprite控制項負責顯示技能遮罩。技能遮罩我們只需要選擇一個灰色或者黑色的圖片然後設定一定的透明度即可。FilledSprite控制項可以讓圖片按照一定的方式來填充,這有什麼好處呢?比如在很多遊戲中,技能的冷卻效果可以是從技能圖片的底部向上填充或者是按照一定的速度進行順時針/逆時針方向的填充。那麼,對於這種需求我們就可以使用FilledSprite來實現。下面來看具體的做法:
接下來我們用一個空的遊戲體將技能表徵圖和遮罩包裹起來,這裡我們做了三個技能表徵圖,並將遮罩層圖片的透明度設為150。好了,下面我們來關注下FilledSprite這個控制項,我們注意到它有一個重要的參數Fill Dir即填充方向,在這裡我們可以改變這個值實現不同的填充效果,我們這裡就選擇順時針
360度填充。此外,這裡有一個FillAmount的參數表示的是填充的比例,這是一個介於0到1之間的值,該值取1時表示完全填充,即整個遮罩層是顯示出來的,此時表示技能正在冷卻;該值取0時表示不填充,即整個遮罩層都是透明的,此時技能冷卻結束。根據這樣的原理,我們很容易實現下面的指令碼:
//如果沒有處於冷卻狀態則進入冷卻if(!isSkillCooling){ui_skillMask.fillAmount=1;isSkillCooling=true;}//如果處於冷卻則開始計時if(isSkillCooling){ui_skillMask.fillAmount-=(1.0F/SkillCoolTime)*Time.deltaTime;if(ui_skillMask.fillAmount<=0.01F){ui_skillMask.fillAmount=0;isSkillCooling=false;}}我們來看看實際的效果:
我們可以注意到技能冷卻效果基本出來了,可是我們需要不是技能欄一遍遍地重新整理啊,我們希望的是當技能冷卻結束後,當玩家按下某些鍵位或者點擊技能表徵圖時實現相應的技能,當玩家釋放技能技術後,技能欄重新開始冷卻,基於這樣的想法,在第一個指令碼的基礎上我們有了改進後的代碼:
using UnityEngine;using System.Collections;public class cdSkill : MonoBehaviour {//技能冷卻時間為2.0spublic float SkillCoolTime=2.0F;//玩家釋放技能的時間private float mSkillUseTime=0;//技能長度為1.5spublic float SkillLength=1.5F;//技能冷卻遮罩private GameObject go_skillMask;private UIFilledSprite ui_skillMask;//是否處於冷卻狀態private bool isSkillCooling=false;void Awake(){//擷取技能冷卻遮罩層go_skillMask=transform.FindChild("SkillMask").gameObject;//擷取UIFilledSpriteui_skillMask=go_skillMask.GetComponent<UIFilledSprite>();//綁定一個Click事件UIEventListener.Get(transform.gameObject).onClick=SkillEvent;}void Update () {SkillCooling();}void SkillCooling(){//如果沒有處於冷卻狀態則進入冷卻if(!isSkillCooling){ui_skillMask.fillAmount=1;isSkillCooling=true;}//如果處於冷卻則開始計時if(isSkillCooling){ui_skillMask.fillAmount-=(1.0F/SkillCoolTime)*Time.deltaTime;if(ui_skillMask.fillAmount<=0.01F){ui_skillMask.fillAmount=0;isSkillCooling=false;}}if(mSkillUseTime<SkillCoolTime){mSkillUseTime+=Time.deltaTime;}else{mSkillUseTime=SkillCoolTime;}}void SkillEvent(GameObject go){ if(mSkillUseTime==SkillCoolTime){ Debug.Log("在這裡加入具體的技能效果"); mSkillUseTime=0; isSkillCooling=false; }}}好了,這樣我們就實現了今天文章中的兩個內容:血條和技能冷卻。希望大家喜歡啊,這段時間博主寫代碼的時間真心不多啊,因為快畢業了......最後大家來一起欣賞下博主做的這個小遊戲吧!特效情境神馬的,請直接無視!........
每日箴言:人最大的對手,往往不是別人,而是自己的懶惰。你必須拼盡全力,才有資格說自己運氣不好。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
喜歡我的部落格請記住我的名字:秦元培,我的部落格地址是blog.csdn.net/qinyuanpei。
轉載請註明出處,本文作者:秦元培, 本文出處:http://blog.csdn.net/qinyuanpei/article/details/40744781
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
11月4日更新:
由於博主的疏忽,代碼中有一個地方寫錯了,在技能冷卻這部分的第二段代碼中,請將第50行代碼注釋掉,抱歉啊
問Unity3d,怎用代碼控制NGUI控制項,如Button、Lable、SlicedSprite等
很簡單的啊
public UILabel text;
聲明,然後指令碼給一個物體,直接把label拖上去,然後引用的 時候直接使用text.text = "中文";
這是label。
至於button你想問的是按鈕的事件嗎?
添加指令碼buttonmessage,然後把寫有事件的指令碼拖給target,下面的function name填你的方法名
誰有Unity3d 利用Ngui控制項實現的登入驗證源碼 指令碼中應該怎獲得Ngui的input控制項的值?詳細點
你關聯Input的label,然後得到label的text就行了,就是你的輸入