How to make a function that returns a value based on its input in C#

Godot Version

v4.4

Question

Decided to learn a bit of C# to offload some especially convoluted maths to, but just I can’t figure out a couple basic things. To start, I’m trying to port the following script to C#:

extends Node

func _ready()->void:
	print("gaaaaaahhhhhhh")

func bza360(ang:float, deg:bool)->float:
	var output:float
	output = ang if deg == true else output = rad_to_deg(ang)
	if (output < 0): while (output < 0):
		output += 360
	elif (output >= 360): while (output >= 360):
		output -= 360
	return output;

func _process(delta:float)->void:
	print("this day should clarence closely be mewed up")

My current attempt:

using Godot;
using System;

public partial class utils2 : Node
{
	public override void _Ready()
	{
		GD.Print("gaaaaaahhhhhhh");
	}
	
	public override float bza360(double Ang, bool Deg)
	{
		private float Output = 0f
		(Deg == true) ? Output = Ang : Output = GD.RadToDeg(Ang);
		if (Output < 0f)
		{
			while (Output < 0f)
			{
				Output += 360f;
			}
		}
		else if (Output >= 360f)
		{
			while (Output >= 360f)
			{
				Output -= 360f;
			}
		}
		return Output;
	}
	
	public override void _Process(double delta)
	{
		GD.Print("this day should clarence closely be mewed up");
	}
}

Which is throwing like 20 errors but the editor isn’t even getting the line positions right so it’s very hard to figure out what it’s on about. The _ready() and _process()es both work
The goal is to be able to call this script as a global, like cam_ang = utils.bza360(cam_ang,1)

This works

using Godot;
using System;

public partial class utils2 : Node
{
	public static float bza360(float Ang, bool Deg)
	{
		float Output;
		Output = (Deg == true) ? Ang : Mathf.RadToDeg(Ang);
		if (Output < 0f){while (Output < 0f)
		{
			Output += 360f;
		}}
		if (Output >= 360f){while (Output >= 360f)
		{
			Output -= 360f;
		}}
		return Output;
	}
}

I’d like to add that you should be very careful with using static for functions. I recommend reading up on what static does, as it can be very confusing at first, and as a general rule, unless it’s a helper function of some kind, that only modifies some simple data, you should always avoid using the static keyword. (In this case it seems fine, as you don’t addess member variables, but for future reference.)

Since you just started to learn c#, here a few hints for improvements:

  • You don’t need to compare a boolean with a boolean. Just use the boolean itself.
  • Your ifs are pointless since the whiles already check the same condition.
  • You don’t need a loop, you can use the ‘remainder’ operator %.
var input = deg ? Ang : Mathf.RadToDeg(ang);

var output = input % 360;
if (output < 0) output += 360;
return output;
  • Finally, you don’t need to implement it yourself at all. Mathf.PosMod does exactly what you need:
var input = var input = deg ? Ang : Mathf.RadToDeg(ang);
return Mathf.PosMod(input, 360);
1 Like

Yeah, the rule of thumb in refactoring is if the method is not mutating the instance(changing internal state) it is a candidate for static.

That way you know which methods touch the instance data and which do not. The added benefit is it’s like a fence to future changes where you know it’s static and you can’t just go and add another line that changes more internal state, it’s off limits.

Kind of like private data fields and get/set, the get/set allow the change and private members protect the state from outside/non contract changes.

2cents

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.