Переглянути джерело

Make LookAtModifier3D adopt to bone name method

Silc Lizard (Tokage) Renew 10 місяців тому
батько
коміт
b76cdf525b

+ 8 - 2
doc/classes/LookAtModifier3D.xml

@@ -32,8 +32,11 @@
 		</method>
 	</methods>
 	<members>
-		<member name="bone" type="int" setter="set_bone" getter="get_bone" default="0">
-			The bone index of the [Skeleton3D] that the modification will operate on.
+		<member name="bone" type="int" setter="set_bone" getter="get_bone" default="-1">
+			Index of the [member bone_name] in the parent [Skeleton3D].
+		</member>
+		<member name="bone_name" type="String" setter="set_bone_name" getter="get_bone_name" default="&quot;&quot;">
+			The bone name of the [Skeleton3D] that the modification will operate on.
 		</member>
 		<member name="duration" type="float" setter="set_duration" getter="get_duration" default="0.0">
 			The duration of the time-based interpolation. Interpolation is triggered at the following cases:
@@ -48,6 +51,9 @@
 			The forward axis of the bone. This [SkeletonModifier3D] modifies the bone so that this axis points toward the [member target_node].
 		</member>
 		<member name="origin_bone" type="int" setter="set_origin_bone" getter="get_origin_bone">
+			Index of the [member origin_bone_name] in the parent [Skeleton3D].
+		</member>
+		<member name="origin_bone_name" type="String" setter="set_origin_bone_name" getter="get_origin_bone_name">
 			If [member origin_from] is [constant ORIGIN_FROM_SPECIFIC_BONE], the bone global pose position specified for this is used as origin.
 		</member>
 		<member name="origin_external_node" type="NodePath" setter="set_origin_external_node" getter="get_origin_external_node">

+ 54 - 6
scene/3d/look_at_modifier_3d.cpp

