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

# 概要

前回、unity公式チュートリアルの2Dシューティングゲームの第二回、第三回でプレイヤークラスと弾クラス用に親クラスのゲームキャラクラスを作りました。

[unityでオブジェクト指向な作り方ってなんなの＼(^o^)／　その１](http://qiita.com/hypxyosukephl/items/2a51edb1934f0ea7f93e)


今回は第四回で敵クラスを作成しますが、そこで新たに作成するSpaceshipクラス。unityではこれを作ってプレイヤーや敵のオブジェクトにアタッチすることで戦闘機系クラス？として使って下さいということなんだろうか…

[シューティングチュートリアルサイト　第04回 敵を作成しよう](https://github.com/unity3d-jp-tutorials/2d-shooting-game/wiki/%E7%AC%AC04%E5%9B%9E-%E6%95%B5%E3%82%92%E4%BD%9C%E6%88%90%E3%81%97%E3%82%88%E3%81%86)

こちらも自分のできる範囲でオブジェクト指向を意識して変更をしていこうと思います。



## Spaceshipクラスを作成（GameCharaクラスを継承する）

### 継承前のチュートリアルに書かれていたSpaceshipクラス

```csharp.Spaceship.cs

using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]
public class Spaceship : MonoBehaviour
{
    // 移動スピード
    public float speed;

    // 弾を撃つ間隔
    public float shotDelay;

    // 弾のPrefab
    public GameObject bullet;

    // 弾を撃つかどうか
    public bool canShot;

    // 弾の作成
    public void Shot (Transform origin)
    {
        Instantiate (bullet, origin.position, origin.rotation);
    }

    // 機体の移動
    public void Move (Vector2 direction)
    {
        GetComponent<Rigidbody2D>().velocity = direction * speed;
    }
}
```

前回作成したGameCharaクラスを使い、自分なりに作成しました。

### 継承後のSpaceshipクラス

```csharp.Spaceship.cs
using UnityEngine;
using System.Collections;

public class SpaceShip : GameChara {

	//弾の発射間隔
	public float shotDelay;
	//弾を打てるか
	public bool canShot;
	//次の弾を打つインターバルが終わっているか
	private bool isRunning = false;

	public GameObject bulletPrefab;

	//弾の作成
	protected IEnumerator Shot(Transform origin){
		if (!canShot)
			yield break;
		if (isRunning)
			yield break;
		isRunning = true;
		Instantiate (bulletPrefab, origin.position, origin.rotation);
		yield return new WaitForSeconds(shotDelay);
		isRunning = false;
	}
}

```

これにより、プレイヤークラス、敵クラスにも変更を加えました。

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

```csharp.Player.cs

using UnityEngine;
using System.Collections;

public class Player : SpaceShip {

	// Use this for initialization
	void Start () {
		
	}

	// Update is called once per frame
	void Update () {
		float x = Input.GetAxisRaw ("Horizontal");

		float y = Input.GetAxisRaw ("Vertical");
		//移動する向きを求める
		Vector2 direction = new Vector2 (x_speed * x, y_speed * y);

		base.Move (direction);

		if (Input.GetKey (KeyCode.Z)) {
			//プレイヤーと同じ位置/角度で発射
			StartCoroutine(Shot(transform));
		}
	}
}
```

### 変更後の敵クラス

```csharp.Enemy.cs

using UnityEngine;
using System.Collections;

public class Enemy : SpaceShip {

	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
		Vector2 direction = new Vector2 (x_speed, -y_speed);
		base.Move (direction);
		StartCoroutine(Shot(transform));
	}
}
```
プレイヤークラスでビルドすると弾を勝手に撃つよりもボタンを押して撃つようにしたかったので、Zを押して弾を撃つようにしました。
あとspeed変数が一つだとどうも自分的に嫌だったので、x_speedとy_speedという変数を追加しました。

これによりGameCharaクラスは以下に変更しました。（変更してばっかだな！）

### 変更後のゲームキャラクラス

```csharp.GameChara.cs

using UnityEngine;

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

	public float x_speed;

	public float y_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;
	}
}
```

# まとめ（感想と次回に向けて）
変更してばっかで自分的に既に諦めムードが出てしまっています…でもせっかく記事に書いてるので頑張ります((+_+))
継承することを意識しすぎているせいか、unityの本来の特性を生かした、コンポーネントの作成（部品作成）というよりも、一つのクラスに様々な機能を付けちゃう感じになりそうだなあと思いました。

次回は爆発アニメーションのプレハブを作成するのと、当たり判定処理の作成です。特に当たり判定はオブジェクト指向において重要な処理ですね。（何がどう重要なのか

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