Spatialギズモプラグイン

はじめに

Spatialギズモプラグインは、あらゆる種類のSpatialノードにアタッチされたギズモを定義するためにエディタおよびカスタムプラグインによって使用されます。

このチュートリアルでは、独自のカスタムギズモを定義するための2つの主なアプローチを示します。最初のオプションはシンプルなギズモに適しており、プラグイン構造の混乱を減らします。2番目のオプションでは、ギズモごとのデータを保存できます。

注釈

このチュートリアルは、一般的なプラグインの作成方法を既に知っていることを前提としています。疑わしい場合は、プラグインの作成 ページを参照してください。

EditorSpatialGizmoPlugin

選択するアプローチに関係なく、新しい EditorSpatialGizmoPlugin を作成する必要があります。これにより、新しいギズモタイプの名前を設定し、ギズモを非表示にするかどうかなど、他の動作を定義できます。

これは基本的なセットアップです:

# MyCustomGizmoPlugin.gd
extends EditorSpatialGizmoPlugin


func get_name():
    return "CustomNode"
# MyCustomEditorPlugin.gd
tool
extends EditorPlugin


const MyCustomGizmoPlugin = preload("res://addons/my-addon/MyCustomGizmoPlugin.gd")

var gizmo_plugin = MyCustomGizmoPlugin.new()


func _enter_tree():
    add_spatial_gizmo_plugin(gizmo_plugin)


func _exit_tree():
    remove_spatial_gizmo_plugin(gizmo_plugin)

シンプルなギズモの場合、EditorSpatialGizmoPlugin を継承するだけで十分です。ギズモごとのデータを保存する場合、またはGodot 3.0ギズモを3.1+に移植する場合は、2番目のアプローチを使用する必要があります。

シンプルなアプローチ

最初のステップは、カスタムギズモプラグインで、has_gizmo() メソッドをオーバーライドして、spatialパラメーターがターゲットタイプの場合に true を返すようにすることです。

# ...


func has_gizmo(spatial):
    return spatial is MyCustomSpatial


# ...

次に、redraw() のようなメソッドまたはすべてのハンドル関連のメソッドをオーバーライドできます。

# ...


func _init():
    create_material("main", Color(1, 0, 0))
    create_handle_material("handles")


func redraw(gizmo):
    gizmo.clear()

    var spatial = gizmo.get_spatial_node()

    var lines = PoolVector3Array()

    lines.push_back(Vector3(0, 1, 0))
    lines.push_back(Vector3(0, spatial.my_custom_value, 0))

    var handles = PoolVector3Array()

    handles.push_back(Vector3(0, 1, 0))
    handles.push_back(Vector3(0, spatial.my_custom_value, 0))

    gizmo.add_lines(lines, get_material("main", gizmo), false)
    gizmo.add_handles(handles, get_material("handles", gizmo))


# ...

_init メソッドでマテリアルを作成し、get_material() <class_EditorSpatialGizmoPlugin_method_get_material> ` を使用して `redraw メソッドで取得したことに注意してください。このメソッドは、ギズモの状態(選択または編集可能、またはその両方)に応じて、マテリアルのバリアントの1つを取得します。

したがって、最終的なプラグインは次のようになります:

extends EditorSpatialGizmoPlugin


const MyCustomSpatial = preload("res://addons/my-addon/MyCustomSpatial.gd")


func _init():
    create_material("main", Color(1,0,0))
    create_handle_material("handles")


func has_gizmo(spatial):
    return spatial is MyCustomSpatial


func redraw(gizmo):
    gizmo.clear()

    var spatial = gizmo.get_spatial_node()

    var lines = PoolVector3Array()

    lines.push_back(Vector3(0, 1, 0))
    lines.push_back(Vector3(0, spatial.my_custom_value, 0))

    var handles = PoolVector3Array()

    handles.push_back(Vector3(0, 1, 0))
    handles.push_back(Vector3(0, spatial.my_custom_value, 0))

    gizmo.add_lines(lines, get_material("main", gizmo), false)
    gizmo.add_handles(handles, get_material("handles", gizmo))


# You should implement the rest of handle-related callbacks
# (get_handle_name(), get_handle_value(), commit_handle()...).

redrawメソッドにいくつかのハンドルを追加しただけですが、ハンドルが適切に機能するようにするには、残りのハンドル関連のコールバックを EditorSpatialGizmoPlugin に実装する必要があります。

代替アプローチ

場合によっては、:ref:`EditorSpatialGizmo <class_EditorSpatialGizmo>`の独自の実装を提供したいこともあります。これには、各ギズモに状態を保存したい場合や、古いギズモプラグインを移植しているため、書き換えプロセスを行わない場合などがあります。

これらの場合、行う必要があるのは、新しいギズモプラグインで create_gizmo() をオーバーライドするだけです。したがって、ターゲットにするSpatialノードのカスタムギズモ実装を返します。

# MyCustomGizmoPlugin.gd
extends EditorSpatialGizmoPlugin


const MyCustomSpatial = preload("res://addons/my-addon/MyCustomSpatial.gd")
const MyCustomGizmo = preload("res://addons/my-addon/MyCustomGizmo.gd")


func _init():
    create_material("main", Color(1, 0, 0))
    create_handle_material("handles")


func create_gizmo(spatial):
    if spatial is MyCustomSpatial:
        return MyCustomGizmo.new()
    else:
        return null

This way all the gizmo logic and drawing methods can be implemented in a new class extending EditorSpatialGizmo, like so:

# MyCustomGizmo.gd
extends EditorSpatialGizmo


# You can store data in the gizmo itself (more useful when working with handles).
var gizmo_size = 3.0


func redraw():
    clear()

    var spatial = get_spatial_node()

    var lines = PoolVector3Array()

    lines.push_back(Vector3(0, 1, 0))
    lines.push_back(Vector3(gizmo_size, spatial.my_custom_value, 0))

    var handles = PoolVector3Array()

    handles.push_back(Vector3(0, 1, 0))
    handles.push_back(Vector3(gizmo_size, spatial.my_custom_value, 0))

    var material = get_plugin().get_material("main", self)
    add_lines(lines, material, false)

    var handles_material = get_plugin().get_material("handles", self)
    add_handles(handles, handles_material)


# You should implement the rest of handle-related callbacks
# (get_handle_name(), get_handle_value(), commit_handle()...).

redrawメソッドにいくつかのハンドルを追加しただけですが、ハンドルが正しく機能するようにするには、残りのハンドル関連のコールバックを EditorSpatialGizmo に実装する必要があります。