🎮

godot4.3, rustで実装したArea2D拡張クラスでarea_enteredのシグナルを処理する

2024/12/04に公開

はじめに

godot 4.3を利用しており、rustでArea2Dのクラス(struct)を実装し、area_enteredのシグナルで衝突しているarea2dを処理するときの備忘録です。

Area2Dの拡張の実装

godot4.3のArea2Dなどのクラスをベースにしたものを以下のように実装するとする。

use godot::prelude::*;
use godot::classes::Area2D;

#[derive(GodotClass)]
#[class(base=Area2D)]
struct MyArea2D {
    //...
}

#[godot_api]
impl MyArea2D {
    #[func]
    fn on_area_entered(&mut self, area2d: Gd<Area2D>) {
        // area_enteredのシグナルを受け取ったときの処理
    }
}

シグナルの接続

rustで実装したon_area_enteredにMyArea2Dのarea_enteredシグナルを接続してon_area_enteredが実行する方法として、2つの方法がある。

  1. godotのGUI上でMyArea2Dのシグナルを接続するパネルで選択し、MyArea2Dのon_area_entered関数を選択して接続する。rustで#[func]と実装して引数が合致しているものが表示される。
  2. readyなどでシグナルを接続する実装を行う

rustでの実装例

#[godot_api]
impl IArea2D for MyArea2D {

    // ...

    fn ready(&mut self) {
        // Area2D等のシグナルの接続
        let fn = self.base().callable("on_area_exited");
        self.base_mut().connect("area_exited", &fn);
    }


    // ...
}

on_area_entered引数のarea2dに実装している関数を実行する

area2dのプロパティを取得する

(#[export])などで実装したプロパティを取得する場合
例としてMyArea2D structに実装したmypropertyを取得する例

#[godot_api]
impl MyArea2D {
    #[func]
    fn on_area_entered(&mut self, area2d: Gd<Area2D>) {
        // area_enteredのシグナルを受け取ったときの処理
        if let Ok(m) = area2d.clone().try_cast::<MyArea2D>() {
            let myprop: String = m.bind().get_myproperty().into();
        }

    }
}

area2dに実装した関数を実行する

area_enteredの対象としてMyArea2Dのように独自に実装したクラスの関数(#[func])を呼び出したい場合。
そのままではarea2dがmutableでないので.callで関数を実行できない。

例としてEnemyというArea2Dの拡張に実装したtake_damage関数を呼び出す場合。

// 敵にダメージを与える
let mut enemy = area_2d.try_cast::<Enemy>().unwrap();
enemy.call("take_damage", &[10.to_variant()]);

Discussion