1.はじめに
1.1 経緯
夏休みの自由研究という名のお遊び。(僕たちはもう夏休みです!)
1.2 やりたいこと
大きく分けて問題が三つ
- Cinema4D(モデリングソフト、有料版)等で作った3DモデルをUnityにインポート。当たり判定を付ける。
- カメラについてマウスでFPSゲームみたいに視点を移動(一人称視点)
- プレイヤーオブジェクトについて向いてる方向に移動
こんなんでゲームは作れそうです。
2.インポートしたモデルに当たり判定を付ける。
2.1 モデリングソフト側の設定(割と重要)
モデリングソフト、ツールは問いませんが、オブジェクトファイルにエクスポートできると思います。Blender
で作ったモデルだとUnity
はプロジェクトファイルのままでも読み込んでくれますがこれは使用しません。必ず一つのオブジェクトとしてエクスポートしてください。一つのオブジェクトとしてというのは一つのメッシュとしてというのと同義です。後でUnityに配置したときに以下のように子オブジェクトが一つであれば大丈夫です。
ファイル形式は.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
)を選択してください。右のInspector
にMesh Filter
もしくはMesh Render
という項目がなければエクスポートからやり直してください。あればSAColliderBuilder
は適応できます。選択した状態でInspector
の一番最後、Add Component
をおして検索窓からSA
まで入れると何個かに絞られます。そこでSA Mesh Collinder Builder
を選択しましょう。
追加されたコンポーネント内のShape Type
をMesh
に、Mesh Type
をConvex Hull
にしたらProcess
を押して適応を始めましょう。しばらくかかるので少し待ちましょう。
これで完了です。モデリングの仕方によって当たり判定の範囲が異なりました。特に階段など、一部を切り取る感じでモデリングすると変な当たり判定になります。ですが、当たり判定が想像していた形より小さくなることはないので、メッシュに埋まることはないと思います。
3.視点移動
一人称視点(追従)とマウスによる視点移動を実装します。まとめて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ってね★
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 (フォローしてくださいお願いします。)