[Godot] C# 两种状态条实现
实现效果

实现方法
基础场景
我们在场景中添加了一个Label用来显示文本,两个按钮绑定了信号,用来控制数值的增加

第一种实现
在场景中创建一个进度条节点(ProgressBar或者TextureProgressBar),并根据需求调整所需要的样式,而我们代码控制的属性在Range一栏

大家可以悬停查看属性的功能,我们可以通过修改Value的值来决定进度条的值
现在我们编写脚本,代码如下
using Godot;
using System;
public partial class NumSider : Node2D
{
public int Num = 10;
private Label T_Num;
private ProgressBar S_Num;
public override void _Ready()
{
T_Num = GetNode<Label>("./Num");
S_Num = GetNode<ProgressBar>("./S_Num");
}
public override void _Process(double delta)
{
UpdateUI();
}
void UpdateUI()
{
T_Num.Text = $"Num:{Num}";
S_Num.Value = Num;
if (Num > 10)
Num = 10;
else if (Num < 0)
Num = 0;
}
public void Add()
{
Num++;
}
public void Sub()
{
Num--;
}
}
保存代码,运行场景,简单的状态条就实现了

第二种实现
我们可以在场景中添加HBoxContainer或VBoxContainer节点,这个节点可以让子节点 横/竖 向排列,我们可以通过修改Theme override中的Constants/Separation属性来设置子节点之间的距离

有一点需要注意,添加的子节点可能因为一些原因导致显示不正常,我们可以修改节点中的Custom minimum size来控制子节点的最小长宽
还有一种办法,比如我的子节点用的是TextureRect,我们可以看情况设置子节点的Expand mode和Expand mode属性,来控制子节点的缩放模式等
总之,大家按照自己的使用情况设置
我们创建一个子节点的场景,我简单的用TextureRect显示了一个子弹的图像,之后,大家可以尝试把这个子节点场景添加到容器中,来查看是否能正常显示
之后,我们写出控制容器子节点数量的代码
using Godot;
using System;
public partial class NumSider : Node2D
{
[Export] private PackedScene bullte; //子节点场景
public int Num = 10;
private Label T_Num;
private HBoxContainer Boxs;
public override void _Ready()
{
T_Num = GetNode<Label>("./Num");
Boxs = GetNode<HBoxContainer>("./Mag"); //获取容器
}
public override void _Process(double delta)
{
UpdateUI();
}
void UpdateUI()
{
T_Num.Text = $"Num:{Num}";
if (Num > 10)
Num = 10;
else if (Num < 0)
Num = 0;
UpdateMag();
}
void UpdateMag()
{
foreach (var i in Boxs.GetChildren())
{
i.QueueFree(); //删除容器的所有子节点
}
for (int i = 0; i < Num; i++)
{
var node2D = bullte.Instantiate();
Boxs.AddChild(node2D); //按照Num数值来创建相应数量的子节点
}
}
public void Add()
{
Num++;
}
public void Sub()
{
Num--;
}
}
我们简单粗暴的删除了容器的所有子节点,然后又重新按照值添加了对应数量的子节点,大家在实际使用中可以换其他的办法,我这样写还是太草率了
保存脚本,在引擎中构建一下代码,然后把子节点场景文件放到检查器的脚本中(当然你也可以在脚本里面直接获取子节点场景)

现在我们可以运行场景,看看效果

当然我们也可以简单的实现下面的效果

大家应该也能看出来是怎么实现的,定义一个最大的数量,然后在生成数值相对的子对象后,再生成最大数量减现有数量的另外一个作为空的子对象
void UpdateMag()
{
foreach (var i in Boxs.GetChildren())
{
i.QueueFree();
}
for (int i = 0; i < Num; i++)
{
var node2D = bullte.Instantiate();
Boxs.AddChild(node2D);
}
for (int i = 0; i < MaxNum - Num; i++)
{
var node2D = bullte0.Instantiate();
Boxs.AddChild(node2D);
}
}
总结
在实际开发中,可能会出现各种问题,大家可以按照自己的需求来实现功能,我这里就简单的写了一个实现方法给大家作为参考,而且尽量不要频繁调用,在值更改的时候调用一下即可

