LoginSignup
54
68

More than 5 years have passed since last update.

UnityでRPGを作る

Last updated at Posted at 2015-01-10

基本コンセプト

ロールプレイングゲーム
http://ja.wikipedia.org/wiki/ロールプレイングゲーム

ゲームコンセプト

  • ダンジョンでクリスタルを集める
  • 徘徊する敵に接触してはいけない

設計コンセプト

  • 2Dメカニムを使用
  • コライダーは使用しないで、座標のマトリクス判定を行なう

素材

  • RPGツクールの素材を使用する
  • ひとマス32×32での素材を収集する
  • 必要な素材は、プレイヤー、敵、マップの3つ

プレイヤー
のんびりまったり:
http://momope8.blog67.fc2.com/blog-entry-237.html

敵素材
狐火日記:
http://leerfuchs.blog94.fc2.com/blog-entry-91.html

マップ素材
Jetblack Rooming House:
http://blog.goo.ne.jp/shikkokunotoki3

プレイヤー、敵テクスチャーの作成

2Dアニメーションを作成するので、SpriteRendererの設定と、SpriteEditorを使用して、画像のトリミングを行なう。

SpriteRendererの設定

SpriteRenderer
http://docs.unity3d.com/ScriptReference/SpriteRenderer.html


Untitled_-_TCA_RPG_-_iPhone__iPod_Touch_and_iPad-3.png

タイリングされたプレイヤーの画像を選択し、インスペクターで設定。
TextureTypeをSpriteに、SpriteModeをMultipleに設定。

設定が完了したら、SpriteEditorでトリミングする。


Untitled_-_TCA_RPG_-_iPhone__iPod_Touch_and_iPad-5.png

SpriteEditorを展開したら、左上のSliceボタンを押下し、トリミングサイズの設定を行なう。
RPGツクールの素材は、大体32×32で納められている。
更新完了したらSliceボタンを押下し、右上のApplyボタンを押下する。


アニメーションの作成

Unityの便利な機能を使用して、パラパラアニメーションを作成する。

対象のテクスチャーを選択し、ヒエラルキーにドラック&ドロップする。
このタイルは、正面、後ろ、右、左の4つの方向があるので、それぞれのアニメーションでまとめて作成する。

基本的に、一番若いSpriteNameがオブジェクト名、アニメーター名になり、アニメーションのファイル名を適宜設定するような仕様になっている。

現在のUnityでは、アニメーションファイルと一緒に、アニメーターファイルが生成されるが、実際に使うアニメーターファイルはひとつだけなので、不要なものは削除してしまって問題ない。ひとつ作ってしまえば、コピーしてアニメーションを差し替えるのみで対応が出来る。

Untitled_-_TCA_RPG_-_iPhone__iPod_Touch_and_iPad-12.png

今回は敵キャラを4色分作りました。

メカニムの設定

アニメーションの設定が完了したら、アニメーターの設定を行ないます。
ここでは「メカニム」という、アニメーションコントロールのためのツールを使います。

スクリーンショット 2015-02-14 10.07.31.png

作成したアニメーションを、メカニムの設定画面にドラック&ドロップします。
ひとつの色(敵キャラ)に必要なアニメーションを配置したら、それぞれを右クリックメニューのMakeTransitionで繋いで行きます。

完了したら、アニメーション切り替えのためのパラメーターを設定します。

左下の「+」ボタンを押下し、「int」のパラメーターを設定します。
右側のテキストBOXにはパラメーター名、左には「0」を入力しましょう。

スクリーンショット_2015-02-14_10_55_03-2.png

アニメーションコントローラの作成

PlayerController.cs
using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Animator))]

public class PlayerController : MonoBehaviour {
    private Animator m_player;
    public int m_playerState = 0;
    private SpriteRenderer m_idlestate;

    public Sprite F;
    public Sprite B;
    public Sprite R;
    public Sprite L;

    private Vector3 m_playerPosition = new Vector3(0, 0, 0);


    // Use this for initialization
    void Start () {
        m_player = GetComponent<Animator>();
        m_idlestate = GetComponent<SpriteRenderer>();

    }

    // Update is called once per frame
    void Update () {

        if (Input.GetKey(KeyCode.DownArrow)){
            m_player.speed = 1;
            m_player.SetInteger("Walk", 0); 
        }

        if (Input.GetKey(KeyCode.UpArrow)){
            m_player.speed = 1;
            m_player.SetInteger("Walk", 1);
        }

        if (Input.GetKey(KeyCode.RightArrow)){
            m_player.speed = 1;
            m_player.SetInteger("Walk", 3);
        }

        if (Input.GetKey(KeyCode.LeftArrow)){
            m_player.speed = 1;
            m_player.SetInteger("Walk", 2);
        }

        if (Input.GetKeyUp(KeyCode.DownArrow)){
            m_player.speed = 0;
        }


        if (Input.GetKeyUp(KeyCode.UpArrow)){
            m_player.speed = 0;
        }


        if (Input.GetKeyUp(KeyCode.RightArrow)){
            m_player.speed = 0;
        }


        if (Input.GetKeyUp(KeyCode.LeftArrow)){
            m_player.speed = 0;
        }
    }

}

Mapの作成

フィールド(マップ)を作成するために、マップチップの準備と、MapLoaderの作成を行ないます。

