kotonagaのブログ

Unityとか

Unityで2DRPGを作ってみる 3日目

昨日までのところで、キャラクターの見た目のところは出来たので、今日はインプット関連のスクリプトを書いていきます。
それだけだとすぐ終わってしまうので、適当に歩き回る村人も作ります。

CharacterControlの作成

プレイヤーと村人で共通の処理があるので、CharacterControlというクラスを作り、プレイヤーと村人はそれを継承する形にします。
CharacterControl.cs

/*
The MIT License (MIT)

Copyright (c) 2014 Kotonaga

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

using UnityEngine;

public class CharacterControl : MonoBehaviour {
    public float m_speed;
    protected Animator m_animator;
    protected float m_directionX = 0;
    protected float m_directionY = 0;
    protected bool m_walking = false;
    
    protected void Awake() {
        this.m_animator = GetComponent();
    }
    
    protected void Update () {
        if(this.m_animator){        
            if(this.m_walking){
                transform.Translate(new Vector3(this.m_directionX, this.m_directionY, 0) * Time.deltaTime * m_speed);
                transform.position = new Vector3(transform.position.x,transform.position.y,transform.position.y / 1000f);
            }
            this.m_animator.SetFloat("DirectionX", this.m_directionX);
            this.m_animator.SetFloat("DirectionY", this.m_directionY);
            this.m_animator.SetBool("Walking", this.m_walking);
        }
    }
}

PlayerControlの作成

Unityには、Inputクラスというのがあり、これを使うとインプット関係のコーディングが非常に楽です。
Input.GetAxisに、"Horizontal"を入れるとX軸の入力が、"Vertical"を入れるとY軸の入力が分かります。
この値を利用するPlayerControlクラスを作成します。
PlayerControl.cs

/*
The MIT License (MIT)

Copyright (c) 2014 Kotonaga

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

using UnityEngine;

public class PlayerControl : CharacterControl {
    new void Update () {
        if(this.m_animator){
            // 入力の取得
            float horizontal = Input.GetAxis("Horizontal");
            float vertical = Input.GetAxis("Vertical");
            
            this.m_walking = true;
            
            if(horizontal==0 && vertical==0){
                this.m_walking = false;
            }else{
                this.m_directionX = horizontal;
                this.m_directionY = vertical;
            }
        }
        base.Update();
    }
}

VillagerControlの作成

次に村人を作りますが、その前に昨日作成したGameObjectの名前をCharacterBaseに変更し、Prefabとして保存します。
f:id:kotonaga:20141229161530p:plain
それから、HierarchyのCharacterBaseの名前をPlayerに変更し、CharacterBaseをPrefabからHierarchyにD&Dします。
f:id:kotonaga:20141229161749p:plain
新しく出来たCharacterBaseの名前をVillager01にします。キャラクタの画像はデフォルトでpipo-charachip001になっているので、Villager01のCharacterスクリプトのImageを、pipo-charachip002などに変更します。
f:id:kotonaga:20141229162133p:plain
この村人に設定するスクリプトを作成します。
VillagerControl.cs

/*
The MIT License (MIT)

Copyright (c) 2014 Kotonaga

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

using UnityEngine;
using System.Collections;

public class VillagerControl : CharacterControl {
    private float m_defaultSpeed;
    
    void Start () {
        this.m_defaultSpeed = this.m_speed;
        StartCoroutine("Walk");
    }
    
    private IEnumerator Walk(){
        for(;;){
            this.m_walking = true;
            this.m_speed = this.m_defaultSpeed * Random.Range (0.5f,1f);
            this.m_directionX = Random.Range (-1f,1f);
            this.m_directionY = Random.Range (-1f,1f);
            yield return new WaitForSeconds(Random.Range(0f,5f));
            this.Wait();
            yield return new WaitForSeconds(Random.Range(0f,5f));
        }
    }
    
    private void Wait(){
        this.m_walking = false;
    }
}

村人の動きとしては、ランダムに移動量と移動方向を決めて、0~5秒間でランダムに移動し、0~5秒間をランダムに停止すると言うのを繰り返します。
こういう動作はイテレータを使用したコルーチンを使うことで実現できます。

作成したスクリプトの割り当て

作成したスクリプトを割り当てます。PlayerオブジェクトにPlayerControl.csを
f:id:kotonaga:20141229164641p:plain
Villager01オブジェクトにVillager01オブジェクトを割り当てます。
f:id:kotonaga:20141229164726p:plain
割り当てたら、PlayerのSpeedを128、Villager01のSpeedを32にします。

ここまで出来ましたら、再生ボタンを押すと、村人が自動的に歩き出すと思います。カーソルキーを押すことで、Playerを操作できます。
f:id:kotonaga:20141229165618p:plain
今は当たり判定を付けていないので、お互いにすり抜けることが出来ます。

次回はフィールドマップの作成をする予定です。(行き詰まっているので、公開まで時間がかかるかも…)