オブジェクトクラス

参考

This page describes the C++ implementation of objects in Godot. Looking for the Object class reference? Have a look here.

一般的な定義

Objectは、ほとんどすべての基本クラスです。Godotのほとんどのクラスは、直接的または間接的に継承されます。オブジェクトはリフレクションと編集可能なプロパティを提供し、それらを宣言することは、このような単一のマクロを使用する必要があります。

class CustomObject : public Object {

    GDCLASS(CustomObject, Object); // this is required to inherit
};

これにより、オブジェクトは、例えば、多くの機能を得ることができます

obj = memnew(CustomObject);
print_line("Object class: ", obj->get_class()); // print object class

obj2 = Object::cast_to<OtherClass>(obj); // converting between classes, this also works without RTTI enabled.

リファレンス:

オブジェクトの登録

ClassDB は、Objectから継承する登録済みクラスのリスト全体と、すべてのメソッドプロパティと整数定数への動的バインディングを保持する静的クラスです。

クラスは呼び出しによって登録されます:

ClassDB::register_class<MyCustomClass>()

登録すると、クラスをスクリプト、コードでインスタンス化したり、デシリアライズ時に再度作成したりできます。

仮想として登録することは同じですが、インスタンス化することはできません。

ClassDB::register_virtual_class<MyCustomClass>()

オブジェクトから派生したクラスは、静的な関数である static void _bind_methods() を上書きすることができます。1つのクラスが登録されると、この静的関数が呼び出され、すべてのオブジェクトのメソッド、プロパティ、定数などが登録されます。この関数は1回だけ呼び出されます。オブジェクト派生クラスがインスタンス化されていても登録されていない場合は、仮想として自動的に登録されます。

_bind_methods の内部には、実行できる事がいくつかあります。関数の登録は次の 1 つです:

ClassDB::bind_method(D_METHOD("methodname", "arg1name", "arg2name"), &MyCustomMethod);

引数の既定値は、逆の順序で渡すことができます:

ClassDB::bind_method(D_METHOD("methodname", "arg1name", "arg2name"), &MyCustomType::method, DEFVAL(-1)); // default value for arg2name

D_METHOD は、効率を高めるために「メソッド名」をStringNameに変換するマクロです。引数名はイントロスペクションに使用されますが、リリース時にコンパイルするとマクロはそれらを無視するので、文字列は使用されず、最適化されます。

その他の例については、コントロールまたはオブジェクトの _bind_methods を確認してください。

十分に文書化されていないモジュールや機能を追加するだけなら、 D_METHOD() マクロは無視しても問題なく、簡潔にするために名前を渡す文字列を渡すことができます。

リファレンス:

定数

クラスには、多くの場合、次のような列挙型があります:

enum SomeMode {
   MODE_FIRST,
   MODE_SECOND
};

メソッドにバインドするときにこれらを動作させるには、enumをintに変換できるように宣言する必要があります。これにはマクロが用意されています:

VARIANT_ENUM_CAST(MyClass::SomeMode); // now functions that take SomeMode can be bound.

定数は、次の方法を使用して _bind_methods 内でバインドすることもできます:

BIND_CONSTANT(MODE_FIRST);
BIND_CONSTANT(MODE_SECOND);

プロパティ (設定/取得)

オブジェクトはプロパティをエクスポートし、プロパティは次の場合に役立ちます:

  • オブジェクトのシリアル化と逆シリアル化。

  • オブジェクト派生クラスの編集可能な値のリストを作成します。

プロパティは通常、PropertyInfo()クラスによって定義されます。通常は次のように構築されます:

PropertyInfo(type, name, hint, hint_string, usage_flags)

例:

PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_RANGE, "0,49,1", PROPERTY_USAGE_EDITOR)

これは「amount」という名前の整数プロパティであり、ヒントは範囲です。範囲は0から49まで1のステップ(整数)です。 エディタ(値を視覚的に編集)でのみ使用できますが、シリアル化されません。

別の例:

PropertyInfo(Variant::STRING, "modes", PROPERTY_HINT_ENUM, "Enabled,Disabled,Turbo")

これは文字列プロパティであり、任意の文字列を受け取ることができますが、エディタは定義されたヒントのみを許可します。使用状況フラグが指定されていないため、既定のフラグは PROPERTY_USAGE_STORAGE および PROPERTY_USAGE_EDITOR です。

