using Godot; using System; [Tool] public partial class ProgCircle : MeshInstance3D { [Export] public int Segments { get; set; } = 64; [Export] public float Progress { get; set; } = 0f; [Export] public float Thickness { get; set; } = 0.1f; [Export] public float Radius { get; set; } = 1f; [Export] public Color RingColor { get; set; } = Colors.White; private ArrayMesh meshData = new ArrayMesh(); public override void _Ready() { UpdateRing(); } public override void _Process(double delta) { UpdateRing(); // optional, remove if static } public void UpdateRing() { int vertexCount = (Segments + 1) * 2; var vertices = new Vector3[vertexCount]; var colors = new Color[vertexCount]; var indices = new int[Segments * 6]; for (int i = 0; i <= Segments; i++) { float t = (float)i / Segments * Progress; float angle = t * Mathf.Tau; float cos = Mathf.Cos(angle); float sin = Mathf.Sin(angle); Color linearColor = RingColor.SrgbToLinear(); // Outer vertex vertices[i * 2] = new Vector3(cos * Radius, sin * Radius, 0); colors[i * 2] = linearColor; // Inner vertex vertices[i * 2 + 1] = new Vector3(cos * (Radius - Thickness), sin * (Radius - Thickness), 0); colors[i * 2 + 1] = linearColor; if (i > 0) { int baseIndex = (i - 1) * 6; int vBase = (i - 1) * 2; // First triangle indices[baseIndex] = vBase; indices[baseIndex + 1] = vBase + 1; indices[baseIndex + 2] = vBase + 2; // Second triangle indices[baseIndex + 3] = vBase + 2; indices[baseIndex + 4] = vBase + 1; indices[baseIndex + 5] = vBase + 3; } } var arrays = new Godot.Collections.Array(); arrays.Resize((int)Mesh.ArrayType.Max); arrays[(int)Mesh.ArrayType.Vertex] = vertices; arrays[(int)Mesh.ArrayType.Color] = colors; arrays[(int)Mesh.ArrayType.Index] = indices; meshData.ClearSurfaces(); meshData.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, arrays); // Make sure the material uses vertex colors if (MaterialOverride == null) { var mat = new StandardMaterial3D(); mat.VertexColorUseAsAlbedo = true; mat.ShadingMode = BaseMaterial3D.ShadingModeEnum.Unshaded; MaterialOverride = mat; } Mesh = meshData; } }