unityでオブジェクト指向な作り方ってなんなの＼(^o^)／　その１ （GameCharaクラスの作成）

# 概要

現在自分はunity公式チュートリアルの2Dシューティングゲームの作り方を見てunityの勉強をしているが、これを見ているとmonobehaviorを継承してとりあえずアタッチして便利なオブジェクトをどんどん作ってこー！みたいな感じに見える…

[シューティングチュートリアルサイト](https://github.com/unity3d-jp-tutorials/2d-shooting-game/wiki)


ゲーム作りの本を読んでいると自分で親クラスを作ってそれを継承させて〜〜の手順があるが、unityだと自由に作りやす過ぎて、どうもその考えをしなくても良いように見えてしまいます（そんな訳がないですけどね）

そこで、このシューティングチュートリアルサイトで回を進む毎に、一旦自分なりに親クラスを作ってどことなくオブジェクト指向っぽい作りの挑戦をしてみました！その時に苦戦して手が止まってしまった部分を書き記します。

ちなみに自分は社会人プログラマーではあるが、オブジェクト指向や構造型プログラミング等に疎く、今まで動けば良いや精神で勤めてきていたため、技術力に関してはお察し頂けると助かります・・・アドバイスはもちろんウェルカムです！！

## ゲームキャラの親クラス

よくあるやつですね。キャラを作り始めるのは第二回と第三回のプレイヤーと弾の作成でした。
### プレイヤークラス

```csharp.Player.cs

using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour
{
    // 移動スピード
    public float speed = 5;

    // PlayerBulletプレハブ
    public GameObject bullet;

    // Startメソッドをコルーチンとして呼び出す
    IEnumerator Start ()
    {
        while (true) {
            // 弾をプレイヤーと同じ位置/角度で作成
            Instantiate (bullet, transform.position, transform.rotation);
            // 0.05秒待つ
            yield return new WaitForSeconds (0.05f);
        }
    }

    void Update ()
    {
        // 右・左
        float x = Input.GetAxisRaw ("Horizontal");

        // 上・下
        float y = Input.GetAxisRaw ("Vertical");

        // 移動する向きを求める
        Vector2 direction = new Vector2 (x, y).normalized;

        // 移動する向きとスピードを代入する
        GetComponent<Rigidbody2D>().velocity = direction * speed;
    }
}
```

### 弾クラス

```csharp.Bullet.cs
using UnityEngine;

public class Bullet : MonoBehaviour
{
    public int speed = 10;

    void Start ()
    {
        GetComponent<Rigidbody2D>().velocity = transform.up.normalized * speed;
    }
}
```

よし、違った特性を持ったオブジェクトが出来たし、共通の部分は親クラスを作ってまとめてみよう！
そう意気込んでこうなりました。

### ゲームキャラ親クラス

```csharp.GameChara.cs

using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(SpriteRenderer))]
public abstract class GameChara : MonoBehaviour {

	public float speed;

	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}

	protected virtual void Move(Vector2 direction){
		GetComponent<Rigidbody2D> ().velocity = direction * speed;
	}
}
```

チュートリアル内でプレイヤーと弾のオブジェクトは、共にRigidbody2DとSpriteRendererをアタッチしていたのでRequireComponentを付けることでゲームのキャラにはこれらをアタッチし忘れないように制限をしました。（これはチュートリアル第四回で出るテクニックですが先に定義してみました）

### 変更後のプレイヤークラス

```csharp.Player.cs

using UnityEngine;
using System.Collections;

public class Player : GameChara
{
	// PlayerBulletプレハブ
	public GameObject bullet;
	
	// Startメソッドをコルーチンとして呼び出す
	IEnumerator Start ()
	{
		while (true) {
			// 弾をプレイヤーと同じ位置/角度で作成
			Instantiate (bullet, transform.position, transform.rotation);
			// 0.05秒待つ
			yield return new WaitForSeconds (0.05f);
		}
	}
	
	void Update ()
	{
		// 右・左
		float x = Input.GetAxisRaw ("Horizontal");
		
		// 上・下
		float y = Input.GetAxisRaw ("Vertical");
		
		// 移動する向きを求める
		Vector2 direction = new Vector2 (x, y).normalized;
		
		// 移動する向きとスピードを代入する
		base.Move(direction);
	}
}
```

### 変更後の弾クラス

```csharp.Bullet.cs

using UnityEngine;

public class Bullet : GameChara
{
	
	void Start ()
	{
		Vector2 direction = new Vector2 (0,1);
		base.Move (direction);
	}
}
```

# まとめ（次回に向けて）

どうでしょうか…自分だけではこれが良いのか悪いのかが判断できませんでした。まだまだ最初なのでこんなもんかなと思いつつ一旦ここで作業は止めます。
次回は敵を作る部分ですが、ここでチュートリアルではSpaceshipというクラスを作成し、それをプレイヤーと敵のクラスにアタッチしてますね…これはまたどうするのかが良いのか…

この回は以上です。
この時点でアドバイスがあればお願い致します！