Unity3DでCharacterControllerを使ってみる

20081112-4

というわけで前回記事「2D TOOLKIT で横スクロールアクション」で挙動がおかしかった理由は Rigidbody ではなく CharacterController を使った方がよかった。ということでした。
接地状態のフラグ更新方法にまだ少し悩み中。

using UnityEngine;
using System.Collections;

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

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

    // オブジェクト初期化
    void Start() {
        // あらかじめオブジェクトに割り当てられたコンポーネントを取得しておく
        oMainCamera = GameObject.Find("MainCamera").GetComponent<Camera>();
        oSprite = GetComponent<tk2dSprite>();
        oAnime = GetComponent<tk2dSpriteAnimator>();
        oController = GetComponent<CharacterController>();
    }

    // オブジェクト更新処理
    void Update() {
        // カメラをめがみんにあわせる
        oMainCamera.transform.localPosition = new Vector3(
            transform.position.x + 0.75f,
            transform.position.y + 0.5f,
            oMainCamera.transform.position.z);
        // パッド入力処理
        v2AxisMove = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
        // 加速度設定
        v3Force.x = isGround ? (v2AxisMove.x) : 0f;
        // ジャンプ
        if (Input.GetAxis("Jump") > 0f) iJumpButtonDownCount++; else iJumpButtonDownCount = 0;
        if (iJumpButtonDownCount == 1 && isGround && iIgnoreJumpCount == 0) {
            v3Speed.y = 0f;
            v3Force.y = fMegaminJumpPower;
            isGround = false;
            iIgnoreJumpCount = iIgnoreJumpCountMax;
        }
        // 横入力無しの時又は反転時に横方向減速
        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, fMegaminSpeed);
        v3Force.y = 0f;
        // 落下
        v3Speed.y -= fMegaminFallSpeed;
        // パッド入力方向によってめがみんを左右反転させる処理
        if (v2AxisMove.x > 0f) {
            oSprite.scale = Vector3.one;
        } else if (v2AxisMove.x < 0f) {
            oSprite.scale = new Vector3(-1f, 1f, 1f);
        }
        // アニメーションコントロール
        if (isGround) {
            if (Mathf.Abs(v3Speed.x) > 1.0f) {
                oAnime.Play("MegaminRun");
            } else {
                oAnime.Play("MegaminNutral");
            }
        } else {
            if (Mathf.Abs(v3Speed.y) > fMegaminFallSpeed) {
                oAnime.Play("MegaminJump");
            }
        }
        // 移動する
        if (v3Speed.magnitude > 0f) {
            oCollisionFlags = oController.Move(v3Speed * Time.deltaTime);
            if ((oCollisionFlags & CollisionFlags.Below) > 0) {
                isGround = true;
                v3Force.y = 0f;
                v3Speed.y = 0f;
            }
        }
        // ジャンプ不可カウントを更新する
        iIgnoreJumpCount += (iIgnoreJumpCount > 0) ? -1 : 0;
    }
}

「シェアする」

ツイートツイート