ゴマちゃんフロンティア

気まぐれと勢いで作るUnityゲーム開発日記です

【開発メモ】ステージオブジェクト「トランポリン」の実装

time 2016/08/20

というわけで、世界中がリオ五輪で盛り上がっている今日この頃!
便乗するわけではありませんが、こんなものを実装してみました!

shot2ss20160820213023487

所謂「トランポリン」です!
上に乗ると自動的にジャンプし、ジャンプボタンを押すと大ジャンプします。
割とユニークなギミックなためか、最近のゲームでは見かけなくなった気がします。

既に似たようなシステムとして、「ジャンプエリア」というものを作ってあります。
エリア内に入った状態でジャンプすると大ジャンプができます。
トランポリンとの違いは「判定なのでゲーム上では見えない」「入ってもオートでジャンプせず、手動入力した場合に否応なく大ジャンプ」といった感じです。
トランポリンを作れば要らない気もしますが、消す必要もないのでとりあえず残しておく予定です。

トランポリンのモデリングとジャンプ制御

物がないと始まらないので、トランポリンをモデリングしてみます。

shot2ss20160820213813901

うーん・・・何だかただの机に見えなくもない微妙な感じです。
まあモデリングが下手なのは今に始まったことではないので、気にせずいきます!

shot2ss20160820213611949

Unityへインポート後、各種コライダーを設定します。
外枠部分に MeshCollider、中央部分に BoxCollider を追加し、大きさや位置を微調整します。
本当は円形に合わせてコライダーを設定できればよかったのですが、楕円形のコライダーを作る方法が分からなかったので、BoxCollider でなるべく合うように調整しました。
キャラクターとトランポリンの大きさ的にこれでも問題なかったです。

トランポリンを制御するためのスクリプトを作成します。
ひとまず、「上に乗ったときに自動でジャンプする」動きを目指してみます。

using UnityEngine;
using System.Collections;

public class Trampoline : MonoBehaviour {

    public float jumpHeight;
    public float enemyJumpHeight;

    void OnTriggerEnter(Collider c) {
        if (c.gameObject.tag == "Player") {
            CharacterMotor charMotor = c.GetComponent<Player>().getCharacterMotor();

            charMotor.movement.velocity.y = 0;
            iTween.Stop(c.gameObject);
            charMotor.movement.velocity.y = jumpHeight;
        }

        if (c.gameObject.tag == "Enemy") {
            Rigidbody rb = c.GetComponent<Rigidbody>();
            iTween.Stop(c.gameObject);
            rb.velocity = new Vector3(rb.velocity.x, enemyJumpHeight, rb.velocity.z);
        }
    }
}

プレイヤーキャラは CharacterMotor、敵キャラは Rigibody を使用して制御しているため、処理を分ける必要があります。
ジャンプ時に余計な加速度が掛かっている場合、一度リセットしないと想定以上に吹っ飛んでしまったりします。
「velocity.yを0に設定」「iTween.Stop()で余計なiTweenを停止」はそのためです。
前者はともかく、後者は移動関係以外の iTween も止まってしまったりするので、他に iTween を使っている場合は気を付ける必要がありそうです。

ジャンプボタン押下で大ジャンプする処理

トランポリンと言えば、ジャンプボタン押下時に大ジャンプするものが大半です。
ということで、上のスクリプトを少し修正します。

using UnityEngine;
using System.Collections;

public class Trampoline : MonoBehaviour {

    public float jumpHeight;
    public float inputJumpHeight;

    public float enemyJumpHeight;

    void OnTriggerEnter(Collider c) {
        if (TagUtility.getParentTagName(c.gameObject) == "Player") {
            CharacterMotor charMotor = c.GetComponent<Player>().getCharacterMotor();

            charMotor.movement.velocity.y = 0;
            iTween.Stop(c.gameObject);

            if (Input.GetButton("Jump")) {
                charMotor.movement.velocity.y = inputJumpHeight;
            } else {
                charMotor.movement.velocity.y = jumpHeight;
            }
        }

        if (TagUtility.getParentTagName(c.gameObject) == "Enemy") {
            Rigidbody rb = c.GetComponent<Rigidbody>();
            iTween.Stop(c.gameObject);
            rb.velocity = new Vector3(rb.velocity.x, enemyJumpHeight, rb.velocity.z);
        }
    }
}

超シンプルに「コライダー判定時にジャンプボタンが押されているか」で行きます。
また、自動ジャンプと入力時のジャンプでフィールドを分け、区別できるようにします。
敵には入力で大ジャンプなんてないのでそのままです。

20160820_01

実際に動かすとこんな感じに。
モーションとかはさておき、挙動は問題なさそう。

ただし問題があり、2段ジャンプが有効の場合は2段が優先されてしまい、トランポリンの大ジャンプがなくなってしまいます。
今の実装の2段ジャンプはバグの温床になりえるので、いっそ無効化してしまおうかと思っていたりします。
本格的にやるならトランポリンのジャンプ専用モーションを作り、その間2段ジャンプのステートには遷移しないようにすればいけそうです。

まとめ

そんなわけで、トランポリンと使用時のジャンプ制御について作成してみました!
これでステージを作る際に高低差を激しくしても大丈夫ですね。

スポンサーリンク

down

コメントする



ツイッター