diff --git a/Runtime/Nodes/Nudge.meta b/Runtime/Nodes/Nudge.meta
new file mode 100644
index 0000000..8b60b94
--- /dev/null
+++ b/Runtime/Nodes/Nudge.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: c66dc6a1a89e45c4a7ea7ff3082d01bc
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Runtime/Nodes/Nudge/NudgeUnit.cs b/Runtime/Nodes/Nudge/NudgeUnit.cs
new file mode 100644
index 0000000..3eead4c
--- /dev/null
+++ b/Runtime/Nodes/Nudge/NudgeUnit.cs
@@ -0,0 +1,65 @@
+// Visual Pinball Engine
+// Copyright (C) 2026 freezy and VPE Team
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+using Unity.VisualScripting;
+using UnityEngine;
+
+namespace VisualPinball.Unity.VisualScripting
+{
+ [UnitTitle("Nudge")]
+ [UnitSurtitle("Player")]
+ [UnitCategory("Pinball")]
+ public class NudgeUnit : GleUnit
+ {
+ [DoNotSerialize]
+ [PortLabelHidden]
+ public ControlInput InputTrigger;
+
+ [DoNotSerialize]
+ [PortLabelHidden]
+ public ControlOutput OutputTrigger;
+
+ [DoNotSerialize]
+ [PortLabel("Angle")]
+ public ValueInput Angle { get; private set; }
+
+ [DoNotSerialize]
+ [PortLabel("Force")]
+ public ValueInput Force { get; private set; }
+
+ protected override void Definition()
+ {
+ InputTrigger = ControlInput(nameof(InputTrigger), Process);
+ OutputTrigger = ControlOutput(nameof(OutputTrigger));
+ Angle = ValueInput(nameof(Angle), 0f);
+ Force = ValueInput(nameof(Force), 2f);
+ Requirement(Angle, InputTrigger);
+ Requirement(Force, InputTrigger);
+ Succession(InputTrigger, OutputTrigger);
+ }
+
+ private ControlOutput Process(Flow flow)
+ {
+ if (!AssertPlayer(flow)) {
+ Debug.LogError("Cannot find Player.");
+ return OutputTrigger;
+ }
+
+ Player.Nudge(flow.GetValue(Angle), flow.GetValue(Force));
+ return OutputTrigger;
+ }
+ }
+}
diff --git a/Runtime/Nodes/Nudge/NudgeUnit.cs.meta b/Runtime/Nodes/Nudge/NudgeUnit.cs.meta
new file mode 100644
index 0000000..5aa12c4
--- /dev/null
+++ b/Runtime/Nodes/Nudge/NudgeUnit.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6c84b38a9bc44753b29b91e424475e2c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: