ユニティちゃんの2D横スクロールアクション(その7:弾の作成)【チュートリアル】

ども、ゴコーです。
今回からはボタンに応じて攻撃できる様にしてみましょう。

まずは弾を作成します。

弾は、発射したらプレーヤーから見て前方にまっすぐ飛ぶようにしましょう。

まずはヒエラルキー の左上から Create > Cube を選択してCubeを作成して下さい。
Cubeに元々ついている当たり判定は BoxCollider 、つまり3D用の当たり判定なのでRemove しておいてください。
そして、2D用のBoxCollider2DをAddComponentして下さい。

大きさもこのままだと弾がユニティちゃんと同じくらいの大きさで大きすぎるので小さくしておきましょう。

uni-tu-7-0

こんな感じですかね。
後は、名前もこのままではややこしいので名前もBulletとかに変えておいて下さい。

では次にスクリプトを書きましょう。

Bullet.cs

[csharp]

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Rigidbody2D))]
public class Bullet : MonoBehaviour {

public float speed;
public float destroyTime;

public Rigidbody2D cRigidbody2D
{
get
{
return _cRigidbody2D = _cRigidbody2D ?? rigidbody2D;
}
}
Rigidbody2D _cRigidbody2D;

void FixedUpdate()
{
cRigidbody2D.velocity = new Vector2(speed,cRigidbody2D.velocity.y);
destroyTime -= Time.deltaTime;
if(destroyTime <= 0) Destroy(gameObject);
}
}

[/csharp]

RequireComponentなど、以前のパートで説明したことは省略します。

追加したもの

  • プロパティではnull合体演算子も活用し、遅延ロードしている
  • 弾の速度はvelocityに直接入力
  • 指定の時間が過ぎたらDestroy()する

今後解説する、という前提でざっくり書きますね。


  • プロパティではnull合体演算子も活用し、遅延ロードしている

プロパティを使えば実際に呼び出されるタイミングで一度だけGetComponent()されるので大量のGetComponent()をStart()内で実行した為に固まる、何てことが起こりにくくなります。


  • 弾の速度はvelocityに直接入力

以前のパートで、Rigidbody(2D)を活用することでめり込みなどを回避できることは解説しました。
velocityは速度を表しています。今回はこれをspeedで上書きすることで弾を移動させます。

JavaScriptとは違って、x だけに代入、みたいなことは出来ない点に注意です。


  • 指定の時間が過ぎたらDestroy()する

何秒経過しているのか、というのはTime.deltaTime を使えば分かります。
Time.deltaTime は、直前のフレームに要した時間を表しています。

なんのこっちゃですが、これを掘り下げると丸ごと1パート持って行かれそうなのでまた今度。
まあ、正確に時間をカウントできるようにするための処理、という認識でOKです。

今回はdestroyTimeを用意し、カウントダウン、それが0になったら弾を消す、という流れになっています。

実際のゲームで使おうと思ったらDestroy()してるようじゃダメだと思いますが、それもまた今度。
自分でノルマを増やしまくってる気がしますが気にしません。


さて、一通り処理が書けたところで実行です!

uni-tu-7-1

・・・。

uni-tu-7-2

落下した・・・。


これは重力が働いているからです。
Bulletを選択し、Rigidbody2Dコンポーネントを見て下さい。

uni-tu-7-3

Gravity Scale は重力を表しています。
現在は 1 つまり、 1倍になっていますのでこれを 0 にしましょう。

これで落下問題は解決です。


プレハブ化し、入力で呼び出せるようにする

次は弾を呼び出せるようにしましょう。
そのためにはまずプレハブを作成する必要があります。

プレハブというのはクローンを作る素みたいなものです。
これまた掘り下げると1パート持っていかれるので保留。

とりあえず、上記の理解でいってください。

プレハブはヒエラルキーからプロジェクトへD&Dすることで作れます。
画像で説明すると、

uni-tu-7-4

こうして、

uni-tu-7-5

できた!

画像で説明する必要なかったくらい簡単ですね。
チュートリアルによっては、プロジェクトウィンドウで一度空のプレハブを作ってからするものを見かけますけど、こっちの方が速いです。

今回はこのくらいで。

次はプレハブを元に弾を発射してみましょう。
このままでは右にしか進めない弾も修正します。

では、また。

Comments

comments

スポンサーリンク
336*280px

