godot-rust / gdnative

Rust bindings for Godot 3
https://godot-rust.github.io
MIT License
3.61k stars 210 forks source link

Export functions from rust to gdscript #1032

Closed ghost closed 1 year ago

ghost commented 1 year ago

Hi, I have stuck on this page https://godot-rust.github.io/book/gdnative/bind/calling-gdscript.html for a long time. I was trying to export functions from rust to gdscript. I followed the instructions multiple time and it didn't worked out. I did put the dll in the Godot and put it on a Node then prints it. But the methods or the functions still not appearing in gdscript. Godot_v3 5 1-stable_win64_7fLF91teCC

use gdnative::prelude::*;
#[derive(NativeClass)]
#[inherit(Node)]
pub struct Features
{   num: u64, }

#[methods]
impl Features
{   fn new(_: &Node) -> Self
    {   godot_print!("loaded Features!");
        Self { num: 1023 }}

    #[method]
    fn arr_gen(&mut self, amount: i32) -> Vec<f32>
    {   let mut arr = Vec::new();
        for _ in 0..amount
        {   self.num *= 0xd1342543de82ef95;
            arr.push((self.num & 0x7fffffff) as f32); }
        arr }}

fn init(handle: InitHandle)
{   handle.add_class::<Features>(); }

godot_init!(init);
extends Spatial

func _ready():
    pass
    var api = Features.new()
    print_debug(api.arr_gen(10))
chitoyuu commented 1 year ago

Do you have the gdnlib and gdns resources set up? Some examples can be found here: https://github.com/godot-rust/gdnative/tree/master/examples/rpc

ghost commented 1 year ago

Yes I did setup the gdnlib and gdns and it still not exposing the Rust functions in GDScript.

[general]

singleton=false
load_once=true
symbol_prefix="godot_"
reloadable=true

[entry]

Windows.64="res://rust/rust.dll"

[dependencies]

Windows.64=[  ]
[gd_resource type="NativeScript" load_steps=2 format=2]

[ext_resource path="res://rust/rust.gdnlib" type="GDNativeLibrary" id=1]

[resource]
resource_name = "Features"
class_name = "Features"
library = ExtResource( 1 )
chitoyuu commented 1 year ago

The resources seem to be alright, but Godot's handling of globally nameable script classes is known to be a bit temperamental. Try saving the project and re-opening it. If that fails then perhaps you can load the gdns explicitly in your GDScript.

If you still have any further problems, please provide the entire output (stdout + stderr) of the Godot editor.

ghost commented 1 year ago

Thanks for the help, I solved it. Because Command Prompt or stdout hint me an error about overflow.

Godot Engine v3.5.1.stable.official.6fed1ffa3 - https://godotengine.org
OpenGL ES 3.0 Renderer: NVIDIA GeForce GTX 1650/PCIe/SSE2
Async. shader compilation: OFF

loaded Features!
thread '<unnamed>' panicked at 'attempt to multiply with overflow', src\lib.rs:17:25
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
ERROR: gdnative-core: method panicked (check stderr for output)
   at: <unset> (<unset>:0)
ERROR: Panic message: attempt to multiply with overflow
   at: <unset> (C:\Users\Administrator\.cargo\registry\src\github.com-1ecc6299db9ec823\gdnative-core-0.11.3\src\private.rs:199)
Null
   At: res://gd/sekai.gd:6:_ready()

Then I fixed the overflow by using wrapping_mul

    #[method]
    fn arr_gen(&mut self, amount: i32) -> Vec<i32>
    {   let mut ret = Vec::new();
        for _ in 0..amount
        {   self.num = self.num.wrapping_mul(0xd1342543de82ef95);
            ret.push((self.num & 0x7fffffff) as i32); }
        ret }}