skullball/rust/src/soldier_mesh.rs

84 lines
2.5 KiB
Rust

use godot::{
classes::{
AnimationNodeBlendSpace2D, AnimationPlayer, AnimationTree, ISkeletonModifier3D, Skeleton3D,
SkeletonModifier3D,
},
prelude::*,
};
#[derive(GodotClass)]
#[class(base=Node3D, init)]
pub struct SoldierMesh {
#[export]
hand_attachment: Option<Gd<Node3D>>,
#[export]
animation_tree: Option<Gd<AnimationTree>>,
#[export]
skeleton: Option<Gd<Skeleton3D>>,
#[export]
raygun: Option<Gd<PackedScene>>,
#[export]
skeleton_modifier: Option<Gd<SoldierSkeletonModifier>>,
base: Base<Node3D>,
}
#[godot_api]
impl INode3D for SoldierMesh {
fn ready(&mut self) {}
}
impl SoldierMesh {
pub fn update_movement(&mut self, movement: Vector2) {
if let Some(tree) = &mut self.animation_tree {
tree.set("parameters/Movement/blend_position", &movement.to_variant());
}
}
pub fn update_y_look(&mut self, rotation: f32) {
if let Some(skeleton) = &mut self.skeleton_modifier {
skeleton.bind_mut().rotation = rotation;
}
}
pub fn spawn_raygun(&mut self) {
if let Some(raygun) = &self.raygun {
let node = raygun.instantiate_as::<Node3D>();
self.spawn_weapon(node);
}
}
fn spawn_weapon(&mut self, node: Gd<Node3D>) {
if let Some(hand) = &mut self.hand_attachment {
hand.add_child(&node);
}
}
}
#[derive(GodotClass)]
#[class(base=SkeletonModifier3D, init)]
pub struct SoldierSkeletonModifier {
pub rotation: f32,
base: Base<SkeletonModifier3D>,
}
#[godot_api]
impl ISkeletonModifier3D for SoldierSkeletonModifier {
fn process_modification_with_delta(&mut self, _delta: f64) {
let rot = self.rotation;
let rhand_quat = Quaternion::from_euler(Vector3::FORWARD * -rot);
let lhand_quat = Quaternion::from_euler(Vector3::RIGHT * rot);
if let Some(skeleton) = &mut self.base_mut().get_skeleton() {
let head_idx = skeleton.find_bone("HEAD");
let uar_idx = skeleton.find_bone("UA.R");
let uar_rot = skeleton.get_bone_pose_rotation(uar_idx);
let ual_idx = skeleton.find_bone("UA.L");
let ual_rot = skeleton.get_bone_pose_rotation(ual_idx);
skeleton.set_bone_pose_rotation(head_idx, Quaternion::from_euler(Vector3::RIGHT * rot));
skeleton.set_bone_pose_rotation(uar_idx, uar_rot * rhand_quat);
skeleton.set_bone_pose_rotation(ual_idx, ual_rot * lhand_quat);
}
}
}