【Unity実践】#4 プロトタイプ編 ~ プレイヤー作成 part1 ~【Boxゲーム】
今回の内容
ユニティちゃんダウンロードと配置、プレイヤーの移動までを実装します!
※初めての方はこちらから
⇒ 【第1回記事】この連載について
ダウンロードとインポート
ユニティちゃんの3Dモデルデータを以下からダウンロードしましょう。
https://unity-chan.com/download/releaseNote.php?id=SDUnityChan
ダウンロードしたら、Unity にインポートを行います。
インポートは、メニューの「Assets > Import Package > Custom Package」をクリックした後、
先ほどダウンロードしたファイルを選択して下さい。
ファイルを選択するウィンドウが開くので、「import」をクリックしてください。
プロジェクトビューに「UnityChan」フォルダが追加されていれば成功です。
必要なファイルのみ選択することでプロジェクトの容量を削減できますが、
あらかじめ必要なファイルが分かっていない場合には、今回のように全てインポートして、後から不要なファイルを消す形になります。
なお、ここで気にしているのは「プロジェクトのサイズ」であって、ビルド後の「アプリのサイズ」とは異なります。
アプリは基本的にはシーンに必要なファイルのみで作成されるため、全てインポートしているからと言って最終的なアプリのサイズが大きくなる心配はありません。
ユニティちゃんをシーンに配置する
ユニティちゃんをシーンに配置していきます。
プロジェクトビューから、以下をシーンに配置してください。
UnityChan > SD_unitychan > Prefabs > SD_unitychan_humanoid
名前は「Player」として、Transform は以下に設定しましょう。
ここで Player をプレハブ化しておきましょう。
Assets > Prefabs フォルダにドラッグ&ドロップしますが、以下の様にオリジナルのプレハブとするか確認するウィンドウが表示されるので、
「Original Prefab」を選択します。
エラーをダブルクリックして、対象のスクリプトをエディタで開きます。
8行目でコンパイルエラーとなっており、コメントアウトすることでエラーは解消されます。
編集したらファイルを保存して、Unityエディタに戻りましょう。
コンソールのエラーが消えていることを確認したら一度シーンを再生してみます。
ひとまず再生ができましたが、画面の端4カ所に動作確認用のUIが表示されています。
これを消すために、Player の以下のコンポーネントを削除します。
・IdleChanger
・FaceUpdate
・RandomWind
・IKLookAt
なおその際、プロジェクトビューの Player プレハブを編集してください。
削除が完了したら、シーンに配置されている Player をインスペクタービューで確認して、
コンポーネントが削除されていることを確認してください。
シーンを再生すると、先ほどの画面端に表示されていたUIが消えているはずです。
※プレハブの編集
プレハブのコンポーネントを編集すると、そのプレハブから作成されたオブジェクトの設定も変更されます。
この逆で、シーンに配置されているオブジェクトを変更した場合は、元となるプレハブの設定は変更されません。
※Overrides機能で、オブジェクト ⇒ プレハブ の変更も可能です。詳細はコチラから。
簡易的には以下の様に考えておくと問題無いかと思います。
・プレハブ共通の設定変更 ⇒ 元のプレハブを編集
・オブジェクト固有の設定変更 ⇒ 配置したオブジェクトを編集
(関連記事)
【Unity連載】プレハブの使い方②(編集)
最後に、Player にタグを設定しておきます。
これもやはり Player プレハブを操作して、Tagの項目を「Player」に設定してください。
今すぐには使いませんが、近いうちに使用していくので忘れずに設定しましょう。
※ユニティちゃんの各コンポーネント
それぞれ簡単に、以下のような機能となっています。
・IdleChanger(待機時のアニメーションの変更)
・FaceUpdate(顔の表情の変更)
・AutoBlinkforSD(自動でまばたきさせる)
・Spring Manager(揺れの制御。髪など)
・IK Look At(3Dモデルの骨格の制御)
・Random Wind(ランダムな風を生成)
PlayerScript作成
ここからはユニティちゃんを移動させる処理を作成します。
Assets > Scripts フォルダを作成して新規スクリプトファイルを作成し、名前は「PlayerScript」としましょう。
(関連記事)
【Unity連載】プレハブの使い方②(編集)
まずは以下の様に記述します。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerScript : MonoBehaviour { public bool isMove; void Start() { } void FixedUpdate() { if (isMove) { transform.position += transform.forward * 0.03f; } } }
ポイントとしては「isMove」という変数で移動状態を管理している点です。
isMove が true ⇒ プレイヤーが移動するように
isMove が false ⇒ プレイヤーが移動しないように
↑ の動きとなるように、FixedUpdate の処理を作成しています。
ユニティちゃんのモデルはZ軸方向(ローカル座標での)が正面となるように作成されているので、
「transform.forward」を使って正面への移動を実装しています。
transform.forward は、オブジェクトのローカル座標での(0, 0, 1)を表す単位ベクトルです。
簡易的には、オブジェクトの向きを表すベクトルと考えるとわかりやすいかと思います。
※UpdateとFixedUpdate
Update は実行間隔がデバイス(PCやスマホ)の性能等で変動しますが、
FixedUpdate は一定間隔(デフォルトは0.02秒)で呼ばれる仕組みとなっています。
物理演算処理を Update で行うと、場合によっては意図しない挙動となってしまうことが有ります。
今回のプレイヤーの移動も、早すぎたり遅すぎたりするとステージの配置との兼ね合いで問題が生じるため、
FixedUpdate を使用しています。
(関連記事)
【Unity連載】UnityとC#におけるメソッド一覧
一旦スクリプトを保存して、Player にアタッチしましょう。
アタッチする時もやはり、プレハブ側の Player にアタッチしてください。
アタッチしたらシーンを再生してみて下さい。
再生しただけではまだプレイヤーは動きませんが、これは「isMove」が false となっているためです。
後々はこの値をゲーム内から制御しますが、今はまだその仕組みが無いので、
シーン再生中にインスペクタービューで、直接値を変更します。
ユニティちゃんが正面に移動を開始すれば成功です。
ここで以下のような問題に気が付きます。
・床が無いところでも落下していない(以下、1枚目画像)
・壁をすり抜ける(以下、2枚目画像)
・走る時のアニメーションが無い(次回の記事で実装)
まずは上の2つの問題について、この後対応していきます。
RigidBody追加
プレイヤーが落下しない問題はプレイヤーに重力が設定されていないのが原因です。
重力を追加するには 「Rigidbody」コンポーネントを使用します。
Playerのプレハブを選択して、Add Component から「Rigidbody」を追加してください。
詳細設定は後々変えることもあるかと思いますが、今は特に変えずに進めます。
追加ができたらシーンを再生してみましょう。
落下するようにはなったのですが、シーン開始直後から床をすり抜けて落下してしまいます。
床をすり抜けてしまうのは2つ目の問題であった、壁をすり抜けるのと同様の現象で、
当たり判定が無いために起こっています。こちらはこの後対応します。
ちなみに、Rigidbody を追加する前はプレイヤーが床の上を歩いているかのように見えていましたが、
これは配置の関係でそう見えていただけで、実際には床との当たり判定は存在していません。
Rigidbody 追加前は以下の様に、どこに配置しても落下することはありません。
※Rigidbodyに関する記事はこちら
【Unity連載】はじめに知っておくべきRigidbodyコンポーネントの概要
【Unity連載】Rigidbody(物理演算)の使い方①
【Unity連載】Rigidbody(物理演算)の使い方② -velocity-
Collider追加
当たり判定を設定して壁や床とプレイヤーがすり抜けないようにします。
当たり判定を設定するには、コライダー(Colliderコンポーネント)を追加します。
コライダーには形状によって、BoxCollider や SphereCollider などいくつか種類が有りますが、
今回は CapsuleCollider を使用します。
Player のプレハブで、Add Component から CapsuleCollider を追加しましょう。
さらに、Center Y と Radius を以下の通り設定して下さい。
シーンビューでプレイヤーを見てみると以下の様に、ユニティちゃんの形状におおよそ沿った形で、カプセル状のコライダーが設定されています。
※緑の線がコライダーを表しています。
これでプレイヤーのコライダーが設定できました。
ちなみに、プレイヤーと床、プレイヤーと壁、のように異なるオブジェクトを衝突させるには、
両オブジェクトにコライダーを設定する必要があります。
しかし、Cube から生成したオブジェクトには初めから BoxCollider が設定されているため、今回は設定の必要はありません。
シーンを再生して、まずはプレイヤーが床をすり抜けないことを確認しましょう。
さらに、先ほどと同様に「isMove」にチェックを入れて、プレイヤーを動かしてください。
前進して床が無くなると落下するようになっており、壁に衝突するとすり抜けなくなっているかと思います。
これで元々の問題点は解消されたのですが、新しく気になるのが、落下した後にプレイヤーが前に傾いてしまう点です。
(↑ 分かりやすいように極端に再現しています。)
これだけ、今回の記事の最後としてこの後対応します。
※Collider に関する記事はこちら
【Unity連載】はじめに知っておくべきColliderコンポーネントの概要
回転・移動の制限
今回のゲームでは、衝突等によるプレイヤーの回転は避けたいのでその制限を行います。
また、Z軸方向(画面に対して垂直方向)への移動は基本的にナシとしたいので、その制限も加えます。
これらの設定は、Rigidbody コンポーネントから簡単に行えます。
プレイヤーのプレハブで、Rigidbody から以下を設定してください。
・Constraiants > Freeze Position の Z にチェック
・Constraiants > Freeze Rotation の X, Y, Z にチェック
おわりに
今回はプレイヤー実装の第1回目ということで、配置から移動、当たり判定の設定あたりを行いました。
初心者の方は、
・Rigidbody
・Collider
これら2つは非常に大事なコンポーネントとなるので、それぞれの特徴、簡単な使い方は確認しておきましょう。
次回はプレイヤーの実装の続きで、移動アニメーションの設定を行いますのでお楽しみに!
連載目次リンク
関連する連載リンク
© Unity Technologies Japan/UCL