[Unity]【筆記】Loading讀取畫面,百分比緩動

momo的文章

其實momo寫的就非常清楚了

基本上大家都會異步加載的方式來實現loading畫面
畢竟遊戲大了,只用loadlevel會lag 卡卡的

要了解異步,要先了解AsyncOperation類別

有四個Variables

目前要用到的只有兩個

allowSceneActivation和progress

progress的取值在0.1~1之間,不會等於1
為了計算百分比,以下會x100來計算

一般來說,我們都是 A場景到C場景,中間會有個B場景當LOADING畫面

而通常我們載入一些資源較少的場景,loading會很快,這樣你可能連影都沒看到就跳到下個場景了

所以allowSceneActivation 就是用來加載完成後,什麼時候你才要讓他跑下個場景
設為false的話就是永遠不跳到下個場景,直到true才會

======================


async.allowSceneActivation = false;
       
        while (async.progress < 0.9f)
        {
            toProgress = (int)async.progress * 100;
            while (displayProgress < toProgress)
            {
                ++displayProgress;
                SetLoadingSlider(displayProgress);
                yield return new WaitForEndOfFrame();
            }
            yield return new WaitForEndOfFrame();
        }
        toProgress = 100;
        while (displayProgress < toProgress)
        {
            ++displayProgress;
            SetLoadingSlider(displayProgress);
            yield return new WaitForEndOfFrame();
        }


基本上跟momo那篇一樣,不過IEnumerator loadScene()內在加入上面代碼
async.allowSceneActivation = false; 就是加載完之後不允許直接跳下個畫面

async.progress

讀取進度通常會小於0.9的時候就跳畫面了,因此用兩個while迴圈
一個是在0.9前,一個是在0.9後,也就是讀取完場景前跟讀取完場景後

