defold メモ

defold で気づいたことを書いていきます


gui_script から go.get_id() すると

You can only access go.* functions and values from a script instance (.script file)  

のエラーとなる
が, もともと取得済で global 下などに保存していた go_id に post することはできる


下記のエラーのさい, リビルドしてもエラー解消しなかったが, defold 再起動でエラー解消した

WARNING:RESOURCE: Resource not found: /assets/xx/xx.luac
WARNING:RESOURCE: Unable to create resource: /assets/xx/xx.scriptc
WARNING:RESOURCE: Unable to create resource: /assets/xx/xx.goc
ERROR:GAMEOBJECT: Could not instantiate game object from prototype /assets/xx/xx.goc.
WARNING:RESOURCE: Unable to create resource: /main/main.collectionc

go.get_world_position() で取得する world_position は go.set_position() のあと即時反映されない

非同期で反映される

go.get_position() で取れる position は即時反映されている


parent の付け替えと同時に, z 位置を 新 parent との相対位置で指定して変更したいとき

注意) 下記の考察を書いているとき, go.set_parent() 関数はまだないころでした
go.set_parent() ができてから, この関数でも試してみましたが, 内部的には msg.post() で parent 設定していると思われます
なので, 下記の記述はまだ有効と思います

x, y 位置は そのままか, せめて 意図しない位置に突然表示されないようにしたい

提供されている関数などの確認

parent の付け替え は

msg.post(url, "set_parent", {parent_id = p_id, keep_world_transform = 1})

で行う

msg.post() なのでこの処理は非同期

parent 付け替え後に実行する callback function を与える仕組みはなさそう

パラメータ keep_world_transform = 1 or 0 で world_position を維持するか parent との相対 position を維持するかを選択できる

ただしこれは x, y, z まとめてとなる
z だけ別に設定はできない

world position から指定する go.set_world_position() のような関数は 提供されていない

go.set_position() は即時反映されるが, その直後にその go.get_world_position() は即時反映されていないので取得できない

以上を踏まえ,

parent 付け替えと同時の z 指定 を一箇所で処理したい場合は,

z に新しい相対位置を設定

現位置 の 新 parent からの 相対 x, y を 算出して設定

keep_world_transform = 0 で parent 付け替え

が妥当 (と思われる)

これでも 1 フレームだけ変な位置に見えているかもしれないので, それもいやであれば, 位置変更も msg.post() 経由で行うようにし, disable, 位置変更, enable と順番に msg.post() する

と, ここまで考えて, msg.post() で位置変更する仕組みまで作るのであれば, keep_world_transform = 1 で parent 付け替えしたあと msg.post() 経由で z 位置変更するのが 2手でスマート


go.property(“key”, val) で val に function は設定できない

よって go instance に 動的に function を外部から与えられない

msg.post() のパラメータを介して function を与えようとしてもエラーとなる

やりたい場合の
案1: 与えたい function を global で管理し, idx をふっておく その idx を go.property(key, idx) にセットしておき, go.set(id, key, idx) で与える

また, 他の property 値をもとにそのとき計算して得られる値を外部から取ることもできない
( go instance ( self ) に getXxxx() といった関数 ( method ) をつけても 外部からは値を取ることができない )

あらかじめ計算した値を property に設定しておき, 外部からはその値を単純に取得する

毎フレーム変わる値の場合は, 毎フレーム計算し, 設定しておく必要がある

配列の要素数を取得したい場合もこの方法が妥当 (次に記載の方法ではできない)

または 計算に必要な値をすべて go.property(key, val) しておいて, 外部の static method ( global function ) から go.get(id, key) で取得し, 計算する


go.property(“key”, val) で val に array は設定できない

よって go ( self ) 配下の array に 外部から 追加, 削除などしたい 場合は on_message() を介して非同期で行う

array の要素を 外部から get することはできない


z 位置は -1 ~ 1 のあいだ


update() の中で go.delete() を呼んで自分自身を delete しても, update() 内のそのあとの処理は継続される

よって, 以降を実行しない処理イメージのときは, 明示的に return する


factory.create() で与えたパラメータは 作成される go instance の init() 内でも取れる


