NPC をコーディングして領地運営するゲーム開発(エラー処理)
通しプレイしながら機能実装しています。
今回は、プレイ中に起きたエラーの処理について書きます。あと、城塞で敵を防衛するのに使う「矢」を作るまでをプレイしていきます。
goto 使ったことによるエラーの対処
NPC を操作する Lua スクリプトで continue を使う代わりに goto を使ったわけですが、Unity アセットの MoonSharp でエラーが起きてしまいました。
↓エラーになった記述`
while true do
::continue::
coroutine.yield()
-- 建築予定地がなければ自宅に移動させる。
local sites = world:buildings(Buildings.PlannedConstructionSite)
if #sites <= 0 then
character:goHome()
goto continue
end
調べたり試行錯誤した結果、このように書くことでエラーが起きなくなりました。
↓エラーにならない記述
::continue::
while true do
coroutine.yield()
多分、goto で local sites = の行が2回評価されることでエラーが起きた気もするのですが、私が Lua に詳しくなくて謎です。
とりあえずエラーにならない記述をサンプルとして掲載しようと思います。
# 異なる変数を渡したことによるエラー時のメッセージ表示
ゲーム側が用意した Lua スクリプトのメソッドを呼び出してエラーになったとき、今までは下記のように「どこでエラーが起きた」かだけ表示されていました。
↓表示されるエラーメッセージ
LuaScripts/character.lua:(84,3-35): attempt to index a nil value`
このエラーこの場合の意味は「そのメソッドはありません」です。
ただ、この character.lua はプレイヤーは閲覧できないし、どのメソッドからの呼び出しなのかもわからないのでデバッグ不可能な状況でした。
なので、エラーまでの呼出履歴を表示するようにしました。
↓修正したエラーメッセージ`
LuaScripts/character.lua:(84,3-35): attempt to index a nil value
an argument was passed that is not of type Building
stack traceback:
[clr]: in function 'Character:canWork'
E:\Document\ScriptedLand\_CustomStages\World_01\Test\lord.lua:(13,6-48): in function '<E:\Document\ScriptedLand\_CustomStages\World_01\Test\lord.lua:4>'
こうすることで、character:canWork() の呼び出しないでエラーが起きてて、それはこの canWork() に渡した引数の型が Building でないよ、というのがわかるようになった、はずです。
# 工房で矢を作ってるあたりの動画
で、機能追加しつつ、いろいろ実装して少し賑やかになった様子の動画がこれです。
<player src="2732836" size="100%" />
よいと思います。
# まとめと今後の予定
ちょっとずつですけど機能追加や改修をしています。引き続きがんばります。