[超初心者向け]Unityチュートリアル「はじめてのUnity」のブロック崩しと同等をC#で::(4)ラケットを動かす

  • 5
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

この解説は

Unityのサイトに昔からあるチュートリアルに、以下があります。
「はじめてのUnity」(旧)
http://tutorial.unity3d.jp/archive/my-first-unity/

これを独自にC#化したものをベースとしています。以下を
この解説は以下の段階があります、前の内容を実行した上でのものとして参照して下さい。現時点(20151026)では、新しい「はじめてのUnity」の玉転がしゲームが公開されています。本サイトのブロック崩しと併せて学習すると広がりがあり、初期の学習にはとても有効です。

プレイヤーが操作出来るラケットを作る

今回は、ゲームでよく使われる操作が出来るものを用意します。玉を打つので、ラケットとしましょう。

ラケットを用意する

上に在るメニューの[GameObject]>[3D Object]>[Cube]を選んで下さい。
Gyazo

これをラケットにします。Inspectorタブで、以下を変更します。

  • 名前を分かりやすいようにracket
  • TransformPositionを中央の手前に:例では(0,0,-6)
  • TransformScaleを横長に:例では(3,1,1)

Gyazo

ラケットを操作可能にする

操作するには入力に関する設定と、入力に反応するScriptが必要になります。

Inputのセッティングをする

メニューから[Edit]>[Project Settings]>[Input]を選びます。
ここで、キーの設定を変えたい場合は、必要に応じて変更しますが、今回はそのままにします。
ここのデータから読み込まれると思って下さい。
Gyazo

RacketRigidbodyコンポーネントを追加する

Racketオブジェクトを選択している状態で、メニューから、[Compornent]>[Physics]>[Rigidbody]を選びます。
Gyazo

プロパティ 説明 今回の設定値 設定すると変化すること
Mass オブジェクトの質量 (単位 : kg)。 50 動き出す反応
Drag 空気抵抗。0 の場合、空気抵抗が 0 30 キーを離してから停止までの減速
Angular Drag 回転する際の空気抵抗。0 の場合、空気抵抗なし。 0 回転なし
Use Gravity 有効にすると、オブジェクトは重力の影響を受けます。 off 重力反応なし
Constraints/Freeze Position 座標の固定 yとzをon 横方向だけ移動
Constraints/Freeze Rotation 回転の固定 xとyとzをon 回転しない

動作の反応を見て、MassDragを調整します。

RacketにScriptコンポーネントを追加する

Racketオブジェクトを選択している状態で、Inspectorタブの一番下にある[Add compornent]をクリックして、Scriptアセットを作成、追加します。ファイル形式はcsを選びます。
Gyazo

Assetタブ内に、Racket.csができているのを確認します。
Gyazo

Racket.csをダブルクリックし、Inputによって力が加わるように変更します。

Racket.cs
using UnityEngine;
using System.Collections;

public class Racket : MonoBehaviour {

    private float accel = 1000.0f;//加える力の大きさ

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {
        //力を加える
        this.GetComponent<Rigidbody>().AddForce(
            transform.right*Input.GetAxisRaw("Horizontal")*accel,
            ForceMode.Impulse);
    }
}

これで動くようになりました。Scriptを説明します。

code 意味 今回の設定
private float accel = 1000.0f; 加える力の大きさ 大きくすると動きが機敏になる
Addforce 力を加えるメソッド
transform.right*Input.GetAxisRaw("Horizontal") * accel 加える力のVector3D 入力の左右×accell
ForceMode.Impulse 力の加え方 'Impulse'で瞬時に

transform.rightは単位ベクトルで、右方向を示します。これに、Input.GetAxisRaw("Horizontal")を乗算しています。Input.GetAxisRaw("Horizontal")の値は、Vector3型で返り、カーソルキーの押下状態で、右と左の向きを-1(左),0(ニュートラル),+1(右)返します。これ以外にキー押下だけでの判定で組み立てることも可能ですが、片側を押しながらもう一方を押すなど同時押しの動作が簡単に出来るので、これを用いるのは有用です。

Racketの動作を調整する

上記でのパラメータは一例として設定していますが、機敏に動かしたい場合などは適宜、調整して下さい。

動作の機敏さなどを変更する

以下を変えることで動作が変化します。

変更対象 変更する部分 設定すると変化すること
Rigidbodyコンポーネント Mass 動き出す反応
Rigidbodyコンポーネント Drag キーを離してから停止までの減速
Racket.cs accel 動く大きさ

ラケットの壁抜けの対応

RigidbodyコンポーネントのMassを小さな値にすると、極端に速くなり壁を抜けてしまいます。こうした現象は、当たり判定によって変わります。画像を更新している時に当たり判定をしている状態がデフォルトで、「その瞬間に物体が重なり合ってるか」で判定します。この場合、物体の速度が速く、左右のLeftWall,RightWallの大きさを飛び越える速度で動くと、壁を抜けていきます。
これに対処するには、いくつか考え方があります。

壁を抜けない状態でとどまるよう速度を考えて調整する

壁を抜けない程度に速度を抑える事で、当たり判定を変えないままでも可能になります。今の動き方では、端から端に移動し続けると最大速度になるので、それで抜けなければ問題ありません。

その他の方法(参考)

他には、こうした方法があります。

当たり判定を継続的に行い精度を高める

どちらを選択するかは考え方次第です。継続的に当たり判定するには、Rigidbodyコンポーネントで、以下の設定を行います。これで壁は抜けませんが、少し処理が重くなります。
Gyazo

壁の大きさ、或いは当たり判定領域(Colliderコンポーネント)を大きくする

速度よりも大きな幅を持った壁にする、あるいはColliderコンポーネントを大きくすると、当たり判定がおおきくなって抜けなくなる可能性が高まります。

壁を抜けない状態でとどまるよう矯正する

壁よりも外側に在る場合に内側の座標にx座標を強制的に戻す、最大速度を抑える等の方法があります。確実な方法になりますが、動作が物理的にならないので、ぎこちなくなる場合もあります。

Ballの壁抜けの対応

RacketBallも衝突するので、Ballも考慮する必要があります。BallRigidbodyコンポーネントのCollidion Detectionも、変更すると確実になります。


まとめ

  • プレイヤーが動かす物体は、Inputから得られる情報で力を加えると、操作できる
  • 当たり判定は、その瞬間だけで判定していると、速度が速い場合は抜けてしまう
  • 当たり判定は継続的に判定も可能になるが、動作が重くなる場合もあるので注意する

この解説は以下の段階があります、前の内容を実行した上でのものとして参照して下さい。