factory.create() のパラメータに parent はない よって, create() 時に position と parent を指定して 親との相対 position で位置設定することはできない

そうしたことがしたい場合には, parent の script から factory.create() し, そのとき与える position を 自身 ( parent ) の world_position + 相対 position にするのが無難

もしくは, collection ではじめから 親子関係を持つ go 群 を作成しておき, その collection を collectionfactory.create() する


collision は片側からだけ取りたい場合でも collision の mask 設定が相互に付いていなければ取れない


sys.save(file, data) で保存する data table の key は number か string のみ

key に hash は入れられず, err となるので注意

hash を table の val に入れて save すると, err とはならないが, いったん アプリケーションを閉じてから, また開いて同データを load すると

[12722210162474435462 (unknown)]

といったようになってしまう

なぜこうなるのか, そもそも hash() とはどういったもので, 何の利点のために導入されているのかが まだ自分には不明だが, とりあえずこれを回避する

プログラム中では hash を key にしていることが多いが, save data ではこれを string に変換する

hash -> string の逆変換 mapping は持ちたくなかったが, save を作るにあたり持たざるをえないと思われる

vmath.vector3() を save, load することはできる


go の sprite の 色味, 透明度 をパラメータで変えることはできない

( render , shader の知識があればできるのかもしれないがまだそこの知識はない )

gui node ならパラメータから 色味, 透明度 を変えられる


tilemap の tile の 一つ一つに別のフィルターをかけて color を変えることは material や dender.script の編集などをしてもできなさそう

(自分がマニュアルを読んだ限りではできなそうであった)


tilemap の component に動的に position を set して動かすことはできない
背景の 2重スクロールをやるには それぞれの go を作成して 動かす必要がありそう


go.property() に nil を設定することはできない

go.property("key", nil)

とすると, 実行時に

Invalid type (nil) supplied to go.property, must be either a number, boolean, hash, URL, vector3, vector4 or quaternion.

の err となる

各型の 0, 空 に相当する値を代入しておくのが無難

go.property("key", hash(""))
go.property("key", 0)
go.property("key", false)

などとしておく

また, 定義時は上記のように 0, 空 相当の値を入れておいても, 処理中に nil が入ってしまったときに, go.get(“key”) で取得しようとすると次の err となるので注意

'target_url' does not have any property called 'key'

この err msg からだと nil が入ってしまっていることを類推しにくいので 頭の片隅においておくこと


go.property() に _ から始まる変数名を使用できる

go.property("_key", hash(""))

のような property を作っても問題ない


xxx.script の go.property() 部分を dofile() で共通化することはできない (と思われる)

xxx.script の go.property() 部分を共通化したかったので, 共通部分を 別ファイルで作成し, dofile() で実行するようにしたが, できなかった

require() でやろうとしても require() は 1度しか呼ばれないため lua の仕様としてできない

とりあえず, 共通化はあきらめて, 逐次 定義することにする


gui_script から go.script の go.property() で定義されているプロパティ変数を 取得することはできない

よって, gui_script で go.property() 変数を使いたい場合は, gui に msg.post() するさいのパラメータで渡す


gui.animate() のさい, 異なる property であれば, 同一 node に複数の animation を設定することは可

うまく操作しない場合は何らかの別の原因がある


別の gui を重ねて表示するとき, それぞれの node の描画順を明示的に制御することはできない

同時に表示する gui は あらかじめ洗い出しておいて, 1つの gui として作成するのが無難

1つの gui の中であれば node の表示順を指定できる


gui の text node は node 作成 tree の順と関係なく, 文字が手前に表示される


go 内の label の文字も, 他の go の z position や sprite の z position と 関係なく, 手前に表示される


node が gui.set_enabled(node, false) で gui.clone() されたとき, できた node も gui.is_enabled() == false となる


gui.delete_node() は配下の node も自動的に削除される 複製は gui.clone() と gui.clone_tree() とわかれているが, 削除は gui.delete_node() のみ


はじめから親子関係をもつ go 定義 file をつくることはできない
collection でならはじめから親子関係をもつ go 群 を作成可能


go.property() に vmath.vector3() を定義できる