I'm looking to squeeze just a bit more performance out of my most frequent calls, but I keep running into problems when trying to convert my GDscript to C#. Most of the problems have been about passing around types and the latest one has to do with getting a type error when trying to get a variable from an instance.
The C# so far:
using Godot;
using System;
public class HiveControl : Node2D
{
[Export] private int antCount = 800;
private PackedScene antObject;
private KinematicBody2D ant;
private Godot.Collections.Array<KinematicBody2D> currentChildren = new Godot.Collections.Array<KinematicBody2D>();
private int childCount;
private int behaviourCounter;
private const double updateTime = 0.02;
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
antObject = (PackedScene)GD.Load("res://Ant.tscn");
do
{
var ant = (KinematicBody2D)antObject.Instance();
antCount-- ;
ant.Call("start", this.Position);
currentChildren.Add(ant);
this.AddChild(ant);
childCount++ ;
} while ( antCount > 0 );
}
// // Called every frame. 'delta' is the elapsed time since the previous frame.
// public override void _Process(float delta)
// {
//
// }
public override void _PhysicsProcess(float delta)
{
switch (behaviourCounter)
{
case 0:
GD.Print("0");
ChildProc(new int[] {0, (int)(childCount * 0.20)}, delta);
break;
case 1:
ChildProc(new int[] {(int)(childCount * 0.20), (int)(childCount * 0.40)}, delta);
GD.Print("1");
break;
case 2:
ChildProc(new int[] {(int)(childCount * 0.40), (int)(childCount * 0.60)}, delta);
GD.Print("2");
break;
case 3:
ChildProc(new int[] {(int)(childCount * 0.60), (int)(childCount * 0.80)}, delta);
GD.Print("3");
break;
case 4:
ChildProc(new int[] {(int)(childCount * 0.80), (int)(childCount)}, delta);
GD.Print("4");
break;
default:
GD.Print("Default");
break;
}
behaviourCounter += 1;
if (behaviourCounter %5 == 0)
{
behaviourCounter = 0;
}
}
public void ChildProc(int[] indexRange, float d)
{
GD.Print("I arrived!");
//int indexLength = indexRange.Count() - 1;
for (int i = indexRange[0]; i <= indexRange[1]; i++)
{
var child = currentChildren[i];
child.collision = child.MoveAndCollide(child.velocity * d);
if (child.updateTimer < TIME_TO_UPDATE)
{
GD.Print("Ahhhhhh!");
}
}
}
public void Wander(KinematicBody2D child)
{
child.Rotate(1);
}
}
The working GDScript:
extends Node2D
export var antCount: int = 800
const ants = preload("res://Ant.tscn")
var ant: Object
var currentChildren: Array
var childCount: int
var behaviourCounter: int
const TIME_TO_UPDATE = 0.02
func _ready():
while antCount > 0:
ant = ants.instance()
antCount -= 1
add_child(ant)
ant.start(position + Vector2(rand_range(-4,4),rand_range(-4,4)))
currentChildren.insert(0,ant)
childCount += 1
#func _process(_delta):
# pass
# Spread ant updates across five segements of time
func _physics_process(delta):
match behaviourCounter:
0: childProc([0, int(childCount * 0.20)], delta)
1: childProc([int(childCount * 0.20), int(childCount * 0.40)], delta)
2: childProc([int(childCount * 0.40), int(childCount * 0.60)], delta)
3: childProc([int(childCount * 0.60), int(childCount * 0.80)], delta)
4: childProc([int(childCount * 0.80), int(childCount)], delta)
#_: behaviourCounter = 0
behaviourCounter += 1
if behaviourCounter %5 == 0:
behaviourCounter = 0
# Update ant behaviour
func childProc(indexRange, d):
var indexLength = len(indexRange) - 1
for index in range(indexRange[0],indexRange[indexLength]):
var child = currentChildren[index]
child.collision = child.move_and_collide(child.velocity * d)
if child.updateTimer < TIME_TO_UPDATE:
return
else:
match child.currentBehaviour:
"wandering":
child.position += d * child.velocity * child.walkSpeed
if child.collision:
child.rotate(child.rejectionRotation * d)
wander(child)
# Wander behavior
func wander(child):
child.rotate(rand_range(-0.25,0.25))
child.velocity = Vector2(1 + rand_range(-0.5,0.5), 0).rotated(child.rotation)
#func wander(child, d):
# child.direction = Vector2(rand_range(-1, 1),rand_range(-1, 1)) - child.velocity
# child.rotationTo = child.transform.x.angle_to(child.direction)
# child.rotate(sign(child.rotationTo) * min(d * 0.5 * child.turnSpeed, abs(child.rotationTo)))
# child.velocity = Vector2(1, 0).rotated(child.rotation)
The C# gives an error about KinematicBody2D not having any of the child
variables I'm trying to reference. So, I guess the problem comes down to C# getting variables of an instance differently, but the Godot documentation didn't seem to be very helpful on this front.