Unity本の作例改造-Chapter3-11:スコアを加算するオブジェクトをつくる

こんにちは!Unityの入門書で通称”ヒヨコ本”として親しまれている”Unity5入門 最新開発環境による簡単3D&2Dゲーム制作 “の作例に色々とゲーム要素を追加してオリジナルゲームに仕上げる内容を連載をしています。


Chapter1:Unityの概要と基礎知識
Chapter2:インターフェイスと使い方
Chapter3:Unityを使ってみよう!
Chapter4:キャラクターを動かしてみよう!
Chapter5:ゲームのUIを作ってみよう!
Chapter6:ゲームを作ろう!(1)
Chapter7:ゲームを作ろう!(2)
Chapter8:2D機能を使ってみよう!

スコアを加算するオブジェクトを作成する

前回は”ゲームスコアを画面に表示する“を行いました。今回はボールが接触するとスコアを加算するオブジェクトを作成してみたいと思います。

オブジェクトを作成する

まず、[Hierarchy]ウィンドウ > [Create] > 3D Object > Cube を選択。

オブジェクト名を”Spinner”に変更します。

[Hierarchy]ウィンドウ > Spinner を選択。[Inspector]ウィンドウ > Transformコンポーネントのプロパティを次のように調整します。
Position X -3.7 / Y 6.8 / Z 0.7
Rotation X 0 / Y 0 / Z 0
Scale X 0.3 / Y 2 / Z 1.5

配置したオブジェクトを[Game]ビューで確認するとこんな感じです。(タイトル画面は非表示にしてあります)

ボールが接触したらスコアを加算するスクリプトを作成する

[Hierarchy]ウィンドウ > Spinner を選択。[Inspector]ウィンドウ > [Add Component]ボタン > New Scriptを選択して下記の通り入力。[Create and Add]ボタンをクリック。
Name: Spinner / Language: C Sharp

スクリプト”Spinner”を編集する

[Project]ウィンドウ > スクリプト”Spinner”をダブルクリックでエディタで開き、下記コードを入力します。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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;
}
}
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; } }
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;
    }
}

加算するスコアを設定

[Hierarchy]ウィンドウ > Spinner を選択。[Inspector]ウィンドウ > Spinner (Script) > Score Point フィールドにボールが接触した時に加算するスコア値を入力します。今回は”10″を入力しました。

動作確認

ゲームを再生して動作を確認。オブジェクト”Spinner”にボールが接触した時に右上のスコア表示が変わって加算されたらOKです。

オブジェクトの回転を制御するスクリプトを作成する

配置したオブジェクト”Spinner”を回転させてスコアの加算にタイミングの要素を追加してみます。
[Project]ウィンドウ > スクリプト”Spinner”をダブルクリックでエディタで開き、9-28行目を変更します。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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;
}
}
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; } }
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”の回転速度を設定

[Hierarchy]ウィンドウ > Spinner を選択。[Inspector]ウィンドウ > Spinner (Script) > Speed フィールドに回転速度の値を入力します。今回は”100″を入力しました。
プラス値を入れると反時計回り、マイナス値を入れると時計回りに回転します。

動作確認

オブジェクト”Spinner”にボールが接触するとわずかに押し戻されるので得点が増える場合がありますね。

オブジェクト”Spinner”にボールが接触した時に跳ね返るようにする

ちょっと物足りないので、ピンボールのように跳ね返る設定を追加してみましょう。
[Project]ウィンドウ > スクリプト”Spinner”をダブルクリックでエディタで開き、13-14行目と38-42行目を変更します。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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);
}
}
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); } }
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”にボールが接触した時に加える力を設定する

[Hierarchy]ウィンドウ > Spinner を選択。[Inspector]ウィンドウ > Spinner (Script) > Thrust フィールドに値を入力します。今回は右上方向に跳ね返るように X 5、Y 5 を入力しました。

動作確認

オブジェクト”Spinner”にボールが接触すると右上方向に跳ね返ります。ボールを発生させるタイミングによって接触と跳ね返りがループする場合があるので変数の値を調整した方がいいですね。

オブジェクト”Spinner”のプレハブ化して複数配置

オブジェクト”Spinner”の設定ができたのでプレハブ化して複数配置。
回転の速い”Spinner”は得点を少なく、回転の遅い”Spinner”は得点を多くしてみました。

左上の”Spinner_1″

右側の”Spinner_2″

左下の”Spinner_3″

[Game]ビューでみるとこんな感じです。

動作確認

ここまでの内容をWebGLでビルドしてみました。スコアが加算されるようになったのでゲームらしくなってきました。

コメント

  1. ちばしもん より:

    manager.score += scorePointでエラーが出ましたパブリックって書きますか

    • corevale より:

      コメントありがとうございます!
      “Manager.score”はスクリプト”Manager”に書いている変数”score”ですが、他のスクリプトから参照するために”public static int score”と書いています。
      質問いただいたコメントでは”Manager.score”の”M”が小文字で書かれていますがスペル間違いはないでしょうか?
      解決しない場合、[Console]ウィンドウに表示されるエラーメッセージをコメントに書いてもらえば、エラーの原因を推測できると思います。

  2. ちばしもん より:

    小文字にするとエラーが出ました

    • corevale より:

      スクリプトファイル”Manager”のファイル名のつづりは正しいでしょうか?
      解決しない場合、[Console]ウィンドウに表示されるエラーメッセージをコピー&ペーストでコメントに書いてもらえば、エラーの原因を推測できると思います。

  3. ちばしもん より:

    すみませんが漢字読めないので教えてください!
    いつまこのサイトを見ています!

  4. ちばしもん より:

    Managerはどのスクリプトに書きますか?

    • corevale より:

      コメントありがとうございます!
      スクリプトファイル”Manager”の内容は過去の記事 http://corevale.com/unity/3298 で紹介しています。
      解決しない場合、[Console]ウィンドウに表示されるエラーメッセージをコピー&ペーストでコメントに書いてもらえば、エラーの原因を推測できると思います。

  5. ちばしもん より:

    すみませんが漢字読めないので教えてください!
    いつもありがとうございます!