【第3回】斜方投射でボールを打ち出してみるUnityチュートリアル
- 2018.04.09
- Unityチュートリアル
- Unity, チュートリアル

自由落下する物体の作り方、物体の跳ね返りについて紹介しましたが、今回は鉛直方向の動きだけではなく、斜めにボールを打ち上げる動きを作ってみます。
物理で言う所の斜方投射。前回までと違って、重力だけでなく、別の外力を加える必要があります。
そう、スクリプトデビューのお時間です。このブログではC#を使ってスクリプトを書いていきます。
といってもそんなに難しい機能を入れる予定ではなく、ゲームを実行するとボールが飛んでいく、くらいの機能です。
前回までのチュートリアルはこちら。
今回の目的
ゲームを実行するとボールが斜方投射される機能を作ります。
今回は動きを確認するのがメインの目的なので、スクリプトを書いてゲーム実行時に斜方投射を確認してみます。
プロジェクトの準備
上の記事で作ったプロジェクトがそのまま使えます。
このページに先にたどり着いた方は、先に上の記事をご覧いただくといいかもしれません。
オブジェクトの配置換え
斜方投射が見やすいように、これまで配置したオブジェクト達をちょっと模様替え。
地面を大きくする
斜方投射だと水平方向の運動が生まれるので、地面を大きくしておきます。
今回カメラに写したいのは物理っぽくX-Y平面。なので、『Scene』ウィンドウの右上にあるシーンギズモを使ってそれっぽく画面を表示します。

シーンギズモは、『Scene』ウィンドウが映し出す向きを軸に合わせて素早く変えてくれる便利な仕掛け。Gizmoは小さい仕掛けとか装置といった意味の言葉です。
私の場合はグレムリンに出てくるアレとかドラクエに出てくるアレが先に思い浮かびます。メラ連打はトラウマ。
さて、シーンギズモでは、選択した軸がこちらを向くようになります。今回は画面奥がZ軸の+方向になるように、青い部分の反対側を選択しましょ。こんな感じになればOK。

この方向に合わせて地面を伸ばしていきます。『Plane』オブジェクトを選択し、TransformにあるPositionのXを15に、ScaleのXを4にします。

地面の大きさを変えた後は、画面左上にあるハンドツールを使って表示位置を変えたり、マウスのホイールなどを使って拡大・縮小して見やすくします。

球の初期位置を変更
球の初期位置も変えておきます。地面から打ち上げられる感じにしたいので、高さを修正。
『Sphere』オブジェクトを選択し、Transform内にあるPositionのYを0.5にします。UnityのSphereはデフォルトで直径が1(単位はメートル)になっているので、高さを0.5にしておくとちょうど地面の上に接している状態になります。

カメラの位置も変更
カメラの位置も忘れずに変更しておきます。上で表示した『Scene』ウィンドウのような画面になるようにしましょ。
『Main Camera』オブジェクトを選択し、Transform内にあるPositionのXを15、Yを4、Zを-20にします。

『Game』画面はだいたいこのような感じになりました。次はいよいよスクリプトを書きます。

