続いては、Godot で画面に表示したスライムを実際に動かしてみましょう。まず入力方法を決め、次に座標を変更して動かします。最後にスライムをアニメーションさせます。
※ いきなりここに来た方は、先に「Godot を始めよう」をお読みください。


  • 入力設定
メニュー > プロジェクト > プロジェクト設定...を選択します。
プロジェクト設定
プロジェクト設定にインプットマップというタブがあります。このタブをクリックします。
空のインプットマップ
右側に組み込みアクションを表示とあるので、これをクリックします。
組み込みアクション
よく使う入力に関しては、最初からシステムが用意してくれてるんです。アクション(Action)に、たくさん入力名が並んでいます。簡単に代表的なアクションを説明します。

ui_accept決定ボタン
ui_select選択ボタン
ui_cancelキャンセルボタン
ui_left左に移動
ui_right右に移動
ui_up上に移動
ui_down下に移動

ものすごくたくさんあるので、正直持て余してしまいます。また、ui_accept だからと言って、決定に使わなきゃいけないわけでもありません。この名前は単なる識別子なので、極端な話。ui_accept を押したらプレイヤーが攻撃するってのに使っても良いわけです。ただ、あとから見てワケが分からなくなりますので、名称から想像できる使い方に留めておいたほうが無難です。

さて、組み込みアクションは最初から定義されていますので、今回はこの中から 4方向に移動の識別子を使うことにします。
※既に110回も毎月リピートして飲み続けています。魚系のオイルはなかなか摂りづらいので、私はこういうサプリに頼っています。無味無臭、毎朝6粒飲んでます。ここまで飲み続けていると効果の程は分からなくなってますけどね…


  • プログラムをどこに書くのか
現在、前回の Godot を始めよう から続けて読んでいる場合は、以下のようなノード構成になっていると思います。
ノード構成
Node2D がルートノード、そこにマップ表示として Sprite2D である BackGround がぶら下がっています。そして、そのマップの上に Sprite2D ノードの Slime がぶら下がっています。このような構成の場合、基本はそのシーンのルートノードにプログラムを配置します。Godot では標準言語として GDScript(ジーディースクリプト)が用意されています。Godot に特化したスクリプト言語ですので、こちらを使っていきます。

ます、スクリプトを記述するソースファイルを用意します。左上のシーンから、ルートノードである Node2D をクリックします。すると、インスペクターの表示が Node2D の内容に変化します。
Node2Dのインスペクター
一番下に Script <空> という項目があります。この <空> をマウスでクリックします。
スクリプトの新規作成
これから新しく作るのですから、ここでは「新規スクリプト...」を選択します。
スクリプトをアタッチする
「ノードにスクリプトをアタッチする」──少し日本語としては馴染まないですね^^; これは Node2D ノードに新しいスクリプトファイルを作成し、それを適用するという意味です。パスはスクリプトの名前をつけます。今はオススメの名前のままにしておきましょう。最初から grass.gd と名前がついているのは、シーン名称が grass.tscn だからです。通常はこのようにシーン毎に専用のスクリプトを適用することになるので、このままで良いと思います。拡張子 .gd は Godot の省略形でしょう、たぶん、きっと。

さて、grass.gd を追加適用すると、自動的に表示が Script に変わります。もし、変わらなかった場合は、シーンの Node2D に表示されているスクリプトアイコンをクリックすれば変わります。
スクリプトの編集
さて、スクリプトファイルを作ったは良いのですが、中身が空っぽです。いくつかシステムが用意している関数エントリがあります。C# のフォームプロパティで最初から Load とか FormClosed とか用意されているようなものです。

え? C# は知らない? では C 言語でいう int main(int argc, char *argv[]) のようなものです。……え、C 言語も知らない? N80-BASIC だけ? ははは、それなら「最初からいくつかサブルーチンが用意されている」と思っておきましょう。思うんです!😁

GDScript では関数は func から始まります。よく使う代表的な関数エントリを2つ紹介します。今回は 2D でよく使うという意味なので、3D や物理演算でのエントリは列挙していません。

func _ready():初期化処理
func _process(delta):毎フレーム自動呼び出し(メインルーチン)

とりあえず、この2つだけ知っておけば、実は簡単なゲームなら作れてしまいます。_process の delta は前回のフレームからの経過時間(秒単位)を示します。これを積算すると、ゲーム全体のおおよその経過時間を求めることもできます。今回はこの _process を使ってテストします。



  • 入力して動かす

入力設定の項で説明した入力の識別子を使うと、いとも簡単にゲーム中の入力を得ることが出来ます。例えば方向ボタンの下を押しているかどうかは、
if Input.is_action_pressed("ui_down"):
# 処理
このように書けます。Input.is_action_pressed は押している間ずっと true が返ってきます。連続入力をしたくない場合は、ここを Input.is_action_just_pressed とすれば、押した瞬間だけ true になります。

💡Tips
GDScript では処理範囲はインデントで管理しています。C 言語では {} で範囲設定でしたが、GDScript ではインデントが全てです。うっかりインデントを壊すと全く意図しない動作になりますので注意してください。

入力側はこれでなんとなく分かったと思いますが、今度は動かされる側です。Slime ノードをスクリプトからどう認識させるかですが、これは便利な書き方があります。

@onready var slime = $BackGround/Slime

一つずつ説明します。まず、@onready はスクリプトの最初の初期化で必ず処理する指定となります。処理されるタイミングは _ready() が呼ばれる直前です。var は変数宣言です。GDScript では型宣言は必ずしも必須ではないのです。ただ、変数には var と書けば、あとはシステムが勝手に判断します。slime は変数名です。そして、Slimeノードの格納ですが、$ を入力すると、ノードパスの入力になります。自動入力ヘルパーが大変優秀なので、sli まで入力すると正しいパスを選択肢として表示してくれるので、それを選択するだけです。
自動入力ヘルパー
これでスクリプト側から slime ノードのインスペクター設定を弄れるようになりました。動かすという事は、座標を変更するということです。slime の元となっている Sprite2D は position と global_position という2つのプロパティが座標系としてあります。position は親である BackGround 座標系からの相対座標、global_position は表示上での確定座標となります…が、ちょっと難しいですよね。今回は global_position を弄ることにします。これを弄れば絶対に動きます(たぶん)。
関数名にも自動入力ヘルパーが効く
では、実際に入力していきます。func _pro と打ち込んだ時点で、またしても自動入力ヘルパーが、入力候補を出してきました。_rocess を選択します。

func _process(delta: float) -> void:

func は関数である印、_process は関数名です。delta は引数です。: に続いて float とあるのは、delta の型指定です。この型指定はなくても動いてしまうのですが、引数の型を明確化することで、自動入力ヘルパーが働くこともあるので、私は型指定を書く事をオススメします。-> は返却値指定です。void としているので返却値はありません。関数宣言の終了として : で〆ます。

さて、簡単に左右に動かすスクリプトを組んでみます。
左右に動かすスクリプト
おや?関数名の行が黄色くなりました。よく見ると編集エリアの下側に警告が出ています。
警告1
この警告アイコンをクリックすると
警告内容
どうしてこの警告が出ているかの説明が表示されます…英語で^^; 警告とかエラーのメッセージがちゃんと翻訳されている例を私は知りません。ここが日本語だと、我々日本人にはラクなんですがねぇ。まあ、ギリギリ読めますよね?
UNUSED_PARAMETER パラメータが使われていない
deltaバラメータは_process()関数内で使用されていません。意図しているのなら、アンダースコアを先頭に付加して _delta としなさい。
と、書いてあります。そう、未使用の変数、引数、関数があると警告されるので、未使用が意図的なのであればアンダースコア(_)を先頭に付けろってのが、Godot ルールなのです。
警告が消えた
無事に警告が消えました。では、さっそく動かしてみましょう。▶アイコンを押してもいいですが、私は断然 [F5] 押下による動作開始を推奨します。そのほうが手っ取り早いから😁 画面が表示されたらカーソルボタンの左右で動かしてみてください。
動く!
どうでしたか。ここまで問題なく進めて入れば、左右に動かせると思います。えっ!? 動きが遅い?なんとなく動きもぎこちない?それはそうかもです。理由は_processの呼び出しは一定周期とは言い切れないためです。正しく速度を調整するのであれば、deltaを利用します。
移動速度調整版
const SPEED を変更すれば、移動速度を任意に変更できます。このように delta を上手く活用すれば、移動速度をコントロールすることが出来ます。slime.global_position には Y座標も当然あります。キー入力識別子には "ui_up" と "ui_down" もありますので、自分で4方向の移動に変更してみてください。
※効果があるかどうかは分からないまま既に60回リピート。つまりは5年も飲み続けています。妻はこれに加えて医師から処方されている骨粗鬆症防止薬も服用。気休めかもしれません。これの特徴はとにかく安いってのと美味いって事。単なる毎日の駄菓子と思っても良いかもです。


  • アニメーション

最後に Slime をアニメーションさせましょう。Sprite2D のままでも出来なくはないですが、折角 Godot を使っているのですから、Godot のアニメーション機能を使いたいと思います。

・画像の準備

兎にも角にも、まずはアニメーションさせる画像データです。私の方で用意しておきましたので、以下のデータをダウンロードして解凍してください。

画像は OpenGameArt サイト掲載のデータです。
※ License Creative Commons Zero (CC0)

スライムの画像が3つありますので、まとめてファイルシステムの res:// にドラッグ&ドロップしてください。正常にドラッグ&ドロップできればこのような表示に切り替わります。
ファイルシステムにスライム画像を追加
  • Sprite2D ノードを追加する
続いてノードの準備です。現在の Sprite2D で作られている Slime を選択して [delete]キーを押してください。
既存のSlimeノードを消す
確認ダイアログが出ますので OK をクリックします。これで今まで使ってた Slime は消えました。続いてアニメーションさせる新しいノードを追加します。BackGround を右クリックしてください。
BackGroundを右クリック
子ノードを追加を選択します。Nodeを新規作成というダイアログが出ますので、検索で animate と打ち込むと AnimatedSprite2D が見つかりますので、その項目を選択して作成ボタンをクリックします。私は面倒なので AnimatedSprite2D 項目をダブルクリックしてます。
AnimatedSprite2Dを追加する
追加したアニメノードにいきなり警告アイコンが付いてます。
追加したAnimatedSprite2Dにいきなり警告が
ま、まだ何も悪いコトしてないのに…(まだ?)。こういう時(警告とかエラーのアイコン)はまずはクリックしましょう。するとこんなダイアログが表示されます。
ノードの設定に関する警告
なるほど、とにかく SpriteFrames を作れと言ってるだなと分かります。そこでインスペクターを見てみると…
SpriteFrameが空になっている
あるある、Sprite Frames 項目があります。そして、<空> になってます。Godot では <空> と表示されてたら、これをクリックすると何かが起きます。てぇい!
SpriteFrame空をクリック
案の定、選択肢が出てきました。今回始めて作り始めているので、ここは新規 > SpriteFrames を選択です。
SpriteFrameが追加されて警告は消えた
<空>の表示が消えて、シーンに出ていた警告マークも消えました。消えましたが、それだけです。ここがちょっとだけ分かりづらいポイントなんですが、この時、アニメ編集用の SpriteFrames は作られましたが、作られだけで何も編集されていない状態なのです。編集をするためには、もう一度 Sprite Frames 項目の SpriteFrames(スクショでは途中で文字が切れてSpriteFraとなってる)をクリックします。

ウィンドウ中央下部にアニメーション編集が出来そうな感じアニメ編集フレーム
に変わりました。このままだとちょっと狭いので枠のサイズを変更します。
枠を広げた
さて、ここからどうするか。default はそのままでも良いんですが、なんとなく名前を変えてみましょう。default を軽くクリックすると、名前編集になります。とりあえず移動に使うので、move と変えておきます。
moveに名前を変更
この move がアニメーションの種類です。上にある追加アイコンを押すと、いくつでも項目を増やすことが出来ます。attack として攻撃アニメだとか、damage としてダメージアニメとか、いくつも作って増やすことができます。今回は最初のテストだから move ひとつだけで進めます。

