こんにちは!Unityの入門書で通称”ヒヨコ本”として親しまれている”Unity5入門 最新開発環境による簡単3D&2Dゲーム制作 “の作例に色々とゲーム要素を追加してオリジナルゲームに仕上げる内容を連載をしています。
前回は”ゲームスコアを画面に表示する“を行いました。今回はボールが接触するとスコアを加算するオブジェクトを作成してみたいと思います。
まず、[Hierarchy]ウィンドウ > [Create] > 3D Object > Cube を選択。
オブジェクト名を”Spinner”に変更します。
[Hierarchy]ウィンドウ > Spinner を選択。[Inspector]ウィンドウ > Transformコンポーネントのプロパティを次のように調整します。配置したオブジェクトを[Game]ビューで確認するとこんな感じです。(タイトル画面は非表示にしてあります)
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Spinner : MonoBehaviour { // 加算するスコアの値を格納する変数 public int scorePoint; // 接触した時の処理 void OnCollisionEnter(Collision collision) { // スコアを加算 //(スクリプト"Manager"の変数"score"を変更) Manager.score += scorePoint; } }
ゲームを再生して動作を確認。オブジェクト”Spinner”にボールが接触した時に右上のスコア表示が変わって加算されたらOKです。
配置したオブジェクト”Spinner”を回転させてスコアの加算にタイミングの要素を追加してみます。
[Project]ウィンドウ > スクリプト”Spinner”をダブルクリックでエディタで開き、9-28行目を変更します。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Spinner : MonoBehaviour { // 加算するスコアの値を格納する変数 public int scorePoint; // オブジェクト角度 public float objRot; // 回転速度 public float speed; // ゲーム実行中の処理 void Update() { // 回転角度が360度以上、もしくは-360度以下の場合 if (objRot > 360 || objRot < - 360) { // 回転角度を"0"にする objRot = 0; } // 回転角度"spin"を加算する(回転速度"speed"を乗算) objRot += Time.deltaTime * speed; // オブジェクトを回転する //(角度のz値に回転角度"spin"を代入する) transform.rotation = Quaternion.Euler(0, 0, objRot); } // 接触した時の処理 void OnCollisionEnter(Collision collision) { // スコアを加算 //(スクリプト"Manager"の変数"score"を変更) Manager.score += scorePoint; } }
ゲーム実行中の処理でオブジェクトの角度を加算して回転しますが、変数値がどんどん増えてしまうのが気になるので、360度または-360度を超えるといったん0度に戻しています。
オブジェクト”Spinner”にボールが接触するとわずかに押し戻されるので得点が増える場合がありますね。
ちょっと物足りないので、ピンボールのように跳ね返る設定を追加してみましょう。
[Project]ウィンドウ > スクリプト”Spinner”をダブルクリックでエディタで開き、13-14行目と38-42行目を変更します。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Spinner : MonoBehaviour { // 加算するスコアの値を格納する変数 public int scorePoint; // オブジェクト角度 public float objRot; // 回転速度 public float speed; // オブジェクトに力を加える力と方向の値 public Vector3 thrust; // ゲーム実行中の処理 void Update() { // 回転角度が360度以上、もしくは-360度以下の場合 if (objRot > 360 || objRot < - 360) { // 回転角度を"0"にする objRot = 0; } // 回転角度"spin"を加算する(回転速度"speed"を乗算) objRot += Time.deltaTime * speed; // オブジェクトを回転する //(角度のz値に回転角度"spin"を代入する) transform.rotation = Quaternion.Euler(0, 0, objRot); } // 接触した時の処理 void OnCollisionEnter(Collision collision) { // スコアを加算 //(スクリプト"Manager"の変数"score"を変更) Manager.score += scorePoint; // 接触したオブジェクトの"Rigidbody"コンポーネントを取得して変数"rb"に格納 Rigidbody rb = collision.gameObject.GetComponent<Rigidbody>(); // 変数"thrust"の値の強さと方向にボールに力を加える //(変数"rb"に格納された""Rigidbody"コンポーネント"に力を加える) rb.AddForce(thrust , ForceMode.Impulse); } }
オブジェクト”Spinner”にボールが接触すると右上方向に跳ね返ります。ボールを発生させるタイミングによって接触と跳ね返りがループする場合があるので変数の値を調整した方がいいですね。
オブジェクト”Spinner”の設定ができたのでプレハブ化して複数配置。
回転の速い”Spinner”は得点を少なく、回転の遅い”Spinner”は得点を多くしてみました。
左上の”Spinner_1″
右側の”Spinner_2″
左下の”Spinner_3″
[Game]ビューでみるとこんな感じです。ここまでの内容をWebGLでビルドしてみました。スコアが加算されるようになったのでゲームらしくなってきました。
View Comments
manager.score += scorePointでエラーが出ましたパブリックって書きますか
コメントありがとうございます!
"Manager.score"はスクリプト"Manager"に書いている変数"score"ですが、他のスクリプトから参照するために"public static int score"と書いています。
質問いただいたコメントでは"Manager.score"の"M"が小文字で書かれていますがスペル間違いはないでしょうか?
解決しない場合、[Console]ウィンドウに表示されるエラーメッセージをコメントに書いてもらえば、エラーの原因を推測できると思います。
小文字にするとエラーが出ました
スクリプトファイル"Manager"のファイル名のつづりは正しいでしょうか?
解決しない場合、[Console]ウィンドウに表示されるエラーメッセージをコピー&ペーストでコメントに書いてもらえば、エラーの原因を推測できると思います。
すみませんが漢字読めないので教えてください!
いつまこのサイトを見ています!
Managerはどのスクリプトに書きますか?
コメントありがとうございます!
スクリプトファイル"Manager"の内容は過去の記事 http://corevale.com/unity/3298 で紹介しています。
解決しない場合、[Console]ウィンドウに表示されるエラーメッセージをコピー&ペーストでコメントに書いてもらえば、エラーの原因を推測できると思います。
すみませんが漢字読めないので教えてください!
いつもありがとうございます!