Godot入門
環境構築
VSCodeとの連携:
これをやっておくと便利ではあるが、Godot上のエディタも引き続き使う(debuggerなど)ので、設定した上でチェックボックスは外しておくのがよさそう
VSCode側に出るエラーの潰し方:
ビルド・デバッグまでVSCodeで完結する場合
Cursorの場合:
https://docs.godotengine.org/en/stable/ をドキュメントとして登録しておくと良いかも
GitHubとの連携
他人の作ったプロジェクトをクローンする場合、.godotフォルダはプロジェクトを開くと自動で作られるので大丈夫勉強
オンラインで完結するチュートリアル(英語)
ローカルでやれるチュートリアル(日本語・公式)
図形系に使えるかもしれないのでメモ:
二次元配列の書き方:
演算子の書き方:まだ早いけどテストの書き方:
色の扱い方:
クラスを作りたい時は:
- ファイル名を他のクラス(例:ColorRect)に揃えて、パスカルケースにしておくと良い
- class_nameをファイル冒頭・extendsの後にでも記載しておく
extends ColorRect
class_name WallBase
superで親クラスの関数拡張(override)が可能
func add_trim(value: int) -> void:
super.add_trim(value)
size.y = get_grid() * get_edge_pos()
return
クリックの当たり判定を取れるようにするには:
- クリックしたいもの(例えば敵)を
Area2D
で作成 - 子ノードに
CollisionShape2D
を追加- インスペクタの
Shape
で敵の形状に適したShape
を選択する
- インスペクタの
- 敵(
Area2D
)を開き、インスペクタのノードでCollisionObject2D > input_event()
を選ぶ - gdscriptに
func _on_***_input_event()
が追加されるので、クリックした時の処理を書く- 例えばクリックしたら消えるようにするなら、if文を書いて
queue_free()
する
- 例えばクリックしたら消えるようにするなら、if文を書いて
メモ:Controlを入れ子で使うことで、片方をカメラ的に使うことができる(2Dゲームにおいて)
Subviewportを試したが、Subviewportではマウスクリック座標がずれたり、クリックを渡すこと自体が難しかったり、トラブルが多く解決できなかった
ENUMの書き方:
ゲームの状態を管理するStateを作る
extends Node
enum State {PRE_GAME, PLAYING, PAUSED, GAME_OVER, GAME_CLEAR}
var _current_state:int = State.PRE_GAME
func current_state() -> int:
return _current_state
func game_over() -> void:
_current_state = State.GAME_OVER
print("game over")
return
func game_clear() -> void:
_current_state = State.GAME_CLEAR
print("game clear")
return
上記のStateのように、プロジェクト全体で共有したい値はグローバル変数として設定できる
上記のファイルを「State」としてグローバル変数に設定した場合、他ファイルで以下のように呼ぶことができる
func _on_input_event(viewport: Node, event: InputEvent, shape_idx: int) -> void:
if State.current_state() == State.State.GAME_OVER or \
State.current_state() == State.State.GAME_CLEAR:
return
Switch文はmatchを使う
経過時間はTimerではなくTime
いわゆるポーズ画面などはDialogを使うと良さそう
Dialogに載せたColorRectに透過度を指定して、それを描画に反映させるときは、DialogのTransparentをOnにする
使わなかったけど有益:カスタムシグナル
ただ、使いすぎは読みにくいコードの元なので注意
グローバル変数など、既に作った仕組みだけで解決できることも多そう
時間の表示変換:
ランダムな値の作り方色々
公式のこっちを見た方がよいかも
static func()、static varを使うことで、複数呼び出したもの(例えば敵)に共通する状態を持たせることができる
instantiate()は通常そのシーンを呼び出したい.gd側に書くことが多いが(例えば敵.gdをmain.gdで呼び出す)、そのシーン自体でinstantiate()を呼ぶstatic func new_enemy(引数)
を作り、本来呼び出したい.gd側でEnemy.new_enemy(引数)することができる
これにより、呼び出す時点で引数を渡すことが可能になる
なお、static func内で使う変数は通常のvarではなくstatic varとなる
instantiate()の発音はインスタンシエイト(nationがネーションになるのと同じ法則)
new()とinstantiate()の大きな違いは、instantiate()ではシーンが持つ子ノードまで含めて呼ばれるのに対して、new()ではスクリプトしか呼ばれない(子ノードなどが呼ばれずnullになってしまう)
ブラウザゲームへのエクスポート:
今回はgithub pagesを使用した
やり方まとめ:
- 開発で使用しているレポジトリのrootフォルダにdocsフォルダを作成する
- と、開発で使用しているファイルと混ざらないので良い
- godotでエクスポートする
- docsフォルダにエクスポートされたものが入るようにフォルダ指定する
- htmlのファイル名はindex.htmlにしておく(と後々良い)
- GitHubのレポジトリの設定ページを開き、以下の感じで設定する
- わざわざexportsブランチを切るかはお好みで(必要はない)
- この時にindex.htmlが無いと、ルートページにアクセスした時に404エラーになる
秒数表示など、桁数が頻繁に変わるとテキスト表示がチラついてしまうものの調整方法
snapped()で浮動小数点数を任意の小数点数に丸める
Paddingで足りない桁をスペースや0で埋め、任意の桁数に揃える
を組み合わせると、以下のように書ける
_time.text = str("%3.2f" % snapped(elapsed_time() / 1000.0, 0.01)) + "秒"
UI:Themeの作り方
ボタンなどの見た目をまとめて管理するのに使用する
- 最初から角丸や影、ちょっと斜めにするなどの見た目が想定されていて、設定のコピペもできるのでhoverなども作りやすい
- 一々再生しなくても、Theme内のプレビューで軽い動作確認ならできる
UI: Twitterシェアボタンの作り方
見栄えを整えたいのであれば、LinkButtonではなく、通常のButtonなどを使うとよい
(LinkButtonでは、あらかじめURIがプロパティとして用意されているので、気楽にリンクボタンを作成できるが、通常のボタンと異なり、いわゆるテキストに下線が引かれるだけのスタイリングしかできず、Themeを適用しても見た目が変更されない)
OS.shell_open()を使うことで、LinkButtonと同様の挙動となる
var twitter_pretext:String = "https://twitter.com/intent/tweet?url=https://sample.com&via=sampleaccount&text="
var twitter_text:String = ""
var twitter_posttext:String = "&hashtags=GodotEngine,indiedev"
twitter_text = twitter_pretext + "Cleared in " + score + "! " + twitter_posttext
func _on_share_button_pressed() -> void:
OS.shell_open(twitter_text)
return
情報元:
翻訳:CSVでの翻訳ファイルの作成〜適用まで
基本
- ↑のように、KEY, lang, Stringを設定したCSVファイルを作る。
- Project SettingsのLocalizationタブの「Add」から作成したCSVファイルをインポートする。
- 以下のように、CSVに記載したKEYをtr()に渡す。
PauseButton.text = tr("PAUSE")
翻訳が正しく機能しているかは、TranslationServer.set_locale(language)
で言語を切り替えて確認すると良い。
language
には英語ならen
、日本語ならja
が入る。
(動作確認後のコード削除・コメントアウトを忘れずに)
翻訳関連の応用知識
スコア:n点、のように可変するテキストの場合、%sなどのプレースホルダーを使うことができる。
var format_score = "スコア:%s"
score.text = format_score % "10点"
#翻訳時にプレースホルダで値を渡す場合(配列で複数渡すことが可能)
share_text = tr("SCORE_MESSAGE") % [score, time]
プレースホルダーの種類は%s以外にも様々存在する。
動画での説明は以下を参照した:
その他詳細は公式を参照:算術関数(使ったものメモ:随時追加)
abs()
負の値を正の値にする
var b = abs(-1.2) # b is 1.2
fmod()
%
ではintしか扱えないため、floatを扱う場合はfmod()
を使用する
var remainder = fmod(7, 5.5) # remainder is 1.5
アニメーションの付け方