gd2cs - Convert GDScript to C#

An asset by SvenHollesen
The page banner background of a mountain and forest
gd2cs - Convert GDScript to C# thumbnail image
gd2cs - Convert GDScript to C# thumbnail image
gd2cs - Convert GDScript to C# hero image

Quick Information

0 ratings
gd2cs - Convert GDScript to C# icon image
SvenHollesen
gd2cs - Convert GDScript to C#

Convert GDScript classes to C#. A one click solution that may save you hundreds of hours.This plugin offers a graphical editor UI for the gd2cs.py python script.It requires python and the python module "regex". But don't worry, it will detect and guide you through the necessary installs if you don't have them installed.Visit the Github page ( View Files ) for more information.Please backup all your data before using this addon! I cannot be held liable for data lost and damages caused.

Supported Engine Version
3.2
Version String
1.0
License Version
GPLv3
Support Level
community
Modified Date
3 years ago
Git URL
Issue URL

README Donate

README

gd2cs.py

Regex based Python script that converts arbitrary gdscript code to C#
Wrapped in a graphical UI plugin for use in the Godot Editor.
It's far from perfect, but it it should let you skip most of the gruntwork when converting.
It analyzes syntax only. No fancy code analysis.

Make sure to back-up all your files. No warranty of any kind is given. The author of this script cannot be held liable for any damage it may cause.

Use at your own risk.


Known issues :
- Keywords in strings or comments may be replaced
- Ternary operators such as A?B:C are too expensive to parse correctly and are therefore ignored in some transformations.

Usage :
In Godot:
Just drop the addon directly into your godot projects addon folder, then activate it in your Project Settings.
Then navigate to Project->Tools->gd2cs .
Hover over buttons or input controls to find out what they do.

From Python:
Specify the input gd file via -f "*" and the target output file via -o "*" .
Use -t * to specify the number of spaces in a tab (default = 4). This will replace consecutive spaces with tabs so the regex patterns can match a mix of space-offsets and tab-offsets (eg "else:\n    pass" will become "else:\n\tpass").

Example :
python3 gd2cs.py/gd2cs.py -i "Test_Script_Godot.gd" -o "Output/TestScript.cs"

Example Code Conversion (apr. real life example. Intentionally formatted badly to show where the converter will fail) :

tool
extends Node


enum {UNIT_NEUTRAL, UNIT_ENEMY, UNIT_ALLY}
enum Named {THING_1, THING_2, ANOTHER_THING = -1}

export(Date,Param)      const Date = preload("res://path")
const ABC = true
var G:float setget setterA, getterA
var DEF = -0.1 # Step

var f = typeof(4+6/12)

signal a()
signal b(a:int,b:Type)

var string_test_1 = 'an "Elephant"'
var string_test_2 = 'an
 \'Elephantos\''

# "Default" 'Data' (I recommend splitting this kind of stuff into separate json files in c#)
const _default_data = {
    "t" : 100,
    "r
    afg" : 'asfgh',
    "u" : false,# Example Comment
    "r":["a",{"b":false}],
    "t":{"e":{"g":1,"f":2},},
};

func setterA(v:float):
    return
    pass

func getterA()->float:
    return 1.

func ready():
    var s = range(abs(-1),randi())
    
    .ready();

    if ABC: # Comment
        assert(false)
    elif false:
        print("Hello"+" "+"World")
    else:
        (a+b)()
    return [
    [0,e,[0,{}]], # a
    [1,{},[0,{}]],
    ];

# Do stuff
func r(value:T,val=false,s)->bool:
    if value == null : return !true

    var type = typeof(value)
    match type :
        TYPE_BOOL,TYPE_INT,TYPE_NIL:
            return value
        TYPE_DICTIONARY:
            var result = {}
            for k in value:
                result[k] = value[k]
            return result
            
func default_async_function():
    yield(self,'a');
            


Result :


using System;
using Godot;
using Dictionary = Godot.Collections.Dictionary;
using Array = Godot.Collections.Array;

[Tool]
public class GameDataTest2 : Node
{
     
    enum {UNIT_NEUTRAL, UNIT_ENEMY, UNIT_ALLY};
    enum Named {THING_1, THING_2, ANOTHER_THING = -1}
    
