Help us understand the problem. What is going on with this article?

Unityで3Dモデルを駆け回る。(インポートされた3Dモデルへの当たり判定付与、一人称視点、視点移動、向いてる方向に進む)

1.はじめに

1.1 経緯

夏休みの自由研究という名のお遊び。(僕たちはもう夏休みです!)

1.2 やりたいこと

大きく分けて問題が三つ
1. Cinema4D(モデリングソフト、有料版)等で作った3DモデルをUnityにインポート。当たり判定を付ける。
2. カメラについてマウスでFPSゲームみたいに視点を移動(一人称視点)
3. プレイヤーオブジェクトについて向いてる方向に移動
こんなんでゲームは作れそうです。

2.インポートしたモデルに当たり判定を付ける。

2.1 モデリングソフト側の設定(割と重要)

モデリングソフト、ツールは問いませんが、オブジェクトファイルにエクスポートできると思います。Blenderで作ったモデルだとUnityはプロジェクトファイルのままでも読み込んでくれますがこれは使用しません。必ず一つのオブジェクトとしてエクスポートしてください。一つのオブジェクトとしてというのは一つのメッシュとしてというのと同義です。後でUnityに配置したときに以下のように子オブジェクトが一つであれば大丈夫です。
image.png

ファイル形式は.objを推奨します。(マテリアルは適応されません)

2.2 当たり判定の付与

2.2.1 アセット「SAColliderBuilder」を導入

このままではオブジェクトがすり抜けてしまいますので当たり判定を付けましょう。しかし、Unityではこの当たり判定の設定、勝手にやってくれないんです。そこで使うのがSAColliderBuilderというアセットです。アセットストアから「SAColliderBuilder」と検索すれば出てきます。Dawnloadしてimportしましょう。

2.2.2 モデルの配置

Sceneディレクトリ内に.objファイルをドラッグアンドドロップして、Hierarchyにそれを配置しましょう。この時2.1の画像のようになってればオッケーです。子オブジェクトが複数あるときは設定しなおしてください。

2.2.3 適応

子オブジェクト(2.1の画像ではdefault)を選択してください。右のInspectorMesh FilterもしくはMesh Renderという項目がなければエクスポートからやり直してください。あればSAColliderBuilderは適応できます。選択した状態でInspectorの一番最後、Add Componentをおして検索窓からSAまで入れると何個かに絞られます。そこでSA Mesh Collinder Builderを選択しましょう。
聖光学院立体モデル案内計画 - SampleScene - PC, Mac & Linux Standalone - Unity 2019.2.0b10 Personal _DX11_ 2019_07_26 19_18_57.png
追加されたコンポーネント内のShape TypeMeshに、Mesh TypeConvex HullにしたらProcessを押して適応を始めましょう。しばらくかかるので少し待ちましょう。
image.png
これで完了です。モデリングの仕方によって当たり判定の範囲が異なりました。特に階段など、一部を切り取る感じでモデリングすると変な当たり判定になります。ですが、当たり判定が想像していた形より小さくなることはないので、メッシュに埋まることはないと思います。

3.視点移動

一人称視点(追従)とマウスによる視点移動を実装します。まとめてCameraSetter.csというファイルにしてしまいましょう。

CameraSetter.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraSetter : MonoBehaviour
{
    // 追従先
    public GameObject Player;
    // 視点回転スピード
    public float RotateSpeed = 0.1f;

    // 追従先との距離ベクトル
    private Vector3 OffsetVector;
    // 追従先のTransform
    private Transform PlayerTransform;

    void Start()
    {
        // 一番最初に一回だけ呼ばれる。
        // 追従先との距離を覚える。
        OffsetVector = transform.position - Player.transform.position;
        // 追従先のTransformを取る。(カメラが向いた方向に追従先も回転させるため)
        PlayerTransform = Player.GetComponent<Transform>();
    }

    void Update()
    {
        // 追従先との距離を保つ
        transform.position = Player.transform.position + OffsetVector;

        // マウスの回転を感知して回転ベクトル化
        Vector3 angle = new Vector3(
            Input.GetAxis("Mouse X") * 1.0f,
            Input.GetAxis("Mouse Y") * -1.0f,
            0
        );
        // 回転ベクトルをカメラのもとのベクトルに加算
        transform.eulerAngles += new Vector3(angle.y, angle.x);
        // 追従先も加算して回転させる。
        PlayerTransform.transform.eulerAngles += new Vector3(0, angle.x, 0);

    }
}

4.向いてる方向に進む

Wキーで前に、Sキーで後ろに移動しましょう。三角関数を使うのでわからない人はggってね★

PlayerSetter.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerSetter : MonoBehaviour {

    // 自分のオブジェクト
    public GameObject Player;
    // X軸への移動スピード
    public float MoveSpeedX = 20.0f;
    // Z軸への移動スピード
    public float MoveSpeedZ = 20.0f;

    // ジャンプの高さ
    private float MoveSpeedY = 10f;
    private Rigidbody rb;

    void Start()
    {
        // プレイヤーオブジェクトの物理演算数を取得。
        rb = Player.GetComponent<Rigidbody>();
    }

    // 毎フレームごとに実行される。
    void FixedUpdate() { 

        // wを押したとき
        if (Input.GetKey(KeyCode.W))
        {
            rb.AddForce(Mathf.Cos(transform.localEulerAngles.y * Mathf.Deg2Rad) * MoveSpeedX, 0, -Mathf.Sin(transform.localEulerAngles.y * Mathf.Deg2Rad) * MoveSpeedX);
        }

        // sを押したとき
        if (Input.GetKey(KeyCode.S))
        {Pla
            rb.AddForce(-Mathf.Cos(transform.localEulerAngles.y * Mathf.Deg2Rad) * MoveSpeedX, 0, Mathf.Sin(transform.localEulerAngles.y * Mathf.Deg2Rad) * MoveSpeedX);
        }

        // スペースを押したとき
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Vector3 go = new Vector3(0, MoveSpeedY, 0);
            rb.velocity = go;

        }
    }
}

5.適応

カメラをプレイヤーオブジェクトの目の位置に設置して、CameraSetter.csをカメラにPlayerSetter.csをプレイヤーオブジェクトに適応しましょう。あとはそれぞれのInspectorで適応したファイルの設定をすませばOKです。あ、プレイヤーオブジェクトにリジッドボディのコンポーネントを付けるのを忘れないようにしてください。

6.まとめ

ということでこんなちょっとしたコードでFPSで大地を駆け回ることができました。

キャラクターの動かし方ですが、AddForceでよかったのでしょうか?ちょっと違和感を感じます。(特にジャンプとか)
どなたか教えていただけると幸いです。

ではよい夏休みを!
Twitter: https://twitter.com/Cyber_Hacnosuke (フォローしてくださいお願いします。)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away