※もうなんていうか見ただけで酸っぱそうというかヨダレが出るというか。ビタミンC系のは酸っぱいだけで間違いなくビタミン入ってるよねと思えるのが良いですよね。私は好きです。そして、これまた安い。ただ、駄菓子の類のようにドカドカ食べては高い買い物になりますのでご注意をw
move にカーソルが合っているのを確認してから、ファイルシステムで slime0.png, slime1.png, slime2.png をまとめて掴んで、アニメーションフレームにドラッグ&ドロップします。
アニメフレームが追加された
アニメーションフレームに、ドロップしたスライム画像が並びました。実はこれで既にアニメーションの指定は出来ていたりします。再生ボタンをクリックしてください。…えっ!? 何も変化しないって?アニメーションのプレビューは、ウィンドウ上部の編集画面となります。2Dボタンを押して切り替えてください。
ビューの切り替えボタンで2Dを押す
もしかすると、これだけではまだ表示されていないかもしれません。追加した Sprite2D などの表示系ノードは、表示位置のデフォルトが 0,0 になっています。そのため、追加したスライムは編集領域の左上である原点にいます。マウスのホイールボタンを押しながらドラッグで編集位置の変更、マウスホイールで拡大率が変わります。見える位置に持ってきてください。
スライムみーっけ!
動いてますよね?ただ、ちょっと動きがぎこちない気がするので調整しましょう。0 → 1 → 2 と画像が変化しています。2 の次は 0 に戻ります。0 から 2 に変化すると、スライムが上にびにょーんと伸びてますが、次の瞬間、また一番最初にいきなり戻ってるので違和感があるのです。2 の次は 1 に戻したいですよね。

そこでファイルシステムから slime1.png をアニメーションフレームにドラッグ&ドロップして追加します。
アニメフレームを追加
どうですか、動きが良くなったと思いませんか?あとはアニメの速度調整です。全体の速度はフレームレートで調整します。デフォルトで 5.0 になっていますので、ここに 10 と入力してみましょう。マウスで当該箇所をクリックして、5.0 を消して、キーボードから 10 と入力して enter です。
10FPSに速度を変更
アニメがキビキビと動くようになりましたよね。今度はフレーム単位の調整です。一番小さい時と一番伸びた時は、少し間を持たせてみます。まず、アニメーションフレームで 0 のスライムをクリックします。次にフレーム持続時間をクリックします。1.0 となってるのを消して、3.0 にしてみます。
フレーム持続時間の調整
良い感じになったと思いません?このようにプログラムだけどアニメを調整するのとは全く異なり、プレビューで実際の動きを見ながらアニメーションの調整ができるのが、この AnimatedSprite2D の強みです。
スライムを画面中央に
あとは、初期位置を画面の中央に移動して、AnimatedSprite2D の設定は完了です。ああ、しまった名前が AnimatedSprite2D のままでしたね。Slime に変更しておきましょう。シーンで名前をクリックすれば、名前の変更が出来るんでしたよね?覚えてますかー
名前をスライムに変更
[F5]を押して実行確認。名前を元と同じ Slime に戻してあるので、そのままキーボードの左右でスライムが動かせます。…が、アニメーションしていないです。これはスクリプトから、再生指示を出していないのが原因です。シーンのスクリプトアイコンをクリックするか、ファイルシステムで grass.gd をダブルクリックするかで、スクリプトの編集に切り替えます。
スクリプトの再編集
アニメーションは一度指定すればずっとループしていますので、最初に一度だけで開始指定をすればよいです。そのため、今回は _ready() でアニメーションを開始させましょう。空いているスペースで func _r まで入力すると自動入力ヘルパーが _ready() -> void: を表示するので、それを選択します。
_readyを追加
この _ready() にアニメーションの開始を記述します。今は中身がないのでエラーになっていますが、スクリプトコードを記述すれば消えますので今は気にしません。slime は AnimatedSprite2D なので .play() メソッドが使えます。ここに "move" と指定すれば、さきほど作成したアニメが再生されるというわけです。
playを追記
これでアニメ開始の設定ができました。[F5]を押して実行してみましょう。
アニメーション出来た。
ここまで問題なく作ってきていれば問題なくアニメしながらスライムを動かせるようになったはずです。ここまでが Godot で2Dゲームを作るうえでの基本中の基本となります。まずは思うままにマップを表示させて、何匹もキャラを登場させられるように遊んでみましょう。

Godot 初期設定に続きます。


※こちらは毎食時に1粒ずつ飲むタイプ。カプセルに入ってるので酸っぱさは感じない。おかげで私には効果があるのかないのかよく分からないという^^; ただ、酸っぱいのが苦手という人には良いかもしれません。