2D TOOLKIT でメトロヴァニア4

20110825-1

■■■■■ 今回はソース解説 ■■■■■

まだ作りかけですが現時点でのキャラクター制御のソースコードを公開してみます。

解説はコメントに書かれています。2D TOOLKIT 依存の部分を削除すれば普通のゲームオブジェクトでも動きます。

■■■■■ みょん本体 ■■■■■

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(CharacterController))]
public class Player : MonoBehaviour {

    tk2dSprite oSprite = null;          // スプライト
    tk2dSpriteAnimator oAnime = null;   // アニメ
    CharacterController oController = null; // キャラクタコントローラ
    CollisionFlags oCollisionFlags = CollisionFlags.None; // 衝突判定情報
    Camera oMainCamera = null;          // カメラ
    Vector2 v2AxisMove = Vector2.zero;  // パッド入力
    Vector3 v3Force = Vector3.zero;     // 内部加速度
    Vector3 v3Speed = Vector3.zero;     // 内部速度
    bool isGround = false;              // 接地状態
    int iIgnoreJumpCount = 0;           // ジャンプ不可タイム
    int iIgnoreJumpCountMax = 5;        // 最大ジャンプ不可タイム
    int iJumpButtonDownCount = 0;       // ジャンプボタン押下カウンタ

    // モーションによってプレイヤーの所属レイヤーを切り替えるためのプロパティ
    public int iMegaminNormalLayer = 8;     // 通常レイヤー
    public int iMegaminJumpLayer = 9;       // ジャンプ中レイヤー
    public int iMegaminSlidingLayer = 10;   // スライディング中レイヤー

    // プレイヤーの基本スペックプロパティ
    public float fMegaminSpeed = 4f;         // 横速度
    public float fMegaminJumpPower = 11f;    // ジャンプ力
    public float fMegaminFallSpeed = 0.31f;  // 落下速度

    // 2D TOOLKIT 用のモーション定義
	public string stAnimeNeutral = "YoumuStand";    // ニュートラルモーション
	public string stAnimeWalk = "YoumuWalk";        // 歩き
	public string stAnimeRun = "YoumuRun";          // 走り
	public string stAnimeJumpUp = "YoumuRun";       // ジャンプ(上昇中)
	public string stAnimeJumpDown = "YoumuRun";     // ジャンプ(下降中)

    // GUIデバッグ用
    GUIStyle oStyle;
    public bool bDebug = true;

    // オブジェクト初期化
    void Start() {
        // あらかじめオブジェクトに割り当てられたコンポーネントを取得しておく
        oSprite = GetComponent<tk2dSprite>();           // 2D TOOLKIT スプライト
        oAnime = GetComponent<tk2dSpriteAnimator>();    // 2D TOOLKIT スプライトアニメーター
        oController = GetComponent<CharacterController>();  // キャラクターコントローラ
        oMainCamera = GameObject.Find("Main Camera").GetComponent<Camera>();    // カメラ

        // デバッグ表示のスタイルを設定(赤色)
        oStyle = new GUIStyle();
        oStyle.normal.textColor = Color.red;
    }

