0凳寺、牢騷
最近一周左右的時間在做新手引導(dǎo)的開發(fā)柴信,這是第二次負(fù)責(zé)引導(dǎo)了套啤,我的內(nèi)心是崩潰的……上個項目的引導(dǎo)開發(fā)+維護都在自己手里,又要寫代碼随常,又要配文件苦不堪言啊潜沦。而且框架設(shè)計上總覺得欠缺些東西,想看看其他人的做法學(xué)習(xí)一番绪氛,結(jié)果這邊開始負(fù)責(zé)的人要離職OMG……前人留下了一個開發(fā)方案唆鸡,看了看沒法用,只好自己再來了枣察。
這次從策劃那里了解的他們之前項目引導(dǎo)開發(fā)的大概方式争占,得到了一些還不錯的思路,然而被主策拒絕了序目,最終設(shè)計出來的和之前我那一版差不多……希望后面能再有好的思路吧臂痕。
最近打算把開發(fā)過程中的一些東西記錄下來,前幾篇先寫幾個小工具猿涨,后面看情況說下前人方案中不可行的東西和框架的設(shè)計握童,希望能得到大佬的指點。
1叛赚、寫在前面
這次的開發(fā)環(huán)境是Unity5.4.1+UGUI澡绩,下面的工具在不同Unity版本中實現(xiàn)方式可能有一定的區(qū)別稽揭,請注意版本差別。
2肥卡、介紹
這篇要寫的是用UGUI實現(xiàn)一個事件轉(zhuǎn)發(fā)組件(EventForward):將一個Button上接收到的Click事件溪掀,轉(zhuǎn)發(fā)到另一個Button上。這里的組件不僅限于Button召调,只要是能接受UGUI的操作的組件都可以膨桥÷耄可轉(zhuǎn)發(fā)的事件也可以是任意的唠叛,不過我只實現(xiàn)了Click。
這個組件的思路來源是NGUI的UIForwardEvents組件沮稚,之前做引導(dǎo)的時候艺沼,就是用的這個組件。雖然在我當(dāng)時的版本里蕴掏,已經(jīng)是一個Obsolete組件了障般,但它讓事件處理變得非常簡潔,去掉實在可惜盛杰。
下面介紹下事件轉(zhuǎn)發(fā)的用處挽荡。
需求:引導(dǎo)過程中,需要用一個半透的遮罩把不能操作的內(nèi)容擋住即供,能操作的對象要高亮顯示出來定拟。
方案:給引導(dǎo)UI(TutorialCanvas)設(shè)置一個較高的SortLayer,里面用一個全屏的Image作為遮罩逗嫡。把要引導(dǎo)的對象青自,復(fù)制一份放到TutorialCanvas中,這樣對象上應(yīng)有的UI表現(xiàn)都可以保留下來(比如按鈕按上去的縮放效果)驱证,而且只有復(fù)制體能響應(yīng)玩家操作延窜。
我們項目主要邏輯都在Lua中,所有的UI事件都是用代碼綁定上去的抹锄,因此復(fù)制出來的對象只是徒有其表逆瑞,沒法完成玩家的操作。為了給復(fù)制體加上靈魂伙单,就需要EventForward了~把復(fù)制體接收到的事件获高,轉(zhuǎn)發(fā)給原對象,不需要侵入現(xiàn)有邏輯就能完成引導(dǎo)车份。
3谋减、EventForward代碼
/// <summary>
/// UGUI事件轉(zhuǎn)發(fā)
/// </summary>
public class EventForward : MonoBehaviour, IPointerClickHandler
{
/// <summary>
/// 接收轉(zhuǎn)發(fā)事件的對象
/// </summary>
public GameObject Target;
/// <summary>
/// 任意事件執(zhí)行成功后執(zhí)行的回調(diào)
/// </summary>
public Action SuccessAction;
private void _DoSuccess()
{
if (null != SuccessAction)
{
SuccessAction();
}
}
public void OnPointerClick(PointerEventData eventData)
{
if(null == Target) return;
// Target上有能處理當(dāng)前事件的函數(shù)才會返回true
if (ExecuteEvents.Execute(Target, eventData, ExecuteEvents.pointerClickHandler))
{
_DoSuccess();
}
}
}
這里我實現(xiàn)了接口IPointerClickHandler來響應(yīng)Click事件,UGUI所有事件都有一個對應(yīng)的接口扫沼,這些在SupportedEvents里有介紹出爹,需要其它事件的朋友可以根據(jù)Manual自行拓展庄吼。
---
寫文章的過程中忽然想到,之前NGUI做事件轉(zhuǎn)發(fā)的方式在UGUI中應(yīng)該也能用……之前的做法不需要多復(fù)制一個對象出來严就,也算一種低耦合的表現(xiàn)吧总寻。我大概寫下之前NGUI的做法,有時間再確認(rèn)可行性梢为。
在引導(dǎo)UI中創(chuàng)建一個接收事件的BoxCollider(EventForwardColli)渐行,引導(dǎo)的時候,將EventForwardColli的位置铸董、大小調(diào)整到和引導(dǎo)目標(biāo)上的一樣祟印,然后通過UIForwardEvents將EventForwardColli上接收到的一部分事件轉(zhuǎn)發(fā)給引導(dǎo)目標(biāo)。
需要轉(zhuǎn)發(fā)的事件是可配置的粟害,因為有些地方只需要點擊蕴忆,有些地方只需要長按,有些地方需要點擊+長按悲幅。點擊+長按通常用來保留引導(dǎo)目標(biāo)上的縮放效果套鹅。
這種方式避免了復(fù)制、銷毀GameObject帶來的性能開銷汰具,在表現(xiàn)上也更加保險卓鹿。我現(xiàn)在項目的縮放效果是,先放大后復(fù)原留荔,這樣復(fù)制體能完全擋住原始對象吟孙。如果是先縮小再復(fù)原呢,那就穿幫了Orz……玩家在復(fù)制體縮小的時候存谎,能看到后面還有一個一模一樣按鈕在拔疚。
事件轉(zhuǎn)發(fā)就到這了,睡覺既荚!*