どこまでも自由な日々

パソコン初心者主婦のブログです。

Shooting Game チュートリアル 第05回

第5回 当たり判定とアニメーションイベントとレイヤー

すすめていきます。

みんなだいすき当たり判定!

 

5.1 プレイヤーに当たり判定を付ける

Colliderコライダーを使うよ。colliderとは衝突型加速器と訳すらしい。

なんか小さい仮面ライダーみたいなのを想像してたよ。

 

BoxColliderを選択。大きさは注意書きにそって、0.05に設定してみる。

f:id:moph-moph:20150529083830p:plain

5.2 エネミーに当たり判定を付ける

f:id:moph-moph:20150529084141p:plain

EditColliderを押して編集。

f:id:moph-moph:20150529084157p:plain

5.3 弾に当たり判定を付ける

これも上と同様に。

プレハブをシーンビューに持っていって、直して、Apply。

 

5.4 スクリプトから当たり判定を検出する

「OnTriggerEnter2D」「OnTriggerStay2D」「OnTriggerExit2D」

それぞれどう違うの?

 

とりあえずSpaceship.csは問題なし。

…あれ?ぶつかってないのに爆発したよ?

そのまますすめてみる。

5.5 爆発の制御

5.6 爆発した後のゲームオブジェクト削除

アニメーションのなかでタイミングを指定するかんじ。

5.7 弾とエネミーが削除されるエリアを作る

OnTriggerExit2D…「そのエリアから出たら」。

 

ちょっと疲れてきたので休憩。

f:id:moph-moph:20150529091313p:plain

つぎ、レイヤーで当たり判定の制御。

あれ、さっき設定したSortingLayeresと何が違うのだろう?

Sorthingは2D描画の順番だった。下に行くほど表(こちら)に近い。PhotoShopとかと逆なイメージ。

Layerは表示は関係なさそう。

Layerは、主にRendering設定のグループ分けに使う。

らしい。(TagとLayer - Unityな日々(Unity Geek)

今回は、それぞれの当たり判定の条件を設定。

うんうん、問題なく進んでいきます。

 

と思ったら、当たり判定が上手くいっていない。

EnemyBulletにあたっても爆発しない。

おかしい!!

 

と思ったら、Layer名のスペルミスでした。

順調すぎー。

 

5.8 PlayerBulletゲームオブジェクトの削除

あれ、「◎秒後」が出てきた!

Destroy (gameObject, lifetime);

lifetime秒はfloatで。これ、覚えておこう。

 

ふぅー。

以前挫折したところよりだいぶ進んでる気がする。

続きます。

 

 

Shooting Game チュートリアル 第04回

第4回 敵を作成しよう

すすめていきます。

 

4.1 スクリプトの使い回し

はいはい、使い回しは得意です!…ということじゃないですよね。

そもそもいまさらですがコンポーネント=部品、構成要素。と確認。

そして今回作るSpaceship.csはEnemyとPlayer共通ってことね。

継承とは違う??

こちらもエラー出ます。例によって修正。↓

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Rigidbody2D))]

public class Spaceship : MonoBehaviour {

    public float speed;
    public float shotDelay;
    public GameObject bullet;

    public void Shot(Transform origin){
        Instantiate (bullet, origin.position, origin.rotation);
    }

    public void Move(Vector2 direction){
        Rigidbody2D rb2 = GetComponent <Rigidbody2D> ();
        rb2.velocity = direction * speed;
    }
}

OK。

次にPlayer.csを変更。

これは動かない。

 

using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {

    public float speed = 5;
//    public GameObject bullet;

    Spaceship spaceship;
    
//    private Rigidbody2D rb2;
    private Transform bulletTransform;

    void Start() {

//        rb2 = GetComponent<Rigidbody2D>();//取得
        spaceship = GetComponent<Spaceship>;
        StartCoroutine ("FirstCoroutine");

    }


    IEnumerator FirstCoroutine ()
    {
        while (true) {

            //bulletTransform = GetComponent<Transform>();
            //Instantiate (bullet, bulletTransform.position, bulletTransform.rotation);
            spaceship.Shot (transform);

            yield return new WaitForSeconds (spaceship.shotDelay);
        }
    }


    void Update () {
        float x = Input.GetAxisRaw("Horizontal");        
        float y = Input.GetAxisRaw("Vertical");

        Vector2 direction = new Vector2(x, y).normalized;

//        rb2.velocity = direction * speed;//使用
        spaceship.Move (direction);
    }
}

 

これで動きました。

