【Godot 4.0】スマホ３Dゲームを作るための勉強　その１２　キャラクターデザインとアニメーション

　ゲームエンジンGodot4.0で3Dスマホゲームを作りたいと思いますが、その前にお勉強しています。
　2023/3/1もstable版がリリースされました。おめでとうございます！
 [Godot_v4.0-stable_win64.exe.zip](https://godotengine.org/download/windows/)を使用しています。

# 目的
　３Dの基本図形を組み合わせてキャラクターをデザインします。
　またアニメーションも設定して動かします。

# Bulletをデザインする
　Playerが発射するもののデザインをします。発射するのは人っぽいものにしましょう。

# ベースプロジェクト
下記で作成したプロジェクトをベースに機能追加をします。
　【Godot 4.0】スマホ３Dゲームを作るための勉強　その１１　敵も攻撃するようにしました
　https://qiita.com/FootInGlow/items/885fd54f8f4992361e06

　github(Godotのプロジェクトマネージャーからインポートして利用できます）
　https://github.com/footinglow/Godot4/tree/main/02_study/S11_enemy_fire_002

## 新規でシーンを作成する
　シーンメニューから新規シーンを実行します。
　３Dシーンのボタンを押下してNode3Dを追加しましょう。名称を「DesignMySoldier」にします。
　Ctrl-S等で保存しましょう。design_my_soldier.tscnという名称になると思います。

## 体と頭を追加する
　DesignMySoldierの子ノードにMeshInstance3Dを追加して、「Body」に名称変更します。
　Bodyの子ノードにMeshInstance3Dを追加して、「Head」に名称変更します。

* Body(MeshInstance3D）にカプセル型を設定します。
　インスペクタ内のMeshInstance3D/Meshを新規CapsuleMeshに設定します。
　インスペクタ内のMeshInstance3D/Meshのアイコンをクリックして、Heightを1.5mにします。

* Head(MeshInstance3D）に球型を設定します。
　インスペクタ内のMeshInstance3D/Meshを新規SphereMeshに設定します。
　インスペクタ内のNode3D/Transform/position/yを1.2mに設定します。

　頭と体ができました。
![Screenshot 2023_03_05 0_02_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/7ac504d0-5768-0a9b-2091-0f0725a669f3.png)

## 腕を追加する
　腕を振るようにしたいので、肩（となるポイント）を追加して、その子として腕を追加します。
　肩の回転のポイントはMarker3Dと使用するとエディター内で視認できるので便利です。

　Bodyの子ノードとしてMarker3Dを追加します。「Shoulder_Right」に名称を変更します。
　インスペクタ内のNode3D/Transform/position/xを0.7m、yを0.7mに設定します。
　後面図で表示すると見やすいです。
![C__Users_hathr_Videos_Captures [ main ↓0 ↑0 ] 2023_03_05 0_03_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/11d81553-bd95-f81e-56df-0d2c5d1297e0.png)

　Shoulder_Rightの子ノードとしてMeshInstance3Dを追加します。「Arm」に名称変更します。
　Armを選択した状態で、インスペクタ内のMeshInstance3D/Meshを新規CapsuleMeshに設定します。
　インスペクタ内のMeshInstance3D/Meshのアイコンをクリックして、Radiusを0.2m、Heightを1.0mにします。
　インスペクタ内のNode3D/Transform/position/yを-0.5mに設定します。
　右腕ができました。
![C__Users_hathr_Videos_Captures [ main ↓0 ↑0 ] 2023_03_05 0_06_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/5d77a2a5-ee79-b559-39ef-23f81dc0f81f.png)

　次に左腕を作りましょう。
　「Shoulder_Right」をコピーして、「Body」を右クリックして貼り付けをします。
　「Shoulder_Right2」ができるので、「Shoulder_Left」に名称を変更します。
　Shoulder_Leftを選択してインスペクタ内のNode3D/Transform/position/yを-0.7mに設定します。
　左腕ができました。
![C__Users_hathr_Videos_Captures [ main ↓0 ↑0 ] 2023_03_05 0_08_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/348da5f7-7697-f069-5bdb-3fc4c839aa89.png)

## 両足を追加します。
　腕をもとに右足を追加しましょう。
　「Shoulder_Right」をコピーして、「Body」を右クリックして貼り付けをします。
　「Shoulder_Right2」ができるので、「Hip_Right」に名称を変更します。
　「Arm」は「Leg」に名称変更します。
　Hip_Rightを選択してインスペクタ内のNode3D/Transform/positionのxに0.2m、ｙに-0.7mを設定します。
![C__Users_hathr_Videos_Captures [ main ↓0 ↑0 ] 2023_03_05 0_11_56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/72d3d628-5bb3-aa43-8a4e-3ece4dbccb2c.png)

　左足を追加します。
　「Hip_Right」をコピーして、「Body」を右クリックして貼り付けをします。
　「Hip_Right2」ができるので、「Hip_Left」に名称を変更します。
　Hip_Leftを選択してインスペクタ内のNode3D/Transform/position/xを-0.2mに設定します。
![C__Users_hathr_Videos_Captures [ main ↓0 ↑0 ] 2023_03_05 0_14_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/3d8f764c-7a8b-523a-ffd1-7e44ec662fb1.png)

　Bulletのデザイン、DesignMySoldierが完成しました！

# 歩くアニメーションを追加する
　歩かせましょう。
　DesignMySoldierを右クリックから「子ノードを追加」して、AnimationPlayerを追加します。
　AnimationPlayerには複数のアニメーションを登録することできます。「Walk」という名前で新規にアニメーションを追加しましょう。

　AnimationPlayerノードを選択すると中央下部にアニメーション用のWindowsが表示されます。
![C__Users_hathr_Videos_Captures 2023_03_05 0_16_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/1f8dc2d1-461d-61ca-a16a-f4066c8f8893.png)

　中央の「アニメーション」メニューをクリックして、「新規」を実行します。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3639313035302f36613062346331612d636339362d633264392d313438642d3864616238376262666435642e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/01f6a767-599c-ef1b-3514-d47a5275a67d.png)
「Walk」と入力してOK押下します。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3639313035302f33353237376562392d306564312d616438322d386264342d3035336637383335666238662e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/c453ad1f-e9dd-10ff-7289-db12ff1c2cfd.png)
アニメーション名「Walk」の編集画面です。横軸は時間です。右のほうに「１」とあるのは1秒のアニメーションという意味になります。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3639313035302f65643663346430642d353432642d313264352d626166632d3735343133353432626165372e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/11842904-90fc-2c4f-17ed-212bdf4df415.png)

　まずは右肩を回転することで、右腕を振るように見えるアニメーションを最初に動かしましょう。
トラックを追加ボタンを押下して「プロパティトラック」を選択します。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3639313035302f36646331643765632d313730382d346233362d626433632d6665366535323730353934632e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/cb88331d-fbb1-7692-13e1-615fba353d4f.png)
右肩であるShoulder_Rightを選択します。
![スクリーンショット (39).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/89350738-c50d-fbc0-1882-616146de5d0f.png)
右肩Shoulder_Rightのプロパティのうちアニメーションで変更可能な一覧が表示されます。
回転したいので、rotationを選択してOKします。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3639313035302f61343361333264652d346362372d343462392d363238302d6561633530323961663865342e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/0f86df67-02bb-4cd7-00df-837813997aa7.png)
「Shoulder_Right」のrotationがトラックに追加されました。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3639313035302f36343239326531322d326564322d643839372d303737322d3331653134666336663730342e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/48aeb072-6f91-f88c-2c54-6514c0c6cff0.png)

　歩くアニメーションは自動で再生して、歩いている間はずっと腕をふりつづけたいです。
　また右手を後ろから前にふって、前から後ろに戻すまで2秒にしたいと思います。
　下記のように設定します。　
　
　・読み込み後自動再生をON（クリックして青にする）
　・アニメーションループを有効（クリックして青にする）
　・アニメーションの長さを２秒
　![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3639313035302f35333665633239372d356330372d393430342d306338382d3064343431623039613130662e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/ec3c781b-d6aa-5563-a29a-673cb4a32991.png)

　次にキーポイントを追加します。アニメーションの長さを2秒に設定したので、０～2秒の時間軸上にキーポイントを作成して、そのときのrotationの値を設定します。キーポイントとキーポイントの間の値はGodotが自動で途中の値を計算してくれるのでとても便利です。

　rotationの右側、0秒のあたりを右クリックして「キーを挿入」を実行します。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3639313035302f31373065306161352d333066332d396362352d656366312d3934663361346563626139312e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/b5a3df14-96d2-9adc-de1e-0123c2367c38.png)
　このようにキーを挿入したところにキーポイントを表す点が追加されます。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3639313035302f38666230313631372d393737612d393739392d323261372d3836386636616433353631332e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/3a1f196b-4a8e-4f03-3c30-b9af894792ef.png)
　1秒のあたりにも右クリックしてキーポイントを追加しましょう。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3639313035302f30613338326337372d613364642d613464622d613036312d3230646530343132353466382e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/37aa8834-d88d-4ba9-9564-268cb2cc411f.png)
　0秒の時と1秒の時のrotationを設定しましょう。
　まず0秒のキーポイントをクリックすると、インスペクタにキーポイントの情報が表示されます。Timeが0ピッタリではない場合０にします。xを-45°にします。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3639313035302f32613734333731332d633838332d653932622d393537612d3661633932336132336130632e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/94375248-7df7-cc3c-5d7c-6b6e699fb0fe.png)
　次に1秒のキーポイントをクリックします。
　Timeを1.0にして、xは45°にします。

　では動きを見てみましょう。
　アニメーションウインドウ左上に、▶（右向き三角）のボタンを押下します。
　右手をふっているでしょうか。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3639313035302f34633666373130642d613630642d383864362d396465382d6166663862373533353930662e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/550ff0a0-a78e-89d3-921b-98eee1326811.png)

　では同じ操作をShoulder_Left、Hip_Right、Hip_Leftにも行いましょう。
　トラックを追加ボタンを押下して「プロパティトラック」を選択し、対象のノード（Shoulder_Left、Hip_Right、Hip_Left）を選択して、rotationを追加します。
　キーポイントを０秒と１秒に追加しましょう。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3639313035302f66333236316230312d616633612d383164312d633064622d3366643436346266373730362e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/dc4aba04-c257-559e-28ea-91ff58ff477f.png)

 rotation/xを下記のように設定します。右腕と左腕は逆、右腕、右足は逆にふるようにします。
|ノート|０秒の時のrotation/xの値|1秒の時のrotation/xの値|
|:-|:--:|:-:|
|Shoulder_Right|-45°|45°|
|Shoulder_Left|45°|-45°|
|Hip_Right|45°|-45°|
|Hip_Left|-45°|45°|

　実行しましょう。
　右腕と左腕は交互に動いているか確認しましょう。
　右腕と右足、左腕と左足が交互に動いている確認しましょう。
![(_) design_my_soldier.tscn - S11_enemy_fire_002 - Godot Engine 2023_03_05 0_32_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/7661c7da-4b20-9ed4-8142-bb32b06fd943.png)

　次の作業に入る前に保存します。

# Bulletにデザインを適用します。
　Bullet.tscnに今作成したデザインを以下のいずれかの手順で適用しましょう。

　Bullet.tscnを開いてから下記いずれかの手順でdesign_my_soldier.tscnを追加します。
　・ファイルシステム内のdesign_my_soldier.tscnをBullet.tscn内のBulletノードにドラッグアンドドロップする
　・Bulletを右クリックしてInstantiate Child Sceneを実行後design_my_soldier.tscnを選択

　サイズ感があっていませんので縮小する必要があります。右側にあるのがもともとのBulletのサイズです。（比較できるように、Ｘ軸プラス方向に適当に移動しました。後で削除します）
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3639313035302f32626436393564372d336338312d326139652d613035662d6665363238626131326664352e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/d3f5b26d-43ab-4ebf-2372-533e36527478.png)

　DesignMySoldierを選択します。
　インスペクタ内のNode3D/Transform/scale/xを0.2に設定します。
　xを変更するとｙとｚも同じ値になりますね。
　元のサイズ感と同じくらいになりました。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3639313035302f37646338356631392d353031612d613233312d663363662d3631396134393338333237312e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/2b6b04fc-9311-9432-40f7-9d8bae815b19.png)
　もともとあったMeshInstance3Dは不要になったので削除しましょう。

　キャラクターはグローバル座標系のｙ＝０に設定すると地面に立っているように設定します。
　３Ｄ表示で左側面図等で表示すると地面に埋まっていますね。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3639313035302f65363330363631642d663331612d386134342d646235622d3133386630663631623636662e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/4655605a-f873-2ad1-22ab-2e7da1e20176.png)

　Bulletを選択してNode3D/Transform/position/ｙを0.3mにしましょう。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3639313035302f62383337353830362d326231662d373665622d323164382d3632663537343334363730622e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/59551cb3-755b-2f3f-2f9f-7d12bbd07997.png)

:::note
CollisionShape3Dと大体同じ位置、同じ大きさになっていることを確認しましょう。
:::

　実行しましょう。
　発射すると人が歩いていきます。

# 影をつけて立体的にします。
　せっかくの戦士がのっぺりしているので、影をつけて立体的にしましょう。
　
　global.tscnのDirectionalLight3Dを選択して、インスペクタのDirectionalLight3D/Light3D/Shadowをオンにします。
　影がつきましたね。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3639313035302f64626530323131632d646465342d336630662d313237622d6535303438613632646564362e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/b1b18664-423e-1a89-705f-f57acfc28e5b.png)

　影が長すぎるのでDirectionalLight3Dの向きを変更します。
　DirectionalLight3Dを選択して、インスペクタ内のNode3D/Transform/rotationのｘを-60°、ｙを50°に設定します。

　実行します。
　いい感じに影が付きました。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3639313035302f64343534616462372d393336302d333263372d316362632d6263306535636232663435312e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/834fc83f-2ce1-6d43-4009-e26d9aba4713.png)

# 戦うアニメーションを追加する
　ひとつ戦うアニメーションを追加しましょう。
　両腕を高く振り上げて、殴りつけるようにします。

## Battleアニメーションを新規追加する
　design_my_soldier.tscnを開いて、DesignMySoldierノードの子ノードのAnimationPlayerを選択すると、すでに作成したWalkのアニメーションが表示されます。
　「アニメーション」ボタンを押下して、「新規」をクリックします。
![スクリーンショット (40).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/a6b66845-b76f-cd6a-b5e9-815808de3e39.png)
　新規アニメーション名は「Battle」にしましょう。
![スクリーンショット (41).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/ace3b63a-5c33-3ef0-0676-ecd21094fdb7.png)

　両肩をアニメーションするので、「＋トラックを追加」から「Shoulder_Right」のrotationと「Shoulder_Left」rotationを追加します。
　
　下記のように設定します。
　・読み込み後自動再生はOFFのまま（アイコンの色が白がOFF、青がONです）
　・アニメーションループを有効（クリックして青にする）
　・アニメーションの長さを１秒

　「Shoulder_Right」のrotationの右側0秒と0.5秒のところを右クリックして、「キーを挿入」しましょう。
　「Shoulder_Left」rotationにも同様にキーポイントを追加します。
![design_my_soldier.tscn - S13_CharacterDesignAnimation_002 - Godot Engine 2023_03_05 22_48_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/c0988527-afc7-1271-d80c-d6f017ea3e4a.png)

:::note
　アニメーションの「読み込み後自動再生」はアニメーションの中で1個だけに設定できます。
　Battleの読み込み後自動再生を一度ONにするとWalkの読み込み後自動再生がOFFになっているので、改めて、Walkを選択して読み込み後自動再生をONにしてください。
![スクリーンショット (54).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/caf06bb7-882d-a561-cda0-a186ba50cec8.png)
:::

　挿入したキーをクリックすると右側のインスペクタに詳細情報が表示されるのでそれぞれ以下のように設定しまします。
|ノート|0秒の時のrotation/xの値|0.5秒の時のrotation/xの値|
|:-|:--:|:-:|
|Shoulder_Right|135°|215°|
|Shoulder_Left|215°|135°|

　例えば、Shoulder_Rightの0.5秒のキーをクリックして下記のように設定します。
![C__Users_hathr_Videos_Captures 2023_03_05 19_21_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/0999ebc5-82e7-e5b7-8f9a-c3535cf04a54.png)

　アニメーションの再生ボタン（▶）クリックして再生しましょう。
![(_) design_my_soldier.tscn - S11_enemy_fire_002 - Godot Engine 2023_03_05 19_27_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/95455aac-c27a-64d3-b89f-4f2cf83efb0d.png)

## GDScriptでアニメーションを選択する
　GDScriptでWalkアニメーションとBattleアニメーションを選択するようにします。

　Battle中を判断するのは、Bullet.tscnのBulletノードにアタッチしたbullet.gd内で行いますが、アニメーションの設定はdesign_my_soldier.tscn内のスクリプトで実行する必要があるので、design_my_soldier.tscnのDesignMySoldierノードにスクリプトを追加して、アニメーション指示をするAPIを追加します。

　design_my_soldier.tscnを開いて、DesignMySoldierノードを右クリックして、「スクリプトをアタッチ」します。
![スクリーンショット (43).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/5db52d4c-1698-69ae-ec4e-823207e8cb84.png)

　下記のようにアニメーションを実行するAPIを追加しましょう。
 
```GDScript
extends Node3D

func animation_play(name):
	$AnimationPlayer.play(name)
```

* $AnimationPlayer.play(name)
 play関数の引数nameに設定したアニメーション名のアニメーションを実行します。

　次はBullet.gdを修正して、今追加したanimation_playメソッド呼ぶ処理を追加します。
　「func _physics_process(delta):」メソッド内で衝突判定をした後、衝突した場合は、「battle_pos」に衝突位置が設定されるので、battle_posが設定されている場合はBattleアニメーションを再生して、そうではない場合は、Walkアニメーションを再生するようにします。


``` GDScript
 :
	# HPが0になったら消える
	if m_hp < 0:
		queue_free()

	# アニメーションの設定
	if battle_pos:
		$DesignMySoldier.animation_play("Battle")
	else:
		$DesignMySoldier.animation_play("Walk")
	
	# バトル中の相手、センシングした敵の順に目標位置を設定する
	if battle_pos:
 :
```

　実行しましょう。
　最初歩いている人が、EnemyもしくはEnemyBulletに衝突すると戦いを始めます。
![Screenshot 2023_03_05 19_41_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691050/d397502a-45c2-dfd4-05d7-bf6368a4f15c.png)


　以上