LoginSignup
27
28

More than 5 years have passed since last update.

Unityでテキストデータからゲームステージを作成する

Posted at

前回 の続きです。

今までは、UnityのUIでステージを構成していましたが、スクリプトを使ってテキストデータからステージを作成するようにします。
こうすると簡単にステージを増やしていくことが可能になります。

必要なものをPrefab化しておく

まず、今まで作っていたGameObjectをPrefab化しておきます。
Prefab化しておくと、他のSceneでも簡単に使うことができます。

BarやLadderやBlockは既にPrefab化済みなので、以下のものを忘れずにPrefab化します。

  • DirectionLight
  • Main Camera
  • unityChan

Hierarchy から Project→Assets→Prefab に ドラッグアンドドロップします。
名前は ○○Prefab とかにします。

新しいSceneを作成する

今までのSceneはもうしばらく開発用に使うので、今まで使っていたサンプル用のSceneとは別に、新しいSceneを作成します。
UnityではSceneは大きな区切りで、全GameObjectがリセットされます(させないようにもできるようです)。

Scene作成

メニューから [File] -> [New Scene] を選びます。名前を Stage としておきます。
Prefabから Directional Light を設置しておきます。これもスクリプトで設置できますが、どうせ固定なので最初に設置してしまいます。

Stage作成用のScriptを作る

空のGame Objectを作って、Scriptを登録する

GameObject -> Empty Object で 何も表示されない Game Objectを作ります。
ここにScriptをComponentとして登録します。

そのGameObjectの Add Component から Script を選択して StageController.cs を作成して登録します。

StageController.cs

ポイントは以下のことでしょうか。

PrefabのInstance化

PrefabからGameObjectをScriptで作成するには Instantiateを使います。
ステージデータの記号に応じて、対応するPrefabを対応する座標に設置すればOKです。

var instance = (GameObject)Instantiate(obj, new Vector3(x, y, 0), Quaternion.identity);

実際のPrefabは public field にしておいて、GUIから設定してもらうことにしておきます。
この辺とても便利で良いですね。

Camera Objectの Targetを設定

Main Camera object は、Targetを追い回すようになっているため、Targetを指定してあげないといけません。
指定したいのは UnityChanの座標なので、UnityChanのObjetを画面生成時に保持しておいて、
後からMain Cameraのtarget field に設定しています。まあ一応動くのでこれでよしとします。

Scriptは以下のようになりました。

StageController.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

public class StageController : MonoBehaviour {
    public GameObject blockPrefab;
    public GameObject ladderPrefab;
    public GameObject barPrefab;
    public GameObject playerPrefab;
    public GameObject cameraPrefab;

    const char BLOCK = '#';
    const char LADDER = 'H';
    const char BAR = '-';
    const char PLAYER = 'P';

    private GameObject playerObject;

    private Dictionary<char, GameObject> prefabMap;

    // Use this for initialization
    void Start () {
        prefabMap = new Dictionary<char, GameObject> {
            {BLOCK, blockPrefab},
            {LADDER, ladderPrefab},
            {BAR, barPrefab},
            {PLAYER, playerPrefab},
        };

        BuildStage(STAGE_DATA);
        if (playerObject) {
            var camera = (GameObject)Instantiate(cameraPrefab);
            var cameraScript = camera.GetComponent<Camera>();
            cameraScript.target = playerObject.transform;
        }

    }

    void BuildStage(string stageData) {
        // Left Botton's position is (0,0)
        var lines = stageData.Split('\n');
        int y = lines.Count();
        foreach (var line in lines) {
            y--;
            int x = 0;
            foreach (var ch in line) {
                GameObject obj;
                prefabMap.TryGetValue(ch, out obj);
                if (obj) {
                    var instance = (GameObject)Instantiate(obj, new Vector3(x, y, 0), Quaternion.identity);
                    if (ch == PLAYER) {
                        playerObject = instance;
                    }
                }
                x++;
            }
        }
    }


    const string STAGE_DATA = @"
#         H    #
# P       H    #
#         H    #
#  #HHHHHHH    #
#         H    #
#---------H    #
#         H    #
####H###########
#   H--------- #
#   H          #
#   H ####     #
#   H----      #
#   H    ##### #
#   H          #
#   H          #
################";
}

StageControllerスクリプトにPrefabを関連付け

StageController.cs の Prefab Field に 目的にあった Prefabをドラッグ・アンド・ドロップなどで登録していきます。

Stage_unity_-_RoadRunner_-_Web_Player_と_テキストデータからゲームステージを作成する_と_Assembly-CSharp_-_Script_StageController_cs_-_MonoDevelop-Unity_と_ターミナル_—_screen_—_130×36.png

他微調整

カメラが近すぎて全体が見えなかったので、Main Camera の 'Field of View' を 60 → 100 に変更しました。

Stage_unity_-_RoadRunner_-_Web_Player.png

Unityちゃんがだいぶ小さくなって少し寂しいですが、まあ仕方ないかな。。。

おわりに

27
28
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
27
28