UnityでFPS視点のPlayerを作る方法

今回は、FPS視点のPlayerの動きを制御していきます。
どういことかと言うと、
・回転操作
・直進操作
を別々に制御するということです。

以前、CameraをPlayer視点に紐付ける方法を紹介しました。
これだけでは、FPS的な動きを制御することは出来ず、Playerの動きも制御して上げる必要があります。

PCで制御することを前提に、コードを紹介します。
矢印Keyを読み取る、x・ z 変数を用意します。
最終的にやりたいのは、
・xのとき(矢印キーでいう左右)は、Playerの向きをコントロール
・zのとき(矢印キーでいう上下)は、Playerの前進・後退をコントロール
するということです。

x = Input.GetAxisRaw("Horizontal");
z = Input.GetAxisRaw("Vertical");

(1):矢印キーの左右に対して、Playerの向きをコントロールする。

float x = Input.GetAxis("Horizontal");
transform.Rotate(0,x,0, Space.World);

以前、UnityのRotateについて記事を書いたのでご確認ください。
y軸を回転させることで、x軸・z軸との面に対して回転します。

(2): 矢印キーの上下に対して、Playerの向きを前進と後退を制御する

    float z = Input.GetAxis("Vertical");

矢印キーの上下インプットを取得します。
重要なことは、 矢印キーの上下に対してPlayerが向いている方向に対して前進・後退をする必要があります。
sin cos を用いて、velocityを制御していくことで実現させます。
幾つかのステップに分けて説明していきます。

(a):Playerの向いている角度をsin,cosのΘの変化に対応するように調整
(b): オイラー角度 → ラジアンへ変更
(c): velocityへx軸、z軸方向へ代入

(a):Playerの向いている角度をsin,cosのΘの変化に対応するように調整

float angleY = ((360 - transform.eulerAngles.y) + 90) % 360;

transform.eulerAngles.y でPlayerが向いているオイラー角度を出力します。
ここで確認したいことは、Playerが向いている角度と、角度の変化です。

sin cos を利用していきます。
高校の数学で学んだ、あれです。
右向きにx軸・上向きにy軸・反時計回りにΘが増加していく、あれです。

Unity上でのPlayerの向いている角度を  transform.eulerAngles.y で確認すると
時計回りに角度が増加していきます。
なので、ここを修正すると
360 - transform.eulerAngles.y //①
z軸の方角が角度が0になっており、x軸に対して角度を0に変えたいので
(360 - transform.eulerAngles.y) + 90)//②
ただ、これだと、90~450度の範囲内になるので
((360 - transform.eulerAngles.y) + 90) % 360//③

(b): オイラー角度 → ラジアンへ変更

    float radian = angleY * Mathf.Deg2Rad;

(c): velocityへx軸、z軸方向へ代入

float sin = Mathf.Sin(radian);     
float cos = Mathf.Cos(radian);     
rb.velocity = new Vector3(cos, 0, sin);

これで、向いてる角度に前進、後退をするPlayerができます。

Unityで、FPS視点のCameraを作成する方法

FPSゲームが盛り上がっていますね。
今回は、FPS視点のCameraを作る方法について解説します。

▼簡単に流れ
( 1 ):Playerの子階層に、新しくGameObject cameraFollowを作成
( 2 ):Main camera に New Scriptを追加
( 3 ):GameObject cameraFollow に、Main Camera position, rotationを紐づける

( 1 ):Playerの子階層に、新しくGameObject cameraFollowを作成

Hierarchy でPlayerの子階層にgameobjectを追加

cameraFollow の positionにMain cameraのpositionをもってきます。
好きな位置でいいです。
※注意したいのは、ここのpositionはPlayerに対しての相対的なpositionになること。

( 2 ):Main camera に New Scriptを追加

Hierarchyの中の、MainCameraを選択した状態で、
Add Component → New Script

( 3 ): GameObject cameraFollow に、Main Camera position, rotationを紐づける

(2)で作成したMain Cameraのscriptにコードを書きます。

void Update() {     

\\ cameraFollow はPlayerの子階層に作成したgameobject
transform.position = GameObject.Find(" cameraFollow ").transform.position; 
   
transform.rotation = GameObject.Find(" cameraFollow  ").transform.rotation; 

}

Unity初心者がRotationを理解するための第一歩

transform.rotationは
Quaternion というデータフォーマットを基に決定されています。

一般的に利用されているオイラー角度(360度で1回転)とは異なる概念で、
直感的な理解が難しいと思います。

Inspector上では、オイラー角度で表示されているし、変更もできると思う方もいるかもですね。
どうやら、Inspecterに表示の際はQuaternion→オイラーへ変換されて表示されているようです。

つまり、
Quaternion と オイラー角度 はお互いに変換可能な数値ということです。

Quaternion.eulerAngles : 
Quaternion → オイラー角への変換メソッド

