前回に続きまして、
ロードランナー風に下記のようなフィールドを作ってその中を動き回れるようにしてみます。
Unityちゃんの制御コードやアニメーションなどは美しくないんですが、その辺は今後の課題にしようと思います。
ブロックの座標を調整する
現時点で、ブロックやUnityちゃんが見た目的に調度良いようにするには微妙に座標を調整しないといけません。
例えば、ブロックが(x,y)=(0,0)で、Unityちゃんが(x,y)=(0,1)にいる状態だと下図のように間が開いてしまいます。
ブロックを(0,0.5)に配置すればちょうどよいのですが、今後ステージ配置するときにいちいちそういう微調整をしたくありません。
一工夫してみることにします。
空Objectにぶら下げて相対座標をずらす
[GameObject] -> [CreateEmpty] で空のObjectを作ります。名前をBlockPrefab
とします(後でPrefab化するので)。
そのBlockPrefabに対して、作っていた Cube をドラッグアンドドロップして子どもとしてぶら下げます。
こんな感じになります。
そして、その子供のCubeの属性をInspectorでPositionを(0, 0.5, 0)と設定します。これは親のBlockPrefab
に対する相対座標になります。
# そしてPrefab化しておきましょう。
こうしておくことで、このBlockを(0,0)に配置したときにUnityちゃんとぴったりくっついて見えるようになります。
んー他に良い方法あるのかなぁ。
はしごを作る
同様に空Objectを一つ作り、そこにいくつかCylinderオブジェクトを並べます。
んーこういうのはAssetStoreとかにあるのかな。
Tagを付ける
はしごは今後の当たり判定のときに識別したいので、Tagを付けておきます。Ladder
としておきましょう。
下記の部分から [Add Tag]から付け加えたあと、再度選択すればOKです。
当たり判定をTriggerに切り替える
親の子供として、ぶら下がっているObjectは当たり判定を持っています。しかし、力学的な相互作用をさせたくありません(はしごに衝突して押し戻されるというのはおかしい)。そういう場合は、下記のようにisTrigger
をチェックしておきます。またここのTagもLadder
にしておきます(不要かな・・?)。
バーを作る
同様にBarを作ります。
- Tagを
Bar
として付加します。 - isTrigger を Trueにします
- Barにはぶら下がっているような位置関係にしたいので、このColliderの座標をずらしておきます。
- 下記の図ではXのScaleが0.05なので 14というのは 0.7 を表しています(たぶん)
位置関係などの微調整は実際に動かしながら確認するのが良いと思います。
フィールドを配置する
適当にフィールドに配置します。冒頭の画像のようにしてみました。
Unityちゃんを小さくする
Unityちゃんの大きさが少し大きいので小さくします。 Scaleを全て0.6にするくらいでちょうど良いでしょうか。
スクリプトを更新する
UnityChanDemo1スクリプトを以下のように更新します。
「落下」「はしご」「バー」「地面」という状態によっていろいろ振る舞いを変えないといけません。
なんかフラグがいっぱいになっていて美しくないですね。
Animator側の使い方も併せて今後の課題です。
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;
}
}
}
今回作ったもの
見ての通り、動くには動きますが、キャラクターのアニメーションなどはかなりおかしいです。
いろいろいじっているんですが、なかなか思い通りにならなくて、元に戻したんですよね。。。
んー、精進せねば。。。