LoginSignup
10
9

More than 5 years have passed since last update.

Unityちゃんをはしごとバーに対して正しく干渉するようにする

Last updated at Posted at 2014-04-19

前回に続きまして、
ロードランナー風に下記のようなフィールドを作ってその中を動き回れるようにしてみます。

demo1_unity_-_RoadRunner_-_Web_Player.png

Unityちゃんの制御コードやアニメーションなどは美しくないんですが、その辺は今後の課題にしようと思います。

ブロックの座標を調整する

現時点で、ブロックやUnityちゃんが見た目的に調度良いようにするには微妙に座標を調整しないといけません。
例えば、ブロックが(x,y)=(0,0)で、Unityちゃんが(x,y)=(0,1)にいる状態だと下図のように間が開いてしまいます。

demo1_unity_-_RoadRunner_-_Web_Player.png

ブロックを(0,0.5)に配置すればちょうどよいのですが、今後ステージ配置するときにいちいちそういう微調整をしたくありません。
一工夫してみることにします。

空Objectにぶら下げて相対座標をずらす

[GameObject] -> [CreateEmpty] で空のObjectを作ります。名前をBlockPrefabとします(後でPrefab化するので)。
そのBlockPrefabに対して、作っていた Cube をドラッグアンドドロップして子どもとしてぶら下げます。
こんな感じになります。
demo1_unity_-_RoadRunner_-_Web_Player.png

そして、その子供のCubeの属性をInspectorでPositionを(0, 0.5, 0)と設定します。これは親のBlockPrefabに対する相対座標になります。
# そしてPrefab化しておきましょう。

demo1_unity_-_RoadRunner_-_Web_Player_と_Unityちゃんをはしごとバーに対して正しく干渉するようにする.png

こうしておくことで、このBlockを(0,0)に配置したときにUnityちゃんとぴったりくっついて見えるようになります。

んー他に良い方法あるのかなぁ。

はしごを作る

同様に空Objectを一つ作り、そこにいくつかCylinderオブジェクトを並べます。

demo1_unity_-_RoadRunner_-_Web_Player.png

んーこういうのはAssetStoreとかにあるのかな。

Tagを付ける

はしごは今後の当たり判定のときに識別したいので、Tagを付けておきます。Ladderとしておきましょう。
下記の部分から [Add Tag]から付け加えたあと、再度選択すればOKです。

demo1_unity_-_RoadRunner_-_Web_Player.png

当たり判定をTriggerに切り替える

親の子供として、ぶら下がっているObjectは当たり判定を持っています。しかし、力学的な相互作用をさせたくありません(はしごに衝突して押し戻されるというのはおかしい)。そういう場合は、下記のようにisTriggerをチェックしておきます。またここのTagもLadderにしておきます(不要かな・・?)。

demo1_unity_-_RoadRunner_-_Web_Player_と_Unityちゃんをはしごとバーに対して正しく干渉するようにする.png

バーを作る

demo1_unity_-_RoadRunner_-_Web_Player.png

同様にBarを作ります。

  • TagをBarとして付加します。
  • isTrigger を Trueにします
  • Barにはぶら下がっているような位置関係にしたいので、このColliderの座標をずらしておきます。
    • 下記の図ではXのScaleが0.05なので 14というのは 0.7 を表しています(たぶん)

demo1_unity_-_RoadRunner_-_Web_Player_と_Unityちゃんをはしごとバーに対して正しく干渉するようにする.png

位置関係などの微調整は実際に動かしながら確認するのが良いと思います。

フィールドを配置する

適当にフィールドに配置します。冒頭の画像のようにしてみました。

Unityちゃんを小さくする

demo1_unity_-_RoadRunner_-_Web_Player_と_Unityちゃんをはしごとバーに対して正しく干渉するようにする.png

Unityちゃんの大きさが少し大きいので小さくします。 Scaleを全て0.6にするくらいでちょうど良いでしょうか。

スクリプトを更新する

UnityChanDemo1スクリプトを以下のように更新します。
「落下」「はしご」「バー」「地面」という状態によっていろいろ振る舞いを変えないといけません。
なんかフラグがいっぱいになっていて美しくないですね。
Animator側の使い方も併せて今後の課題です。

UnityChanDemo1.cs
using UnityEngine;
using System.Collections;

public class UnityChanDemo1 : MonoBehaviour {
    private const string LADDER = "Ladder";
    private const string BAR = "Bar";
    private const string BLOCK = "Block";

    private Animator animator;

    public int ladderEnter = 0;
    public int barEnter = 0;
    public bool isFalling = false;

    // Use this for initialization
    void Start () {
        animator = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update () {
        bool is_running = false;
        if (!isFalling) { // If Not Falling, can move to Left/Right
            if (Input.GetKey("right")) {
                transform.position += new Vector3(0.05f, 0, 0);
                transform.rotation = Quaternion.Euler(new Vector3(0, 90, 0));
                is_running = true;
            } else if (Input.GetKey ("left")) {
                transform.position += new Vector3(-0.05f, 0, 0);
                transform.rotation = Quaternion.Euler(new Vector3(0, -90, 0));
                is_running = true;
            }
        }
        animator.SetBool("is_running", is_running);

        // if entering in any ladder collision, can move Up/Down
        if (Input.GetKey("up") && ladderEnter > 0) {
                transform.position += new Vector3(0, 0.05f, 0);
        } else if (Input.GetKey("down") && ladderEnter > 0) {
            transform.position += new Vector3(0, -0.05f, 0);
        } else if (Input.GetKey("down") && barEnter > 0) { // if entering in bar and KeyDown, bar are released.
            barEnter = 0;
        }

        // if entering in any ladder or bar, gravity is off
        if (ladderEnter > 0 || barEnter > 0) {
            rigidbody.useGravity = false;
            rigidbody.velocity = Vector3.zero;
        } else {
            rigidbody.useGravity = true;
        }

        // if Velocity.y reach some degree, Falling is True
        if (rigidbody.velocity.y <  -0.05f) {
            isFalling = true;
        } else {
            isFalling = false;
        }
    }

    void OnTriggerEnter(Collider other) {
        switch(other.gameObject.tag) {
        case LADDER:
            ladderEnter += 1;
            break;
        case BAR:
            barEnter += 1;
            break;
        }
    }

    void OnTriggerExit(Collider other) {
        switch(other.gameObject.tag) {
        case LADDER:
            ladderEnter -= 1;
            break;
        case BAR:
            if (barEnter > 0) {
                barEnter -= 1;
            }
            break;
        }
    }
}

今回作ったもの

ここにWebPlayerでPublishしてみました

見ての通り、動くには動きますが、キャラクターのアニメーションなどはかなりおかしいです。
いろいろいじっているんですが、なかなか思い通りにならなくて、元に戻したんですよね。。。
んー、精進せねば。。。

10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9