MapLoader

・ヒエラルキーに空のゲームオブジェクトを配置します
・MapLoader.csを追加(生成)します
・インスペクターに▷Floorが表示されているので、sizeに使用するチップの数を入力し、追加されたGameObject追加欄にプレハブをD&Dします。

Map.cs
using UnityEngine;
using System.Collections;

public class MapLoader : MonoBehaviour {

    public float m_chipsize = 0.16f;
    public GameObject[] m_floor1;
    private int m_map =0;

    [SerializeField]
    private GameObject m_player = null;
    Controller m_controller = null;

    private float x = 0;
    private float y = 0;

    public int[] m_ngchip = new int[]{10, 12, 13}; 


    public int[][] m_mapArray2 = new int[][]{
        new int[] { 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7},
        new int[] { 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8},
        new int[] { 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8},
        new int[] { 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8},
        new int[] { 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5},
        new int[] { 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5},
        new int[] { 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5},
        new int[] { 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5},
        new int[] { 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5},
        new int[] { 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,10,12,12,12,12,12,12, 5, 5, 5, 5, 5, 5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5},
        new int[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,13 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5},
    };

    void Awake (){
        m_controller = m_player.GetComponent<Controller>();
        m_controller.MapchipNG(m_ngchip);
    }

    // Use this for initialization
    void Start () {

        foreach (int[] array in m_mapArray2)
        {
            foreach (int s in array)
            {
                Instantiate(m_floor1[s], new Vector3(x, y, 0), Quaternion.identity);
                x = x + 1;
            }
            x = 0;
            y = y + 1;
        }

    }

    // Update is called once per frame
    void Update () {

    }
}

コントローラーを作成する

controller.cs
using UnityEngine;
using System.Collections;

public class CharactourController : MonoBehaviour {

    public GameObject m_map;
    public MapLoader m_map01;
    Transform m_position;

    public int[] m_ngmap_p = new int[]{0,0,0};

    enum Move { on, off }

    Move m_move = Move.off;

    // Use this for initialization
    void Start ()
    {
        m_map = GameObject.Find ("Map");
        m_map01 = m_map.GetComponent<MapLoader> ();
        m_position = GetComponent<Transform> ();

    }

    // Update is called once per frame
    void Update ()
    {
        if (Input.GetKey (KeyCode.UpArrow))
            StartCoroutine (MovePlayer ("u", 1));
        if (Input.GetKey (KeyCode.DownArrow))
            StartCoroutine (MovePlayer ("d", -1));
        if (Input.GetKey (KeyCode.RightArrow))
            StartCoroutine (MovePlayer ("r", 1));
        if (Input.GetKey (KeyCode.LeftArrow))
            StartCoroutine (MovePlayer ("l", -1));
    }

    bool MapCollider( int x, int y ){

        Debug.Log("NextPosi;" + x + "," + y + "\n" + m_map01.m_mapArray[y][x]);

        foreach (int s in m_ngmap_p) if(m_map01.m_mapArray[y][x] == s) return false;
        return true;

    }

    public void MapchipNG(int[] ngchip){

        int i = 0;

        foreach (int s in ngchip){
            m_ngmap_p[i] = s;
            i++;
        }
    }

    private IEnumerator MovePlayer (string s, int i)
    {

        float m = 0.1f; /// 移動速度

        float x = this.transform.localPosition.x;
        float y = this.transform.localPosition.y;
        float z = this.transform.localPosition.z;

        float my = y;
        float mx = x;

        if (m_move == Move.off) {
            m_move = Move.on;

            switch (s) {
            case "u":
                Debug.Log ("Move UP");

                if (MapCollider((int)x, (int)y+1)) {
                    for (int f = 0; f <= 10; f++) {
                        m_position.localPosition = new Vector3 (x, my, z);
                        if(f == 10) m_position.localPosition = new Vector3 (x, y, z);
                        my = my + m;

                        yield return new WaitForSeconds (0.01f);
                    }
                }
                break;

            case "d":
                Debug.Log ("Move DOWN");

                if (MapCollider((int)x, (int)y-1)) {
                    for (int f = 0; f <= 10; f++) {
                        m_position.localPosition = new Vector3 (x, my, z);
                        my = my - m;

                        yield return new WaitForSeconds (0.01f);
                    }
                }
                break;

            case "r":
                Debug.Log ("Move Right");

                if (MapCollider((int) x + 1, (int)y)) {
                    for (int f = 0; f <= 10; f++) {
                        m_position.localPosition = new Vector3 (mx, y, z);
                        mx = mx + m;

                        yield return new WaitForSeconds (0.01f);
                    }
                }
                break;

            case "l":
                Debug.Log ("Move Left");
                if (MapCollider((int)x - 1, (int)y)){
                for (int f = 0; f <= 10; f++) {
                        m_position.localPosition = new Vector3 (mx, y, z);
                        mx = mx - m;

                        yield return new WaitForSeconds (0.01f);
                    }
                }
                break;

            default:

                break;
            }

            m_position.localPosition = new Vector3 ( (float)System.Math.Round(mx, 0), (float)System.Math.Round(my, 0), z);
            Debug.Log( m_position.localPosition );

            yield return new WaitForSeconds (0.2f);
            m_move = Move.off;
        }
    }
}


54
68
4

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
54
68