1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
use gdnative::api::*;
use gdnative::prelude::*;
/// The SpinningCube "class"
#[derive(NativeClass)]
#[inherit(MeshInstance)]
#[register_with(Self::register_builder)]
pub struct SpinningCubeReverse {
start: Vector3,
time: f32,
#[property(path = "base/rotate_speed")]
rotate_speed: f64,
}
// __One__ `impl` block can have the `#[methods]` attribute, which will generate
// code to automatically bind any exported methods to Godot.
#[methods]
impl SpinningCubeReverse {
// Register the builder for methods, properties and/or signals.
fn register_builder(_builder: &ClassBuilder<Self>) {
godot_print!("SpinningCube builder is registered!");
}
/// The "constructor" of the class.
fn new(_owner: &MeshInstance) -> Self {
SpinningCubeReverse {
start: Vector3::new(0.0, 0.0, 0.0),
time: 0.0,
rotate_speed: 0.05,
}
}
// In order to make a method known to Godot, the #[export] attribute has to be used.
// In Godot script-classes do not actually inherit the parent class.
// Instead they are "attached" to the parent object, called the "owner".
// The owner is passed to every single exposed method.
#[export]
unsafe fn _ready(&mut self, owner: &MeshInstance) {
owner.set_physics_process(true);
}
#[export]
unsafe fn _physics_process(&mut self, owner: &MeshInstance, delta: f64) {
use gdnative::api::SpatialMaterial;
self.time += delta as f32;
owner.rotate_y(self.rotate_speed * delta * -1.0);
let offset = Vector3::new(0.0, 1.0, 0.0) * self.time.cos() * 0.5;
owner.set_translation(self.start + offset);
if let Some(mat) = owner.get_surface_material(0) {
let mat = mat.assume_safe();
let mat = mat.cast::<SpatialMaterial>().expect("Incorrect material");
mat.set_albedo(Color::from_rgba(self.time.cos().abs(), 0.0, 0.0, 1.0));
}
}
}
|