デジタルフロッグ

Unityのアプリの開発をしながらいろいろと忘れないための備忘録でございます。

AssetBundleをサーバーから取得

    IEnumerator Loadbundle()
    {
        string url = "http://hogehogehogehoge/hoge";
        var www = new WWW(url);
        yield return www;
        var assetBundle = www.assetBundle;
        var prefab= assetBundle.LoadAsset<GameObject>("Object");
        GameObject obj = (GameObject)Instantiate( prefab );
        obj.name = obj.name.Replace( "(Clone)", "" );
    }
    

とりあえずこんな感じでとりたいものはとれます。ただ、Materialを使用しているものをAssetBundleを落としてきて使おうとするとShaderの設定がたまらないことになってしまっている事があります。

なのでそういう時は自身でスクリプトから直してあげてください。

ちなみに自分はSpineを使いたかったのですが、最初ピンクの■集合体がうごうご動いている状態でしたので

        var material = assetBundle.LoadAsset<Material>("Material_Name");
        material.shader = Shader.Find( "Spine/Skeleton" );

これで解決しました。パーティクルを落としてきて使うときなどはまたそれはそれに合わせてShader.Findで変更してあげる必要がありそうです。

シーンを追加してアクティブを切り替える流れ。

    IEnumerator AddScene()
    {
        //シーンを非同期で追加する
        SceneManager.LoadScene( "Scene Name", LoadSceneMode.Additive);
        //シーン名を指定する
        Scene scene = SceneManager.GetSceneByName("Scene Name");
        while ( !scene.isLoaded )
        {
            yield return null;
        }
        //指定したシーン名をアクティブにする
        SceneManager.SetActiveScene( scene );
    }


コルーチンで実装をしたのですが、whileを入れないとシーンの読み込みが完了する前にアクティブを切り替えようとしてしまってうまくアクティブの切り替えが出来なかったのでコルーチンで処理をするようにしました。

次のシーンに移った時にデータを渡したい時や一時的に別のシーンを重ねて表示させたい時などに使えます。
もしも重ねるだけで重ねたシーンで何か変更を加えるという事がないのであればシーンのアクティブを切り替える必要性はないとは思います。

ちなみに…

SceneManager.UnloadScene( "Scene Name" )

これでシーンのアンロードが行えますので必要なければ削除してしまいましょう。

ボタンのイベントをスクリプトから登録、削除する方法

ボタンのイベントを削除する方法ですが、これは非永続的なイベントしか削除ができません。たしか

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

public class hogehoge: MonoBehaviour
{

    Button btn;

    void Awake()
    {
        btn = this.gameObject.GetComponent<Button>();
        //ボタンのイベントを追加する
        btn.onClick.AddListener( () => BtnAction() );
    }

    void BtnAction()
    {
        Debug.Log( "btnAction" );
        this.RemoveBtnAction();
    }


    void RemoveBtnAction()
    {
        //ボタンのイベントをすべて削除する
        btn.onClick.RemoveAllListeners();
    }

}

非永続的なイベントとはAddListenerで追加されたイベントのことを指していて、GameObjectのInspectorのButtonコンポーネントスクリプトをアタッチしてイベント登録されたイベントに関しては永続的なイベントとなるので、RemoveAllListenersを使っても削除することができません。

docs.unity3d.com

ローカルのAssetBundleを読み込んで表示させてみよう

karaagedigital.hatenablog.jp

前回書いたアセットバンドルを使ってみようでエクスポートするまでは作りました。

ローカルから読み込む場合には作成したアセットバンドルをStreamingAssetsというフォルダを作ってそこに突っ込んだ方が後々よさそうです。
公式にも書いているのでサッと読んでみてください。

docs.unity3d.com

今回前回作成したものではなく新しくプロジェクトを作成して作りました。

f:id:karaagedigital:20161119160121p:plain

GameViewに表示されているものをプレハブにしてImageFolderというものに突っ込みました。
これを200個同じものを作りすべてAssetBundle名をimageにしました。

アセットバンドルにすると何がどうかっていうとこの画像を見てもらうとわかると思います。

f:id:karaagedigital:20161119160608p:plain

一つ8KBもあるプレハブが200もあるので1.5MBぐらいになるのですが、アセットバンドルにしてしまうと18KBでおさまります。
Textureとかになるとここまで圧縮するのは厳しいですが…
中規模~の開発になるとどうしてもプロジェクトのサイズが大きくなってしまうので出来る限りアセットバンドルにしてしまった方がよさそうです。

作ったimageという名前のアセットバンドルをStreamingAssetsというフォルダを作ってそこに配置してください。

下記スクリプトを作って自分はHierarchyのCanvasにアタッチしました。

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

public class Getbundle : MonoBehaviour {

	// Use this for initialization
	void Start () {
        StartCoroutine(DownLoad()); 
	}

    IEnumerator DownLoad()
    {
        string bundleUrl = Application.streamingAssetsPath + "/image";
        AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(bundleUrl);
        while (!request.isDone)
        {
            yield return null;
        }
        AssetBundle assetBundle = request.assetBundle;
        AssetBundleRequest image = assetBundle.LoadAssetAsync<GameObject>("Image 99");
        GameObject obj = (GameObject)Instantiate( image.asset );
        obj.transform.SetParent(transform, false);
        obj.GetComponent<RectTransform>().anchoredPosition = new Vector2(2, 2);
    }
}

