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

ガレージ暮らしのトライタム

プログラムやツールの解説や技術を公開する場所

Unityでカメラの方向に合わせて移動するプログラム

 デモンズソウル、ダークソウルシリーズ、はたまた別のアクションゲームでよく取り入れられている移動方法を作るプログラムです。

-これで出来ること
カメラの方向に合わせた移動ができます
-これでできないこと
ジャンプができません
 

f:id:traitam:20160602111322p:plain
動きとしては上の画像のような流れになります(図が雑なのはご容赦)。
カメラの回転座標を取得して、その方向を前とします。
そしてその数値をプレイヤーの移動量と掛け合わせてプレイヤーの移動とします。
--

-私の開発環境
 Unity5.3.1f
 Visual Studio 2013

ソースコード

using UnityEngine;
using System.Collections;

public class MoveForPlayer : MonoBehaviour {
    /*参考文献:http://qiita.com/yando/items/c406690c9ad87ecfc8e5
     * StandardAsset ThirdPersonUserControl.cs
     */
    private Transform CamPos;
    private Vector3 Camforward;
    private Vector3 ido;
    private Vector3 Animdir = Vector3.zero;

    float runspeed = 0.2f;

    void Start()
    {
        if (Camera.main != null)
        {
            CamPos = Camera.main.transform;
        }
        else
        {
            Debug.LogWarning(
    "Warning: no main camera found. Third person character needs a Camera tagged \"MainCamera\", for camera-relative controls.");
        }
    }

    void Update()
    {

    }

    private void FixedUpdate()
    {
        //キーボード数値取得。プレイヤーの方向として扱う
        float h = Input.GetAxis("Horizontal");//横
        float v = Input.GetAxis("Vertical");//縦

        //カメラのTransformが取得されてれば実行
        if (CamPos != null)
        {
            //2つのベクトルの各成分の乗算(Vector3.Scale)。単位ベクトル化(.normalized)
            Camforward = Vector3.Scale(CamPos.forward, new Vector3(1, 0, 1)).normalized;
            //移動ベクトルをidoというトランスフォームに代入
            ido = v * Camforward * runspeed + h * CamPos.right * runspeed;
            //Debug.Log(ido);
        }

        //現在のポジションにidoのトランスフォームの数値を入れる
        transform.position = new Vector3(
        transform.position.x + ido.x,
        0,
        transform.position.z + ido.z);

        //方向転換用Transform

        Vector3 AnimDir = ido;
        AnimDir.y = 0;
        //方向転換
        if (AnimDir.sqrMagnitude > 0.001)
        {
            Vector3 newDir = Vector3.RotateTowards(transform.forward,AnimDir,5f*Time.deltaTime,0f);
            transform.rotation = Quaternion.LookRotation(newDir);
        }

    }

}

-説明

private Transform CamPos;
メインカメラポジション保存用トランスフォームです
private Vector3 Camforward;
カメラの向いている方向保存用ベクターです
private Vector3 ido;
プレイヤー移動用ベクターです
private Vector3 Animdir = Vector3.zero;
プレイヤー方向転換用ベクターです(初期化オールゼロ)
float runspeed = 0.2f;
プレイヤー移動量調整用フロートです

    void Start()

この関数内では、メインカメラの取得を行います。
Camera.main.transformでメインカメラのトランスフォームが取得できます。
もしメインカメラという名称が無ければ取得できず、nullを返しエラーを吐く仕組みです。

    void Update()

    private void FixedUpdate()

この関数内では、もしカメラポジションが取れていれば使える関数です。
この内部がこのスクリプトのミソになってます。
この部分だけでカメラの方向に合わせて移動することができます。

以下のUpdate関数内に入っているコードは方向転換させるためのスクリプトです。
一度XとZ座標を取得してから、それを活用して移動している方向に合わせてプレイヤーが回転し、移動している方向を向きます。

-最後に
また、このスクリプトはUnity StandardAsset FreeLookCameraRigというプレハブを活用しています。
これはスタンダードアセットのカメラから使えます。もしスタンダードアセットをDLしていない場合はDLしてください。(アセットに追加したら [Assets -> StandardAssets -> Cameras -> Prefabs -> FreeLookCameraRig] にあります)

プレイヤーには説明したスクリプトを。ヒエラルキーにFreeLookCameraRigを設置し、Free Look Cam.csのアバター選択をプレイヤーアバターに設置すればOKです。