using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {

public float speed = 5;
public GameObject bullet;
Spaceship spaceship;
// private Transform bulletTransform;

void Start() {
spaceship = GetComponent<Spaceship>();
// bulletTransform = GetComponent<Transform>();
StartCoroutine ("FirstCoroutine");

}


IEnumerator FirstCoroutine ()
{

while (true) {

spaceship.Shot (transform);
yield return new WaitForSeconds (spaceship.shotDelay);
}
}


void Update () {
float x = Input.GetAxisRaw("Horizontal");
float y = Input.GetAxisRaw("Vertical");

Vector2 direction = new Vector2(x, y).normalized;

spaceship.Move (direction);
}
}

 bullet関係はSpaceship.csで書いてるから消しちゃうってことですね。

 

4.2 敵を表示する

問題なし。

 

4.3 敵専用のスクリプトを書く

 今更わかってきたけど、インスタンス化するときに*をつけないんだね!

そしておそろしいことにエラー無しで動いた。

using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour {

    Spaceship spaceship;
    private Transform tran;

    void Start () {
     
        spaceship = GetComponent<Spaceship>();
        tran = GetComponent<Transform> ();
        spaceship.Move (tran.up * -1);

        StartCoroutine ("shotCoroutine");

    }

    IEnumerator shotCoroutine(){
        while (true) {    
            for(int i = 0; i < tran.childCount; i++){
                Transform shotPosition = tran.GetChild(i);
                spaceship.Shot(shotPosition);
            }
            yield return new WaitForSeconds (spaceship.shotDelay);
        }
    }

 

このwhile文のtrueはどういうこと?

待機中ずっとっていう意味でいいのかな??

 

 そんでそのまま進行。Enemy.csはwhile文の出前に入れ込んで。

using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour {

    Spaceship spaceship;
    private Transform tran;

    void Start () {
     
        spaceship = GetComponent<Spaceship>();
        tran = GetComponent<Transform> ();
        spaceship.Move (tran.up * -1);

        StartCoroutine ("shotCoroutine");

    }

    IEnumerator shotCoroutine(){
        if (spaceship.canShot == false) {
            yield break;
        }


        while (true) {
        
            for(int i = 0; i < tran.childCount; i++){
                Transform shotPosition = tran.GetChild(i);
                spaceship.Shot(shotPosition);

            }
            yield return new WaitForSeconds (spaceship.shotDelay);
        
        }
    }
}

 続きます。

f:id:moph-moph:20150529083326p:plain

Shooting Game チュートリアル 第03回

第03回 プレイヤーから弾を撃つ

すすめていきます。

3.1 プレイヤーの弾を作成する

問題なし。

 

3.2 プレイヤーの弾を動かす

空のGameObjectをまるでフォルダのように。

そしてスクリプトを書いて、、あ、これはエラー出るパターン。

前回と同じように書きなおす。

 

using UnityEngine;
using System.Collections;

public class Bullet : MonoBehaviour {

    public int speed = 10;
    private Rigidbody2D rb2;

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

 そしてプレハブ更新。

 

3.3 プレイヤーから弾を発射する

あ、ここでコルーチンが出てきていたのね。

 

これでは動かなくて。

    IEnumerator Start ()
    {
        rb2 = GetComponent<Rigidbody2D>();    

        while (true) {
            Instantiate (bullet, transform.position, transform.rotation);
            yield return new WaitForSeconds (0.05f);
        }
    }

 なんやかんやと前回同様こちらを参考にさせていただきました。

っていうかもうほぼ写してます。ありがとうございます。

 

using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {

    public float speed = 5;
    public GameObject bullet;

    private Rigidbody2D rb2;
    private Transform bulletTransform;

    void Start() {

        rb2 = GetComponent<Rigidbody2D>();//取得
        StartCoroutine ("FirstCoroutine");
    }


    IEnumerator FirstCoroutine ()
    {
        while (true) {

            bulletTransform = GetComponent<Transform>();
            Instantiate (bullet, bulletTransform.position, bulletTransform.rotation);
            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;

        rb2.velocity = direction * speed;//使用
    }
}

無事動きました。

 

3.4 スプライトの描画順

で、超いまさらなんですけどBulletの位置、チュートリアルのまま(x=0.14,-0,14)だとちょっとずれてるので0.07と-0.07に直しました。

f:id:moph-moph:20150529031924p:plain

そんでレイヤーも直してOK。

 

f:id:moph-moph:20150529032203p:plain

次回に続きます。

 

 

Shooting Game チュートリアル 第02回

プレイヤーの移動

 すすめていきます。

2.1 読む前におさえておこう

はーい!といったものの、理解はできてないかもしれない。

 

2.2 Prefabからゲームオブジェクトを作成

2.3 プレイヤーを動かす準備

どちらもOK。

2.4 プレイヤーにスクリプトをアタッチ

そう、「はじめてのUnity」チュートリアルではJSでした。

でも今回からはC#。ちょっとどきどきです。

(筆者はObjective-Cを少し触った程度しか経験ありません)

 

ということでメモしつつ。

 

プレイヤーの移動スクリプトは今回

Input.GetAxisRaw(string axisName)

を使う。左が-1、右が1、なにもないときは0を取得。

アナログスティックなどの場合は0と1の間の値も検出できる

Input.GetAxis(string axisName)

を使用する。

 

キー入力から速度ベクトル(物体の移動する向きと速さをベクトルであらわしたもの)をrigidbody2D.velocityに代入するそうだ。??

とりあえずコードをかく。

でアタッチ、実行しようとしたらエラー。

f:id:moph-moph:20150529013032p:plain

 

なんか前もこういうエラー出たような気がしてきた!

そうそう、Unity5だとなんか取得しないといけない。

こちらを参考にさせていただいた。が、動かない…

f:id:moph-moph:20150529013948p:plain

あ、どっかに全角の空白があるらしい。恥。

うんうん、左右の入力で動くようになりました。

 

using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {

    public float speed = 5;
    private Rigidbody2D rb2; //宣言

    void Start() {

        rb2 = GetComponent<Rigidbody2D>();//取得     
    }

    void Update () {
        float x = Input.GetAxisRaw("Horizontal");        
        float y = Input.GetAxisRaw("Vertical");

        Vector2 direction = new Vector2(x, y).normalized;

        rb2.velocity = direction * speed;//使用
    }
}

 

続きます。

 

f:id:moph-moph:20150529014804p:plain

 

Shooting Game チュートリアル 第01回

スプライト / スプライトアニメーションの作成

 

すすめていきます。

 

1.1 Sprite Editorスプライトエディターで1枚のテクスチャから複数のスプライトを作成する

まずはスプライトの読み込み。

そもそもスプライトって単語の意味をちゃんと理解していなかったのでここで確認。2Dビットマップのことね。

 

スプライトエディタがあるということでこれに沿って作っておけばいいっていうのもわかった。

分割サイズも指定できるから一定であればいいのね。

順番としては

0,1,2,3,4,5,6,7,

8,9,10,11,12,13,14,…

と左上から右に向かっていき

次にその下段に、という感じ。

1.2 自機(Playerプレイヤー)のアニメーション

次にアニメーションにするspritesを選択してシーンビューに。

アニメーションファイルは.animで保存される。

わーい!

1.3 敵(Enemyエネミー)のアニメーション

特に問題なし。

 

1.4 弾の作成

問題なし。こっちは小さめだけどちゃんとスライスしてくれたね。

 

1.5 爆発のアニメーション

今更だけど、そもそもの素材になるスプライトファイルは.pngなのだね。

 

そんでプレハブ化。

「1つづつ」ドラッグしましょうと書いてあったのでまとめてドラッグしてみたら、Multipleと出てドラッグできなかった。なんでだろう?

 

とりあえず01回はあっという間におしまい。

 

f:id:moph-moph:20150529010411p:plain

Shooting Game チュートリアル 第00回

Unity5で公式チュートリアルをはじめていきます。

Unity - Tutorial - 2D Shooting Game

 

以前途中までやって放置したのですが今回また最初から、記録しながらすすめていこうと思います。

(なぜ放置したのかも覚えていないので…)

 

というわけで公式から今回のプロジェクトファイルをダウンロード。

Unityを起動。

あれあれ、Project Upgrade Required と出ます。

サンプルのプロジェクトは古いバージョンだよ、ということらしい。

Upgradeを押すことにします。

 

そのあとは問題なく、環境設定完了。

全12回、さぁがんばろう。

 

Unity5で背景画像の表示非表示を切り替えたい

背景画像を非表示にしておいて、条件によって表示させるようにしたい。

 

f:id:moph-moph:20150528155211p:plain

  renderer.enabled = false;

 これだけで非表示になるそうなので試してみる。

…うまくいかない。

 

表示非表示を切り替えたいコンポーネントにこのようなコードを入れたらうまくいった。

 

using UnityEngine;
using System.Collections;

public class backImage : MonoBehaviour {
    private Renderer _renderer; //ここ

    void Start () {
        _renderer = GetComponent<Renderer>(); //
        _renderer.enabled = false; //trueで表示
    }
   
}

 ふぅー。

できた!

f:id:moph-moph:20150528155227p:plain

できたら外部から扱いたいんだけど。

初心者なので難しい。