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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
class_name UnitModel
extends Node3D
var skeleton : Skeleton3D = null
var anim_player : AnimationPlayer = null
var anim_lib : AnimationLibrary = null
var sub_units : Array[UnitModel]
var meshes : Array[MeshInstance3D]
# COLOUR VARIABLES
@export_group("Colors")
@export var primary_colour : Color:
set(col_in):
primary_colour = col_in
_set_shader_parameter(&"colour_primary", primary_colour)
for unit : UnitModel in sub_units:
unit.primary_colour = col_in
@export var secondary_colour: Color:
set(col_in):
secondary_colour = col_in
_set_shader_parameter(&"colour_secondary", secondary_colour)
for unit : UnitModel in sub_units:
unit.secondary_colour = col_in
@export var tertiary_colour : Color:
set(col_in):
tertiary_colour = col_in
_set_shader_parameter(&"colour_tertiary", tertiary_colour)
for unit : UnitModel in sub_units:
unit.tertiary_colour = col_in
# ANIMATION VARIABLES
@export_group("Animation")
@export var idle_anim : Animation:
set(anim_in):
load_animation("idle", anim_in)
idle_anim = anim_in
@export var move_anim : Animation:
set(anim_in):
load_animation("move", anim_in)
move_anim = anim_in
@export var attack_anim : Animation:
set(anim_in):
load_animation("attack", anim_in)
attack_anim = anim_in
enum Anim { NONE, IDLE, MOVE, ATTACK }
const ANIMATION_LIBRARY : StringName = &"default_lib"
const ANIMATION_IDLE : String = ANIMATION_LIBRARY + "/idle"
const ANIMATION_MOVE : String = ANIMATION_LIBRARY + "/move"
const ANIMATION_ATTACK : String = ANIMATION_LIBRARY + "/attack"
@export var current_anim : Anim:
set(anim_in):
for unit : UnitModel in sub_units:
unit.current_anim = anim_in
if anim_player:
match anim_in:
Anim.IDLE:
if idle_anim:
anim_player.set_current_animation(ANIMATION_IDLE)
_set_tex_scroll(scroll_speed_idle)
current_anim = Anim.IDLE
return
Anim.MOVE:
if move_anim:
anim_player.set_current_animation(ANIMATION_MOVE)
_set_tex_scroll(scroll_speed_move)
current_anim = Anim.MOVE
return
Anim.ATTACK:
if attack_anim:
anim_player.set_current_animation(ANIMATION_ATTACK)
_set_tex_scroll(scroll_speed_attack)
current_anim = Anim.ATTACK
return
_: #None
pass
anim_player.stop()
_set_tex_scroll(0.0)
current_anim = Anim.NONE
# TEXTURE SCROLL SPEEDS (TANKS TRACKS AND SMOKE)
@export_subgroup("Texture_Scroll")
@export var scroll_speed_idle : float:
set(speed_in):
scroll_speed_idle = speed_in
for unit : UnitModel in sub_units:
unit.scroll_speed_idle = speed_in
@export var scroll_speed_move : float:
set(speed_in):
scroll_speed_move = speed_in
for unit : UnitModel in sub_units:
unit.scroll_speed_move = speed_in
@export var scroll_speed_attack : float:
set(speed_in):
scroll_speed_attack = speed_in
for unit : UnitModel in sub_units:
unit.scroll_speed_attack = speed_in
func unit_init() -> void:
for child : Node in get_children():
if child is MeshInstance3D:
meshes.append(child)
elif child is Skeleton3D:
skeleton = child
func add_anim_player() -> void:
anim_player = AnimationPlayer.new()
anim_player.name = "anim_player"
anim_lib = AnimationLibrary.new()
anim_lib.resource_name = ANIMATION_LIBRARY
anim_player.add_animation_library(ANIMATION_LIBRARY, anim_lib)
add_child(anim_player)
func has_bone(bone_name : String) -> bool:
return skeleton and skeleton.find_bone(bone_name) > -1
func attach_model(bone_name : String, model : Node3D) -> Error:
if not model:
push_error("Cannot attach null model to bone \"", bone_name, "\" of UnitModel ", get_name())
return FAILED
if not skeleton:
push_error("Cannot attach model \"", model.get_name(), "\" to bone \"", bone_name, "\" of UnitModel ", get_name(), " - has no skeleton!")
return FAILED
var bone_idx : int = skeleton.find_bone(bone_name)
if bone_idx < 0 or bone_idx >= skeleton.get_bone_count():
push_error("Invalid bone \"", bone_name, "\" (index ", bone_idx, ") for attachment \"", model.get_name(), "\" to UnitModel \"", get_name(), "\"")
return FAILED
var bone_attachment := BoneAttachment3D.new()
bone_attachment.name = bone_name
bone_attachment.bone_idx = bone_idx
bone_attachment.add_child(model)
skeleton.add_child(bone_attachment)
if model is UnitModel:
sub_units.push_back(model)
model.current_anim = current_anim
model.primary_colour = primary_colour
model.secondary_colour = secondary_colour
model.tertiary_colour = tertiary_colour
return OK
func _set_shader_parameter(param_name : StringName, param_val : Variant) -> void:
for mesh : MeshInstance3D in meshes:
mesh.set_instance_shader_parameter(param_name, param_val)
func _set_tex_scroll(speed : float) -> void:
_set_shader_parameter(&"scroll_speed", speed)
func set_flag_index(index : int) -> void:
_set_shader_parameter(&"flag_index", index)
func load_animation(prop_name : String, animIn : Animation) -> void:
if not animIn:
return
if not anim_player:
add_anim_player()
anim_lib.add_animation(prop_name,animIn)
|