Vecto3 型で、(x軸の角度,  y軸の角度, z軸の角度)というデータ
数値はfloat
transform.rotation.eulerAngles で、transformのオイラー角度が算出

https://docs.unity3d.com/ja/540/ScriptReference/Quaternion-eulerAngles.html

Quaternion.Euler :
オイラー角 → Quaternionへの変換メソッド
上記、Quaternion と オイラー角度 を変換させる方法を説明してきました。

これらを用いれば、オイラー角度を用いて、rotationを操作する方法も可能ということです。

しかし、オイラー角度を用いた簡単な方法があります。
それがRotateメソッドです。

Transform,rotate(x, y, z, relativeTo )
x軸・y軸・z軸に対して、Transformを回転させる角度を変更することが可能です。
現在のTransformに対して、角度を加算します。

relativeToとは
ローカル座標を基準にするのか ・ ワールド座標を基準にするのかを指定することが出来ます。

x, y, zは、オイラー角度で、数値はflaot

UnityのCanvas RenderModeについて深堀りしてみたVer2

以前、UnityのCanvasについて紹介しました。
Render ModeをScreen-Space Cameraについてお話しました。
Screen-Space Cameraとは、CameraのViewの範囲の特定エリアに常にCanvasを配置しておく、といった設定でした。

今回は、World Spaceについて深堀りしてみたいと思います。

通常の使い方でいうと、Scene全体を示す World SpaceにCanvasを貼り付けることを想像する人もあるかもしれないですが、今回は特定Objectに対してWorld Spaceを設定することです。

特定のObjectをA Objectとした際に、Aを親・Canvasを子としてRender ModeをWorld Spaceに設定します。

そうすることで何が出来るようになるかと言うと、
特定のObject Aに対して、クッツイた状態のCanvasが設定することが出来るのです。
イメージがつきますでしょうか??

よくある例でいうと
・ゲームのHPを特定のPlayerにクッツイた状態で表記
・Playerに表記する矢印キーをくっついた状態で表記
など色々と応用可能かと思います。

UnityのCanvasのRender Modeについて深堀りしてみた

Render Modeについて調べていたら、めちゃくちゃ分かりやすい記事に出会いました。
https://light11.hatenadiary.com/entry/2019/04/15/232416

で、これでも相当理解できたのですが、
Render ModeをScreen-Space Cameraの理解を深めました。
というか、Canvasのサイズに起因している要素について2つのパラメータが影響しています。

(1):CanvasをScene上に配置してください。
(2):Render ModeをScreen-Space Cameraへ変更
(3):Render Mode > Render CameraにMain Cameraを設置

ここまで前準備で行ってみてください。

ここから調整してみて欲しいパラメーターは
①:Canvasの Plane Distance
②:Main Cameraの Field of View

この2つのパラメータを調整してみると、Canvasのサイズも同時に変化していることが分かると思います。
当たり前と言えば当たり前なのですが(Screen-Space CameraはCameraのサイズにFitしたCanvasなので)

実際に、パラメーターを調整してみると、Screen-Space Cameraがどんな設定なのか分かると思います。

UnityのNavMeshを使う

Unityを学習してまだまだ日が浅いのです。
C#については、そこそこ理解してコードを記述できるんですが
Unityが持っている様々な機能の理解はまだまだ….

NavMeshは非常に便利だということでして、少し使ってみました。
NavMesh
 → Playerが行動できるエリアを規定するもの
という感じでしょうか。

NavMeshを使い始めるには
ウィンドウ (Window > AI > Navigation) を表示することから始まります。

https://docs.unity3d.com/ja/2018.4/Manual/nav-BuildingNavMesh.html

Navigationには、主に4つの設定内容があります。
・Agent
・Areas
・Bake
・Object

・Agent
 → 後ほど、解説
・Areas
 → どんなエリアが存在するのか。 コストといった概念を設定できる
・Bake
 → NavMeshを設定
・Object
 → ObjcetをNavMeshに設定可能にする

NavMeshは、単体で使うというよりも
NavMeshAgentというコンポーネントを併用することが多いかと思います。
NavMeshAgentは、設定に従い、考えて動いてくれるもの。という感じです。

NavMeshで設定した、エリアの中で、
NavMeshAgentの指示に従って、動くキャラクターを制作することができます。

UnityのAnimatorControllerにおけるTransitionのデフォルト設定について

AnimatorControllerの中で、AnimationClipを遷移させる特定の発火タイミングのみで、実行する環境を設定する方法を紹介します。

遷移させる基と遷移先のAnimationClipを、それぞれclipA・clipBと呼称します。

デフォルト設定の場合は clipA → clipB へ Make Transitionで結んだ際に
自動的に、clipAが終了した際に、clipBへ遷移してしまうということがあります。

なので、この遷移に対して、
Conditionsを設定する必要があります。

Conditionsを設定する為には
( 1 ):Parameterの設定
( 2 ):ConditionsでParameterを追加して、発火条件を指定

そうすると、発火条件のタイミングで遷移するようになります。