今回はImage 99という名前のプレハブを取り出しています。
名前を変えれば他のプレハブを取り出すことも可能です。

ちなみにこれプレハブ全部にアセットバンドル名を付けてますが、格納しているフォルダにアセットバンドル名を設定しておけばそのフォルダの中身がアセットバンドルになるみたいなのでアセットバンドルを作る際はつかいたいものをフォルダに突っ込んでフォルダの名前を設定してエクスポートって形でよさそうです。

アセットバンドルを使ってみよう AssetBundle

まったくこの辺使ってなかったので新しく覚える為にやった事をザザッとまとめていこうと思います。

 

バンドルとは?
ある製品に別の製品が付属して販売、あるいは配布すること。パソコンを「買ってすぐ使える」状態で販売するために、あらかじめOSやアプリケーションソフトをインストールしておくことなどを指す。

e-words.jp


アセットバンドルとは?

選択したアセットを 1つにまとめて Unity からエクスポートできるファイルです。これらのファイルは専用の圧縮フォーマットを使用してアプリケーションからオンデマンドでロードできます。これによりモデル、テクスチャ、オーディオクリップ、または使用されるシーンから切り離してシーン全体などのコンテンツをストリーミングすることができます。

docs.unity3d.com

 

アセットバンドルを作成してみよう

まず最初に適当にtestという名前の.pngファイルを突っ込んでSpriteにしuGUIのImageに当てはめてそのuGUIをプレハブ化しておきました。

 

f:id:karaagedigital:20161112180226p:plain

画像最初にtest.pngをクリックしてInspectorの下の方からAssetBundleとあるのでその右側のNoneをクリックしてNewを選択し、bundleの名前を入力します。

f:id:karaagedigital:20161112180429p:plain

今回はmyfirstassetbundleという名前にしました。パスカル型で記述しましたが、全部小文字にされたので読みづらい…

同じバンドルにアセットを追加する場合はInspectorウィンドウ一番下のメニューから同じ名前のバンドルを選択して割り当てます。

 

f:id:karaagedigital:20161112180528p:plain

初期値ではNoneに設定されているのでプロジェクト本体とともにパッケージ化されます。


公式ドキュメント

http://docs.unity3d.com/ja/current/Manual/BuildingAssetBundles5x.html

に記載されているようにアセットバンドルをエクスポートするにはスクリプトが必要になります。


using UnityEditor;

public class CreateAssetBundles
{
 [MenuItem ("Assets/Build AssetBundles")]
 static void BuildAllAssetBundles ()
 {
  BuildPipeline.BuildAssetBundles ("Assets/AssetBundles",BuildAssetBundleOptions.None, BuildTarget.StandaloneOSXUniversal);
 }
}

そうするとメニューのAssetsからBuild AssetBundlesというメニューが追加されます。

f:id:karaagedigital:20161112180646p:plain

Testというディレクトリでやっていましたが、BuildPipeline.BuildAssetBundles ("Assets/AssetBundles", BuildAssetBundleOptions.None, BuildTarget.StandaloneOSXUniversal);


"Assets/AssetBundles"がディレクトリを指定しているみたいなので、今回は合わせてAssetBundlesとディレクトリ名を変更しておきました。

f:id:karaagedigital:20161112180839p:plain

それでは実際にBuild AssetBundlesを実行してみましょう。

 

f:id:karaagedigital:20161112181001p:plain

f:id:karaagedigital:20161112181002p:plain

myfirstassetbundleディレクトリが作成されており中にはアセットバンドルとマニフェストファイルが入っており、マニフェストファイルにはアセットバンドルに含まれているファイルが記載されています。

f:id:karaagedigital:20161112181009p:plain

 こんな感じでPrefabとSpriteのアセットバンドルとマニフェストファイルが出来ました。

それでこれをサーバーに配置してそこから引っ張ってきて使用するわけです。

一先ずアセットバンドルの作成までという事で次回の記事につなげたいと思います。。。(+_+)

 

それにしても忙しくてまたかなり更新の間隔があいてしまった…

using System; Randomクラスが使えない時の対処法

using UnityEngine;

usgin System;

この両方にRandomが存在していて両方かくと衝突してしまってRandom関数が使えなくなってしまいます。

Random.Range(x,y);

Randomの前にUnityEngine.を付け加えてあげる事でこの問題は解決します。

UnityEngineの中のRandomを使いますよっていう事だと自分の中では解釈しています。

UnityEngine.Random.Range(x,y);

Randomが使えない!という方はこれで試してみて下さい。

uGUIを使った動きのあるフェードインアウト

f:id:karaagedigital:20160924095246g:plain

こんな感じでフェードインアウトしていくのですが、どうでしょう。

ColorのAlphaをいじってフェードインアウトっていうのはとても簡単ですし、自分も使ってたのですがこうしたかっこいい感じでフェードインアウトをしたいと思ってたところ見つかったのでメモ用です。

今回お世話になったお二つのサイトでございます。

4you.bz

tsubakit1.hateblo.jp

cutoutoRangeは

GetComponent<FadeImage> ().Range

で制御が出来るみたいです。