「object.h」には多くのヒントと使用フラグがあります。

プロパティはC#プロパティのように動作し、インデックス作成を使用してスクリプトからアクセスすることもできますが、読みやすさには関数の使用が推奨されるため、一般的にこの使用方法はお勧めできません。また、多くのプロパティは、演算子[]を使用しない限りインデックス作成を不可能にする「アニメーション/フレーム」などのカテゴリにバインドされています。

_bind_methods() から、set/get 関数が存在する限り、プロパティを作成してバインドできます。例:

ADD_PROPERTY(PropertyInfo(Variant::INT, "amount"), "set_amount", "get_amount")

これにより、セッターとゲッターを使用してプロパティが作成されます。

_set/_get/_get_property_list を使用してプロパティをバインドします

より柔軟な必要がある場合(つまり、コンテキスト上のプロパティの追加または削除)に、プロパティを作成する追加の方法が存在します。

次の関数はObject派生クラスでオーバーライドできます。これらの関数は仮想ではありません。仮想にしないでください。オーバーライドのたびに呼び出され、前の関数は無効になりません(多重レベル呼出し)。

protected:
     void _get_property_list(List<PropertyInfo> *r_props) const;      // return list of properties
     bool _get(const StringName &p_property, Variant &r_value) const; // return true if property was found
     bool _set(const StringName &p_property, const Variant &p_value); // return true if property was found

また、 p_property を必要な名前と順番に比較しなければならないため、これは少し効率が悪くなります。

動的キャスト

Godotは、オブジェクト派生クラス間の動的キャストを提供します。例:

void somefunc(Object *some_obj) {

     Button *button = Object::cast_to<Button>(some_obj);
}

キャストが失敗した場合は、NULL が返されます。このシステムは RTTI を使用しますが、RTTI が無効になっている場合dでも、少し遅くなりますが、正常に動作します。これは、HTML5 やコンソール (メモリ使用量が少ない) など、バイナリ サイズが小さいプラットフォームで便利です。

シグナル

オブジェクトは、一連のシグナルを定義できます(他の言語のデリゲートと同様)。それらに接続する方がかなり簡単です:

obj->connect(<signal>, target_instance, target_method)
// for example:
obj->connect("enter_tree", this, "_node_entered_tree")

The method _node_entered_tree must be registered to the class using ClassDB::bind_method (explained before).

クラスへのシグナルの追加は _bind_methods で行われ、ADD_SIGNAL マクロを使用します。例:

ADD_SIGNAL(MethodInfo("been_killed"))

通知

All objects in Godot have a _notification method that allows it to respond to engine level callbacks that may relate to it. More information can be found on the Godotの通知 page.

参照

Referenceはオブジェクトから継承され、参照カウントを保持します。参照カウントオブジェクトタイプのベースです。これらの宣言は、Ref<> template を使用して行う必要があります。例:

class MyReference: public Reference {
    GDCLASS(MyReference, Reference);
};

Ref<MyReference> myref(memnew(MyReference));

myref は参照カウントされます。Ref<>templates が参照を指定しなくなったときに解放されます。

リファレンス:

リソース:

ResourceはReferenceを継承するため、すべてのリソースが参照カウントされます。 リソースには、オプションでディスク上のファイルを参照するパスを含めることができます。 これは resource.set_path(path) で設定できます。 これは通常、リソースローダーによって行われます。 2つの異なるリソースが同じパスを持つことはできません。そうしようとするとエラーになります。

パスのないリソースも問題ありません。

リファレンス:

リソースの読み込み

リソースは、次のようにResourceLoader APIを使用して読み込むことができます:

Ref<Resource> res = ResourceLoader::load("res://someresource.res")

そのリソースへの参照が以前に読み込まれ、メモリ内にある場合、リソースローダーはその参照を返します。つまり、ディスク上で参照されているファイルから同時に読み込まれるリソースは 1 つだけです。

  • リソースインタラクティブローダー (TODO)

リファレンス:

リソースの保存

リソースの保存は、リソースセーバー API を使用して行うことができます:

ResourceSaver::save("res://someresource.res", instance)

Instance will be saved. Sub resources that have a path to a file will be saved as a reference to that resource. Sub resources without a path will be bundled with the saved resource and assigned sub-IDs, like res://someresource.res::1. This also helps to cache them when loaded.

リファレンス: