今回はUnityのアクションゲームで登場することがある透明な床と壁を作っていきたいと思います。
アクションゲームのダンジョン等で一部の床が一定時間毎に透明になって行く先を混乱させたり、先に行けそうなのに透明な壁によって侵入不可能な領域を
見たことがあると思います。
Unityではこれが簡単に出来てしまいます(^_^)v
透明になる床は一定時間毎に透明な床になったり普通の床になったりを繰り返させますが、その時間間隔をインスペクタで設定できるようにします。
また、床が透明になった時に透明な床の上を歩けるか歩けないかも設定出来るようにし、透明な床の種類を選択出来るようにもしてみましょう。
透明にする床を含んだ移動出来るフロアを作成する
まずはCubeを繋げて移動出来るフロアを作成していきます。
空オブジェクトを作成し名前をTransparent Floorとします。
その子要素にCubeを使って透明な床を含んだステージを作成していきます。
Transparent Wallという名前にした部分は通常は見えるようにしておいて、ゲーム開始時に透明にして見えない壁にする予定のゲームオブジェクトです。
↑が作成したステージです。
左右の壁になっている部分がTransparent Wallで編集中は他のゲームオブジェクトと同じように表示しておき、ゲーム中は見えない壁となる部分です。
現時点ではスクリプトを設定していないのでただの壁となっています。
透明な床や壁にする為のスクリプトTransparentFloorの作成
それでは透明にしたい壁や床に設定するTransparentFloorスクリプトを作成していきましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | using UnityEngine; using System.Collections; public class TransparentFloor : MonoBehaviour { // 透明フロアのタイプ public enum FloorType { alwaysTransparent, // 通れない壁 sometimesTransparentAndCollider, // 透明時には接触も出来ない sometimesTransparent, // 透明時に接触は出来る }; // 透明フロアのタイプ [SerializeField] private FloorType floorType; // 透明になる間隔時間 [SerializeField] private float transparentTime = 2f; // 床の状態が変化してからの時間 private float nowTime = 0f; // 見た目表示コンポーネント private MeshRenderer mesh; // 床のコライダ private Collider col; void Start() { mesh = GetComponent<MeshRenderer>(); col = GetComponent<Collider>(); // 透明フロアのタイプが常に透明であれば表示コンポーネントを無効化 if (floorType == FloorType.alwaysTransparent) { mesh.enabled = false; } } void Update() { // いつも透明な場合は以降何もしない if (floorType == FloorType.alwaysTransparent) { return; } // 時間計測 nowTime += Time.deltaTime; // 床が透明になる間隔時間を超えたら if (nowTime >= transparentTime) { // 表示コンポーネントを反転 mesh.enabled = !mesh.enabled; // 透明時に接触も出来ないタイプの場合はコライダも反転 if (floorType == FloorType.sometimesTransparentAndCollider) { col.enabled = !col.enabled; } nowTime = 0f; } } } |
TransparentFloorスクリプトの解説
それではスクリプトの中身を見ていきましょう。
1 2 3 4 5 6 7 8 | // 透明フロアのタイプ public enum FloorType { alwaysTransparent, // 通れない壁 sometimesTransparentAndCollider, // 透明時には接触も出来ない sometimesTransparent, // 透明時に接触は出来る }; |
透明フロアのタイプを列挙型変数FloorTypeとして宣言しておきます。
このタイプはインスペクタで設定出来るようにします。
1 2 3 4 5 6 7 8 9 10 | void Start () { mesh = GetComponent<MeshRenderer>(); col = GetComponent<Collider>(); // 透明フロアのタイプが常に透明であれば表示コンポーネントを無効化 if(floorType == FloorType.alwaysTra) { mesh.enabled = false; } } |
Startメソッドでゲームオブジェクトの表示を担当しているMeshRendererとColliderを取得します。
ゲームオブジェクトに設定されているコライダはSphereColliderやBoxCollider、CapsuleCollider等が設定されていますが、
これらをまとめて使用出来るようにする為にこれらのコライダの親クラスであるColliderで取り扱っています。
つまり、ざっくりまとめて取り扱う多態性を使います。
例えば、カメの名前に『太郎』や『花子』と付けているけど、ざっくり『カメ』として取り扱っています。
透明フロアのタイプがFloorType.alwaysTraだった時はただの透明な壁として使用する為にMeshRendererコンポーネントを無効化します。
コンポーネントの無効化は
1 2 3 | コンポーネント.enabled = false; |
で出来ます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | void Update() { // いつも透明な場合は以降何もしない if (floorType == FloorType.alwaysTransparent) { return; } // 時間計測 nowTime += Time.deltaTime; // 床が透明になる間隔時間を超えたら if (nowTime >= transparentTime) { // 表示コンポーネントを反転 mesh.enabled = !mesh.enabled; // 透明時に接触も出来ないタイプの場合はコライダも反転 if (floorType == FloorType.sometimesTransparentAndCollider) { col.enabled = !col.enabled; } nowTime = 0f; } } |
UpdateメソッドではFloorType.alwaysTransparentの時はそれ以降の処理をしないようにします。
時間を計測し透明フロアタイプがFloorType.alwaysTra以外の時に透明時間間隔を超えていたら
ゲームオブジェクトのMeshRendererを無効化し、透明時に接触出来なくする床FloorType.sometimesTransparentAndColliderであればコライダコンポーネントも無効化にしています。
これでスクリプトが完成しました。
透明な床ステージを試してみましょう
さきほど作成したステージの床と壁のいくつかにスクリプトを設定しfloorTypeを設定します。
Transparent Wallという名前にした壁のTransparentFloorスクリプトのfloorTypeはalwaysTransparentにし、見えない壁とします。
透明にしたい床のいくつかにスクリプトを取りつけインスペクタのfloorTypeにsometimesTransparentとsometimesTransparentAndColliderを設定してください。
それではUnityの実行ボタンを押して透明な床があるステージの上をキャラクターを動かして確認してみましょう。
↑のようにUnity実行中は壁が透明な壁となり、手前の透明になる床はfloorTypeにsometimesTransparentを設定し透明時に乗れる床にしました。
奥の床はfloorTypeにsometimesTransparentAndColliderに設定したので透明時にコライダも無効化される為キャラクターが載っていると下に落とされます。
透明な床や壁の作成はコンポーネントを無効化するだけなので意外と簡単に実装出来ましたね(^_^)v
ゲームステージで見た目として先があるように見せたいけど実際はキャラクターにそれ以上進ませないようにする時透明な壁を作成し、実現する事も出来ます。