parent
02dd1c4b61
commit
02506acf67
|
@ -1,13 +1,10 @@
|
||||||
[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://bycoxdvsaakl"]
|
[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://dnpkeelcoonfh"]
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://dcjja0gufc40f" path="res://Models/Characters/Textures/PolygonFantasyHero_Texture_01_B.png" id="1_ysskd"]
|
[ext_resource type="Texture2D" uid="uid://clhhkyqcf5h8f" path="res://Models/Characters/Textures/FantasyRivals_Texture_01_A.png" id="1_soi1r"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
resource_name = "lambert2"
|
resource_name = "lambert2"
|
||||||
diffuse_mode = 2
|
albedo_color = Color(0.906332, 0.906332, 0.906332, 1)
|
||||||
specular_mode = 2
|
albedo_texture = ExtResource("1_soi1r")
|
||||||
albedo_texture = ExtResource("1_ysskd")
|
metallic = 0.2
|
||||||
rim_tint = 1.0
|
roughness = 0.8
|
||||||
grow_amount = -0.264
|
|
||||||
distance_fade_min_distance = 2.4
|
|
||||||
distance_fade_max_distance = 3.25
|
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://bycoxdvsaakl"]
|
||||||
|
|
||||||
|
[ext_resource type="Texture2D" uid="uid://dcjja0gufc40f" path="res://Models/Characters/Textures/PolygonFantasyHero_Texture_01_B.png" id="1_ysskd"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
resource_name = "lambert2"
|
||||||
|
diffuse_mode = 2
|
||||||
|
specular_mode = 2
|
||||||
|
albedo_texture = ExtResource("1_ysskd")
|
||||||
|
rim_tint = 1.0
|
||||||
|
grow_amount = -0.264
|
||||||
|
distance_fade_min_distance = 2.4
|
||||||
|
distance_fade_max_distance = 3.25
|
|
@ -13,8 +13,8 @@ dest_files=["res://.godot/imported/ModularCharacters.fbx-ce6e3e30d0ba5e348821aac
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
||||||
nodes/root_type=""
|
nodes/root_type="CustomizableCharacter"
|
||||||
nodes/root_name="RootNode"
|
nodes/root_name=""
|
||||||
nodes/apply_root_scale=true
|
nodes/apply_root_scale=true
|
||||||
nodes/root_scale=1.0
|
nodes/root_scale=1.0
|
||||||
meshes/ensure_tangents=true
|
meshes/ensure_tangents=true
|
||||||
|
@ -33,11 +33,11 @@ _subresources={
|
||||||
"materials": {
|
"materials": {
|
||||||
"lambert2": {
|
"lambert2": {
|
||||||
"use_external/enabled": true,
|
"use_external/enabled": true,
|
||||||
"use_external/path": "res://Models/Characters/Materials/lambert2.tres"
|
"use_external/path": "res://Models/Characters/Materials/mod_chars_1.tres"
|
||||||
},
|
},
|
||||||
"lambert3": {
|
"lambert3": {
|
||||||
"use_external/enabled": true,
|
"use_external/enabled": true,
|
||||||
"use_external/path": "res://Models/Characters/Materials/lambert3.tres"
|
"use_external/path": "res://Models/Characters/Materials/mod_chars_2.tres"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nodes": {
|
"nodes": {
|
||||||
|
|
|
@ -375,32 +375,6 @@ radius = 0.548248
|
||||||
height = 1.85415
|
height = 1.85415
|
||||||
|
|
||||||
[node name="Player" type="Player"]
|
[node name="Player" type="Player"]
|
||||||
active_customization = {
|
|
||||||
"ArmLowerLeft": 2,
|
|
||||||
"ArmLowerRight": 3,
|
|
||||||
"ArmUpperLeft": 1,
|
|
||||||
"ArmUpperRight": 3,
|
|
||||||
"BackAttachment": 1,
|
|
||||||
"Ear": -1,
|
|
||||||
"ElbowAttachLeft": -1,
|
|
||||||
"ElbowAttachRight": -1,
|
|
||||||
"Eyebrow": 0,
|
|
||||||
"Hair": 13,
|
|
||||||
"HandLeft": 0,
|
|
||||||
"HandRight": 4,
|
|
||||||
"Head": 15,
|
|
||||||
"HeadCoverings": -1,
|
|
||||||
"HelmetAttachment": -1,
|
|
||||||
"Hips": 3,
|
|
||||||
"HipsAttachment": 3,
|
|
||||||
"KneeAttachLeft": -1,
|
|
||||||
"KneeAttachRight": -1,
|
|
||||||
"LegLeft": 12,
|
|
||||||
"LegRight": 12,
|
|
||||||
"ShoulderAttachLeft": 16,
|
|
||||||
"ShoulderAttachRight": -1,
|
|
||||||
"Torso": 5
|
|
||||||
}
|
|
||||||
slide_on_ceiling = false
|
slide_on_ceiling = false
|
||||||
|
|
||||||
[node name="AnimationTree" type="AnimationTree" parent="."]
|
[node name="AnimationTree" type="AnimationTree" parent="."]
|
||||||
|
@ -424,20 +398,46 @@ shape = SubResource("CapsuleShape3D_hqeid")
|
||||||
[node name="PlayerInput" type="PlayerInput" parent="."]
|
[node name="PlayerInput" type="PlayerInput" parent="."]
|
||||||
|
|
||||||
[node name="Model" parent="." instance=ExtResource("1_b4mv3")]
|
[node name="Model" parent="." instance=ExtResource("1_b4mv3")]
|
||||||
|
active_customization = {
|
||||||
|
"ArmLowerLeft": 5,
|
||||||
|
"ArmLowerRight": 5,
|
||||||
|
"ArmUpperLeft": 1,
|
||||||
|
"ArmUpperRight": 1,
|
||||||
|
"BackAttachment": -1,
|
||||||
|
"Ear": -1,
|
||||||
|
"ElbowAttachLeft": 1,
|
||||||
|
"ElbowAttachRight": 1,
|
||||||
|
"Eyebrow": 1,
|
||||||
|
"Hair": -1,
|
||||||
|
"HandLeft": 1,
|
||||||
|
"HandRight": 1,
|
||||||
|
"Head": 8,
|
||||||
|
"HeadCoverings": -1,
|
||||||
|
"HelmetAttachment": -1,
|
||||||
|
"Hips": 2,
|
||||||
|
"HipsAttachment": 5,
|
||||||
|
"KneeAttachLeft": -1,
|
||||||
|
"KneeAttachRight": -1,
|
||||||
|
"LegLeft": 6,
|
||||||
|
"LegRight": 6,
|
||||||
|
"ShoulderAttachLeft": -1,
|
||||||
|
"ShoulderAttachRight": -1,
|
||||||
|
"Torso": 6
|
||||||
|
}
|
||||||
|
|
||||||
[node name="GeneralSkeleton" parent="Model/RootNode" index="0"]
|
[node name="GeneralSkeleton" parent="Model/RootNode" index="0"]
|
||||||
bones/0/rotation = Quaternion(-2.98023e-08, 5.55112e-17, 5.55112e-17, 1)
|
bones/0/rotation = Quaternion(-2.98023e-08, 5.55112e-17, 5.55112e-17, 1)
|
||||||
bones/1/position = Vector3(0.00655603, 0.823848, -0.0163162)
|
bones/1/position = Vector3(0.0064089, 0.824015, -0.0161932)
|
||||||
bones/1/rotation = Quaternion(-0.0184563, -0.0841674, 0.0119519, 0.996209)
|
bones/1/rotation = Quaternion(-0.0186555, -0.0848505, 0.0122633, 0.996144)
|
||||||
bones/2/rotation = Quaternion(0.0087954, 0.00637039, 0.000268324, 0.999941)
|
bones/2/rotation = Quaternion(0.00877745, 0.00637038, 0.000268667, 0.999941)
|
||||||
bones/3/rotation = Quaternion(0.00863832, 0.00637029, 0.000271212, 0.999942)
|
bones/3/rotation = Quaternion(0.00861796, 0.00637028, 0.0002716, 0.999943)
|
||||||
bones/4/rotation = Quaternion(0.00889527, 0.00637052, 0.000266287, 0.99994)
|
bones/4/rotation = Quaternion(0.0088558, 0.00637049, 0.000267043, 0.99994)
|
||||||
bones/5/rotation = Quaternion(-0.0138771, 0.0325252, -0.0066613, 0.999352)
|
bones/5/rotation = Quaternion(-0.0139191, 0.0328765, -0.00679956, 0.999339)
|
||||||
bones/6/rotation = Quaternion(-0.0138652, 0.0325115, -0.00665304, 0.999353)
|
bones/6/rotation = Quaternion(-0.0139146, 0.0328705, -0.00679594, 0.99934)
|
||||||
bones/10/rotation = Quaternion(0.519859, 0.470118, 0.477057, -0.530238)
|
bones/10/rotation = Quaternion(0.519859, 0.470118, 0.477057, -0.530238)
|
||||||
bones/11/rotation = Quaternion(0.247026, 0.839357, -0.458215, -0.156513)
|
bones/11/rotation = Quaternion(0.247455, 0.839095, -0.458569, -0.156207)
|
||||||
bones/12/rotation = Quaternion(-0.0388633, -0.696869, -0.0391896, 0.715072)
|
bones/12/rotation = Quaternion(-0.039877, -0.696571, -0.0402117, 0.715249)
|
||||||
bones/13/rotation = Quaternion(-0.0420051, 0.558654, -0.140026, 0.816415)
|
bones/13/rotation = Quaternion(-0.0420627, 0.558109, -0.139609, 0.816857)
|
||||||
bones/14/rotation = Quaternion(-0.256269, 0.776338, 0.203807, 0.538599)
|
bones/14/rotation = Quaternion(-0.256269, 0.776338, 0.203807, 0.538599)
|
||||||
bones/15/rotation = Quaternion(0.14485, 0.51961, 0.145065, 0.829446)
|
bones/15/rotation = Quaternion(0.14485, 0.51961, 0.145065, 0.829446)
|
||||||
bones/16/rotation = Quaternion(0.159353, 0.516644, 0.140377, 0.829446)
|
bones/16/rotation = Quaternion(0.159353, 0.516644, 0.140377, 0.829446)
|
||||||
|
@ -448,9 +448,9 @@ bones/21/rotation = Quaternion(0.494946, 0.0399225, 0.106743, 0.861418)
|
||||||
bones/22/rotation = Quaternion(0.554517, 0.0271624, 0.0237916, 0.831389)
|
bones/22/rotation = Quaternion(0.554517, 0.0271624, 0.0237916, 0.831389)
|
||||||
bones/23/rotation = Quaternion(0.554045, 0.0389721, 0.0175394, 0.831389)
|
bones/23/rotation = Quaternion(0.554045, 0.0389721, 0.0175394, 0.831389)
|
||||||
bones/27/rotation = Quaternion(0.5168, -0.475173, -0.481158, -0.52499)
|
bones/27/rotation = Quaternion(0.5168, -0.475173, -0.481158, -0.52499)
|
||||||
bones/28/rotation = Quaternion(-0.116079, 0.860613, -0.45194, 0.204012)
|
bones/28/rotation = Quaternion(-0.115133, 0.860735, -0.451588, 0.20481)
|
||||||
bones/29/rotation = Quaternion(0.0201014, 0.71151, -0.0202694, 0.702096)
|
bones/29/rotation = Quaternion(0.0209625, 0.711686, -0.0211379, 0.701867)
|
||||||
bones/30/rotation = Quaternion(0.00817088, -0.59897, 0.0699655, 0.797667)
|
bones/30/rotation = Quaternion(0.00773145, -0.600065, 0.0707188, 0.796782)
|
||||||
bones/31/rotation = Quaternion(-0.256268, -0.776338, -0.203807, 0.538599)
|
bones/31/rotation = Quaternion(-0.256268, -0.776338, -0.203807, 0.538599)
|
||||||
bones/32/rotation = Quaternion(0.14485, -0.51961, -0.145065, 0.829446)
|
bones/32/rotation = Quaternion(0.14485, -0.51961, -0.145065, 0.829446)
|
||||||
bones/33/rotation = Quaternion(0.159352, -0.516644, -0.140377, 0.829446)
|
bones/33/rotation = Quaternion(0.159352, -0.516644, -0.140377, 0.829446)
|
||||||
|
@ -460,19 +460,19 @@ bones/36/rotation = Quaternion(0.49701, -0.238709, -0.0692157, 0.831389)
|
||||||
bones/38/rotation = Quaternion(0.494946, -0.0399222, -0.106743, 0.861418)
|
bones/38/rotation = Quaternion(0.494946, -0.0399222, -0.106743, 0.861418)
|
||||||
bones/39/rotation = Quaternion(0.554517, -0.0271621, -0.0237913, 0.831389)
|
bones/39/rotation = Quaternion(0.554517, -0.0271621, -0.0237913, 0.831389)
|
||||||
bones/40/rotation = Quaternion(0.554045, -0.0389717, -0.0175393, 0.831389)
|
bones/40/rotation = Quaternion(0.554045, -0.0389717, -0.0175393, 0.831389)
|
||||||
bones/50/rotation = Quaternion(-0.083346, 0.046056, 0.991826, 0.0849313)
|
bones/50/rotation = Quaternion(-0.0826276, 0.0457204, 0.991888, 0.085091)
|
||||||
bones/50/scale = Vector3(1.00002, 0.999999, 1)
|
bones/50/scale = Vector3(1.00002, 0.999999, 1)
|
||||||
bones/51/rotation = Quaternion(0.00967535, 0.960162, -0.279261, -0.00298304)
|
bones/51/rotation = Quaternion(0.00967221, 0.960188, -0.27917, -0.00298206)
|
||||||
bones/51/scale = Vector3(1.00002, 0.999999, 1.00002)
|
bones/51/scale = Vector3(1.00002, 0.999999, 1.00002)
|
||||||
bones/52/rotation = Quaternion(0.0779514, 0.536554, -0.840102, -0.0161721)
|
bones/52/rotation = Quaternion(0.0778185, 0.536789, -0.839965, -0.0161634)
|
||||||
bones/52/scale = Vector3(0.999948, 0.999973, 1.00001)
|
bones/52/scale = Vector3(0.999948, 0.999973, 1.00001)
|
||||||
bones/54/rotation = Quaternion(9.7728e-07, 1, -1.50204e-05, 3.50609e-06)
|
bones/54/rotation = Quaternion(9.7728e-07, 1, -1.50204e-05, 3.50609e-06)
|
||||||
bones/54/scale = Vector3(0.999999, 0.999986, 1.00002)
|
bones/54/scale = Vector3(0.999999, 0.999986, 1.00002)
|
||||||
bones/56/rotation = Quaternion(0.187667, 0.133003, 0.969895, -0.0799738)
|
bones/56/rotation = Quaternion(0.188468, 0.132146, 0.969868, -0.079841)
|
||||||
bones/56/scale = Vector3(1.00002, 0.999999, 1)
|
bones/56/scale = Vector3(1.00002, 0.999999, 1)
|
||||||
bones/57/rotation = Quaternion(-0.0100425, 0.957016, -0.289844, 0.00309644)
|
bones/57/rotation = Quaternion(-0.0100069, 0.957327, -0.288819, 0.00308538)
|
||||||
bones/57/scale = Vector3(1.00001, 0.999999, 1.00001)
|
bones/57/scale = Vector3(1.00001, 0.999999, 1.00001)
|
||||||
bones/58/rotation = Quaternion(-0.0689188, 0.610305, -0.788841, 0.0225531)
|
bones/58/rotation = Quaternion(-0.069029, 0.610718, -0.78851, 0.0226031)
|
||||||
bones/58/scale = Vector3(0.999956, 0.999987, 1.00001)
|
bones/58/scale = Vector3(0.999956, 0.999987, 1.00001)
|
||||||
bones/60/rotation = Quaternion(-6.79618e-07, 1, -9.98378e-06, -2.30227e-06)
|
bones/60/rotation = Quaternion(-6.79618e-07, 1, -9.98378e-06, -2.30227e-06)
|
||||||
bones/60/scale = Vector3(0.999999, 0.999991, 1.00001)
|
bones/60/scale = Vector3(0.999999, 0.999991, 1.00001)
|
||||||
|
@ -600,6 +600,9 @@ visible = false
|
||||||
[node name="Chr_Hair_13" parent="Model/RootNode/GeneralSkeleton" index="40"]
|
[node name="Chr_Hair_13" parent="Model/RootNode/GeneralSkeleton" index="40"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
[node name="Chr_Hair_14" parent="Model/RootNode/GeneralSkeleton" index="41"]
|
||||||
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_Hair_15" parent="Model/RootNode/GeneralSkeleton" index="42"]
|
[node name="Chr_Hair_15" parent="Model/RootNode/GeneralSkeleton" index="42"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
@ -714,6 +717,9 @@ visible = false
|
||||||
[node name="Chr_BackAttachment_01" parent="Model/RootNode/GeneralSkeleton" index="79"]
|
[node name="Chr_BackAttachment_01" parent="Model/RootNode/GeneralSkeleton" index="79"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
[node name="Chr_BackAttachment_02" parent="Model/RootNode/GeneralSkeleton" index="80"]
|
||||||
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_BackAttachment_03" parent="Model/RootNode/GeneralSkeleton" index="81"]
|
[node name="Chr_BackAttachment_03" parent="Model/RootNode/GeneralSkeleton" index="81"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
@ -864,6 +870,9 @@ visible = false
|
||||||
[node name="Chr_ShoulderAttachLeft_16" parent="Model/RootNode/GeneralSkeleton" index="130"]
|
[node name="Chr_ShoulderAttachLeft_16" parent="Model/RootNode/GeneralSkeleton" index="130"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
[node name="Chr_ShoulderAttachLeft_17" parent="Model/RootNode/GeneralSkeleton" index="131"]
|
||||||
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_ShoulderAttachLeft_18" parent="Model/RootNode/GeneralSkeleton" index="132"]
|
[node name="Chr_ShoulderAttachLeft_18" parent="Model/RootNode/GeneralSkeleton" index="132"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
@ -879,9 +888,6 @@ visible = false
|
||||||
[node name="Chr_ElbowAttachRight_01" parent="Model/RootNode/GeneralSkeleton" index="136"]
|
[node name="Chr_ElbowAttachRight_01" parent="Model/RootNode/GeneralSkeleton" index="136"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_ElbowAttachRight_02" parent="Model/RootNode/GeneralSkeleton" index="137"]
|
|
||||||
visible = false
|
|
||||||
|
|
||||||
[node name="Chr_ElbowAttachRight_03" parent="Model/RootNode/GeneralSkeleton" index="138"]
|
[node name="Chr_ElbowAttachRight_03" parent="Model/RootNode/GeneralSkeleton" index="138"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
@ -897,9 +903,6 @@ visible = false
|
||||||
[node name="Chr_ElbowAttachLeft_01" parent="Model/RootNode/GeneralSkeleton" index="142"]
|
[node name="Chr_ElbowAttachLeft_01" parent="Model/RootNode/GeneralSkeleton" index="142"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_ElbowAttachLeft_02" parent="Model/RootNode/GeneralSkeleton" index="143"]
|
|
||||||
visible = false
|
|
||||||
|
|
||||||
[node name="Chr_ElbowAttachLeft_03" parent="Model/RootNode/GeneralSkeleton" index="144"]
|
[node name="Chr_ElbowAttachLeft_03" parent="Model/RootNode/GeneralSkeleton" index="144"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
@ -921,10 +924,10 @@ visible = false
|
||||||
[node name="Chr_HipsAttachment_03" parent="Model/RootNode/GeneralSkeleton" index="150"]
|
[node name="Chr_HipsAttachment_03" parent="Model/RootNode/GeneralSkeleton" index="150"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_HipsAttachment_05" parent="Model/RootNode/GeneralSkeleton" index="152"]
|
[node name="Chr_HipsAttachment_04" parent="Model/RootNode/GeneralSkeleton" index="151"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_HipsAttachment_06" parent="Model/RootNode/GeneralSkeleton" index="153"]
|
[node name="Chr_HipsAttachment_05" parent="Model/RootNode/GeneralSkeleton" index="152"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_HipsAttachment_07" parent="Model/RootNode/GeneralSkeleton" index="154"]
|
[node name="Chr_HipsAttachment_07" parent="Model/RootNode/GeneralSkeleton" index="154"]
|
||||||
|
@ -1044,9 +1047,6 @@ visible = false
|
||||||
[node name="Chr_Head_No_Elements_Female_08" parent="Model/RootNode/GeneralSkeleton" index="192"]
|
[node name="Chr_Head_No_Elements_Female_08" parent="Model/RootNode/GeneralSkeleton" index="192"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_Head_No_Elements_Female_09" parent="Model/RootNode/GeneralSkeleton" index="193"]
|
|
||||||
visible = false
|
|
||||||
|
|
||||||
[node name="Chr_Head_No_Elements_Female_10" parent="Model/RootNode/GeneralSkeleton" index="194"]
|
[node name="Chr_Head_No_Elements_Female_10" parent="Model/RootNode/GeneralSkeleton" index="194"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
@ -1065,6 +1065,9 @@ visible = false
|
||||||
[node name="Chr_Head_Female_01" parent="Model/RootNode/GeneralSkeleton" index="199"]
|
[node name="Chr_Head_Female_01" parent="Model/RootNode/GeneralSkeleton" index="199"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
[node name="Chr_Head_Female_02" parent="Model/RootNode/GeneralSkeleton" index="200"]
|
||||||
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_Head_Female_03" parent="Model/RootNode/GeneralSkeleton" index="201"]
|
[node name="Chr_Head_Female_03" parent="Model/RootNode/GeneralSkeleton" index="201"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
@ -1125,7 +1128,7 @@ visible = false
|
||||||
[node name="Chr_Head_Female_22" parent="Model/RootNode/GeneralSkeleton" index="220"]
|
[node name="Chr_Head_Female_22" parent="Model/RootNode/GeneralSkeleton" index="220"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_Eyebrow_Female_02" parent="Model/RootNode/GeneralSkeleton" index="222"]
|
[node name="Chr_Eyebrow_Female_01" parent="Model/RootNode/GeneralSkeleton" index="221"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_Eyebrow_Female_03" parent="Model/RootNode/GeneralSkeleton" index="223"]
|
[node name="Chr_Eyebrow_Female_03" parent="Model/RootNode/GeneralSkeleton" index="223"]
|
||||||
|
@ -1158,7 +1161,7 @@ visible = false
|
||||||
[node name="Chr_Torso_Female_04" parent="Model/RootNode/GeneralSkeleton" index="232"]
|
[node name="Chr_Torso_Female_04" parent="Model/RootNode/GeneralSkeleton" index="232"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_Torso_Female_06" parent="Model/RootNode/GeneralSkeleton" index="234"]
|
[node name="Chr_Torso_Female_05" parent="Model/RootNode/GeneralSkeleton" index="233"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_Torso_Female_07" parent="Model/RootNode/GeneralSkeleton" index="235"]
|
[node name="Chr_Torso_Female_07" parent="Model/RootNode/GeneralSkeleton" index="235"]
|
||||||
|
@ -1230,10 +1233,10 @@ visible = false
|
||||||
[node name="Chr_ArmUpperRight_Female_00" parent="Model/RootNode/GeneralSkeleton" index="257"]
|
[node name="Chr_ArmUpperRight_Female_00" parent="Model/RootNode/GeneralSkeleton" index="257"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_ArmUpperRight_Female_01" parent="Model/RootNode/GeneralSkeleton" index="258"]
|
[node name="Chr_ArmUpperRight_Female_02" parent="Model/RootNode/GeneralSkeleton" index="259"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_ArmUpperRight_Female_02" parent="Model/RootNode/GeneralSkeleton" index="259"]
|
[node name="Chr_ArmUpperRight_Female_03" parent="Model/RootNode/GeneralSkeleton" index="260"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_ArmUpperRight_Female_04" parent="Model/RootNode/GeneralSkeleton" index="261"]
|
[node name="Chr_ArmUpperRight_Female_04" parent="Model/RootNode/GeneralSkeleton" index="261"]
|
||||||
|
@ -1356,10 +1359,10 @@ visible = false
|
||||||
[node name="Chr_ArmLowerRight_Female_02" parent="Model/RootNode/GeneralSkeleton" index="301"]
|
[node name="Chr_ArmLowerRight_Female_02" parent="Model/RootNode/GeneralSkeleton" index="301"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_ArmLowerRight_Female_04" parent="Model/RootNode/GeneralSkeleton" index="303"]
|
[node name="Chr_ArmLowerRight_Female_03" parent="Model/RootNode/GeneralSkeleton" index="302"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_ArmLowerRight_Female_05" parent="Model/RootNode/GeneralSkeleton" index="304"]
|
[node name="Chr_ArmLowerRight_Female_04" parent="Model/RootNode/GeneralSkeleton" index="303"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_ArmLowerRight_Female_06" parent="Model/RootNode/GeneralSkeleton" index="305"]
|
[node name="Chr_ArmLowerRight_Female_06" parent="Model/RootNode/GeneralSkeleton" index="305"]
|
||||||
|
@ -1407,15 +1410,15 @@ visible = false
|
||||||
[node name="Chr_ArmLowerLeft_Female_01" parent="Model/RootNode/GeneralSkeleton" index="319"]
|
[node name="Chr_ArmLowerLeft_Female_01" parent="Model/RootNode/GeneralSkeleton" index="319"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
[node name="Chr_ArmLowerLeft_Female_02" parent="Model/RootNode/GeneralSkeleton" index="320"]
|
||||||
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_ArmLowerLeft_Female_03" parent="Model/RootNode/GeneralSkeleton" index="321"]
|
[node name="Chr_ArmLowerLeft_Female_03" parent="Model/RootNode/GeneralSkeleton" index="321"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_ArmLowerLeft_Female_04" parent="Model/RootNode/GeneralSkeleton" index="322"]
|
[node name="Chr_ArmLowerLeft_Female_04" parent="Model/RootNode/GeneralSkeleton" index="322"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_ArmLowerLeft_Female_05" parent="Model/RootNode/GeneralSkeleton" index="323"]
|
|
||||||
visible = false
|
|
||||||
|
|
||||||
[node name="Chr_ArmLowerLeft_Female_06" parent="Model/RootNode/GeneralSkeleton" index="324"]
|
[node name="Chr_ArmLowerLeft_Female_06" parent="Model/RootNode/GeneralSkeleton" index="324"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
@ -1458,15 +1461,15 @@ visible = false
|
||||||
[node name="Chr_HandRight_Female_00" parent="Model/RootNode/GeneralSkeleton" index="337"]
|
[node name="Chr_HandRight_Female_00" parent="Model/RootNode/GeneralSkeleton" index="337"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_HandRight_Female_01" parent="Model/RootNode/GeneralSkeleton" index="338"]
|
|
||||||
visible = false
|
|
||||||
|
|
||||||
[node name="Chr_HandRight_Female_02" parent="Model/RootNode/GeneralSkeleton" index="339"]
|
[node name="Chr_HandRight_Female_02" parent="Model/RootNode/GeneralSkeleton" index="339"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_HandRight_Female_03" parent="Model/RootNode/GeneralSkeleton" index="340"]
|
[node name="Chr_HandRight_Female_03" parent="Model/RootNode/GeneralSkeleton" index="340"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
[node name="Chr_HandRight_Female_04" parent="Model/RootNode/GeneralSkeleton" index="341"]
|
||||||
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_HandRight_Female_05" parent="Model/RootNode/GeneralSkeleton" index="342"]
|
[node name="Chr_HandRight_Female_05" parent="Model/RootNode/GeneralSkeleton" index="342"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
@ -1506,7 +1509,7 @@ visible = false
|
||||||
[node name="Chr_HandRight_Female_17" parent="Model/RootNode/GeneralSkeleton" index="354"]
|
[node name="Chr_HandRight_Female_17" parent="Model/RootNode/GeneralSkeleton" index="354"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_HandLeft_Female_01" parent="Model/RootNode/GeneralSkeleton" index="356"]
|
[node name="Chr_HandLeft_Female_00" parent="Model/RootNode/GeneralSkeleton" index="355"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_HandLeft_Female_02" parent="Model/RootNode/GeneralSkeleton" index="357"]
|
[node name="Chr_HandLeft_Female_02" parent="Model/RootNode/GeneralSkeleton" index="357"]
|
||||||
|
@ -1563,7 +1566,7 @@ visible = false
|
||||||
[node name="Chr_Hips_Female_01" parent="Model/RootNode/GeneralSkeleton" index="374"]
|
[node name="Chr_Hips_Female_01" parent="Model/RootNode/GeneralSkeleton" index="374"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_Hips_Female_02" parent="Model/RootNode/GeneralSkeleton" index="375"]
|
[node name="Chr_Hips_Female_03" parent="Model/RootNode/GeneralSkeleton" index="376"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_Hips_Female_04" parent="Model/RootNode/GeneralSkeleton" index="377"]
|
[node name="Chr_Hips_Female_04" parent="Model/RootNode/GeneralSkeleton" index="377"]
|
||||||
|
@ -1659,9 +1662,6 @@ visible = false
|
||||||
[node name="Chr_LegRight_Female_05" parent="Model/RootNode/GeneralSkeleton" index="407"]
|
[node name="Chr_LegRight_Female_05" parent="Model/RootNode/GeneralSkeleton" index="407"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_LegRight_Female_06" parent="Model/RootNode/GeneralSkeleton" index="408"]
|
|
||||||
visible = false
|
|
||||||
|
|
||||||
[node name="Chr_LegRight_Female_07" parent="Model/RootNode/GeneralSkeleton" index="409"]
|
[node name="Chr_LegRight_Female_07" parent="Model/RootNode/GeneralSkeleton" index="409"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
@ -1677,6 +1677,9 @@ visible = false
|
||||||
[node name="Chr_LegRight_Female_11" parent="Model/RootNode/GeneralSkeleton" index="413"]
|
[node name="Chr_LegRight_Female_11" parent="Model/RootNode/GeneralSkeleton" index="413"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
[node name="Chr_LegRight_Female_12" parent="Model/RootNode/GeneralSkeleton" index="414"]
|
||||||
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_LegRight_Female_13" parent="Model/RootNode/GeneralSkeleton" index="415"]
|
[node name="Chr_LegRight_Female_13" parent="Model/RootNode/GeneralSkeleton" index="415"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
@ -1716,9 +1719,6 @@ visible = false
|
||||||
[node name="Chr_LegLeft_Female_05" parent="Model/RootNode/GeneralSkeleton" index="427"]
|
[node name="Chr_LegLeft_Female_05" parent="Model/RootNode/GeneralSkeleton" index="427"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_LegLeft_Female_06" parent="Model/RootNode/GeneralSkeleton" index="428"]
|
|
||||||
visible = false
|
|
||||||
|
|
||||||
[node name="Chr_LegLeft_Female_07" parent="Model/RootNode/GeneralSkeleton" index="429"]
|
[node name="Chr_LegLeft_Female_07" parent="Model/RootNode/GeneralSkeleton" index="429"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
@ -1734,6 +1734,9 @@ visible = false
|
||||||
[node name="Chr_LegLeft_Female_11" parent="Model/RootNode/GeneralSkeleton" index="433"]
|
[node name="Chr_LegLeft_Female_11" parent="Model/RootNode/GeneralSkeleton" index="433"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
[node name="Chr_LegLeft_Female_12" parent="Model/RootNode/GeneralSkeleton" index="434"]
|
||||||
|
visible = false
|
||||||
|
|
||||||
[node name="Chr_LegLeft_Female_13" parent="Model/RootNode/GeneralSkeleton" index="435"]
|
[node name="Chr_LegLeft_Female_13" parent="Model/RootNode/GeneralSkeleton" index="435"]
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
#include "customizable_character.hpp"
|
||||||
|
#include "godot_cpp/variant/utility_functions.hpp"
|
||||||
|
#include "godot_macros.h"
|
||||||
|
|
||||||
|
namespace godot {
|
||||||
|
void CustomizableCharacter::_bind_methods() {
|
||||||
|
#define CLASSNAME CustomizableCharacter
|
||||||
|
GDPROPERTY(active_customization, Variant::DICTIONARY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomizableCharacter::set_customization_active(Node3D *node, bool active) {
|
||||||
|
node->set_visible(active);
|
||||||
|
node->set_process(active);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomizableCharacter::_enter_tree() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomizableCharacter::_ready() {
|
||||||
|
this->customization_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomizableCharacter::select_customization(String category, std::optional<size_t> index) {
|
||||||
|
if (this->customization.find(category) == this->customization.end())
|
||||||
|
return;
|
||||||
|
CustomizationState& pair = this->customization.at(category);
|
||||||
|
// invalid keys are stored as the size of the array
|
||||||
|
if (index.has_value() && index.value() >= pair.options.size())
|
||||||
|
index = std::nullopt;
|
||||||
|
// nothing changes
|
||||||
|
if (index == pair.currentSelected)
|
||||||
|
return;
|
||||||
|
// disable previous chosen option, if any
|
||||||
|
if (pair.currentSelected.has_value())
|
||||||
|
CustomizableCharacter::set_customization_active(pair.options.at(pair.currentSelected.value()), false);
|
||||||
|
// enable chosen option, if any
|
||||||
|
if (index.has_value())
|
||||||
|
CustomizableCharacter::set_customization_active(pair.options.at(index.value()), true);
|
||||||
|
pair.currentSelected = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary CustomizableCharacter::get_active_customization() const {
|
||||||
|
Dictionary result{};
|
||||||
|
// translate the map to a dictionary of categories -> indexes
|
||||||
|
for (std::pair<String, CustomizationState> const& pair : this->customization) {
|
||||||
|
result[pair.first] = pair.second.currentSelected.has_value()
|
||||||
|
? pair.second.currentSelected.value()
|
||||||
|
: -1; // an invalid key will always be -1
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomizableCharacter::set_active_customization(Dictionary value) {
|
||||||
|
for (size_t i = 0; i < value.size(); ++i) {
|
||||||
|
String key = value.keys()[i];
|
||||||
|
size_t selection = value[key];
|
||||||
|
// wether or not the a given key exists in the customization map
|
||||||
|
bool exists = this->customization.find(key) != this->customization.end();
|
||||||
|
// if not, it can be added, as long as the customization map has not yet
|
||||||
|
// been initialized by _ready
|
||||||
|
if (!exists && this->customizationParent == nullptr)
|
||||||
|
this->customization.insert({key, {std::optional{selection}, {}}});
|
||||||
|
// if the key does not exist in customization and _ready is already
|
||||||
|
// called, the key is not valid and discarted
|
||||||
|
else if (!exists)
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
this->select_customization(key, selection >= 0
|
||||||
|
? std::optional{selection}
|
||||||
|
: std::nullopt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomizableCharacter::customization_init() {
|
||||||
|
this->customizationParent =
|
||||||
|
this->get_node<Skeleton3D>("RootNode/GeneralSkeleton");
|
||||||
|
if (this->customizationParent == nullptr)
|
||||||
|
return;
|
||||||
|
for (int i = 0; i < customizationParent->get_child_count(); ++i) {
|
||||||
|
// get the next valid child
|
||||||
|
Node3D* child = Object::cast_to<Node3D>(this->customizationParent->get_child(i));
|
||||||
|
if (child == nullptr)
|
||||||
|
continue;
|
||||||
|
// split it's name into parts based on _
|
||||||
|
// the format for the names will be Chr_<CATEGORY NAME>_<ADDITIONAL IDENTIFIERS>_<NUMBER> numbering IS NOT guaranteed to start at 0 OR 1
|
||||||
|
// the category name will serve as the key to the customization map
|
||||||
|
// additional identifiers are ignored
|
||||||
|
PackedStringArray slices = child->get_name().split("_", false);
|
||||||
|
// create a new customization state if one does not exist for this category
|
||||||
|
if (this->customization.find(slices[1]) == this->customization.end())
|
||||||
|
this->customization.insert({slices[1], {std::optional{0}, {}}});
|
||||||
|
// add the new child to the customization options for this category
|
||||||
|
CustomizationState& state = this->customization.at(slices[1]);
|
||||||
|
state.options.push_back(child);
|
||||||
|
// set invisible if this child is not the current selection
|
||||||
|
CustomizableCharacter::set_customization_active(child, state.currentSelected == state.options.size() - 1);
|
||||||
|
}
|
||||||
|
// collect customization categories that do not contain any options
|
||||||
|
std::vector<String> empty{};
|
||||||
|
for (std::pair<const String, CustomizationState>& pair :
|
||||||
|
this->customization) {
|
||||||
|
if (pair.second.options.size() == 0)
|
||||||
|
empty.push_back(pair.first);
|
||||||
|
if (pair.second.currentSelected.has_value() &&
|
||||||
|
pair.second.currentSelected.value() > pair.second.options.size())
|
||||||
|
pair.second.currentSelected = std::nullopt;
|
||||||
|
UtilityFunctions::print("- ", pair.first);
|
||||||
|
}
|
||||||
|
// remove collected empty categories
|
||||||
|
for (String const& key : empty) {
|
||||||
|
this->customization.erase(key);
|
||||||
|
UtilityFunctions::print("removing ", key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef CUSTOMIZABLE_CHARACTER_HPP
|
||||||
|
#define CUSTOMIZABLE_CHARACTER_HPP
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include <map>
|
||||||
|
#include "godot_cpp/classes/node3d.hpp"
|
||||||
|
#include "godot_cpp/classes/skeleton3d.hpp"
|
||||||
|
|
||||||
|
namespace godot {
|
||||||
|
class CustomizableCharacter : public Node3D {
|
||||||
|
GDCLASS(CustomizableCharacter, Node3D);
|
||||||
|
static void _bind_methods();
|
||||||
|
|
||||||
|
// the current customization state of a body part/attachment
|
||||||
|
struct CustomizationState {
|
||||||
|
// current selected option
|
||||||
|
std::optional<size_t> currentSelected{std::nullopt};
|
||||||
|
// cache of all options
|
||||||
|
std::vector<Node3D *> options{};
|
||||||
|
};
|
||||||
|
|
||||||
|
static void set_customization_active(Node3D *node, bool active);
|
||||||
|
private:
|
||||||
|
// all customization options categorized according to body part
|
||||||
|
std::map<String, CustomizationState> customization{};
|
||||||
|
// the skeleton of the customizable character model
|
||||||
|
Skeleton3D *customizationParent{nullptr};
|
||||||
|
public:
|
||||||
|
virtual void _enter_tree() override;
|
||||||
|
virtual void _ready() override;
|
||||||
|
// Swap out the currently active customization for this category
|
||||||
|
void select_customization(String category, std::optional<size_t> value);
|
||||||
|
// Construct a dictionary of [String, int] where the key is a category
|
||||||
|
// from the customization map. And the value is the index of the
|
||||||
|
// active element from the category.
|
||||||
|
Dictionary get_active_customization() const;
|
||||||
|
// change active customization as if select_customization was called for
|
||||||
|
// every element in a [String, int] dictionary, where key is the category
|
||||||
|
// to assign to and the value is the index of the element to show.
|
||||||
|
void set_active_customization(Dictionary value);
|
||||||
|
void customization_init();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !CUSTOMIZABLE_CHARACTER_HPP
|
105
src/player.cpp
105
src/player.cpp
|
@ -14,9 +14,6 @@
|
||||||
namespace godot {
|
namespace godot {
|
||||||
void Player::_bind_methods() {
|
void Player::_bind_methods() {
|
||||||
#define CLASSNAME Player
|
#define CLASSNAME Player
|
||||||
#ifndef NDEBUG
|
|
||||||
GDPROPERTY(active_customization, Variant::DICTIONARY);
|
|
||||||
#endif
|
|
||||||
GDFUNCTION_ARGS(on_horizontal, "event", "value");
|
GDFUNCTION_ARGS(on_horizontal, "event", "value");
|
||||||
GDFUNCTION_ARGS(on_vertical, "event", "value");
|
GDFUNCTION_ARGS(on_vertical, "event", "value");
|
||||||
GDFUNCTION(get_is_moving);
|
GDFUNCTION(get_is_moving);
|
||||||
|
@ -30,7 +27,6 @@ void Player::_enter_tree() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::_ready() {
|
void Player::_ready() {
|
||||||
this->customization_init();
|
|
||||||
GDGAMEONLY();
|
GDGAMEONLY();
|
||||||
this->flat_view_update();
|
this->flat_view_update();
|
||||||
this->input->listen_to(PlayerInput::Listener("move_left", "move_right", this, "on_horizontal"));
|
this->input->listen_to(PlayerInput::Listener("move_left", "move_right", this, "on_horizontal"));
|
||||||
|
@ -58,11 +54,6 @@ void Player::_physics_process(double deltaTime) {
|
||||||
void Player::damage(Node *origin, int amount) {
|
void Player::damage(Node *origin, int amount) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::set_customization_active(Node3D *node, bool active) {
|
|
||||||
node->set_visible(active);
|
|
||||||
node->set_process(active);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::on_horizontal(Ref<InputEvent> event, float value) {
|
void Player::on_horizontal(Ref<InputEvent> event, float value) {
|
||||||
this->moveInput.x = value;
|
this->moveInput.x = value;
|
||||||
}
|
}
|
||||||
|
@ -71,58 +62,6 @@ void Player::on_vertical(Ref<InputEvent> event, float value) {
|
||||||
this->moveInput.y = value;
|
this->moveInput.y = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::select_customization(String category,
|
|
||||||
std::optional<size_t> index) {
|
|
||||||
if (this->customization.find(category) == this->customization.end())
|
|
||||||
return;
|
|
||||||
CustomizationState& pair = this->customization.at(category);
|
|
||||||
// invalid keys are stored as the size of the array
|
|
||||||
if (index.has_value() && index.value() > pair.options.size())
|
|
||||||
index = std::nullopt;
|
|
||||||
// nothing changesw
|
|
||||||
if (index == pair.currentSelected)
|
|
||||||
return;
|
|
||||||
// disable previous chosen option, if any
|
|
||||||
if (pair.currentSelected.has_value())
|
|
||||||
Player::set_customization_active(pair.options.at(pair.currentSelected.value()), false);
|
|
||||||
// enable chosen option, if any
|
|
||||||
if (index.has_value())
|
|
||||||
Player::set_customization_active(pair.options.at(index.value()), false);
|
|
||||||
pair.currentSelected = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dictionary Player::get_active_customization() const {
|
|
||||||
Dictionary result{};
|
|
||||||
// translate the map to a dictionary of keys and indexes
|
|
||||||
for (std::pair<String, CustomizationState> const& pair :
|
|
||||||
this->customization)
|
|
||||||
result[pair.first] = pair.second.currentSelected.has_value()
|
|
||||||
? pair.second.currentSelected.value()
|
|
||||||
: -1; // an invalid key will always be -1
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::set_active_customization(Dictionary value) {
|
|
||||||
for (size_t i = 0; i < value.size(); ++i) {
|
|
||||||
String key = value.keys()[i];
|
|
||||||
size_t selection = value[key];
|
|
||||||
// wether or not the a given key exists in the customization map
|
|
||||||
bool exists = this->customization.find(key) != this->customization.end();
|
|
||||||
// if not, it can be added, as long as the customization map has not yet
|
|
||||||
// been initialized by _ready
|
|
||||||
if (!exists && !this->is_inside_tree())
|
|
||||||
this->customization.insert({key, {std::optional{selection}, {}}});
|
|
||||||
// if the key does not exist in customization and _ready is already
|
|
||||||
// called, the key is not valid and discarted
|
|
||||||
else if (!exists)
|
|
||||||
return;
|
|
||||||
else
|
|
||||||
this->select_customization(key, selection >= 0
|
|
||||||
? std::optional{selection}
|
|
||||||
: std::nullopt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Player::get_world_move_input() const {
|
Vector3 Player::get_world_move_input() const {
|
||||||
Vector2 n = this->moveInput.normalized();
|
Vector2 n = this->moveInput.normalized();
|
||||||
return flatViewBasis.get_column(0) * n.x
|
return flatViewBasis.get_column(0) * n.x
|
||||||
|
@ -149,50 +88,6 @@ void Player::flat_view_update() {
|
||||||
this->flatViewBasis = Basis{right, right.cross(forward), forward};
|
this->flatViewBasis = Basis{right, right.cross(forward), forward};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::customization_init() {
|
|
||||||
this->customizationParent =
|
|
||||||
this->get_node<Skeleton3D>("Model/RootNode/GeneralSkeleton");
|
|
||||||
if (this->customizationParent == nullptr)
|
|
||||||
return;
|
|
||||||
for (int i = 0; i < customizationParent->get_child_count(); ++i) {
|
|
||||||
// get the next valid child
|
|
||||||
Node3D* child = Object::cast_to<Node3D>(this->customizationParent->get_child(i));
|
|
||||||
if (child == nullptr)
|
|
||||||
continue;
|
|
||||||
// split it's name into parts based on _
|
|
||||||
// the format for the names will be Chr_<CATEGORY NAME>_<ADDITIONAL IDENTIFIERS>_<NUMBER> numbering IS NOT guaranteed to start at 0 OR 1
|
|
||||||
// the category name will serve as the key to the customization map
|
|
||||||
// additional identifiers are ignored
|
|
||||||
PackedStringArray slices = child->get_name().split("_", false);
|
|
||||||
// create a new customization state if one does not exist for this category
|
|
||||||
if (this->customization.find(slices[1]) == this->customization.end())
|
|
||||||
this->customization.insert({slices[1], {std::optional{0}, {}}});
|
|
||||||
// add the new child to the customization options for this category
|
|
||||||
CustomizationState& state = this->customization.at(slices[1]);
|
|
||||||
state.options.push_back(child);
|
|
||||||
// set invisible if this child is not the current selection
|
|
||||||
if (state.currentSelected != state.options.size() - 1) {
|
|
||||||
Player::set_customization_active(child, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// collect customization categories that do not contain any options
|
|
||||||
std::vector<String> empty{};
|
|
||||||
for (std::pair<const String, CustomizationState>& pair :
|
|
||||||
this->customization) {
|
|
||||||
if (pair.second.options.size() == 0)
|
|
||||||
empty.push_back(pair.first);
|
|
||||||
if (pair.second.currentSelected.has_value() &&
|
|
||||||
pair.second.currentSelected.value() > pair.second.options.size())
|
|
||||||
pair.second.currentSelected = std::nullopt;
|
|
||||||
UtilityFunctions::print("- ", pair.first);
|
|
||||||
}
|
|
||||||
// remove collected empty categories
|
|
||||||
for (String const& key : empty) {
|
|
||||||
this->customization.erase(key);
|
|
||||||
UtilityFunctions::print("removing ", key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Player::get_is_moving() const {
|
bool Player::get_is_moving() const {
|
||||||
return this->is_on_floor() && !this->moveInput.is_zero_approx();
|
return this->is_on_floor() && !this->moveInput.is_zero_approx();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,30 +6,19 @@
|
||||||
#include "godot_cpp/classes/animation_tree.hpp"
|
#include "godot_cpp/classes/animation_tree.hpp"
|
||||||
#include "godot_cpp/classes/character_body3d.hpp"
|
#include "godot_cpp/classes/character_body3d.hpp"
|
||||||
#include "godot_cpp/classes/input_event.hpp"
|
#include "godot_cpp/classes/input_event.hpp"
|
||||||
#include "godot_cpp/classes/skeleton3d.hpp"
|
|
||||||
#include "hitable_interface.hpp"
|
#include "hitable_interface.hpp"
|
||||||
#include "player_input.hpp"
|
#include "player_input.hpp"
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
class Player : public CharacterBody3D, public HitableInterface {
|
class Player : public CharacterBody3D, public HitableInterface {
|
||||||
GDCLASS(Player, CharacterBody3D)
|
GDCLASS(Player, CharacterBody3D)
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
// the current customization state of a body part/attachment
|
|
||||||
struct CustomizationState {
|
|
||||||
std::optional<size_t> currentSelected{std::nullopt}; // current selected option
|
|
||||||
std::vector<Node3D *> options{}; // cache of all options
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// all customization options categorized according to body part
|
|
||||||
std::map<String, CustomizationState> customization{};
|
|
||||||
// the root of the character model
|
// the root of the character model
|
||||||
Node3D* model{nullptr};
|
Node3D* model{nullptr};
|
||||||
// the character animation tree
|
// the character animation tree
|
||||||
AnimationTree* animTree{nullptr};
|
AnimationTree* animTree{nullptr};
|
||||||
// the skeleton of the customizable character model
|
|
||||||
Skeleton3D *customizationParent{nullptr};
|
|
||||||
PlayerInput *input{nullptr};
|
PlayerInput *input{nullptr};
|
||||||
Basis flatViewBasis{identity::Basis};
|
Basis flatViewBasis{identity::Basis};
|
||||||
|
|
||||||
|
@ -45,28 +34,15 @@ public:
|
||||||
|
|
||||||
virtual void damage(Node *origin, int amount) override;
|
virtual void damage(Node *origin, int amount) override;
|
||||||
|
|
||||||
static void set_customization_active(Node3D *node, bool active);
|
|
||||||
|
|
||||||
void on_horizontal(Ref<InputEvent> event, float value);
|
void on_horizontal(Ref<InputEvent> event, float value);
|
||||||
void on_vertical(Ref<InputEvent> event, float value);
|
void on_vertical(Ref<InputEvent> event, float value);
|
||||||
|
|
||||||
// Swap out the currently active customization for this category
|
|
||||||
void select_customization(String category, std::optional<size_t> value);
|
|
||||||
// Construct a dictionary of [String, int] where the key is a category
|
|
||||||
// from the customization map. And the value is the index of the
|
|
||||||
// active element from the category.
|
|
||||||
Dictionary get_active_customization() const;
|
|
||||||
// change active customization as if select_customization was called for
|
|
||||||
// every element in a [String, int] dictionary, where key is the category
|
|
||||||
// to assign to and the value is the index of the element to show.
|
|
||||||
void set_active_customization(Dictionary value);
|
|
||||||
// returns moveInput transformed to world space
|
// returns moveInput transformed to world space
|
||||||
Vector3 get_world_move_input() const;
|
Vector3 get_world_move_input() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void rotate_to_movement();
|
void rotate_to_movement();
|
||||||
void flat_view_update();
|
void flat_view_update();
|
||||||
void customization_init();
|
|
||||||
bool get_is_moving() const;
|
bool get_is_moving() const;
|
||||||
};
|
};
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <godot_cpp/core/defs.hpp>
|
#include <godot_cpp/core/defs.hpp>
|
||||||
#include <godot_cpp/godot.hpp>
|
#include <godot_cpp/godot.hpp>
|
||||||
|
|
||||||
|
#include "customizable_character.hpp"
|
||||||
#include "entrance.hpp"
|
#include "entrance.hpp"
|
||||||
#include "game_mode.hpp"
|
#include "game_mode.hpp"
|
||||||
#include "level.hpp"
|
#include "level.hpp"
|
||||||
|
@ -21,6 +22,7 @@ void initialize_gdextension_types(ModuleInitializationLevel p_level) {
|
||||||
ClassDB::register_class<Entrance>();
|
ClassDB::register_class<Entrance>();
|
||||||
ClassDB::register_class<GameMode>();
|
ClassDB::register_class<GameMode>();
|
||||||
ClassDB::register_class<PlayerInput>();
|
ClassDB::register_class<PlayerInput>();
|
||||||
|
ClassDB::register_class<CustomizableCharacter>();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
Loading…
Reference in New Issue