@@ -33,7 +33,7 @@
 void LookAtModifier3D::_validate_property(PropertyInfo &p_property) const {
 	SkeletonModifier3D::_validate_property(p_property);
 
-	if (p_property.name == "bone" || p_property.name == "origin_bone") {
+	if (p_property.name == "bone_name" || p_property.name == "origin_bone_name") {
 		Skeleton3D *skeleton = get_skeleton();
 		if (skeleton) {
 			p_property.hint = PROPERTY_HINT_ENUM;
@@ -49,11 +49,11 @@ void LookAtModifier3D::_validate_property(PropertyInfo &p_property) const {
 			p_property.usage = PROPERTY_USAGE_NONE;
 		}
 	} else if (origin_from == ORIGIN_FROM_EXTERNAL_NODE) {
-		if (p_property.name == "origin_bone") {
+		if (p_property.name == "origin_bone" || p_property.name == "origin_bone_name") {
 			p_property.usage = PROPERTY_USAGE_NONE;
 		}
 	} else {
-		if (p_property.name == "origin_external_node" || p_property.name == "origin_bone") {
+		if (p_property.name == "origin_external_node" || p_property.name == "origin_bone" || p_property.name == "origin_bone_name") {
 			p_property.usage = PROPERTY_USAGE_NONE;
 		}
 	}
@@ -75,8 +75,29 @@ PackedStringArray LookAtModifier3D::get_configuration_warnings() const {
 	return warnings;
 }
 
+void LookAtModifier3D::set_bone_name(const String &p_bone_name) {
+	bone_name = p_bone_name;
+	Skeleton3D *sk = get_skeleton();
+	if (sk) {
+		set_bone(sk->find_bone(bone_name));
+	}
+}
+
+String LookAtModifier3D::get_bone_name() const {
+	return bone_name;
+}
+
 void LookAtModifier3D::set_bone(int p_bone) {
 	bone = p_bone;
+	Skeleton3D *sk = get_skeleton();
+	if (sk) {
+		if (bone <= -1 || bone >= sk->get_bone_count()) {
+			WARN_PRINT("Bone index out of range!");
+			bone = -1;
+		} else {
+			bone_name = sk->get_bone_name(bone);
+		}
+	}
 }
 
 int LookAtModifier3D::get_bone() const {
@@ -132,8 +153,29 @@ LookAtModifier3D::OriginFrom LookAtModifier3D::get_origin_from() const {
 	return origin_from;
 }
 
+void LookAtModifier3D::set_origin_bone_name(const String &p_bone_name) {
+	origin_bone_name = p_bone_name;
+	Skeleton3D *sk = get_skeleton();
+	if (sk) {
+		set_origin_bone(sk->find_bone(origin_bone_name));
+	}
+}
+
+String LookAtModifier3D::get_origin_bone_name() const {
+	return origin_bone_name;
+}
+
 void LookAtModifier3D::set_origin_bone(int p_bone) {
 	origin_bone = p_bone;
+	Skeleton3D *sk = get_skeleton();
+	if (sk) {
+		if (origin_bone <= -1 || origin_bone >= sk->get_bone_count()) {
+			WARN_PRINT("Bone index out of range!");
+			origin_bone = -1;
+		} else {
+			origin_bone_name = sk->get_bone_name(origin_bone);
+		}
+	}
 }
 
 int LookAtModifier3D::get_origin_bone() const {
@@ -330,6 +372,8 @@ void LookAtModifier3D::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_target_node", "target_node"), &LookAtModifier3D::set_target_node);
 	ClassDB::bind_method(D_METHOD("get_target_node"), &LookAtModifier3D::get_target_node);
 
+	ClassDB::bind_method(D_METHOD("set_bone_name", "bone_name"), &LookAtModifier3D::set_bone_name);
+	ClassDB::bind_method(D_METHOD("get_bone_name"), &LookAtModifier3D::get_bone_name);
 	ClassDB::bind_method(D_METHOD("set_bone", "bone"), &LookAtModifier3D::set_bone);
 	ClassDB::bind_method(D_METHOD("get_bone"), &LookAtModifier3D::get_bone);
 	ClassDB::bind_method(D_METHOD("set_forward_axis", "forward_axis"), &LookAtModifier3D::set_forward_axis);
@@ -343,6 +387,8 @@ void LookAtModifier3D::_bind_methods() {
 
 	ClassDB::bind_method(D_METHOD("set_origin_from", "origin_from"), &LookAtModifier3D::set_origin_from);
 	ClassDB::bind_method(D_METHOD("get_origin_from"), &LookAtModifier3D::get_origin_from);
+	ClassDB::bind_method(D_METHOD("set_origin_bone_name", "bone_name"), &LookAtModifier3D::set_origin_bone_name);
+	ClassDB::bind_method(D_METHOD("get_origin_bone_name"), &LookAtModifier3D::get_origin_bone_name);
 	ClassDB::bind_method(D_METHOD("set_origin_bone", "bone"), &LookAtModifier3D::set_origin_bone);
 	ClassDB::bind_method(D_METHOD("get_origin_bone"), &LookAtModifier3D::get_origin_bone);
 	ClassDB::bind_method(D_METHOD("set_origin_external_node", "external_node"), &LookAtModifier3D::set_origin_external_node);
@@ -397,14 +443,16 @@ void LookAtModifier3D::_bind_methods() {
 
 	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target_node", PROPERTY_HINT_NODE_TYPE, "Node3D"), "set_target_node", "get_target_node");
 
-	ADD_PROPERTY(PropertyInfo(Variant::INT, "bone", PROPERTY_HINT_ENUM, ""), "set_bone", "get_bone");
+	ADD_PROPERTY(PropertyInfo(Variant::STRING, "bone_name", PROPERTY_HINT_ENUM_SUGGESTION, ""), "set_bone_name", "get_bone_name");
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "bone", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_bone", "get_bone");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "forward_axis", PROPERTY_HINT_ENUM, "+X,-X,+Y,-Y,+Z,-Z"), "set_forward_axis", "get_forward_axis");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "primary_rotation_axis", PROPERTY_HINT_ENUM, "X,Y,Z"), "set_primary_rotation_axis", "get_primary_rotation_axis");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_secondary_rotation"), "set_use_secondary_rotation", "is_using_secondary_rotation");
 
 	ADD_GROUP("Origin Settings", "origin_");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "origin_from", PROPERTY_HINT_ENUM, "Self,SpecificBone,ExternalNode"), "set_origin_from", "get_origin_from");
-	ADD_PROPERTY(PropertyInfo(Variant::INT, "origin_bone", PROPERTY_HINT_ENUM, ""), "set_origin_bone", "get_origin_bone");
+	ADD_PROPERTY(PropertyInfo(Variant::STRING, "origin_bone_name", PROPERTY_HINT_ENUM_SUGGESTION, ""), "set_origin_bone_name", "get_origin_bone_name");
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "origin_bone", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_origin_bone", "get_origin_bone");
 	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "origin_external_node", PROPERTY_HINT_NODE_TYPE, "Node3D"), "set_origin_external_node", "get_origin_external_node");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "origin_offset"), "set_origin_offset", "get_origin_offset");
 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "origin_safe_margin", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater,suffix:m"), "set_origin_safe_margin", "get_origin_safe_margin");
@@ -474,7 +522,7 @@ void LookAtModifier3D::_process_modification() {
 		destination = skeleton->get_bone_pose_rotation(bone);
 	} else {
 		Transform3D origin_tr;
-		if (origin_from == ORIGIN_FROM_SPECIFIC_BONE && origin_bone < skeleton->get_bone_count()) {
+		if (origin_from == ORIGIN_FROM_SPECIFIC_BONE && origin_bone >= 0 && origin_bone < skeleton->get_bone_count()) {
 			origin_tr = skeleton->get_global_transform() * skeleton->get_bone_global_pose(origin_bone);
 		} else if (origin_from == ORIGIN_FROM_EXTERNAL_NODE) {
 			Node3D *origin_src = Object::cast_to<Node3D>(get_node_or_null(origin_external_node));

+ 7 - 1
scene/3d/look_at_modifier_3d.h

@@ -54,7 +54,8 @@ public:
 	};
 
 private:
-	int bone = 0;
+	String bone_name;
+	int bone = -1;
 
 	Vector3 forward_vector;
 	Vector3 forward_vector_nrm;
@@ -64,6 +65,7 @@ private:
 	bool use_secondary_rotation = true;
 
 	OriginFrom origin_from = ORIGIN_FROM_SELF;
+	String origin_bone_name;
 	int origin_bone = -1;
 	NodePath origin_external_node;
 
@@ -123,6 +125,8 @@ protected:
 	virtual void _process_modification() override;
 
 public:
+	void set_bone_name(const String &p_bone_name);
+	String get_bone_name() const;
 	void set_bone(int p_bone);
 	int get_bone() const;
 
@@ -135,6 +139,8 @@ public:
 
 	void set_origin_from(OriginFrom p_origin_from);
 	OriginFrom get_origin_from() const;
+	void set_origin_bone_name(const String &p_bone_name);
+	String get_origin_bone_name() const;
 	void set_origin_bone(int p_bone);
 	int get_origin_bone() const;
 	void set_origin_external_node(const NodePath &p_external_node);