スクリプトの作成
UnityではC#とJavascriptでスクリプトを書くことができるのでお好きな方を……と言いたいところですが、私がC#を使っているので、このブログではC#でスクリプトを書いていきます。
まずはスクリプトファイルを作成することから。これもUnityの『Project』ウィンドウから作成できます。
整理のために『Scripts』フォルダを作成しておくと後で楽ですね。という訳で、『Project』ウィンドウ内で右クリックまたは二本指タップし、表示されるコンテキストメニューから、[Create] -> [Folder]でフォルダを新規作成します。名前は『Scripts』にしましょ。
『Scripts』フォルダを開いて、同様にコンテキストメニューを開き、[Create] -> [C# Script]を選択。
名前は『SphereBooster』にしましょうか。

出来上がったファイルをダブルクリックすると、エディタでSphereBooster.csが開かれます。

スクリプトのファイルを作成した直後は、デフォルトで以下のようになります。
Start()は、このスクリプトファイルがアタッチされているオブジェクトがActiveになった時、初期化処理として呼ばれる関数です。
……いきなり何言ってんだこいつ。ざっくり言うと初期化のために呼ばれる関数だと思っていれば大丈夫です。スクリプトは、前回のRigidbodyのようにゲームオブジェクトにアタッチできます。今回は最初からシーンに存在している『Sphere』オブジェクトにアタッチする予定なので、ゲーム開始直後に呼ばれる処理だと思ってもらえればOKです。
Update()は毎フレーム呼ばれる関数です。例えば『Sphere』オブジェクトの位置を画面に表示する必要がある時に、このUpdate()メソッドに位置を出力する処理を書いておけば、毎フレームこのUpdate()が呼ばれるので画面に出力し続けてくれます。
これらの関数については、イベント関数としてUnityのマニュアルに記載されているので、こちらも合わせてご参照ください。チュートリアルの中でも触れていきますが、公式の情報に勝るものはありません。
力を加えるには
いよいよスクリプトから物体に外力を加えます。
力を加えるために必要なメソッドは、Rigidbodyコンポーネントに含まれるAddForceメソッド。名前通り力を加えるメソッドです。リファレンスはこちら。
今回は動きを確認することがメインの目的なので、Start()の中に直接書いちゃいましょ。
コメントにも書いてありますが、上から順番に説明をば。
Vector3型について
RigidbodyのAddForceで力を加えるために、力の大きさを渡す必要があります。そのため、Vector3型のforceDirectionで力の向きを定義し、float型のforceMagnitudeで力の大きさを定義しています。
しれっとVector3型を使っていますが、Vector3型はUnityにおいて3Dベクトルと位置を表現してくれるstruct。
左からx, y, zを表しています。Transformコンポーネント内にあったPositionやRotation, ScaleもVector3で表現されています。
今回の例だとx軸方向に1、y軸方向にも1、z軸方向は0として定義しています。
(10.0f, 10.0f, 0f)のように力の大きさを一緒に定義してもいいのですが、後で力の大きさを変えたくなった時にVector3の3つの値を毎回修正するのはだるいのでこの形にしています。
float型への代入
float型に代入する値に『f』を付けているのは、float型だと宣言するため。『f』を付けないとdouble型として扱われるため、コンパイルエラーになります。
参照の取得
AddForceを使うためにはRigidbodyコンポーネントへの参照を取得しないといけません。そのために用意されているのがGetComponentです。
gameObjectはこのスクリプトがアタッチされているゲームオブジェクト、<Rigidbody>はそのゲームオブジェクトにアタッチされているRigidbodyを取得するよ、といったことを表しています。あ、『Sphere』オブジェクトにこのスクリプトをアタッチするのはこのあとね。
AddForceを使う
Rigidbodyへの参照を取得したらいよいよAddForceを使います。引数は力の大きさと向きを表すVector3型の値と、力の加わり方の設定。
力の大きさと向きは変数forceで定義しているのでそれを渡します。
力の加わり方は、ForceModeから選べます。今回はImpulse(撃力)を選択しました。
スクリプトをアタッチ
『SphereBooster.cs』を上記のように編集したら、保存してUnityに戻ります。
スクリプトをアタッチしたいので、『Sphere』オブジェクトを選択し、[Add Component] -> [Scripts] -> [Sphere Booster]と選択していきます。

これで『Sphere』オブジェクトにスクリプトがアタッチされました。

んじゃ早速テストしてみましょ。いつものように、[▶︎]を押してゲームを実行します。

よしよし、無事に斜方投射ができました。
気になる点としては、ゲーム開始直後の運動がカクつくことでしょうか。Start()に処理を全部入れているので、裏で動いている処理と重なって重くなるんですよねぇ……。
という訳で、次回は画面上のボタンを押した時にボールが飛んでいく処理を実装してみます。
まとめ
ゲームを開始するとボールが斜方投射される機能を作りました。
今回からいよいよスクリプトを書くこととなりましたが、初心者の方はコピペではなく手打ち推奨。内容が一旦自分の頭を通るので、記憶に残りやすくなりますからね。
動きは確認できたので、次からはゲーム開始直後だけではなく、ボタンなどを使って任意のタイミングでボールを飛ばせるようにします。
ゲーム開発の攻略チャートを作りました!
-
前の記事
GitHubとSourcetreeをSSHで連携させたログと注意点など 2018.04.08
-
次の記事
【第4回】キー入力でボールを斜方投射するUnityチュートリアル 2018.04.09
コメントを書く