[Unity] ブロック崩しをあのアプリ風にする #7 戻ってきたボールを集合させる

下に当たったョ!全員集合!


集合させる方法は色々あると思います。下の壁に当たり判定のスクリプトをつけてもいいし、ボールにつけてもいいし、あるいはZ軸が決められた値を超えていたら、でもいいと思います。
でも今はまだ10個程度でしか動かしていないのでサクサクだけど、これが50とか100になった時それでもサクサクなのか。僕の古いスマホはそれでもサクサク動いてくれるのか。

なんて言ってても始まらないのでとりあえず書いてみます。

Bwallに判定をつける

当たり判定はBwallが拾うことにします。なのでこのスクリプトはBwallにつけます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bwall : MonoBehaviour {
    BallManager ballManager;

    void Start(){
        ballManager =GameObject.Find ("InputController").GetComponent ();
    }
    void OnCollisionEnter(Collision collision) {
//衝突判定 ボールが戻ってきたことを伝える
        if (collision.gameObject.tag == "Ball") {
            var ball = collision.gameObject;  
            ballManager.BottomTouch(ball);
        }
    }
}


Bwallの仕事はボールが戻ってきたことをBallManagerに伝えるだけです。その時衝突したBallオブジェクトを渡しています。管理はBallManager側で実装します。


ボールが戻ってきた時の処理

BallManagerにBottomTouchメソッドを追加します。

//〜中略〜
    public class BallManager : MonoBehaviour {
//戻ってきたボールの数
    int returnBall;
//〜中略〜

    ublic void Shooting(Vector3 vec){
        isShooting = true;
        returnBall = 0;
//〜中略〜

//ボールが下につくとBwallから呼ばれる
        public void BottomTouch(GameObject ball){
        ball.GetComponent().velocity = Vector3.zero;
//最初に帰ってきたボールなら
        if (returnBall == 0) {
            ballBornPoint.position = ball.transform.position;
        } 
//それ以外は移動
        else {
            StartCoroutine ("setPos",ball);
        }
        returnBall += 1;
        if (returnBall == maxBall) {
            isShooting = false;
        }
    }

//集合コルーチン
    IEnumerator setPos(GameObject ball){
//集合ポイントより離れていれば
        while(Mathf.Abs(ball.transform.position.x- ballBornPoint.position.x)>1) {
//右か左か
            int dir = ball.transform.position.x < ballBornPoint.position.x ? 1 : -1;
            ball.transform.position += new Vector3(dir,0,0);
            yield return null;
        }
        ball.transform.position = ballBornPoint.position;
    }
//〜中略〜


returnBallを定義して戻ってきたボールの数を保存しておきます。Shootingメソッドの中でそれをリセットします。
BottomToucchの中でまず Vector3.zero でballの動きを止めてから、それが最初に戻ってきたボールか判断して、もしそうならballBornPointを移動させます。その位置がそのまま次のシューティングポイントになります。
それ以外はコルーチンでシューティングポイントに集合させます。
その後returnBallをカウントアップして全て戻ってきているようなら再び入力できるようにフラグを立てます。

setPosコルーチン

StartCoroutine()は第二引数で一つだけ値を渡すことができます。ここではballを渡してます。 setPosコルーチンの中ではまず集合地点から1以上離れているかを絶対値でみてます。離れてないなら念のため座標を上書きしてコルーチン終了です。 離れている時は三項演算子で左右どちらにずらせばいいか判断してます。その値ぶん移動してyield return nullで一旦処理を終わらせます。次のループが始まるのは1フレーム後です。


ちゃんと集合がかかり、再び撃てるようになりました。

コメント