Unityを使った3Dゲームの作り方(かめくめ)ゲーム開発エンジンUnityを使った3Dゲームの制作に参考になる情報を公開しています。2021.02.23シンプルなアクションゲームを作ってみようの第7回です。今回はシーンに配置したキャラクターを動かすスクリプトを作成していきます。前回はUnityでのスクリプトの作成の基本的な事についてやりました。シンプルなアクションゲームを作ってみよう6-スクリプトの基本-シンプルなアクションゲーム用のスクリプトを作る前に、スクリプトの基本的な事を勉強します。gametukurikata.com2021.02.22シンプルなアクションゲームを作ってみようの他の記事はシンプルなアクションゲームを作ってみようシンプルなアクションゲームを作るのを通してUnityの使い方を学ぶカテゴリです。gametukurikata.comから参照出来ます。スポンサーリンクキャラクター用のスクリプトを作成まずはAssets/Scriptsフォルダ内にPlayerControllerスクリプトを作成し、Stage1シーンに配置したEthanにドラッグ&ドロップをして取り付けます。PlayerControllerスクリプトにはキーボードの入力によってキャラクターを移動させるスクリプトを記述していきます。Studioで開きます。Update(){}}スクリプトが長いので少しずつ記述していきます。処理はPlayerControllerスクリプトに追加していきますが、フィールドはクラスのブロックのすぐ後、メソッドはフィールドの下に書いていく事とします(メソッドの順番は自分でわかりやすい順番にしてください)。スクリプトの基本的な事を忘れてしまった場合は、前回の記事を見て確認してください。シンプルなアクションゲームを作ってみよう6-スクリプトの基本-シンプルなアクションゲーム用のスクリプトを作る前に、スクリプトの基本的な事を勉強します。gametukurikata.com2021.02.22また、スクリプトのエラーがコンソールに出た時は、エラー内容を確認し、修正してください。エラーの修正方法は以下の記事も参照してください。Unityのスクリプトでエラーが出た時の対処Unityのスクリプトを組んでいると必ず発生するのがコンパイルエラーです。このコンパイルエラーを修正する方法を実例とともに紹介したいと思います。gametukurikata.com2018.03.14フィールド宣言部分まずは使用するフィールド宣言を追加します。2f;rigidBodyはEthanに取り付けているRigidbodyコンポーネント、myColliderにはEthanに取り付けているCapsuleColliderを入れます。現時点では宣言のみで後で入れます。inputはユーザーが入力したXYZの入力値を入れます。XYZの3つの値を使う場合はVector3型を使うと便利です。今回の入力で使うのはXZだけなのでVector2型でもいいですが、velocityと合わせる為にVector3型にしました。velocityはユーザーの入力値から速度を計算したものを入れます。isGroundedはキャラクターが地面と接地しているかどうか?を表します。実際に接地しているかどうかを判定する為には、自分で処理を書く必要があります。[SerializeField]アトリビュートを取り付けているのは、Unityエディターでプレイボタンを押した時に、キャラクターが地面と接地しているかどうかの判定をインスペクタで確認する為です(確認しない場合はアトリビュートは要りません)。moveSpeedはキャラクターの移動スピードに使います。こちらにも[SerializeField]アトリビュートが付いていて、インスペクタで値を設定出来ます。StartメソッドStartメソッドに処理を追加します。GetComponent<CapsuleCollider>();}フィールドで宣言したrigidBodyとmyColliderにスクリプトが取り付けられているゲームオブジェクトのコンポーネントから取得し代入しています。GetComponent<取得する型>();123GetComponent<取得する型>();で自身(スクリプトが設定されているゲームオブジェクト)に取り付けている指定した型のコンポーネントを取得出来ます。Startメソッド内でコンポーネントを取得してその参照をフィールドに保持しておくと、後でそのコンポーネントを使いたい時に再度コンポーネントを取得する必要がないので、アクセスが速くなります。UpdateメソッドUpdateメソッドに処理を追加します。移動速度の計算Move();}接地確認をするCheckGroundメソッドの呼び出しと、移動速度の計算をするMoveメソッドの呼び出しをしています。この二つのメソッドはまだ作っていないのでこの後作成していきます。接地を確認するメソッドを作成します。false;}}CheckGroundメソッドの最初でisGroundedがtrueかfalseかをif文で確認しています。if文は()の中の条件がtrueかfalseかを判断し、trueであれば{}の中身を実行します。isGroundedがtrueの時は接地しているということなので接地確認をする必要がないので、returnを使ってそれ以降の処理をせずに呼び出し元に帰します(今回の場合はUpdateメソッド内で呼び出しているのでそこに戻る)。戻り値がvoidの場合でもreturnが使えますが、当然戻り値はないので戻り値は指定しません。returnは即座に呼び出し元に戻せるので便利ですが、使いどころを間違えると本来は実行したい処理を飛ばして呼び出し元に戻ってしまうので注意が必要です。returnを使うと分かり辛いという方は使わないでif文でisGroundedがfalseの時に接地の確認をするというように処理を変更してもかまいません。接地確認の処理}isGroundedがfalseの場合はそれ以降の処理に進み、またif文で条件分岐をします。今回は床から落下した場合はisGroundedがtrueのままですが、落下時にfalseにしたい場合はこれらの条件なしに常に地面をチェックするようにします。!(エクスクラメーションマーク)を付けるとtrueとfalseを反転させます。Physics.CheckSphereメソッドは球の形の範囲を作成し、その範囲で何らかのレイヤーが設定されたコライダと接しているかどうかを判定するものです。第1引数には球の中心位置、第2引数には球の半径、第3引数には接触したと判定するゲームオブジェクトに設定されたレイヤーを指定します。レイヤーについてはこの記事で別途やります。該当するレイヤーマスク)今回は中心位置にrigidBody.positionで位置を取得し指定していますが、位置を取得したい場合はtransform.positionでも取得出来ます。Rigidbodyを介して位置を取得した方が高速になるようです。詳細はUnityのスクリプトリファレンスに載っています。位置docs.unity3d.com球の半径にはキャラクターに取り付けたCapsuleColliderの半径より少し小さい半径を指定しています。これはキャラクターの横にゲームオブジェクトが来た場合にも接地したと判定されるのを避ける為、キャラクターのコライダよりも少し小さい値にしています。該当するレイヤーマスクではLayerMask.GetMask("Ground")123LayerMask.GetMask("Ground")上のようにGroundという名前のレイヤーが設定されたゲームオブジェクトのコライダと接触した場合のみに限定しています。Physics.CheckSphereがtrueになった場合はisGroundedをtrueにし、Y方向の速度を0にしています。Y方向の速度を0にしていますが、いずれジャンプ機能を作る時にvelocityのY方向の速度を操作して作る場合は必要になりますが、Rigidbodyを操作する場合は必要ありません。Physics.CheckSphereのようにある形状の範囲で他のコライダと接触したかどうかや、レイ(線)を飛ばして他のコライダと接触したかどうか等の判定メソッドは他にもたくさんあります。用途によって使い分けるといいです。スクリプトリファレンス物理システムのグローバル設定とヘルパーメソッドです。次に移動速度を計算するMoveメソッドを作成します。moveSpeed);}接地している場合はvelocityにVector3.zeroでXYZが0のVector3の値を入れています。その後Input.GetAxis(“Horizontal”)で横方向、Input.GetAxis(“Vertical”)で前後方向の入力値を得て、それをVector3のXとZにそれぞれ設定します。Input.GetAxisは引数で指定した名前のキーやコントローラースティックの入力値を取得出来ます。Settings...を選択し確認や設定をします。Managerで設定されています。Buttonにrightが設定されています。これは→キーを押した時にプラス、←キーを押した時にマイナスの値が得られます。Buttonは第2のボタンでaキーでマイナス、dキーでプラスとなります。Horizontalでは、一つの名前に二つのキーの割り当てがされています(別途スティック用のHorizontalもあります)。入力値であるinputが決まったら、その入力値を使って移動速度を計算します。moveSpeed);input.normalizedでベクトルの正規化(長さ1のベクトルにする)をしています。これは入力の方向だけを得る為で、長さはmoveSpeed分にしたい為です。inputはVector3の値なので、XとZに入力値のそれぞれの成分を入れてmoveSpeedを掛けています。0.2f);}OnDrawGizmosメソッドを作成するとシーンビューやゲームビューなどにギズモを表示することが出来ます。ギズモは目印として使用したり、実際はどのような形状なのかを視覚的に確認したい時に使用します。Color.redでギズモの色を赤色に設定しています。Gizmos.DrawLineメソッドで第1引数の位置から第2引数の位置まで線を引いています。ここでは接地を確認する時の計算を線を使って視覚的に確認出来るようにしています。ここで、transform.positionをrigidBody.positionにした方がいいのではないか?と思われる方もいるかもしれませんが、rigidBodyはStartメソッドで取得しているので、Unityエディターでプレイボタンを押さない限りRigidbodyコンポーネントを取得出来ません。ギズモはプレイボタンを押していない時でもシーンビュー等で表示されるので、rigidBodyがNull(設定されていない)というエラーがコンソールに表示されてしまいます。次にFixedUpdateメソッドを作成します。Timestepの秒数毎に呼び出されます。デフォルトでは0.02になっているので0.02秒毎にFixedUpdateメソッドが実行されます。処理が多い場合はズレます。Time.fixedDeltaTime);}}Mathf.Approximatelyメソッドでfloat型の値を比較出来ます。!でboolを反転しています。何らかの入力がされていればその下のブロックの処理を行います。RigidbodyのMoveRotationメソッドを使用するとRigidbodyを回転出来ます。Quaternion.LookRotationメソッドは引数で指定した方向の回転(Quaternion値)を取得出来ます。上のスクリプトの場合はinput.normalizedで入力した方向を取得しています。ここら辺は少し難しいですね・・・(-_-)Mathf.Approximatelyを使わない場合はinput.magnitude(入力の大きさ)が0より大きい時だけ回転させます。入力方向に向けるrigidBody.MoveRotation(Quaternion.LookRotation(input.normalized));}次に移動させる処理です。Time.fixedDeltaTime);}velocity.magnitudeで速度(ベクトル)の長さを求められます。速さ(スカラー)が0より大きければ移動処理をします。RigidbodyのMovePositionメソッドを使用すると移動出来ます。引数には移動先の位置を指定します。上のスクリプトの場合は現在の位置に1フレーム分の速度を足した分の位置を指定し、移動させています。Time.fixedDeltaTimeで前回のFixedUpdateメソッドから現在のFixedUpdateメソッドまでの時間を取得出来ます。固定フレームレートなのでだいたい(デフォルトでは)0.02です。Rigidbodyの位置を直接変更しない方がいい先ほどのスクリプトでRigidbodyのMoveRotationやMovePositionを使って回転や移動処理を実行するようにしました。Time.fixedDeltaTime;のように直接位置を変更することも出来ます。Rigidbodyを使って物理的に移動や回転処理をする場合は、まずtransformを使った処理と同時に使うと動作がおかしくなる可能性があるので使わないようにします。rigidBody.positionを使って位置を変更する処理もなるべく使わない方がいいです。位置や回転を直接変更すると、小刻みにワープして移動や回転をしているのと同じなので物理的に移動や回転をしているのとは違います。MoveRotationやMovePositionの場合はRigidbodyコンポーネントのinterplateで補間の設定をしている場合に、フレーム間の補間が有効になるので、すり抜けが起こりにくくなります。同様にRigidbodyのプロパティのvelocityを直接変更して速度を変えるのもあまりよくないようです。Rigidbodyのvelocityを直接変更するのは、ジャンプなど直ぐに遠くに飛ばしたい時等の限定的な使用が良いようです。MoveRotationやMovePositionを使う場合はRigidbodyのIsKinematicにチェックを入れておかないと補完機能が働かず小刻みにワープしているのと変わらないみたいです。あれば直接位置を変換してるのと同じです。(^_^;)AddForceやAddTorque今回はRigidbodyのMoveRotationとMovePositionを使ってキャラクターの回転と移動させますが、その他にAddForceメソッドで力を加えたり、AddTorqueメソッドで回転に力を加えられます。Rigidbodyの物理的な特性を利用する場合はAddForceやAddTorqueを使って力を加えるやり方が良さそうです。Planeゲームオブジェクトにレイヤーを設定これでスクリプトが出来たので、次はスクリプトの中で接地の確認に使用しているGroundレイヤーを作成し、床のゲームオブジェクトであるPlaneゲームオブジェクトにGroundレイヤーを設定したいと思います。タグとレイヤーとは?タグはゲームオブジェクトを識別する名前のようなものです。レイヤーはゲームオブジェクトに設定出来るグループです。タグとレイヤーは似たような感じですが、レイヤーの場合は所属するグループを設定します。Matrixで衝突判定をするレイヤーの設定が出来ます。ここでチェックを外せば該当するレイヤー同士の衝突が行われなくなります。Matrixに表示される縦と横のBulletが交錯する部分のチェックを外します。Groundレイヤーを作成し、Planeに設定していきます。Layerを選択します。6にGroundと入力します。Layerは最初から作られているレイヤーです。Groundレイヤーを作成したら、再度ヒエラルキーでPlaneゲームオブジェクトを選択し、LayerからGroundを設定します。これでPlaneゲームオブジェクトにはGroundレイヤーが設定され、スクリプトでGroundレイヤーで判定する時に、このPlaneは地面であると認識出来ます。グループ名をGroundとしただけで、Groundという名前にすると地面になるわけではありませんので注意が必要です。実行して確認これでキャラクター移動のスクリプトが出来たので、Unityエディターのプレイボタンを押して実行し、矢印キーを押してEthanが移動するかどうかを確認してみましょう。以下のようになりました。終わりにこのカテゴリではRigidbody+コライダでキャラクターの移動処理を作っているので、CharacterControllerを使った移動処理よりも少し難しくなっています。最初はなんじゃこれ!難しすぎ!と思うかもしれませんが、何回もスクリプトを作っていれば段々と慣れてきます。́Д`)キャラクターは移動しましたが、アニメーションが行われていないので、そこら辺を次回やりたいと思います。Controllerを作成していきます。シンプルなアクションゲームを作ってみようシンプルなアクションゲームを作ってみよう1-新しいプロジェクトの作成と完成品サンプルゲームの実行-シンプルなアクションゲームを作っていく為に、Unityの新しいプロジェクトの作成をします。完成したサンプルゲームを実行して確認が出来ます。シンプルなアクションゲームを作ってみようシンプルなアクションゲームを作ってみよう13-タイマーの作成をする-シンプルなアクションゲームでキャラクターがゴールするまでの時間を計測するタイマーを作成していきます。シンプルなアクションゲームを作ってみようシンプルなアクションゲームを作ってみよう2-アセットストアの使用-シンプルなアクションゲームを作る為にアセットストアを使用してみます。シンプルなアクションゲームを作ってみようシンプルなアクションゲームを作ってみよう19-ジャンプ機能を作成する-シンプルなアクションゲームのプレイヤーにジャンプ機能を取り付けていきます。二段階のジャンプも出来るようにします。シンプルなアクションゲームを作ってみようシンプルなアクションゲームを作ってみよう16-障害物を作成する-シンプルなアクションゲームでプレイヤーキャラクターを邪魔する障害物を作成し、障害物が消えたらナビメッシュ上を動く敵も移動出来るようにしていきます。シンプルなアクションゲームを作ってみよう6-スクリプトの基本-シンプルなアクションゲームを作ってみよう8-アニメーションの状態と遷移-ホーム作ってみようシリーズシンプルなアクションゲームを作ってみようスポンサーリンクサイト内検索が出来ますプロフィール管理人のかめくめちゃんです。(-_-)メールはこちらにお願いします(記事に関する質問は送らないでください、返信は期待しないでください(._.))。kamekumechan@gmail.comいずれはSIRENやバイオハザードみたいなアクションゲームを作りたいと思っています。ゲームシナリオが書けないので面白いゲームはなかなか作れません・・・・。(^_^;)名前の由来はカメが好きだからです。プロフィールになってないな・・・・(-.-)Unityをこれから始める人へこれからUnityを使ってみようという方はUnityを使った3Dゲームの作り方(かめくめ)の歩き方Unityを使った3Dゲームの作り方(かめくめ)で、はじめてUnityの学習をする時の当ブログの記事を読む順番を書きました。機能を積み上げていく形になるので便利かも?gametukurikata.com2019.06.21の記事に記載の順番で見て頂くとUnityの基本的な使い方がわかり、簡単なアクションゲームや、TPSゲームの作成までが出来ます。自作タイピングゲームタイピングゲームを作りました。WebGL形式なのでPCのブラウザで遊べます。以下からプレイ出来ます。FinalTypingUnityを使って作成したローマ字入力のタイピングゲームです。gametukurikata.com2022.01.02お知らせ2023/01/24個人的にUnity2022.2.3f1をインストールしました。2022/10/14UnityのIKを使って足の位置と角度を地面に合わせる機能Unityのゲームでキャラクターの両足が別の高さの地面の上にある時にそれぞれの足をそれぞれの地面につけるようにする機能を作成しますgametukurikata.com2016.04.11機能を少し修正しました。2020/09/19コメント欄は閉鎖しました。今までコメントを投稿してくださった方はありがとうございました。(^^)/2018/08/07わたくしに出来る事は既に記事にしてあるので、ブログ右上の検索窓を活用してください。(._.)またブログの最初の方の機能を積み上げていく記事に関しての疑問点は当ブログ記事のスクリプトの説明と寄せられた質問への回答Unityを使った3Dゲームの作り方(かめくめ)の機能積み上げ形式の記事のスクリプトの説明と寄せられた記事の機能についての質問への回答を掲載しています。gametukurikata.com2019.08.01Unityを使い始めたばかりの人がつまづきやすい点を解消するUnityを使い始めたばかりの人が結構な確率で陥る不具合や疑問点を解消していきます。基本的にはブログに寄せられた質問への回答という感じです。gametukurikata.com2018.12.04も参照してみてください。小・中学生によるデジタルコンテンツ開発の全国大会ですuycc.unity3d.jp2022年大会の先行エントリーが開始されているようです。当ブログはハイスピードプランです。WordPressの編集画面の動作が早くなった。当ブログはハイスピードプランです。WordPressの編集画面の動作が早くなった。記事の内容に質問がある方へUnityを使った3Dゲームの作り方(かめくめ)の歩き方UnityのJavaScriptとC#を読み替えてどちらでも対応出来るようにするホーム検索トップサイドバータイトルとURLをコピーしました。