1.第一個while迴圈,還沒讀取完
當displayProgress小於當前讀取進度的百分比
就++,然後利用 SetLoadingSlider ,返回畫面的進度條讓他緩動 (( 就是1~90,每次跳躍都可以看到1.2.3.4這樣跳,才不會一開始10% 數字立馬跳到90%

2.第二個while迴圈,讀取完後

因為async.progress不會等於1,也就是 toProgress 不會讀取到100% ((詳細讀第一個迴圈

手動的把toProgress設為100 後進入第二個迴圈
接著跟上面一樣,就完成啦~


完整代碼  :
(感謝 [鴿子獸] 葷教授 的修正 )

using UnityEngine;
using System.Collections;
using UnityEngine.UI;


public class Loading : MonoBehaviour
{



    AsyncOperation async;
    int Progress
    {
        get { return _progress; }
        set {
            _progress = value;
            if(_progress>=100) { async.allowSceneActivation = true; }
        }
    }
    int _progress = 0;
    public Slider LoadingSlider;


    void Start()
    {
        StartCoroutine(loadScene());
    }

    IEnumerator loadScene()
    {
        int Progress = 0;
        int toProgress = 0;
        async = Application.LoadLevelAsync(Globe.loadName);
        async.allowSceneActivation = false;

        while (async.progress < 0.9f)
        {
            toProgress = (int)async.progress * 100;
            while (Progress < toProgress)
            {
                ++Progress;
                SetLoadingSlider(Progress);
                yield return new WaitForEndOfFrame();
            }
            yield return new WaitForEndOfFrame();
        }
        toProgress = 100;
        while (Progress < toProgress)
        {
            ++Progress;
            SetLoadingSlider(Progress);
            yield return new WaitForEndOfFrame();
        }

    }

    void SetLoadingSlider(int p_progress)
    {
        float tmp = (float)((float)p_progress / 100);
        LoadingSlider.value = tmp;
    }
}
Share:
Read More

[Unity]【筆記】創建自己的有限狀態機



________________________________________________________


有限狀態機,大概大家都聽過吧,沒聽過的

這裡請

不過基本上都是用到的時候學啦,以前有看了幾天,發現我的智力不足,先放棄

但最近專題要開始使用,所以...火坑我來了

看完中文,建議研究一下英文的,下面有實作

這裡

本篇是根據英文的實作改了一下做出來的筆記,說是筆記,因為是雛形,然後又不知道哪邊觀念可能錯誤,請多多指教一下XD

_________________________________________________________

研究了這麼久,我認為實作有限狀態機,最重要的概念是

繼承,抽象

整個看起來是這樣,完成之後才要在創建個AIController去使用它





首先先創建個基類BaseState,此類別為抽象類別

繼承他的實作他的DoSomething(Gameobject npc)方法,這個抽象方法
很重要,因為所有繼承他的類別都有這個方法,至於為何,等到用到會再說明


接下來,開始創建使用它的機器,((先不用創建它有哪些狀態))

這個類也是不用繼承MonoBehavior,因為真正要用狀態機的不是這個類

首先,狀態"機",的機,肯定是集合很多狀態而成的,因此宣告一個List把所有狀態都

裝在一起,再宣告當前狀態 currentstate ,在建構子上為這個list創建空間,狀態機可能

會有,新增、查詢、刪除...等 ,因為只是筆記最簡單的怎麼用,因此用一個普通的新增

方法就好。



好,接下來可以想一下你要什麼狀態了,這裡先用A狀態跟B狀態來表示,創建每個狀態

然後繼承於BaseState類




B狀態也跟這上面一樣,我就不貼囉,然後選好狀態之後,差不多就完成了

接下來要創建個控制器,也就是最終你會貼到Unity的編輯室窗上的component,也可以說成AI


首先,在這個AI裡面,要先創建個狀態機,也就是剛剛集合所有State的 FSMMachine

接著把所有會用到的State宣告一下







接著宣告完之後,在Start方法中把它(狀態) 加入到創建的fsm中













fsm中,加入了a、b狀態,currentstate是目前狀態,因為一開始沒指定,所以在start方法也順變指定為a

接著再Update中,呼叫doSomthing方法,傳入gameobject







注意這邊 fsm.currentstate ,上面再Start方法中指定為a,因此目前做的是a的dosomthing方法

如果把fsm.currentstate = b的話,就會執行b的dosomthing方法,這裡就是精華所在了

換另外一個狀態,上一個狀態就不會再繼續執行,就像switch case做的狀態機一樣

而目前的Controller中,沒辦法轉換狀態,因此加入一個ToState方法






傳入一State,然後改變fsm的currentstate(當前狀態)

完整如下



























這個類就完成了,接著去每個狀態中實現他們的方法













如果按下滑鼠左鍵,則轉換到狀態b,因該不用多解釋了吧XD

接著把Controller掛到隨便一個物體上,運行就會像這樣








另外,Unity還有使用interface實現FSM的方法,個人比較喜歡那個,比較簡潔。



參考資料 : http://wiki.unity3d.com/index.php/Finite_State_Machine















Share:
Read More

[Unity] 使用PHP,更新MySql內Json資料

最近學了一下unity跟mysql結合,發現挺有用的

配合上json更好儲存數據

原本是把所有欄位轉成json數據傳送,但如果一堆要存的數據的話

使用的欄位,未免過多,因此找了找些資料,發現可以用TEXT欄位寫所有json數據

再傳到unity解析、更新,這樣就不必花費太多欄位了

unity跟mysql的關係,大概的關係是這樣

中間兩個是php腳本


一、創建資料庫
PS.用的是xampp


資料庫名稱為unitydatabase 
資料表名稱為UserData
兩個欄位 id , data
然後先新增一欄資料,id為1
data 裡面要打什麼都可以

二、創建php

其中UnityDatabase是你的數據庫名稱,root是你的帳戶名、root後面的是密碼
我是沒設,所以中間留白
第四行是連接數據庫
第六行sql語句select * form (你的資料表)

最後json_encode();是把剛剛選的資料表內的資料轉換成json格示輸出到網頁上
儲存好後 網頁網址就會是
http://127.0.0.1/DownloadDB.php //等等unity內會用到,要記好路徑



unitydata是自訂義的變數,後面那句 $_POST是跟unity連接的點
$_POST["xxxxx"]  xxxxx 是Unity內,表單要傳送的變數名,要記住
其他基本上都一樣,最後一句是更新目前資料庫內data欄位的數據,是用id=1去尋找的



三、創建unity腳本

 定義兩個path,用來更新資料庫和下載資料庫

再來創建兩個按鈕,個別執行兩個函數,下載和上傳
 定義想要儲存的資料


JsonSave方法是用來把所有儲存的資料轉換成json格式,日後用來上傳到資料庫

















定義之前兩個按鈕的方法



















downloadjson方法:
使用內建的WWW方法,開啟之前宣告好的path
拿到後,使用JsonMapper方法,將網頁內的json數據拿下來
由於拿下來的數據會包含所有欄位的資料,因此下面的
string jsc = json["Data"].ToString(); 是限定只獲取Data欄位內的資料
為了改變數據,再次將jsc轉換,然後將想要改的資料騰上去
這樣unity內的數據就轉換完成啦

updatajson方法:
宣告個WWWForm,第二行unitydata就是一開始updateDB.php那個post括弧內的String兩個一定要一樣,後面就是要傳入的資料,JsonSave上面有提及,就是所有資料打包成string
OK後,用WWW將form傳入,然後undateDB.php就會更新mysql的資料庫了

四、完成

DownloadDB看起來會是這樣






資料庫內長的像這樣










在unity面板內可以更新,但第一次使用由於Data裡面會是空的
所以下載下來的沒辦法使用,要先update一次才行。


Script內容是這樣




Share:
Read More