@@ -78,12 +78,30 @@ The GUI scene encapsulates all of the Game User Interface. It comes with
78
78
a barebones script where we get the path to nodes that exist inside the
79
79
scene:
80
80
81
- ::
81
+ .. tabs ::
82
+ .. code-tab :: gdscript GDScript
82
83
83
84
onready var number_label = $Bars/LifeBar/Count/Background/Number
84
85
onready var bar = $Bars/LifeBar/TextureProgress
85
86
onready var tween = $Tween
86
87
88
+ .. code-tab :: csharp
89
+
90
+ public class Gui : MarginContainer
91
+ {
92
+ private Tween _tween;
93
+ private Label _numberLabel;
94
+ private TextureProgress _bar;
95
+
96
+ public override void _Ready()
97
+ {
98
+ // C# doesn't have an onready feature, this works just the same
99
+ _bar = (TextureProgress) GetNode("Bars/LifeBar/TextureProgress");
100
+ _tween = (Tween) GetNode("Tween");
101
+ _numberLabel = (Label) GetNode("Bars/LifeBar/Count/Background/Number");
102
+ }
103
+ }
104
+
87
105
- ``number_label `` displays a life count as a number. It's a ``Label ``
88
106
node
89
107
- ``bar `` is the life bar itself. It's a ``TextureProgress `` node
@@ -127,12 +145,22 @@ open its script. In the ``_ready`` function, we're going to store the
127
145
``Player ``'s ``max_health `` in a new variable and use it to set the
128
146
``bar ``'s ``max_value ``:
129
147
130
- ::
148
+ .. tabs ::
149
+ .. code-tab :: gdscript GDScript
131
150
132
151
func _ready():
133
152
var player_max_health = $"../Characters/Player".max_health
134
153
bar.max_value = player_max_health
135
154
155
+ .. code-tab :: csharp
156
+
157
+ public override void _Ready()
158
+ {
159
+ // add this below _bar, _tween, and _numberLabel
160
+ var player = (Player) GetNode("../Characters/Player");
161
+ _bar.MaxValue = player.MaxHealth;
162
+ }
163
+
136
164
Let's break it down. ``$"../Characters/Player" `` is a shorthand that
137
165
goes one node up in the scene tree, and retrieves the
138
166
``Characters/Player `` node from there. It gives us access to the node.
@@ -247,11 +275,25 @@ Inside the parens after the function name, add a ``player_health``
247
275
argument. When the player emits the ``health_changed `` signal it will send
248
276
its current ``health `` alongside it. Your code should look like:
249
277
250
- ::
278
+ .. tabs ::
279
+ .. code-tab :: gdscript GDScript
251
280
252
281
func _on_Player_health_changed(player_health):
253
282
pass
254
283
284
+ .. code-tab :: csharp
285
+
286
+ public void OnPlayerHealthChanged(int playerHealth)
287
+ {
288
+ }
289
+
290
+ .. note ::
291
+
292
+ The engine does not convert PascalCase to snake_case, for C# examples we'll be using
293
+ PascalCase for method names & camelCase for method parameters which follows the official `C#
294
+ naming conventions. <https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/capitalization-conventions> `_
295
+
296
+
255
297
.. figure :: img/lifebar_tutorial_player_gd_emits_health_changed_code.png
256
298
257
299
In Player.gd, when the Player emits the health\_ changed signal, it also
@@ -270,22 +312,38 @@ Inside ``_on_Player_health_changed`` let's call a second function called
270
312
Create a new ``update_health `` method below ``_on_Player_health_changed ``.
271
313
It takes a new\_ value as its only argument:
272
314
273
- ::
315
+ .. tabs ::
316
+ .. code-tab :: gdscript GDScript
274
317
275
318
func update_health(new_value):
276
319
320
+ .. code-tab :: csharp
321
+
322
+ public void UpdateHealth(int health)
323
+ {
324
+ }
325
+
277
326
This method needs to:
278
327
279
328
- set the ``Number `` node's ``text `` to ``new_value `` converted to a
280
329
string
281
330
- set the ``TextureProgress ``'s ``value `` to ``new_value ``
282
331
283
- ::
332
+ .. tabs ::
333
+ .. code-tab :: gdscript GDScript
284
334
285
335
func update_health(new_value):
286
336
number_label.text = str(new_value)
287
337
bar.value = new_value
288
338
339
+ .. code-tab :: csharp
340
+
341
+ public void UpdateHealth(int health)
342
+ {
343
+ _numberLabel.Text = health.ToString();
344
+ _bar.Value = health;
345
+ }
346
+
289
347
.. tip ::
290
348
291
349
``str `` is a built-in function that converts about any value to
@@ -342,11 +400,23 @@ At the top of the script, define a new variable, name it
342
400
clear its content. Let's animate the ``animated_health `` value. Call the
343
401
``Tween `` node's ``interpolate_property `` method:
344
402
345
- ::
403
+ .. tabs ::
404
+ .. code-tab :: gdscript GDScript
346
405
347
406
func update_health(new_value):
348
407
tween.interpolate_property(self, "animated_health", animated_health, new_value, 0.6, Tween.TRANS_LINEAR, Tween.EASE_IN)
349
408
409
+ .. code-tab :: csharp
410
+
411
+ // add this to the top of your class
412
+ private int _animatedHealth = 0;
413
+
414
+ public void UpdateHealth(int health)
415
+ {
416
+ _tween.InterpolateProperty(this, "_animatedHealth", _animatedHealth, health, 0.6f, Tween.TransitionType.Linear,
417
+ Tween.EaseType.In);
418
+ }
419
+
350
420
Let's break down the call:
351
421
352
422
::
@@ -380,11 +450,19 @@ The animation will not play until we activated the ``Tween`` node with
380
450
``tween.start() ``. We only have to do this once if the node is not
381
451
active. Add this code after the last line:
382
452
383
- ::
453
+ .. tabs ::
454
+ .. code-tab :: gdscript GDScript
384
455
385
456
if not tween.is_active():
386
457
tween.start()
387
458
459
+ .. code-tab :: csharp
460
+
461
+ if (!_tween.IsActive())
462
+ {
463
+ _tween.Start();
464
+ }
465
+
388
466
.. note ::
389
467
390
468
Although we could animate the `health ` property on the `Player `, we really shouldn't. Characters should lose life instantly when they get hit. It makes it a lot easier to manage their state, like to know when one died. You always want to store animations in a separate data container or node. The `tween ` node is perfect for code-controlled animations. For hand-made animations, check out `AnimationPlayer `.
@@ -397,24 +475,48 @@ actual ``Bar`` and ``Number`` nodes anymore. Let's fix this.
397
475
398
476
So far, the update\_ health method looks like this:
399
477
400
- ::
478
+ .. tabs ::
479
+ .. code-tab :: gdscript GDScript
401
480
402
481
func update_health(new_value):
403
482
tween.interpolate_property(self, "animated_health", animated_health, new_value, 0.6, Tween.TRANS_LINEAR, Tween.EASE_IN)
404
483
if not tween.is_active():
405
484
tween.start()
406
485
486
+ .. code-tab :: csharp
487
+
488
+ public void UpdateHealth(int health)
489
+ {
490
+ _tween.InterpolateProperty(this, "_animatedHealth", _animatedHealth, health, 0.6f, Tween.TransitionType.Linear,
491
+ Tween.EaseType.In);
492
+
493
+ if(!_tween.IsActive())
494
+ {
495
+ _tween.Start();
496
+ }
497
+ }
498
+
499
+
407
500
In this specific case, because ``number_label `` takes text, we need to
408
501
use the ``_process `` method to animate it. Let's now update the
409
502
``Number `` and ``TextureProgress `` nodes like before, inside of
410
503
``_process ``:
411
504
412
- ::
505
+ .. tabs ::
506
+ .. code-tab :: gdscript GDScript
413
507
414
508
func _process(delta):
415
509
number_label.text = str(animated_health)
416
510
bar.value = animated_health
417
511
512
+ .. code-tab :: csharp
513
+
514
+ public override void _Process(float delta)
515
+ {
516
+ _numberLabel.Text = _animatedHealth.ToString();
517
+ _bar.Value = _animatedHealth;
518
+ }
519
+
418
520
.. note ::
419
521
420
522
`number_label ` and `bar ` are variables that store references to the `Number ` and `TextureProgress ` nodes.
@@ -432,13 +534,23 @@ local variable named ``round_value`` to store the rounded
432
534
``animated_health ``. Then assign it to ``number_label.text `` and
433
535
``bar.value ``:
434
536
435
- ::
537
+ .. tabs ::
538
+ .. code-tab :: gdscript GDScript
436
539
437
540
func _process(delta):
438
541
var round_value = round(animated_health)
439
542
number_label.text = str(round_value)
440
543
bar.value = round_value
441
544
545
+ .. code-tab :: csharp
546
+
547
+ public override void _Process(float delta)
548
+ {
549
+ var roundValue = Mathf.Round(_animatedHealth);
550
+ _numberLabel.Text = roundValue.ToString();
551
+ _bar.Value = roundValue;
552
+ }
553
+
442
554
Try the game again to see a nice blocky animation.
443
555
444
556
.. figure :: img/lifebar_tutorial_number_animation_working.gif
@@ -506,36 +618,63 @@ the top of the ``_on_Player_died`` method and name them ``start_color``
506
618
and ``end_color ``. Use the ``Color() `` constructor to build two
507
619
``Color `` values.
508
620
509
- ::
621
+ .. tabs ::
622
+ .. code-tab :: gdscript GDScript
510
623
511
624
func _on_Player_died():
512
625
var start_color = Color(1.0, 1.0, 1.0, 1.0)
513
626
var end_color = Color(1.0, 1.0, 1.0, 0.0)
514
627
628
+ .. code-tab :: csharp
629
+
630
+ public void OnPlayerDied()
631
+ {
632
+ var startColor = new Color(1.0f, 1.0f, 1.0f);
633
+ var endColor = new Color(1.0f, 1.0f, 1.0f, 0.0f);
634
+ }
635
+
515
636
``Color(1.0, 1.0, 1.0) `` corresponds to white. The fourth argument,
516
637
respectively ``1.0 `` and ``0.0 `` in ``start_color `` and ``end_color ``,
517
638
is the alpha channel.
518
639
519
640
We then have to call the ``interpolate_property `` method of the
520
641
``Tween `` node again:
521
642
522
- ::
643
+ .. tabs ::
644
+ .. code-tab :: gdscript GDScript
523
645
524
646
tween.interpolate_property(self, "modulate", start_color, end_color, 1.0, Tween.TRANS_LINEAR, Tween.EASE_IN)
525
647
648
+ .. code-tab :: csharp
649
+
650
+ _tween.InterpolateProperty(this, "modulate", startColor, endColor, 1.0f, Tween.TransitionType.Linear,
651
+ Tween.EaseType.In);
652
+
526
653
This time we change the ``modulate `` property and have it animate from
527
654
``start_color `` to the ``end_color ``. The duration is of one second,
528
655
with a linear transition. Here again, because the transition is linear,
529
656
the easing does not matter. Here's the complete ``_on_Player_died ``
530
657
method:
531
658
532
- ::
659
+ .. tabs ::
660
+ .. code-tab :: gdscript GDScript
533
661
534
662
func _on_Player_died():
535
663
var start_color = Color(1.0, 1.0, 1.0, 1.0)
536
664
var end_color = Color(1.0, 1.0, 1.0, 0.0)
537
665
tween.interpolate_property(self, "modulate", start_color, end_color, 1.0, Tween.TRANS_LINEAR, Tween.EASE_IN)
538
666
667
+ .. code-tab :: csharp
668
+
669
+ public void OnPlayerDied()
670
+ {
671
+ var startColor = new Color(1.0f, 1.0f, 1.0f);
672
+ var endColor = new Color(1.0f, 1.0f, 1.0f, 0.0f);
673
+
674
+ _tween.InterpolateProperty(this, "modulate", startColor, endColor, 1.0f, Tween.TransitionType.Linear,
675
+ Tween.EaseType.In);
676
+ }
677
+
539
678
And that is it. You may now play the game to see the final result!
540
679
541
680
.. figure :: img/lifebar_tutorial_final_result.gif
0 commit comments