    // オブジェクト更新処理
    void Update() {
		// ボタン判定
		bool isJump = Input.GetButtonDown("Jump");  // 押した瞬間に true
		bool isDash = Input.GetButton("Fire1");     // 押しっぱなしでも true

        // カメラをめがみんにあわせる(カメラ制御は別オブジェクトにすべきですよね~)
        oMainCamera.transform.localPosition = new Vector3(
            transform.position.x,
            transform.position.y + 0.5f,
            oMainCamera.transform.position.z);

        // パッド入力のベクトルを取得
        v2AxisMove = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));

        // 加速度設定
        //v3Force.x = isGround ? (v2AxisMove.x) : 0f;               // 空中制御できない
        v3Force.x = isGround ? (v2AxisMove.x) : (v2AxisMove.x);     // 空中制御ができる

        // ジャンプ
        if (isJump) iJumpButtonDownCount++; else iJumpButtonDownCount = 0;  // この処理は不要かも(名残)
        if (iJumpButtonDownCount == 1 && ((oCollisionFlags & CollisionFlags.Below) > 0) && iIgnoreJumpCount == 0) {
            v3Speed.y = 0f;
            v3Force.y = fMegaminJumpPower * (isDash ? 1.2f : 1.0f); // ジャンプ力(Y初速度)
            isGround = false;   // 接地フラグOFF
            iIgnoreJumpCount = iIgnoreJumpCountMax; // 連続ぴょんぴょん防止用カウンタ
			oAnime.Play(stAnimeJumpUp); // 2D TOOLKIT モーション設定
        }

        // 横入力無しの時又は反転時に横方向減速
        if (v2AxisMove.x == 0 || Mathf.Sign(v2AxisMove.x) != Mathf.Sign(v3Speed.x)) v3Speed.x *= 0.5f;

        // 加速と最高速度抑制
        v3Speed += v3Force;
        v3Speed.x = Mathf.Clamp(v3Speed.x, -fMegaminSpeed * (isDash ? 2f : 1f), fMegaminSpeed * (isDash ? 2f : 1f));
        v3Force.y = 0f; // ジャンプ初速を足したらリセットする(ロケットのように飛んじゃうから)

        // 落下
        v3Speed.y -= fMegaminFallSpeed;

        // パッド入力方向によってキャラクタを左右反転させる処理
        if (v2AxisMove.x > 0f) {
            transform.localScale = Vector3.one;
        } else if (v2AxisMove.x < 0f) {
            transform.localScale = new Vector3(-1f, 1f, 1f);
        }

        // アニメーションコントロール
        if (isGround) {
            if (Mathf.Abs(v3Speed.x) > 1.0f) {
				oAnime.Play(isDash ? stAnimeRun : stAnimeWalk);
            } else {
				oAnime.Play(stAnimeNeutral);
            }
		} else {
			if (v3Speed.y < 0f) {
				oAnime.Play(stAnimeJumpDown);
			}
		}

        // 移動する
        if (v3Speed.magnitude > 0f) {
            oCollisionFlags = oController.Move(v3Speed * Time.deltaTime);
            if ((oCollisionFlags & CollisionFlags.Below) > 0) {
                isGround = true;
                v3Force.y = 0f;
                v3Speed.y = 0f;
            }
        }
        // Z軸方向にずれたら補正する
        transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y, 0);
        // ジャンプ不可カウントを更新する
        iIgnoreJumpCount += (iIgnoreJumpCount > 0) ? -1 : 0;

        // ジャンプ状態によってレイヤーを切り替える
        // (ジャンプ中はすり抜ける足場と当たり判定を行わないようにする処理)
        gameObject.layer = (v3Speed.y > 0f) ? iMegaminJumpLayer : iMegaminNormalLayer;
    }

    void OnGUI() {
        if (!bDebug) return;
        GUILayout.BeginArea(new Rect(8, 8, Screen.width - 16, Screen.height - 16));
        GUILayout.Label("isGround      : " + (isGround ? "On" : "Off"), oStyle);
        GUILayout.Label("Speed         : " + v3Speed.ToString(), oStyle);
        GUILayout.Label("Force         : " + v3Force.ToString(), oStyle);
        GUILayout.Label("Above         : " + ((oCollisionFlags & CollisionFlags.Above) > 0 ? "On" : "Off"), oStyle);
        GUILayout.Label("Below         : " + ((oCollisionFlags & CollisionFlags.Below) > 0 ? "On" : "Off"), oStyle);
        GUILayout.Label("Sides         : " + ((oCollisionFlags & CollisionFlags.Sides) > 0 ? "On" : "Off"), oStyle);
        GUILayout.Label("CollidedAbove : " + ((oCollisionFlags & CollisionFlags.CollidedAbove) > 0 ? "On" : "Off"), oStyle);
        GUILayout.Label("CollidedBelow : " + ((oCollisionFlags & CollisionFlags.CollidedBelow) > 0 ? "On" : "Off"), oStyle);
        GUILayout.Label("CollidedSides : " + ((oCollisionFlags & CollisionFlags.CollidedSides) > 0 ? "On" : "Off"), oStyle);
		GUILayout.EndArea();
    }
}

■■■■■ みょん腕 ■■■■■

こちらはアタッチポイントで本体に接続された腕用のスクリプトです。

攻撃ボタンで剣を振り、振り終わると元のニュートラルモーションへ戻ります。剣の振り終わりの検知は 2D TOOLKIT でデリゲートが用意されているのでモーションのリセットが行えます。

using UnityEngine;
using System.Collections;

public class PlayerHand : MonoBehaviour {

	tk2dSpriteAnimator oAnime = null;   // アニメ

	// Use this for initialization
	void Start () {
		// あらかじめオブジェクトに割り当てられたコンポーネントを取得しておく
		oAnime = GetComponent<tk2dSpriteAnimator>();
	}

	// Update is called once per frame
	void Update () {
		// ボタン判定
		bool isAttack = Input.GetButtonDown("Fire2");
		// 剣振り
        // 攻撃ボタン押下且つ、アニメ状態が剣振りでなければ true
		if (isAttack && !oAnime.IsPlaying("HandSwing")) {
            oAnime.Play("HandSwing"); // 剣振りモーション設定
			oAnime.AnimationCompleted = SwingCompleteDelegate;  // モーション終了時デリゲート設定
		}
	}

	// アニメ終了デリゲート
    // モーション再生が終了したらこの関数がコールされる
    // ループアニメだと呼ばれないので注意
	void SwingCompleteDelegate(tk2dSpriteAnimator sprite, tk2dSpriteAnimationClip clip) {
		// 剣構え
		oAnime.Play("HandStand");   // ニュートラルモーション
		oAnime.AnimationCompleted = null;   // デリゲートリセット
	}
}

■■■■■ 次回は ■■■■■

お友達からサウンド周りの事を聞かれたので次回はサウンド周りの記事を書いてみます。そして、タイルマップを使った破壊できる壁の作り方もやってみます。

「シェアする」

ツイートツイート