作者littleshan (我要加入劍道社!)
看板GameDesign
標題Re: [請益] unity 按鈕跟時間的問題
時間Wed Sep 4 13:12:32 2013
※ 引述《flyfeather92 (老娘)》之銘言:
: 小妹不才 目前是unity新手
: 我想寫一個在特定秒數會跳出button的裝置
: var mySkin : GUISkin;
: var myWeapon : GameObject;
: var WeaponClosed : boolean = false;
: var btnTexture : Texture;
: function OnGUI()
: {
: print (Time.time);
: // Waits 6 seconds
: yield WaitForSeconds (6);
: GUI.skin = mySkin;
: if(GUI.Button(Rect(400, 40, 160, 30),"O"))
: {
: }
: else if(GUI.Button(Rect(400, 80, 160, 30), "X"))
: {
: }
: }
: 可是在GAME裡面連BUTTON都跳不出來
: 之後也想請問各位大大 如果我在if裡面要移動特定的物件該怎麼做?
OnGUI 是 Unity 處理 GUI event 時的 callback function
每個 frame 可能會呼叫它許多次
這意味著 OnGUI 必需在一個 frame 以內結束,否則整個程式會卡住
所以遇到超過一個 frame 的動作必需用另外的方法處理
比較無腦的方式是設一個時間變數
我比較熟 C# 所以下面是用 C# 當例子 (沒實際跑過,小錯誤請見諒)
class ButtonGroup : MonoBehaviour {
float myElapsed =
0.0f;
void Update()
{
myElapsed += Time.deltaTime;
}
void OnGUI()
{
if(myElapsed <
6.0f)
return;
if(GUI.Button(...)){
...
}
}
}
至於移動特定物件,用 coroutine 比較方便
IEnumerator MoveObject(GameObject obj, Vector3 dest,
float duration)
{
Vector3 delta = dest - obj.transform.position
float elapsed =
0.0f;
while(elapsed < duration){
elapsed = Math.Min(duration, elapsed+Time.deltaTime);
obj.position = dest - delta * (
1.0f - elapsed/duration);
yield return null;
}
}
void OnGUI()
{
if(my_elapsed <
6.0f)
return;
if(GUI.Button(...)){
// 在 3 秒內把 myWeapon 移動到 myDestination
StartCoroutine(MoveObject(myWeapon, myDestination,
3.0f))
}
}
但這樣寫有個問題
如果玩家重覆點擊同一個按鈕
就會造成兩個 coroutine 更改同物件的位置,結果通常不是你想要的
所以這邊還要加個 flag 來檢查物件是否已經在移動了
最後
其實 OnGUI 的設計根本就很難用
然後 Unity 的 coroutine 功能也很弱
當你的 UI 元件愈來愈多,整個 code 會變得非常雜亂
因此最好還是建立自己的 GUI 和 coroutine 系統
但這就沒辦法用一篇文章講完了
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.135.3.139
推 chenglap:每次我看到 onGUI 就在想 unity 團隊有多仇視 2D 09/04 13:32
推 changyin:推~StartCoroutine真的要避免出現在Update 或 onGUI上... 09/04 13:41