    [Export(Param)] static readonly Date Date = GD.Load("res://path");
    const bool ABC = true;
    float G {get{return getterA();} set{setterA(value);}}
    float DEF = -0.1f ;// Step
    
    __TYPE__ f = (4+6/12).GetType();
    
    [Signal] delegate void a();
    [Signal] delegate void b(int a,Type b);
    
    string string_test_1 = "an \"Elephant\"";
    __TYPE__ string_test_2 = "an\n"+
    " \'Elephantos\'"
    
    // "Default" 'Data' (I recommend splitting this kind of stuff into separate json files in c#)
    static readonly Dictionary _default_data = new Dictionary(){
        {"t", 100},
        {"r\n"+
    "	afg", "asfgh"},
        {"u", false},// Example Comment
        {"r",new Array(){"a",new Dictionary(){{"b",false}}}},
        {"t",new Dictionary(){{"e",new Dictionary(){{"g",1},{"f",2}}},}},
    };
    
    public void setterA(float v)
    {  
        return;
    
    }
    
    public float getterA()
    {  
        return 1.;
    
    }
    
    public __TYPE__ ready()
    {  
        var s = GD.Range(Mathf.Abs(-1),GD.Randi());
        
        base.ready();
    
        if(ABC) // Comment
        {
            System.Diagnostics.Debug.Assert(false);
        }
        else if(false)
        {
            GD.Print("Hello"+" "+"World");
        }
        else
        {
            (a+b)()
        }
        return new Array(){
        new Array(){0,e,new Array(){0,new Dictionary(){}}}, // a
        new Array(){1,new Dictionary(){},new Array(){0,new Dictionary(){}}},
        };
    
    // Do stuff
    }
    
    public bool r(T value,bool val=false,__TYPE__ s)
    {  
        if(value == null)
             return !true;
    
        var type = (value).GetType();
        switch( type )
        {
            case typeof(bool):
            case typeof(int):
            case null:
                return value;
                break;
            case typeof(Dictionary):
                Dictionary result = new Dictionary(){};
                foreach(var k in value)
                {
                    result[k] = value[k];
                }
                return result;
                
                break;
        }
    }
    
    public async void default_async_function()
    {  
        await ToSignal(this,"a");
    }
    
                
}

As you can see, it's not perfect and it will require you to manually fix the formatting and some underivable type definitions afterwards. But it should save you hundreds of hours on your code conversions. If it does save you time, please consider leaving a donation. It'll flow right back into making this project even better.


What's next :

Smarter Analysis :

- Project-wide class analysis : Scan existing gd and cs scripts, extract classes, methods, fields, and use data to more accurately rename, to automatically load scripts, to infer function return types, etc

- Optional automatic PascalCase conversion on all non-static variables

- process entire folders (recursively)

But before that the focus will be on polishing existing features, increasing performance and publishing it on the Godot Asset Store.

Convert GDScript classes to C#. A one click solution that may save you hundreds of hours.

This plugin offers a graphical editor UI for the gd2cs.py python script.
It requires python and the python module "regex". But don't worry, it will detect and guide you through the necessary installs if you don't have them installed.
Visit the Github page ( View Files ) for more information.

Please backup all your data before using this addon! I cannot be held liable for data lost and damages caused.

Reviews

0 ratings

Your Rating

Headline must be at least 3 characters but not more than 50
Review must be at least 5 characters but not more than 500
Please sign in to add a review

Quick Information

0 ratings
gd2cs - Convert GDScript to C# icon image
SvenHollesen
gd2cs - Convert GDScript to C#

Convert GDScript classes to C#. A one click solution that may save you hundreds of hours.This plugin offers a graphical editor UI for the gd2cs.py python script.It requires python and the python module "regex". But don't worry, it will detect and guide you through the necessary installs if you don't have them installed.Visit the Github page ( View Files ) for more information.Please backup all your data before using this addon! I cannot be held liable for data lost and damages caused.

Supported Engine Version
3.2
Version String
1.0
License Version
GPLv3
Support Level
community
Modified Date
3 years ago
Git URL
Issue URL

Open Source

Released under the AGPLv3 license

Plug and Play

Browse assets directly from Godot

Community Driven

Created by developers for developers