コメント

  1. きなぎ より:

    今まで別のソフトでアクションゲームを作っていたのですが、Unityを最近初めてここの講座を知り、勉強させて貰っていました。
    チュートリアルはここで最後なのでしょうか?

    • backlight1144 より:

      きなぎさん
      コメントありがとうございます。

      チュートリアルは初心者にあまり親切でない構成になっていましたので、現在再構成中なんです。
      再び1からにはなってしまいますが、全くの初心者でもさっとさらえるようにしていますので今しばらくお待ち下さい。

  2. きなぎ より:

    backlight1144さん
    今でも十分わかりやすいと思います。
    プログラムのところはわかりにくいかな、とは思いますけどアクションゲームの作る手順やアニメーションの仕方などとても勉強になりました。

    ひとつ質問してもよろしいでしょうか?

    public Transform cTransform
    {
    get
    {
    if(!_cTransform)
    _cTransform = transform;
    return _cTransform;
    }
    }
    Transform _cTransform;

    ここの文はほんと何をやっているのかわからないので、簡単にで構いませんのでおしえていただけないでしょうか?
    アンダーバーやTransformの前になぜcがついているのか、getしてreturnして、とすべてがわからなくて…。
    お忙しい中申し訳ありませんがよろしくお願いします。

    • backlight1144 より:

      きなぎさん ご質問ありがとうございます。

      質問に関する返答ですが、
      これは「コンポーネントキャッシュ」ということをやっています。

      チュートリアルに沿って説明します。その2「キャラクターの移動」を見て下さい。
      その2の中で「移動」はどうやっているのかというと、
      Rigidbody2D(物理的なことを色々してくれる機能の集まったもの。この機能の集まったものをUnityでは「コンポーネント」と言う)
      にアクセスしてキャラを動かしてもらっているのですが、このアクセス(UnityではこれをGetComponentと言う)にコンピューターは結構頭を使っているのです。
      アクセスの為のキーワードはrigidbody2Dです。
      Rigidbody2Dとrigidbody2Dはどう違うの?という疑問もわいてくるかもしれませんが、これは最後におまけとして書きます。
      初心者なら引っかかるポイントですが書き出すと脇にそれてしまって時間がかかってしまいますので。

      中で起こっていることのイメージは、rigidbody2Dと書かれる度に、
      コンピューターさんという人が、全く住所の分からないRigidbody2Dさんの家を町中を回って探し、やっと見つけて「移動して!」と
      一言伝えた瞬間に、コンピューターさんはまた町のどこかにワープさせられ、再び一から住所を探す羽目になる、ということを1秒間に数十回行っていることと同じレベルです。
      コンピューターはプログラミングの「記憶」という点においては正直おバカさんです。
      住所に限らず、せっかく苦労して計算した答えだろうとなんだろうと記録しておかないと一瞬で忘れるようにされているのでこれは仕方ありません。。

      そこで、コンポーネントキャッシュです。
      これはいわば「住所のメモ」です。
      住所を知っていようと家を訪れるためには多少歩く必要もあります。
      しかし、メモも無しに探し回るのとメモがあって一直線に向かうのとでは雲泥の差がありますね。
      コンポーネントキャッシュしてあれば住所が分かっているため、コンピューターさんの負担もかなり減るというわけです。

      まあ、コンポーネントキャッシュにもいくつか種類はありますし、そもそもやらなくても良い場合もあります。
      それどころかやらない方が良い場合さえあります。
      それらの例外については新しいチュートリアルの中で触れるとして、今回はこんなものでしょう。
      イメージは伝わりましたかね?
      質問の中で書いて頂いたスクリプトの書き方、書いている内容に関しては「C# プロパティ」などで調べると引っかかるかと思いますが、多分理解できないと思います。
      これもそのうち書きます。これも書き始めると絶対長いので…。

      さて、一応Rigidbody2Dとrigidbody2Dについても書いておきます。
      こちらはすぐには理解しなくても良いかもです。
      Rigidbody2Dというのは先ほどから書いてますように「コンポ―ネント(機能の集まり)」です。
      一方、rigidbody2Dというのは、またの名を「GetComponent()」と言います。
      つまり、Rigidbody2Dという機能の集まりにアクセス(GetComponent)する、という意味ですね。
      rigidbody2Dに先ほど触れた時と全く同じことしか書いていないですが、当然です。2つは同じものですからね。

      ではなぜrigidbody2Dというものが生まれたのでしょうか?初心者からすればややこしいものなのに。
      それは「GetComponent()」と何度も書くのがめんどくさいからです。
      他のコンポーネントにアクセス(GetComponent)する、というのはUnityを使う以上、間違い無く何度もすることです。
      何度も使うなら使いやすいようにしちゃおうよ、という発想で生まれたのがrigidbody2Dなどの略語なのです。
      最初はややこしいですが、馴れてしまえばなんてことはありません。むしろ使いやすいと思うはずです。

      ではでは。

  3. きなぎ より:

    とてもわかりやすい説明ありがとうございます!
    例えもわかりやすく、すぐイメージがわきました!
    新しいチュートリアルが今からとても楽しみです。
    C#プロパティはおっしゃるとおり、調べてみていたのですが全然わかりませんでしたw
    これからもとても応援しています!
    ではっ