読者です 読者をやめる 読者になる 読者になる

CharacterControllerをつかってプレーヤーを動かす

Unity

昨日はCharacterControllerを使わずにプレーヤーを動かしたので、今回はその逆、CharacterControllerを使ってプレーヤーを動かす方法。

taka8.hateblo.jp

CharacterControllerとは?

前回紹介したので省略。リンクのみ。

Unity - スクリプトリファレンス: CharacterController

MoveとSimpleMove

CharacterController.Move関数


重力をつけてくれない。自分で記述する必要がある。

Unity - スクリプトリファレンス: CharacterController.Move


CharacterController.SimpleMove関数


重力を自動でつけてくれる。単位はメートル毎秒

Unity - スクリプトリファレンス: CharacterController.SimpleMove


CharacterControllerコンポーネント

Capsule Colliderと同じ形をしています。

Center, Radius, Heightに関しては問題ないと思います。

  • Slope Limit
    • 登れる坂の勾配(単位は度)
    • 90°でも壁は登らない
  • Step Offset
    • 登れる階段の高さ
    • 2mの人型なら0.1~0.4の間
  • Skin Width
    • 実際の当たり判定はCenter, Radius, Heightで設定した範囲より大きい
    • Radiusの10%が目安
  • Min Move Distance
    • 最小移動量。0で良い。


Unity - マニュアル: Character Controller

CharacterControllerScript.cs

SimpleMove関数を用いる場合

using UnityEngine;

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

    public float speed = 3.0F;
    public float rotateSpeed = 3.0F;

    private CharacterController controller;

    void Start()
    {

        // コンポーネントの取得
        controller = GetComponent<CharacterController>();

    }

    void Update()
    {

        // 回転
        transform.Rotate(0, Input.GetAxis("Horizontal") * rotateSpeed, 0);

        // キャラクターのローカル空間での方向
        Vector3 forward = transform.transform.forward;

        float curSpeed = speed * Input.GetAxis("Vertical");

        // SimpleMove関数で移動させる
        controller.SimpleMove(forward * curSpeed);

    }

}


Move関数で動かす場合

using UnityEngine;

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

    public float speed = 3.0F;
    public float rotateSpeed = 3.0F;
    public float gravity = 10f;
    public float jumpPower = 5;

    private Vector3 moveDirection;
    private CharacterController controller;

    void Start()
    {

        // コンポーネントの取得
        controller = GetComponent<CharacterController>();

    }

    void Update()
    {

        if (controller.isGrounded)
        {

            // 回転
            transform.Rotate(0, Input.GetAxis("Horizontal") * rotateSpeed, 0);

            // キャラクターのローカル空間での方向
            moveDirection = transform.transform.forward * speed * Input.GetAxis("Vertical");

            // ジャンプ
            if (Input.GetButtonDown("Jump")) moveDirection.y = jumpPower;

        }
        else
        {

            // 重力
            moveDirection.y -= gravity * Time.deltaTime;

        }

        // SimpleMove関数で移動させる
        controller.Move(moveDirection * Time.deltaTime);

    }

}


Move関数を使う場合はジャンプとかができます。SimpleMove関数の場合はできません。
f:id:Taka8:20160904142406g:plain


CharacterController.isGrounded変数はCharacterControllerが地面に接地しているかどうかを返してくれます。ただ精度が悪いです。たまにジャンプできないのはコイツのせいです。


また、Rigidbodyを使っていないので前回のように鉄球に吹っ飛ばされることはできないです。できないとは言っていない

f:id:Taka8:20160904142907g:plain

記述次第で出来ますが、素直に前回のやり方を採用した方が良いでしょう。