LoginSignup
13
14

More than 5 years have passed since last update.

UnityでHTTPでWeb上にあるステージデータを読み込んで表示する

Posted at

はじめに

前回の続きです。

今回は、ステージデータをWeb上にUploadしておいて、そこから読み込むようにしておきます。
こうすると、アプリケーション本体とは別にステージデータを増やすことができるようになります。

Web上のデータを取得する

どこかのURL (stageUrl) 以下に、ステージ番号別にテキストデータを配置するものとします。
とりあえず <stageUrl>/0001.txt というフォーマットとします。

StageModel.cs

最終的には、ステージデータが何個あるか、とかも管理したいので、その辺を扱うClassをStageModelとして作ろうと思います。適切かどうかわかりませんが、とりあえず Singleton にしておきます。

Web上のデータを取得するには、 WWWという便利Classがあるのでそれを使います。
以下のようになりました。

StageModel.cs
public class StageModel
{
    //// Singleton
    private static StageModel instance = new StageModel(Global.stageUrl);

    private StageModel(string baseUrl) {
        this.baseUrl = baseUrl;
    }

    static public StageModel GetInstance() {
        return instance;
    }

    private string baseUrl;

    public IEnumerator LoadStageData(int stageNum, Action<string> callback) {
        var url = String.Format("{0}/{1:D4}.txt", baseUrl, stageNum);
        var www = new WWW(url);
        Debug.Log(url);
        yield return www;
        callback(www.text);
    }
}

LoadStageData にStage番号とデータが取得出来た際のCallback Actionを指定する形にしておきます。

yield return www のように書くと非同期的な処理になって、 www が規定の処理(この場合はデータを取得する)が終わるまでこのメソッド内の処理の実行はStopして、終わったら続きから呼び出してくれます。その間別の処理は動くことができるので全体をBlockすることはありません。
また、戻り値の型を IEnumerator にしておく必要があります。

エラー処理とか何もしていませんが、おいおい追加しようと思います。

StageController.cs

呼び出し側も少し変更する必要があります。

Unityでは、単にLoadStageDataを呼ぶだけでなく、その戻り値を更に StartCoroutine() に渡す必要があります。
callback Action は data => Build(data) みたいに書けるので楽でいいですね。C#の好きなところです。

Start()
        var model = StageModel.GetInstance();
        StartCoroutine(model.LoadStageData(Global.stage, data => Build(data)));

Start()から実際にStageを構築する部分はBuild(string)メソッドとして分割しました。
変更点全体では以下のようになりました。

StageController.cs
    void Start () {
        Global.stageControler = this;

        prefabMap = new Dictionary<char, GameObject> {
            {BLOCK, blockPrefab},
            {LADDER, ladderPrefab},
            {HIDDEN_LADDER, ladderPrefab},
            {BAR, barPrefab},
            {PLAYER, playerPrefab},
            {TREASURE, treasurePrefab},
            {GOAL, goalPrefab},
            {ENEMY, enemyPrefab},
        };

        var model = StageModel.GetInstance();
        StartCoroutine(model.LoadStageData(Global.stage, data => Build(data)));
    }

    void Build(string data) {
        BuildStage(data);

        if (playerObject) {
            // Camera
            cameraObject = (GameObject)Instantiate(cameraPrefab);
            var cameraScript = cameraObject.GetComponent<Camera>();
            cameraScript.target = playerObject.transform;

            // set target to EnemyControl
            foreach (var enemyObject in enemyObjects) {
                var enemyControl = enemyObject.GetComponent<EnemyControl>();
                enemyControl.target = playerObject.transform;
            }
        }

        Global.paused = false;
    }

Cross Domain問題への対応

今回StageDataをgithubにPushして管理したいと思って、最初は単に Githubの raw なDataを参照させようとしていました。
しかし、Editor内で実行してみると、データがLoadされてきません。

Consoleを見てみると、

SecurityException: No valid crossdomain policy available to allow access

Stage_unity_-_RoadRunner_-_Web_Player.png

というエラーが出ています。

crossdomain.xml

調べてみると、http://docs.unity3d.com/Manual/SecuritySandbox.html に書いてありました。

WebPlayerでは Webplayerが配布されているDomainと同じではないURLに WWWクラスでアクセスした場合エラーになります。
これを回避するには、 http://<Access Host>/crossdomain.xml というファイルを置いて、

crossdomain.xml
<?xml version="1.0"?>
<cross-domain-policy>
    <allow-access-from domain="*" />
</cross-domain-policy>

のように書く必要があります。ここでは、任意のDomainからのアクセスを許可しています(緩い設定)。

また、Web PlayerがHTTPSで配布してあり、WWW ClassのアクセスURLがHTTPの場合、
<allow-access-from domain="*" secure="false" />
secure="false"を追加する必要があります。 参考

データ置き場を変更

このファイルは、 URLのルートディレクトリに置かないといけないのですが、
https://raw.githubusercontent.com/crossdomain.xml のようなURLにファイルを置くことはできません。

仕方がないので、Github Pagesを作って、そこからStageDataを配布するようにしました。
結局以下のようなURLで配布するようにします。

Github Pagesの作り方は http://blogger.weblix.net/2014/01/github-pages-create-web-site.html などが参考になると思います。

おわりに

思ったより手間が掛かりましたが、WebからデータをLoadできるようになりました。

13
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
14