
Publisher
baizeyv
GODolphin
zh-cn: GODOT 的 C# 工具包,包含了从R3仓库中提取的可反应属性的实现,以及从UNITY QFRAMEWORK 中提取的非常好用的工具,并做了一点小小的修改,同时也包含一个现代化外表的 LOG CONSOLE en: GODOT's C# toolkit, including the implementation of reactive properties extracted from the R3 repository, and the very useful tools extracted from UNITY QFRAMEWORK, with a few minor modifications, and also includes a modern-looking LOG CONSOLE
🐬 GODolphin 🐬
- Introduce
- AOP Module
- Log Module
- Resource Module
- Singleton Module
- State Machine Module
- UI Module
- How To Install
Introduce
GODOT's C# toolkit, including the implementation of reactive properties extracted from the R3 repository, and the very useful tools extracted from UNITY QFRAMEWORK, with a few minor modifications, and also includes a modern-looking LOG CONSOLE
AOP Module
Source of demand:
When I am debugging a program, I often need to insert some code before and after a method when calling it somewhere. So I think of AOP, but this function is a bit redundant. After all, I can manually write the code where I want to insert it.
Notice: Only allowed during debugging, otherwise it will cause performance problems
Runtime Example
public override void _Ready()
{
Proxy
.Instance.SetTarget(this)
.SetMethod("TestFOOBAR")
.SetArguments(new object[] { "HELLO" })
.SetInvocationHandler(LogInvocationHandler.Instance)
.Invoke();
}
public void TestFOOBAR(string msg)
{
msg += " --WHAT";
Log.Error().Msg(msg).Do();
}
You Need Create Your Custom InvocationHandler
, extend from AbstractInvocationHandler
public class LogInvocationHandler : AbstractInvocationHandler
{
public static LogInvocationHandler Instance = new LogInvocationHandler();
private LogInvocationHandler() { }
public override void Preprocess()
{
GD.Print("PRE");
}
public override void PostProcess()
{
GD.Print("POST");
}
}
Suggestions:
It is recommended to encapsulate your own static methods directly for easy calling
Log Module
Source of demand:
When I am developing, I need to log in many locations, but their call stacks may be different, so I want to see the call stack of the output. Since the ordinary output of GODOT does not have a call stack, I have this plug-in, and the output of GODOT does not have an accurate time display.
the modern-looking LOG CONSOLE:
The code in the above picture:
var a = 222;
Log.Debug().Var("a value", a).Sep().Msg("hello").Tag("MYMANAGER").Do();
Log.Warn().Msg("test content hello world").Cr().Msg("????").Do();
Log.Error().Msg("test content hello world").Cr().Msg("????").Do();
Log.Info().Msg("test content hello world").Cr().Msg("????").Do();
Log.Debug().Msg("GOGOGO").Do();
for (var i = 0; i Normal Info Log
> ```csharp
> Log.Info().Msg("FOO").Cr().Msg("BAR").Do();
> ```
> Debug Variable Log
> ```csharp
> var a = 222;
> Log.Debug().Var("a value", a).Cr().Msg("BAR").Do();
> ```
> Warning Log
> ```csharp
> Log.Warn().Msg("FOO").Sep().Msg("BAR").Do();
> ```
> Error Log
> ```csharp
> Log.Error().Msg("FOO").Sep().Msg("BAR").Do();
> ```
> Line Break API:
>
> ```csharp
> Log.Warn().Cr().Do()
> ```
> the `Cr()` is line break
> Dividing Line API:
>
> ```csharp
> Log.Warn().Sep().Do()
> ```
> the `Sep()` is dividing line
> Normal Message API:
>
> ```csharp
> Log.Info().Msg("what you say").Do()
> ```
> the `Msg()` is normal message
> Specific Variable API:
>
> ```csharp
> Log.Info().Var("your custom variable name", VariableHere).Do()
> ```
> the `Var()` is specific variable
> Tag API:
>
> ```csharp
> Log.Info().Tag("TAG").Msg("HAHA").Do()
> ```
> the `Tag()` is tag
>
> (TAG will output at the second, the first is log level, you can call `Tag("")` anywhere, but before `Do()`)
## Resource Module
Resource Editor Preview:

## Singleton Module
Singleton Editor Preview:

## State Machine Module
State Machine Editor Preview:

Inheritance and chaining can be mixed
Please use this to create new state machine, not `new()`
```csharp
var machine = StateMachineManager.Instance.CreateMachine("LogTypeMachine");
Chaining Example A:
public partial class StateMachineExample1 : Node
{
public enum States
{
A,
B,
}
public StateMachine sm = new();
public override void _Ready()
{
sm.OnStateChanged(
(prev, now) =>
{
GD.Print($"{prev} => {now}");
}
);
sm.State(States.A)
.OnCondition(() =>
{
return sm.CurrentStateId == States.B;
})
.OnEnter(() =>
{
GD.Print("ENTER A");
})
.OnProcess(() =>
{
GD.Print("PROCESS A");
})
.OnPhysicsProcess(() =>
{
GD.Print("PHYSICS PROCESS A");
})
.OnExit(() =>
{
GD.Print("EXIT A");
});
sm.State(States.B)
.OnCondition(() =>
{
return sm.CurrentStateId == States.A;
});
sm.StartState(States.A);
this.AppendAction(
this.Delay(
2f,
this.Callback(() =>
{
sm.SwitchState(States.B);
})
)
);
}
public override void _Process(double delta)
{
sm._Process(delta);
}
public override void _PhysicsProcess(double delta)
{
sm._PhysicsProcess(delta);
}
public override void _ExitTree()
{
sm.Clear();
}
}
Inheritance Example B:
public partial class StateMachineExample2 : Node
{
public enum States2
{
A,
B,
C,
}
public StateMachine machine = new();
public class StateA : AbstractState
{
public StateA(StateMachine machine, StateMachineExample2 target)
: base(machine, target) { }
protected override bool OnCondition()
{
return machine.CurrentStateId == States2.B;
}
}
public class StateB : AbstractState
{
public StateB(StateMachine machine, StateMachineExample2 target)
: base(machine, target) { }
protected override bool OnCondition()
{
return machine.CurrentStateId == States2.A;
}
}
public override void _Process(double delta)
{
machine._Process(delta);
}
public override void _PhysicsProcess(double delta)
{
machine._PhysicsProcess(delta);
}
public override void _Ready()
{
machine.AddState(States2.A, new StateA(machine, this));
machine.AddState(States2.B, new StateB(machine, this));
// * 支持和链式模式混用
machine
.State(States2.C)
.OnEnter(() =>
{
GD.Print("C Enter");
});
machine.StartState(States2.A);
}
public override void _ExitTree()
{
machine.Clear();
}
}
UI Module
UI Editor Preview:
Press Generate
Button Can Generate UI Template Code.
UI Setting Dialog:
How to install
download the
.zip
and unzip itMove the
GODolphin
folder into theaddons
folder of your Godot project, if you don't have this folder you can just create oneIn Godot, Under
Projects -> Projects Settings -> Plugins
, Enable the plugin you need whose names contain theGODolphin
prefix.