84 lines
2.5 KiB
Rust
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);
|
|
}
|
|
}
|
|
}
|