Unityでのゲーム開発 〜キャラクターとカメラScript〜
キャラクターの移動スクリプト
まずScript(今後のスクリプト)を書く前に保存するフォルダーの作成します。
プロジェクトの[Asset]にカーソルを合わせて右クリック[Create]⇨[Folder]を選択してフォルダ名を「Scripts」に変更してください。
*複数のスクリプトを保存するので今回は複数形の["s"]を付けていますが自分のわかりやすい名前でOK
スクリプトの作成方法
スクリプトフォルダで右クリックを押して[Create]⇨[C#Script]の手順でスクリプトを作成してそのまま名前を変更します。
*ここでの名前変更は重要な役割があり、変更した際にクラス名も一緒に決定して作成します。
!注)スクリプトの名前とスクリプト内のクラス名はリンクしている為、どちらかを間違えて変更してしまった場合はどちらかに合わせる様にしてください。
今回は[Player]と[ThirdPersonCamera]の2つを作成してください。
ついでにキャラクター名も長すぎるので"ThirdPersonController_LITE" ⇨ "Player"へ変更しておくとお今後楽です。
*名前の変更方法は変更したい項目で右クリックをして[Rename]を選択するかHierarchyの上部にある名前の場合から変更可能です。
前回の記事でPlayerに付いていた"Animator"も復活させておいてください。
無くても良いのですがキャラクターがカカシの様な状態になってしまうので分かりづらい場合がある為、のちのちAnimatorの設定もいじるので今回はアタッチされている物を使います。
Playerスクリプトの記述
こちらの記事を参考に致しました。
Unityでカメラの向きを基準に移動する方法と、追従して回転できるカメラの実装
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Player : MonoBehaviour { private float Horizontal; private float Vertical; Rigidbody rb; public float moveSpeed = 5f; void Start() { rb = GetComponent<Rigidbody>(); } void Update() { Horizontal = Input.GetAxisRaw("Horizontal"); Vertical = Input.GetAxisRaw("Vertical"); } void FixedUpdate() { // カメラの方向から、X-Z平面の単位ベクトルを取得 Vector3 cameraForward = Vector3.Scale(Camera.main.transform.forward, new Vector3(1, 0, 1)).normalized; // 方向キーの入力値とカメラの向きから、移動方向を決定 Vector3 moveForward = cameraForward * Vertical + Camera.main.transform.right * Horizontal; // 移動方向にスピードを掛ける。ジャンプや落下がある場合は、別途Y軸方向の速度ベクトルを足す。 rb.velocity = moveForward * moveSpeed + new Vector3(0, rb.velocity.y, 0); // キャラクターの向きを進行方向に if (moveForward != Vector3.zero) { transform.rotation = Quaternion.LookRotation(moveForward); } } }
スクリプトが出来たら下記の様にスクリプトを"Hierarchy"もしくは"Inspector"にドラック&ドロップしてください
移動処理が問題なければ下記の様な動きになると思います。
ThirdPersonCameraの記述
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ThirdPersonCamera : MonoBehaviour { GameObject targetObj; Vector3 targetPos; void Start () { targetObj = GameObject.Find("Player"); targetPos = targetObj.transform.position; } void Update() { // targetの移動量分、自分(カメラ)も移動する transform.position += targetObj.transform.position - targetPos; targetPos = targetObj.transform.position; // マウスホイールをスクロールするとドリーイン・ドリーアウトする float scroll = Input.GetAxis("Mouse ScrollWheel"); transform.position += transform.forward * scroll; // マウスの右クリックを押している間 if (Input.GetMouseButton(1)) { // マウスの移動量 float mouseInputX = Input.GetAxis("Mouse X"); float mouseInputY = Input.GetAxis("Mouse Y"); // targetの位置のY軸を中心に、回転(公転)する transform.RotateAround(targetPos, Vector3.up, mouseInputX * Time.deltaTime * 200f); // カメラの垂直移動(※角度制限なし、必要が無ければコメントアウト) transform.RotateAround(targetPos, transform.right, mouseInputY * Time.deltaTime * 200f); } } }
アタッチする前に"MainCamera"を"ThirdPersonCamera"に名前を変えて下さい。
名前の変更が完了したら上記のPlayerの時と同じ様に"ThirdPersonCamera"へスクリプトをアタッチしてください。
!今回はここまで次回はエイムカメラの設定をやってみたいと思います。
Unity用語
〜共通部分〜
using 〇〇;・・・これはC#スクリプトを作成した際に一緒に作成されるもので、using(使用するとゆう意味)な為usingの後に続く〇〇を使用しますって意味になります。
using System.Collections; using System.Collections.Generic; using UnityEngine;
上記のusing以降の" UnityEngine;"等は「名前空間」と呼ばれています。
色々な設定をまとめている物だと思っておけば良いと思います。特に「using UnityEngine;」はUnityで使用する色々な要素をまとめてくれている物です。
*コレがないとエラーになります_:(´ཀ`」 ∠):
用意された物だけでなく作成した物を下記の様にすると定義する事もできます。
namespace 〇〇;
定義付けしたら他のスクリプトで[using 〇〇;]でアクセス可能になります。
*namespaceのメリットはスクリプトの名前被りを避けるのにも役に立ちます。よく使うスクリプトは被ってしまう為DLしたAssetを複数使うとより被るリスクが増えますがnamespaceを利用すればスクリプト名が被っていても使用できます。
public class 〇〇 : MonoBehaviour・・・〇〇の部分はスクリプト作成した際に生成される為に作成する事に変わります。〇〇クラスを定義する宣言になります。
MonoBehaviour・・・Unityプログラミングにおいて用いられる全てのクラスの基底クラス(親クラス)となるクラスです。もともとUnity上で定義されているクラスであり、プログラマはここから派生して様々な派生クラス(子クラス)を作製します。
Unityで作られるゲーム中で出てくる物体などの動作のきっかけ(イベント)で動かす処理のかたまり(メソッド)等をつなぐ役割をしています。
*場合によって変更する場面も出てくるかと思います。
UnityEngine.MonoBehaviour - Unity スクリプトリファレンス
void Start()・・・プロジェクト開始時に1度だけ呼び出されて処理される項目をプログラムする場所だと思って貰えれば良いと思います。
void Update()・・・プロジェクトでキー入力等で何度も呼び出されて実行される処理項目をプログラムする場所だと思って貰えれば良いと思います。
〜Player部分スクリプト〜
private・・・アクセス修飾子と呼ばれるものです。アクセス修飾子は、クラスや変数等のアクセスレベルを制限するために定義して、他のクラスから参照できるか否かを調整するためのキーワードとなります。
アクセス修飾子によって、変数やクラスが自分のクラスでしか参照できないのか、外部からも参照できるのかを制限できるので、不用意に値を編集できなくする事も可能な為チーム開発の際には重要な項目になります。
アクセス修飾子の種類
public:この型またはメンバーには、同じアセンブリ内の他のコードや、そのアセンブリを参照する別のアセンブリ内の任意のコードからアクセスできます。
private:この型またはメンバーには、同じ class 内または同じ struct 内のコードからのみアクセスできます。
protected:この型またはメンバーには、同じ class 内のコードか、その class から派生した class 内のコードからのみアクセスできます。
internal:この型またはメンバーには、同じアセンブリ内の任意のコードからアクセスできますが、別のアセンブリからはアクセスできません。
protected internal:この型またはメンバーには、それが宣言されているアセンブリ内の任意のコードからアクセスできるほか、別のアセンブリの派生 class 内からアクセスすることができます。
private protected:この型またはメンバーには、同じ class のコードか、その class から派生した型のコードによって、その宣言アセンブリ内でのみ、アクセスできます。
詳しくはこちらから⇩
アクセス修飾子 - C# プログラミング ガイド | Microsoft Docs
Input.GetAxisRaw・・・ジョイスティックやマウスなどの移動量を、-1.0~1.0の数値で取得する関数。
Horizontal・・・カーソルキーの←・→、Aキー・Dキー
マウスの横向きの移動
ゲームパッドの横向きの傾き
*Unityのシステムでこのワードだけで上記の処理を出来る様にしてくれます
Vertical・・・カーソルキーの↑・↓、Wキー・Sキー
マウスの縦向きの移動
ゲームパッドの縦向きの傾き
*Unityのシステムでこのワードだけで上記の処理を出来る様にしてくれます
void FixedUpdate()・・・FixedUpdateメソッドを使う代表的な例は物理演算を行うときです。
Updateメソッドに物理演算を書くと、端末の描画速度によりUpdateメソッドが呼ばれるタイミングにラグなどが出てしまうので、物体の移動がカクカクになったり物理演算の結果に再現性が保てなくなってしまう可能性があります。
FixedUpdateメソッドの方は、Updateメソッドがフレーム落ちしていても、独立して一定時間ごとに呼び出されるので、物理演算の結果再現性が保てるようになります。
ブッ、、、物理演算_:(´ཀ`」 ∠):なんぞやそれって方はWikipediaさんに聞いてみましょう
物理演算エンジン - Wikipedia
「Physics」って単語はよく使用すると思うので覚えておいてもいいと思います。
Forward・・・前方とゆう意味なのでVector3(0, 0, 1) と同じになります。
Quaternion.LookRotation・・・Quaternion[クォータニオン]は回転を表すのに使用されます。
LookRotationは指定された forward と upwards 方向に回転します。
- forward・・・前方向。Vector3(0, 0, 1) と同じ意味。
- upwards・・・上方向を定義するベクトルです。 Vector3(0, 1, 0) と同意。
ふーん、、、⇨Quaternion-LookRotation - Unity スクリプトリファレンス
〜ThirdPersonCamera部分スクリプト〜
Time.deltaTime・・・現在のフレームと前のフレームの間の経過した時間。
これを使えば方向キーを押している間、移動方向に繰り返し移動処理をする事が出来る様になります。
MonoBehaviour.FixedUpdateは、deltaTimeの代わりにfixedDeltaTimeを使用します。