diff --git a/mono/2.5d/2.5D Demo (Mono C#).csproj b/mono/2.5d/2.5D Demo (Mono C#).csproj
new file mode 100644
index 00000000000..6c9d771735a
--- /dev/null
+++ b/mono/2.5d/2.5D Demo (Mono C#).csproj
@@ -0,0 +1,64 @@
+
+
+
+ Debug
+ AnyCPU
+ {5CA791DB-5050-44D0-989B-41D559AB1D50}
+ Library
+ .mono/temp/bin/$(Configuration)
+ Empty.DMono
+ 2.5D Demo (Mono C#)
+ v4.5
+ .mono/temp/obj
+ $(BaseIntermediateOutputPath)/$(Configuration)
+
+
+ true
+ portable
+ false
+ $(GodotDefineConstants);GODOT;DEBUG;
+ prompt
+ 4
+ false
+
+
+ portable
+ true
+ $(GodotDefineConstants);GODOT;
+ prompt
+ 4
+ false
+
+
+ true
+ portable
+ false
+ $(GodotDefineConstants);GODOT;DEBUG;TOOLS;
+ prompt
+ 4
+ false
+
+
+
+ $(ProjectDir)/.mono/assemblies/GodotSharp.dll
+ False
+
+
+ $(ProjectDir)/.mono/assemblies/GodotSharpEditor.dll
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mono/2.5d/2.5D Demo (Mono C#).sln b/mono/2.5d/2.5D Demo (Mono C#).sln
new file mode 100644
index 00000000000..d979d4573d1
--- /dev/null
+++ b/mono/2.5d/2.5D Demo (Mono C#).sln
@@ -0,0 +1,19 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "2.5D Demo (Mono C#)", "2.5D Demo (Mono C#).csproj", "{5CA791DB-5050-44D0-989B-41D559AB1D50}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ Tools|Any CPU = Tools|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5CA791DB-5050-44D0-989B-41D559AB1D50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5CA791DB-5050-44D0-989B-41D559AB1D50}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5CA791DB-5050-44D0-989B-41D559AB1D50}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5CA791DB-5050-44D0-989B-41D559AB1D50}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5CA791DB-5050-44D0-989B-41D559AB1D50}.Tools|Any CPU.ActiveCfg = Tools|Any CPU
+ {5CA791DB-5050-44D0-989B-41D559AB1D50}.Tools|Any CPU.Build.0 = Tools|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/mono/2.5d/Assets/Cube.tscn b/mono/2.5d/Assets/Cube.tscn
new file mode 100644
index 00000000000..58b6e1e4be6
--- /dev/null
+++ b/mono/2.5d/Assets/Cube.tscn
@@ -0,0 +1,20 @@
+[gd_scene load_steps=5 format=2]
+
+[ext_resource path="res://addons/node25d-cs/YSort25D.cs" type="Script" id=1]
+[ext_resource path="res://addons/node25d-cs/icons/ysort25d_icon.png" type="Texture" id=2]
+[ext_resource path="res://Assets/UI/OverlayCube.tscn" type="PackedScene" id=3]
+[ext_resource path="res://Assets/Cube/CubeMath.cs" type="Script" id=4]
+
+[node name="Cube" type="Node2D"]
+script = ExtResource( 1 )
+__meta__ = {
+"_editor_icon": ExtResource( 2 )
+}
+
+[node name="Overlay" parent="." instance=ExtResource( 3 )]
+
+[node name="Camera2D" type="Camera2D" parent="."]
+current = true
+
+[node name="CubeMath" type="Spatial" parent="."]
+script = ExtResource( 4 )
diff --git a/mono/2.5d/Assets/Cube/CubeMath.cs b/mono/2.5d/Assets/Cube/CubeMath.cs
new file mode 100644
index 00000000000..5878826d01f
--- /dev/null
+++ b/mono/2.5d/Assets/Cube/CubeMath.cs
@@ -0,0 +1,68 @@
+using Godot;
+using System;
+
+public class CubeMath : Spatial
+{
+ private static PackedScene cubePointScene = ResourceLoader.Load("res://Assets/Cube/CubePoint.tscn");
+
+ private bool isParentReady = false;
+ private Node2D parent;
+ private Spatial[] cubePointsMath = new Spatial[27]; // The math node of each 2.5D cube point
+ private Spatial[] cubeMathSpatials = new Spatial[27]; // The CubeMath children that find position.
+
+ public override void _Ready()
+ {
+ parent = GetParent();
+
+ // Initialize the cube
+ for (int i = 0; i < 27; i++)
+ {
+ int a = (i / 9) - 1;
+ int b = (i / 3) % 3 - 1;
+ int c = (i % 3) - 1;
+ Vector3 spatialPosition = 5 * (a * Vector3.Right + b * Vector3.Up + c * Vector3.Back);
+
+ cubeMathSpatials[i] = new Spatial();
+ cubeMathSpatials[i].Translation = spatialPosition;
+ cubeMathSpatials[i].Name = "CubeMath #" + i + ", " + a + " " + b + " " + c;
+ AddChild(cubeMathSpatials[i]);
+ }
+ }
+
+ public override void _Process(float delta)
+ {
+ if (Input.IsActionJustPressed("ViewCubeDemo"))
+ {
+ GetTree().ChangeScene("res://Assets/DemoScene.tscn");
+ return;
+ }
+
+ if (isParentReady)
+ {
+ RotateX(delta * (Input.GetActionStrength("MoveBackward") - Input.GetActionStrength("MoveForward")));
+ RotateY(delta * (Input.GetActionStrength("MoveRight") - Input.GetActionStrength("MoveLeft")));
+ RotateZ(delta * (Input.GetActionStrength("MoveCounterclockwise") - Input.GetActionStrength("MoveClockwise")));
+ if (Input.IsActionJustPressed("ResetPosition"))
+ {
+ Transform = Transform.Identity;
+ }
+ for (int i = 0; i < 27; i++)
+ {
+ cubePointsMath[i].GlobalTransform = cubeMathSpatials[i].GlobalTransform;
+ }
+ }
+ else
+ {
+ // This code block will be run only once. It's not in _Ready() because the parent isn't set up there.
+ for (int i = 0; i < 27; i++)
+ {
+ PackedScene myCubePointScene = cubePointScene.Duplicate(true) as PackedScene;
+ Node25D cubePoint = myCubePointScene.Instance() as Node25D;
+ cubePoint.Name = "CubePoint #" + i;
+ cubePointsMath[i] = cubePoint.GetChild(0);
+ parent.AddChild(cubePoint);
+ }
+ isParentReady = true;
+ }
+ }
+}
diff --git a/mono/2.5d/Assets/Cube/CubePoint.tscn b/mono/2.5d/Assets/Cube/CubePoint.tscn
new file mode 100644
index 00000000000..282613c3270
--- /dev/null
+++ b/mono/2.5d/Assets/Cube/CubePoint.tscn
@@ -0,0 +1,16 @@
+[gd_scene load_steps=4 format=2]
+
+[ext_resource path="res://addons/node25d-cs/Node25D.cs" type="Script" id=1]
+[ext_resource path="res://addons/node25d-cs/icons/node25d_icon.png" type="Texture" id=2]
+[ext_resource path="res://Assets/Cube/godot.png" type="Texture" id=3]
+
+[node name="CubePoint" type="Node2D"]
+script = ExtResource( 1 )
+__meta__ = {
+"_editor_icon": ExtResource( 2 )
+}
+
+[node name="CubePointMath" type="Spatial" parent="."]
+
+[node name="CubePointSprite" type="Sprite" parent="."]
+texture = ExtResource( 3 )
diff --git a/mono/2.5d/Assets/Cube/godot.png b/mono/2.5d/Assets/Cube/godot.png
new file mode 100644
index 00000000000..bcc37bb0031
Binary files /dev/null and b/mono/2.5d/Assets/Cube/godot.png differ
diff --git a/mono/2.5d/Assets/Cube/godot.png.import b/mono/2.5d/Assets/Cube/godot.png.import
new file mode 100644
index 00000000000..bca2b0b9974
--- /dev/null
+++ b/mono/2.5d/Assets/Cube/godot.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/godot.png-3e601e6c27d3d4bf4c56687ed358139e.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Assets/Cube/godot.png"
+dest_files=[ "res://.import/godot.png-3e601e6c27d3d4bf4c56687ed358139e.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/Assets/DemoScene.tscn b/mono/2.5d/Assets/DemoScene.tscn
new file mode 100644
index 00000000000..91849c1d35d
--- /dev/null
+++ b/mono/2.5d/Assets/DemoScene.tscn
@@ -0,0 +1,590 @@
+[gd_scene load_steps=14 format=2]
+
+[ext_resource path="res://addons/node25d-cs/YSort25D.cs" type="Script" id=1]
+[ext_resource path="res://addons/node25d-cs/icons/ysort25d_icon.png" type="Texture" id=2]
+[ext_resource path="res://Assets/UI/Overlay.tscn" type="PackedScene" id=3]
+[ext_resource path="res://Assets/Player/Player25D.tscn" type="PackedScene" id=4]
+[ext_resource path="res://Assets/Shadow/Shadow25D.tscn" type="PackedScene" id=5]
+[ext_resource path="res://addons/node25d-cs/Node25D.cs" type="Script" id=6]
+[ext_resource path="res://addons/node25d-cs/icons/node25d_icon.png" type="Texture" id=7]
+[ext_resource path="res://Assets/Platform/Textures/fortyfive.png" type="Texture" id=8]
+[ext_resource path="res://Assets/Platform/PlatformSprite.gd" type="Script" id=9]
+
+[sub_resource type="BoxShape" id=1]
+extents = Vector3( 5, 0.5, 5 )
+
+[sub_resource type="BoxShape" id=2]
+extents = Vector3( 5, 0.5, 5 )
+
+[sub_resource type="BoxShape" id=3]
+extents = Vector3( 5, 0.5, 5 )
+
+[sub_resource type="BoxShape" id=4]
+extents = Vector3( 5, 0.5, 5 )
+
+[node name="DemoScene" type="Node2D"]
+script = ExtResource( 1 )
+__meta__ = {
+"_editor_icon": ExtResource( 2 )
+}
+
+[node name="Overlay" parent="." instance=ExtResource( 3 )]
+
+[node name="Player25D" parent="." instance=ExtResource( 4 )]
+z_index = -3952
+
+[node name="Shadow25D" parent="." instance=ExtResource( 5 )]
+position = Vector2( 1.00261e-06, 11.2685 )
+z_index = -3958
+
+[node name="Platform0" type="Node2D" parent="."]
+position = Vector2( -256, -113.137 )
+z_index = -3954
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform0"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -8, 5, 0 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform0/PlatformMath"]
+shape = SubResource( 1 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform0"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform1" type="Node2D" parent="."]
+position = Vector2( -256, -339.389 )
+z_index = -3956
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform1"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -8, 4.999, -10 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform1/PlatformMath"]
+shape = SubResource( 2 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform1"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform2" type="Node2D" parent="."]
+position = Vector2( 0, 22.6274 )
+z_index = -3964
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform2"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform2/PlatformMath"]
+shape = SubResource( 2 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform2"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform3" type="Node2D" parent="."]
+position = Vector2( 320, 22.6048 )
+z_index = -3960
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform3"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 10, -0.999, 0 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform3/PlatformMath"]
+shape = SubResource( 2 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform3"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform4" type="Node2D" parent="."]
+position = Vector2( 0, -203.624 )
+z_index = -3966
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform4"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.001, -10 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform4/PlatformMath"]
+shape = SubResource( 2 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform4"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform5" type="Node2D" parent="."]
+position = Vector2( 320, -113.114 )
+z_index = -3984
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform5"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 10, -5.001, -10 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform5/PlatformMath"]
+shape = SubResource( 2 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform5"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform6" type="Node2D" parent="."]
+position = Vector2( 320, 113.137 )
+z_index = -3980
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform6"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 10, -5, 0 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform6/PlatformMath"]
+shape = SubResource( 2 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform6"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform7" type="Node2D" parent="."]
+position = Vector2( 320, 339.389 )
+z_index = -3978
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform7"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 10, -4.999, 10 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform7/PlatformMath"]
+shape = SubResource( 3 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform7"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform8" type="Node2D" parent="."]
+position = Vector2( 320, 565.618 )
+z_index = -3974
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform8"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 10, -4.997, 20 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform8/PlatformMath"]
+shape = SubResource( 3 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform8"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform21" type="Node2D" parent="."]
+position = Vector2( 320, 791.869 )
+z_index = -3972
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform21"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 10, -4.996, 30 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform21/PlatformMath"]
+shape = SubResource( 3 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform21"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform22" type="Node2D" parent="."]
+position = Vector2( 320, 1018.12 )
+z_index = -3970
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform22"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 10, -4.995, 40 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform22/PlatformMath"]
+shape = SubResource( 3 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform22"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform9" type="Node2D" parent="."]
+position = Vector2( 640, 339.366 )
+z_index = -3976
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform9"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 20, -4.998, 10 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform9/PlatformMath"]
+shape = SubResource( 4 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform9"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform10" type="Node2D" parent="."]
+position = Vector2( 896, 294.202 )
+z_index = -3994
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform10"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 28, -10.002, 3 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform10/PlatformMath"]
+shape = SubResource( 4 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform10"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform11" type="Node2D" parent="."]
+position = Vector2( 896, 520.453 )
+z_index = -3990
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform11"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 28, -10.001, 13 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform11/PlatformMath"]
+shape = SubResource( 4 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform11"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform12" type="Node2D" parent="."]
+position = Vector2( 896, 746.705 )
+z_index = -3988
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform12"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 28, -10, 23 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform12/PlatformMath"]
+shape = SubResource( 4 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform12"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform13" type="Node2D" parent="."]
+position = Vector2( 576, 746.727 )
+z_index = -3992
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform13"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 18, -10.001, 23 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform13/PlatformMath"]
+shape = SubResource( 4 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform13"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform14" type="Node2D" parent="."]
+position = Vector2( 256, 746.75 )
+z_index = -3996
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform14"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 8, -10.002, 23 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform14/PlatformMath"]
+shape = SubResource( 4 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform14"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform15" type="Node2D" parent="."]
+position = Vector2( -64, 746.773 )
+z_index = -3998
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform15"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -2, -10.003, 23 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform15/PlatformMath"]
+shape = SubResource( 4 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform15"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform23" type="Node2D" parent="."]
+position = Vector2( -384, 746.773 )
+z_index = -4000
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform23"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -12, -10.003, 23 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform23/PlatformMath"]
+shape = SubResource( 4 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform23"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform16" type="Node2D" parent="."]
+position = Vector2( -320, 565.685 )
+z_index = -3982
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform16"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -10, -5, 20 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform16/PlatformMath"]
+shape = SubResource( 4 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform16"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform19" type="Node2D" parent="."]
+position = Vector2( -320, 339.434 )
+z_index = -3986
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform19"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -10, -5.001, 10 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform19/PlatformMath"]
+shape = SubResource( 4 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform19"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform17" type="Node2D" parent="."]
+position = Vector2( -480, 248.902 )
+z_index = -3962
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform17"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -15, -1, 10 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform17/PlatformMath"]
+shape = SubResource( 4 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform17"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
+
+[node name="Platform18" type="Node2D" parent="."]
+position = Vector2( -480, 22.65 )
+z_index = -3968
+script = ExtResource( 6 )
+__meta__ = {
+"_editor_icon": ExtResource( 7 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="Platform18"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -15, -1.001, 0 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="Platform18/PlatformMath"]
+shape = SubResource( 4 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="Platform18"]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 8 )
+script = ExtResource( 9 )
diff --git a/mono/2.5d/Assets/Platform/Platform.tscn b/mono/2.5d/Assets/Platform/Platform.tscn
new file mode 100644
index 00000000000..3efe8fe9206
--- /dev/null
+++ b/mono/2.5d/Assets/Platform/Platform.tscn
@@ -0,0 +1,34 @@
+[gd_scene load_steps=6 format=2]
+
+[ext_resource path="res://addons/node25d-cs/Node25D.cs" type="Script" id=1]
+[ext_resource path="res://addons/node25d-cs/icons/node25d_icon.png" type="Texture" id=2]
+[ext_resource path="res://Assets/Platform/Textures/fortyfive.png" type="Texture" id=3]
+[ext_resource path="res://Assets/Platform/PlatformSprite.gd" type="Script" id=4]
+
+[sub_resource type="BoxShape" id=1]
+extents = Vector3( 5, 0.5, 5 )
+
+[node name="Platform" type="Node2D"]
+editor/display_folded = true
+position = Vector2( -256, -113.137 )
+z_index = -3954
+script = ExtResource( 1 )
+__meta__ = {
+"_editor_icon": ExtResource( 2 )
+}
+
+[node name="PlatformMath" type="StaticBody" parent="."]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -8, 5, 0 )
+collision_layer = 1048575
+collision_mask = 1048575
+
+[node name="CollisionShape" type="CollisionShape" parent="PlatformMath"]
+shape = SubResource( 1 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="PlatformSprite" type="Sprite" parent="."]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 3 )
+script = ExtResource( 4 )
diff --git a/mono/2.5d/Assets/Platform/PlatformSprite.gd b/mono/2.5d/Assets/Platform/PlatformSprite.gd
new file mode 100644
index 00000000000..2ecfee83ec9
--- /dev/null
+++ b/mono/2.5d/Assets/Platform/PlatformSprite.gd
@@ -0,0 +1,22 @@
+extends Sprite
+
+onready var _topDown = preload("res://Assets/Platform/Textures/topdown.png")
+onready var _frontSide = preload("res://Assets/Platform/Textures/frontside.png")
+onready var _fortyFive = preload("res://Assets/Platform/Textures/fortyfive.png")
+onready var _isometric = preload("res://Assets/Platform/Textures/isometric.png")
+onready var _obliqueY = preload("res://Assets/Platform/Textures/obliqueY.png")
+onready var _obliqueZ = preload("res://Assets/Platform/Textures/obliqueZ.png")
+
+func _process(_delta):
+ if (Input.is_action_pressed("TopDownMode")):
+ texture = _topDown;
+ elif (Input.is_action_pressed("FrontSideMode")):
+ texture = _frontSide;
+ elif (Input.is_action_pressed("FortyFiveMode")):
+ texture = _fortyFive;
+ elif (Input.is_action_pressed("IsometricMode")):
+ texture = _isometric;
+ elif (Input.is_action_pressed("ObliqueYMode")):
+ texture = _obliqueY;
+ elif (Input.is_action_pressed("ObliqueZMode")):
+ texture = _obliqueZ;
diff --git a/mono/2.5d/Assets/Platform/Textures/41226408-platform-texture.jpg.import b/mono/2.5d/Assets/Platform/Textures/41226408-platform-texture.jpg.import
new file mode 100644
index 00000000000..eb7a41ab336
--- /dev/null
+++ b/mono/2.5d/Assets/Platform/Textures/41226408-platform-texture.jpg.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/41226408-platform-texture.jpg-f542a57a76da223d47835a0796356330.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Assets/Platform/Textures/41226408-platform-texture.jpg"
+dest_files=[ "res://.import/41226408-platform-texture.jpg-f542a57a76da223d47835a0796356330.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/Assets/Platform/Textures/fortyfive.png b/mono/2.5d/Assets/Platform/Textures/fortyfive.png
new file mode 100644
index 00000000000..aa1f2d7e930
Binary files /dev/null and b/mono/2.5d/Assets/Platform/Textures/fortyfive.png differ
diff --git a/mono/2.5d/Assets/Platform/Textures/fortyfive.png.import b/mono/2.5d/Assets/Platform/Textures/fortyfive.png.import
new file mode 100644
index 00000000000..b06d9dfff65
--- /dev/null
+++ b/mono/2.5d/Assets/Platform/Textures/fortyfive.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/fortyfive.png-4c38ea15f13e9ffa47b7b6d2d372f7b7.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Assets/Platform/Textures/fortyfive.png"
+dest_files=[ "res://.import/fortyfive.png-4c38ea15f13e9ffa47b7b6d2d372f7b7.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/Assets/Platform/Textures/frontside.png b/mono/2.5d/Assets/Platform/Textures/frontside.png
new file mode 100644
index 00000000000..a3760077670
Binary files /dev/null and b/mono/2.5d/Assets/Platform/Textures/frontside.png differ
diff --git a/mono/2.5d/Assets/Platform/Textures/frontside.png.import b/mono/2.5d/Assets/Platform/Textures/frontside.png.import
new file mode 100644
index 00000000000..a78b6873a2e
--- /dev/null
+++ b/mono/2.5d/Assets/Platform/Textures/frontside.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/frontside.png-b701c20bb0163e11d1a2943d07968342.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Assets/Platform/Textures/frontside.png"
+dest_files=[ "res://.import/frontside.png-b701c20bb0163e11d1a2943d07968342.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/Assets/Platform/Textures/isometric.png b/mono/2.5d/Assets/Platform/Textures/isometric.png
new file mode 100644
index 00000000000..b0ebf0b80be
Binary files /dev/null and b/mono/2.5d/Assets/Platform/Textures/isometric.png differ
diff --git a/mono/2.5d/Assets/Platform/Textures/isometric.png.import b/mono/2.5d/Assets/Platform/Textures/isometric.png.import
new file mode 100644
index 00000000000..ddd2a6fb324
--- /dev/null
+++ b/mono/2.5d/Assets/Platform/Textures/isometric.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/isometric.png-9f805c6806563f6b5e6efc28e40dc526.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Assets/Platform/Textures/isometric.png"
+dest_files=[ "res://.import/isometric.png-9f805c6806563f6b5e6efc28e40dc526.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/Assets/Platform/Textures/obliqueY.png b/mono/2.5d/Assets/Platform/Textures/obliqueY.png
new file mode 100644
index 00000000000..be4a2893ae8
Binary files /dev/null and b/mono/2.5d/Assets/Platform/Textures/obliqueY.png differ
diff --git a/mono/2.5d/Assets/Platform/Textures/obliqueY.png.import b/mono/2.5d/Assets/Platform/Textures/obliqueY.png.import
new file mode 100644
index 00000000000..4aa3b6b5cb7
--- /dev/null
+++ b/mono/2.5d/Assets/Platform/Textures/obliqueY.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/obliqueY.png-ad47e2d1aedc6e1f435afcff1690a05d.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Assets/Platform/Textures/obliqueY.png"
+dest_files=[ "res://.import/obliqueY.png-ad47e2d1aedc6e1f435afcff1690a05d.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/Assets/Platform/Textures/obliqueZ.png b/mono/2.5d/Assets/Platform/Textures/obliqueZ.png
new file mode 100644
index 00000000000..a3c84b0f7e9
Binary files /dev/null and b/mono/2.5d/Assets/Platform/Textures/obliqueZ.png differ
diff --git a/mono/2.5d/Assets/Platform/Textures/obliqueZ.png.import b/mono/2.5d/Assets/Platform/Textures/obliqueZ.png.import
new file mode 100644
index 00000000000..daef1b1dcd7
--- /dev/null
+++ b/mono/2.5d/Assets/Platform/Textures/obliqueZ.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/obliqueZ.png-09649ac01117a3b5397ad7c03fb8b169.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Assets/Platform/Textures/obliqueZ.png"
+dest_files=[ "res://.import/obliqueZ.png-09649ac01117a3b5397ad7c03fb8b169.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/Assets/Platform/Textures/topdown.png b/mono/2.5d/Assets/Platform/Textures/topdown.png
new file mode 100644
index 00000000000..178649f7e73
Binary files /dev/null and b/mono/2.5d/Assets/Platform/Textures/topdown.png differ
diff --git a/mono/2.5d/Assets/Platform/Textures/topdown.png.import b/mono/2.5d/Assets/Platform/Textures/topdown.png.import
new file mode 100644
index 00000000000..e81f8574f10
--- /dev/null
+++ b/mono/2.5d/Assets/Platform/Textures/topdown.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/topdown.png-9c3ae17a58ea15426c8a3c9ed85e3f0d.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Assets/Platform/Textures/topdown.png"
+dest_files=[ "res://.import/topdown.png-9c3ae17a58ea15426c8a3c9ed85e3f0d.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/Assets/Player/Player25D.tscn b/mono/2.5d/Assets/Player/Player25D.tscn
new file mode 100644
index 00000000000..fd7d5517b96
--- /dev/null
+++ b/mono/2.5d/Assets/Player/Player25D.tscn
@@ -0,0 +1,35 @@
+[gd_scene load_steps=7 format=2]
+
+[ext_resource path="res://addons/node25d-cs/Node25D.cs" type="Script" id=1]
+[ext_resource path="res://addons/node25d-cs/icons/node25d_icon.png" type="Texture" id=2]
+[ext_resource path="res://Assets/Player/PlayerMath25D.cs" type="Script" id=3]
+[ext_resource path="res://Assets/Player/Textures/stand.png" type="Texture" id=4]
+[ext_resource path="res://Assets/Player/PlayerSprite.cs" type="Script" id=5]
+
+[sub_resource type="BoxShape" id=1]
+extents = Vector3( 0.5, 1, 0.5 )
+
+[node name="Player25D" type="Node2D"]
+position = Vector2( 0, -226.274 )
+z_index = 100
+script = ExtResource( 1 )
+__meta__ = {
+"_editor_icon": ExtResource( 2 )
+}
+
+[node name="PlayerMath25D" type="KinematicBody" parent="."]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 10, 0 )
+script = ExtResource( 3 )
+
+[node name="CollisionShape" type="CollisionShape" parent="PlayerMath25D"]
+shape = SubResource( 1 )
+
+[node name="PlayerSprite" type="Sprite" parent="."]
+scale = Vector2( 1, 0.75 )
+z_index = 1
+texture = ExtResource( 4 )
+vframes = 5
+script = ExtResource( 5 )
+
+[node name="PlayerCamera" type="Camera2D" parent="PlayerSprite"]
+current = true
diff --git a/mono/2.5d/Assets/Player/PlayerMath25D.cs b/mono/2.5d/Assets/Player/PlayerMath25D.cs
new file mode 100644
index 00000000000..7f5872bfb35
--- /dev/null
+++ b/mono/2.5d/Assets/Player/PlayerMath25D.cs
@@ -0,0 +1,92 @@
+using Godot;
+using System;
+#if REAL_T_IS_DOUBLE
+using real_t = System.Double;
+#else
+using real_t = System.Single;
+#endif
+
+///
+/// Handles Player-specific behavior like moving. We calculate such things with KinematicBody.
+///
+public class PlayerMath25D : KinematicBody
+{
+ private Node25D parent;
+ public real_t verticalSpeed = 0;
+ public bool isometricControls = true;
+
+ public override void _Ready()
+ {
+ parent = GetParent();
+ }
+
+ public override void _Process(real_t delta)
+ {
+ if (Input.IsActionJustPressed("ViewCubeDemo"))
+ {
+ GetTree().ChangeScene("res://Assets/Cube.tscn");
+ return;
+ }
+
+ if (Input.IsActionJustPressed("ToggleIsometricControls"))
+ {
+ isometricControls = !isometricControls;
+ }
+
+ if (Input.IsActionPressed("ResetPosition"))
+ {
+ Transform = new Transform(Basis.Identity, Vector3.Up * 10);
+ verticalSpeed = 0;
+ }
+ else
+ {
+ HorizontalMovement(delta);
+ VerticalMovement(delta);
+ }
+ }
+
+ ///
+ /// Checks WASD and Shift for horizontal movement via MoveAndSlide.
+ ///
+ private void HorizontalMovement(real_t delta)
+ {
+ Vector3 localX = Vector3.Right;
+ Vector3 localZ = Vector3.Back;
+
+ if (isometricControls && (parent.Basis25D == Basis25D.Isometric * Node25D.SCALE))
+ {
+ localX = new Vector3(0.70710678118f, 0, -0.70710678118f);
+ localZ = new Vector3(0.70710678118f, 0, 0.70710678118f);
+ }
+
+ // Gather player input and add directional movement to force Vector3 variables
+ Vector3 moveDir = Vector3.Zero;
+ moveDir += localX * (Input.GetActionStrength("MoveRight") - Input.GetActionStrength("MoveLeft"));
+ moveDir += localZ * (Input.GetActionStrength("MoveBackward") - Input.GetActionStrength("MoveForward"));
+
+ moveDir = moveDir.Normalized() * delta * 600;
+ if (Input.IsActionPressed("MovementModifier"))
+ {
+ moveDir /= 2;
+ }
+ MoveAndSlide(moveDir);
+ }
+
+ ///
+ /// Checks Jump and applies gravity and vertical speed via MoveAndCollide.
+ ///
+ /// Time delta since last call
+ private void VerticalMovement(real_t delta)
+ {
+ if (Input.IsActionJustPressed("Jump"))
+ {
+ verticalSpeed = 1.25f;
+ }
+ verticalSpeed -= delta * 5; // Gravity
+ var k = MoveAndCollide(Vector3.Up * verticalSpeed);
+ if (k != null)
+ {
+ verticalSpeed = 0;
+ }
+ }
+}
diff --git a/mono/2.5d/Assets/Player/PlayerSprite.cs b/mono/2.5d/Assets/Player/PlayerSprite.cs
new file mode 100644
index 00000000000..fa58b79502d
--- /dev/null
+++ b/mono/2.5d/Assets/Player/PlayerSprite.cs
@@ -0,0 +1,202 @@
+using Godot;
+using System;
+#if REAL_T_IS_DOUBLE
+using real_t = System.Double;
+#else
+using real_t = System.Single;
+#endif
+
+public class PlayerSprite : Sprite
+{
+ private static Texture stand = ResourceLoader.Load("res://Assets/Player/Textures/stand.png");
+ private static Texture jump = ResourceLoader.Load("res://Assets/Player/Textures/jump.png");
+ private static Texture run = ResourceLoader.Load("res://Assets/Player/Textures/run.png");
+ private const int FRAMERATE = 15;
+
+ private int direction;
+ private float progress;
+ private Node25D parent;
+ private PlayerMath25D parentMath;
+
+ public override void _Ready()
+ {
+ parent = GetParent();
+ parentMath = parent.GetChild(0);
+ }
+
+ public override void _Process(real_t delta)
+ {
+ SpriteBasis();
+ bool movement = CheckMovement();
+ parentMath.MoveAndSlide(new Vector3(0, -0.001f, 0), new Vector3(0, 1, 0)); // Why Godot, why is this necessary...
+ if (parentMath.IsOnFloor())
+ {
+ if (movement)
+ {
+ // TODO: https://github.com/godotengine/godot/issues/28748
+ Hframes = 6;
+ Texture = run;
+ if (Input.IsActionPressed("MovementModifier"))
+ {
+ delta /= 2;
+ }
+ progress = (progress + FRAMERATE * delta) % 6;
+ Frame = direction * 6 + (int)progress;
+ }
+ else
+ {
+ Hframes = 1;
+ Texture = stand;
+ progress = 0;
+ Frame = direction;
+ }
+ }
+ else
+ {
+ Hframes = 2;
+ Texture = jump;
+ progress = 0;
+ int jumping = parentMath.verticalSpeed < 0 ? 1 : 0;
+ Frame = direction * 2 + jumping;
+ }
+ }
+
+ ///
+ /// Change the basis of the sprite to try and make it fit multiple view modes.
+ ///
+ private void SpriteBasis()
+ {
+ Transform2D t = Transform;
+ if (Input.IsActionPressed("TopDownMode"))
+ {
+ t.x = new Vector2(1, 0);
+ t.y = new Vector2(0, 0.5f);
+ }
+ else if (Input.IsActionPressed("FrontSideMode"))
+ {
+ t.x = new Vector2(1, 0);
+ t.y = new Vector2(0, 1);
+ }
+ else if (Input.IsActionPressed("FortyFiveMode"))
+ {
+ t.x = new Vector2(1, 0);
+ t.y = new Vector2(0, 0.75f);
+ }
+ else if (Input.IsActionPressed("IsometricMode"))
+ {
+ t.x = new Vector2(1, 0);
+ t.y = new Vector2(0, 1);
+ }
+ else if (Input.IsActionPressed("ObliqueYMode"))
+ {
+ t.x = new Vector2(1, 0);
+ t.y = new Vector2(1, 1);
+ }
+ else if (Input.IsActionPressed("ObliqueZMode"))
+ {
+ t.x = new Vector2(1, 0.25f);
+ t.y = new Vector2(0, 1);
+ }
+ Transform = t;
+ }
+
+ // There might be a more efficient way to do this, but I can't think of it.
+ private bool CheckMovement()
+ {
+ // Gather player input and store movement to these int variables. Note: These indeed have to be integers.
+ int x = 0;
+ int z = 0;
+
+ if (Input.IsActionPressed("MoveRight"))
+ {
+ x++;
+ }
+ if (Input.IsActionPressed("MoveLeft"))
+ {
+ x--;
+ }
+ if (Input.IsActionPressed("MoveForward"))
+ {
+ z--;
+ }
+ if (Input.IsActionPressed("MoveBackward"))
+ {
+ z++;
+ }
+
+ // Check for isometric controls and add more to movement accordingly.
+ if (!parentMath.isometricControls && parent.Basis25D == Basis25D.Isometric * Node25D.SCALE)
+ {
+ if (Input.IsActionPressed("MoveRight"))
+ {
+ z++;
+ }
+ if (Input.IsActionPressed("MoveLeft"))
+ {
+ z--;
+ }
+ if (Input.IsActionPressed("MoveForward"))
+ {
+ x++;
+ }
+ if (Input.IsActionPressed("MoveBackward"))
+ {
+ x--;
+ }
+ }
+
+ // Set the direction based on which inputs were pressed.
+ if (x == 0)
+ {
+ if (z == 0)
+ {
+ return false; // No movement
+ }
+ else if (z > 0)
+ {
+ direction = 0;
+ }
+ else
+ {
+ direction = 4;
+ }
+ }
+ else if (x > 0)
+ {
+ if (z == 0)
+ {
+ direction = 2;
+ FlipH = true;
+ }
+ else if (z > 0)
+ {
+ direction = 1;
+ FlipH = true;
+ }
+ else
+ {
+ direction = 3;
+ FlipH = true;
+ }
+ }
+ else
+ {
+ if (z == 0)
+ {
+ direction = 2;
+ FlipH = false;
+ }
+ else if (z > 0)
+ {
+ direction = 1;
+ FlipH = false;
+ }
+ else
+ {
+ direction = 3;
+ FlipH = false;
+ }
+ }
+ return true; // There is movement
+ }
+}
diff --git a/mono/2.5d/Assets/Player/Textures/jump.png b/mono/2.5d/Assets/Player/Textures/jump.png
new file mode 100755
index 00000000000..340d72b8ba1
Binary files /dev/null and b/mono/2.5d/Assets/Player/Textures/jump.png differ
diff --git a/mono/2.5d/Assets/Player/Textures/jump.png.import b/mono/2.5d/Assets/Player/Textures/jump.png.import
new file mode 100644
index 00000000000..e19feacbb12
--- /dev/null
+++ b/mono/2.5d/Assets/Player/Textures/jump.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/jump.png-5601c6bfbcc06e19edd315cdc0e9aa19.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Assets/Player/Textures/jump.png"
+dest_files=[ "res://.import/jump.png-5601c6bfbcc06e19edd315cdc0e9aa19.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/Assets/Player/Textures/run.png b/mono/2.5d/Assets/Player/Textures/run.png
new file mode 100644
index 00000000000..900742aea3d
Binary files /dev/null and b/mono/2.5d/Assets/Player/Textures/run.png differ
diff --git a/mono/2.5d/Assets/Player/Textures/run.png.import b/mono/2.5d/Assets/Player/Textures/run.png.import
new file mode 100644
index 00000000000..f236a4d49eb
--- /dev/null
+++ b/mono/2.5d/Assets/Player/Textures/run.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/run.png-6242270e08c3bf41f513dec4db012e97.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Assets/Player/Textures/run.png"
+dest_files=[ "res://.import/run.png-6242270e08c3bf41f513dec4db012e97.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/Assets/Player/Textures/stand.png b/mono/2.5d/Assets/Player/Textures/stand.png
new file mode 100644
index 00000000000..1fbc364fda0
Binary files /dev/null and b/mono/2.5d/Assets/Player/Textures/stand.png differ
diff --git a/mono/2.5d/Assets/Player/Textures/stand.png.import b/mono/2.5d/Assets/Player/Textures/stand.png.import
new file mode 100644
index 00000000000..031c4c14cf4
--- /dev/null
+++ b/mono/2.5d/Assets/Player/Textures/stand.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/stand.png-2c01e16859e3b0e3a2a857f8a12f998d.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Assets/Player/Textures/stand.png"
+dest_files=[ "res://.import/stand.png-2c01e16859e3b0e3a2a857f8a12f998d.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/Assets/Shadow/Shadow25D.tscn b/mono/2.5d/Assets/Shadow/Shadow25D.tscn
new file mode 100644
index 00000000000..96b7050d740
--- /dev/null
+++ b/mono/2.5d/Assets/Shadow/Shadow25D.tscn
@@ -0,0 +1,34 @@
+[gd_scene load_steps=8 format=2]
+
+[ext_resource path="res://addons/node25d-cs/Node25D.cs" type="Script" id=1]
+[ext_resource path="res://addons/node25d-cs/icons/node25d_icon.png" type="Texture" id=2]
+[ext_resource path="res://addons/node25d-cs/ShadowMath25D.cs" type="Script" id=3]
+[ext_resource path="res://addons/node25d-cs/icons/shadowmath25d_icon.png" type="Texture" id=4]
+[ext_resource path="res://Assets/Shadow/Textures/fortyfive.png" type="Texture" id=5]
+[ext_resource path="res://Assets/Shadow/ShadowSprite.gd" type="Script" id=6]
+
+[sub_resource type="BoxShape" id=1]
+extents = Vector3( 0.5, 0.001, 0.5 )
+
+[node name="Shadow25D" type="Node2D"]
+script = ExtResource( 1 )
+__meta__ = {
+"_editor_icon": ExtResource( 2 )
+}
+
+[node name="ShadowMath25D" type="KinematicBody" parent="."]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 10, 0 )
+collision_layer = 16
+collision_mask = 16
+script = ExtResource( 3 )
+__meta__ = {
+"_editor_icon": ExtResource( 4 )
+}
+
+[node name="CollisionShape" type="CollisionShape" parent="ShadowMath25D"]
+shape = SubResource( 1 )
+
+[node name="ShadowSprite" type="Sprite" parent="."]
+scale = Vector2( 0.5, 0.5 )
+texture = ExtResource( 5 )
+script = ExtResource( 6 )
diff --git a/mono/2.5d/Assets/Shadow/ShadowSprite.gd b/mono/2.5d/Assets/Shadow/ShadowSprite.gd
new file mode 100644
index 00000000000..7a175ba1d72
--- /dev/null
+++ b/mono/2.5d/Assets/Shadow/ShadowSprite.gd
@@ -0,0 +1,22 @@
+extends Sprite
+
+onready var _topDown = preload("res://Assets/Shadow/Textures/topdown.png")
+onready var _frontSide = preload("res://Assets/Shadow/Textures/frontside.png")
+onready var _fortyFive = preload("res://Assets/Shadow/Textures/fortyfive.png")
+onready var _isometric = preload("res://Assets/Shadow/Textures/isometric.png")
+onready var _obliqueY = preload("res://Assets/Shadow/Textures/obliqueY.png")
+onready var _obliqueZ = preload("res://Assets/Shadow/Textures/obliqueZ.png")
+
+func _process(_delta):
+ if (Input.is_action_pressed("TopDownMode")):
+ texture = _topDown;
+ elif (Input.is_action_pressed("FrontSideMode")):
+ texture = _frontSide;
+ elif (Input.is_action_pressed("FortyFiveMode")):
+ texture = _fortyFive;
+ elif (Input.is_action_pressed("IsometricMode")):
+ texture = _isometric;
+ elif (Input.is_action_pressed("ObliqueYMode")):
+ texture = _obliqueY;
+ elif (Input.is_action_pressed("ObliqueZMode")):
+ texture = _obliqueZ;
diff --git a/mono/2.5d/Assets/Shadow/Textures/fortyfive.png b/mono/2.5d/Assets/Shadow/Textures/fortyfive.png
new file mode 100644
index 00000000000..ab28eea280b
Binary files /dev/null and b/mono/2.5d/Assets/Shadow/Textures/fortyfive.png differ
diff --git a/mono/2.5d/Assets/Shadow/Textures/fortyfive.png.import b/mono/2.5d/Assets/Shadow/Textures/fortyfive.png.import
new file mode 100644
index 00000000000..1c5c78a7f44
--- /dev/null
+++ b/mono/2.5d/Assets/Shadow/Textures/fortyfive.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/fortyfive.png-8ab6e92c107e4ba41c93ba207e691ca7.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Assets/Shadow/Textures/fortyfive.png"
+dest_files=[ "res://.import/fortyfive.png-8ab6e92c107e4ba41c93ba207e691ca7.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/Assets/Shadow/Textures/frontside.png b/mono/2.5d/Assets/Shadow/Textures/frontside.png
new file mode 100644
index 00000000000..8af59aa74a7
Binary files /dev/null and b/mono/2.5d/Assets/Shadow/Textures/frontside.png differ
diff --git a/mono/2.5d/Assets/Shadow/Textures/frontside.png.import b/mono/2.5d/Assets/Shadow/Textures/frontside.png.import
new file mode 100644
index 00000000000..018ac91ef4e
--- /dev/null
+++ b/mono/2.5d/Assets/Shadow/Textures/frontside.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/frontside.png-eddbee3a1d7308b87dbef635600f7ef1.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Assets/Shadow/Textures/frontside.png"
+dest_files=[ "res://.import/frontside.png-eddbee3a1d7308b87dbef635600f7ef1.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/Assets/Shadow/Textures/isometric.png b/mono/2.5d/Assets/Shadow/Textures/isometric.png
new file mode 100644
index 00000000000..3b50ae08fbb
Binary files /dev/null and b/mono/2.5d/Assets/Shadow/Textures/isometric.png differ
diff --git a/mono/2.5d/Assets/Shadow/Textures/isometric.png.import b/mono/2.5d/Assets/Shadow/Textures/isometric.png.import
new file mode 100644
index 00000000000..e3a933181e8
--- /dev/null
+++ b/mono/2.5d/Assets/Shadow/Textures/isometric.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/isometric.png-d5269a346abc8c2b6d89777dbfdf9db3.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Assets/Shadow/Textures/isometric.png"
+dest_files=[ "res://.import/isometric.png-d5269a346abc8c2b6d89777dbfdf9db3.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/Assets/Shadow/Textures/obliqueY.png b/mono/2.5d/Assets/Shadow/Textures/obliqueY.png
new file mode 100644
index 00000000000..f48cf507ec9
Binary files /dev/null and b/mono/2.5d/Assets/Shadow/Textures/obliqueY.png differ
diff --git a/mono/2.5d/Assets/Shadow/Textures/obliqueY.png.import b/mono/2.5d/Assets/Shadow/Textures/obliqueY.png.import
new file mode 100644
index 00000000000..6395e40024a
--- /dev/null
+++ b/mono/2.5d/Assets/Shadow/Textures/obliqueY.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/obliqueY.png-4b203d409e2d359d27a599c6ef09db99.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Assets/Shadow/Textures/obliqueY.png"
+dest_files=[ "res://.import/obliqueY.png-4b203d409e2d359d27a599c6ef09db99.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/Assets/Shadow/Textures/obliqueZ.png b/mono/2.5d/Assets/Shadow/Textures/obliqueZ.png
new file mode 100644
index 00000000000..446e9e027c8
Binary files /dev/null and b/mono/2.5d/Assets/Shadow/Textures/obliqueZ.png differ
diff --git a/mono/2.5d/Assets/Shadow/Textures/obliqueZ.png.import b/mono/2.5d/Assets/Shadow/Textures/obliqueZ.png.import
new file mode 100644
index 00000000000..ddc37c6e576
--- /dev/null
+++ b/mono/2.5d/Assets/Shadow/Textures/obliqueZ.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/obliqueZ.png-9490852845def420f14665e4c2c7d364.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Assets/Shadow/Textures/obliqueZ.png"
+dest_files=[ "res://.import/obliqueZ.png-9490852845def420f14665e4c2c7d364.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/Assets/Shadow/Textures/topdown.png b/mono/2.5d/Assets/Shadow/Textures/topdown.png
new file mode 100644
index 00000000000..5cf9a46f485
Binary files /dev/null and b/mono/2.5d/Assets/Shadow/Textures/topdown.png differ
diff --git a/mono/2.5d/Assets/Shadow/Textures/topdown.png.import b/mono/2.5d/Assets/Shadow/Textures/topdown.png.import
new file mode 100644
index 00000000000..58e7d6095ae
--- /dev/null
+++ b/mono/2.5d/Assets/Shadow/Textures/topdown.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/topdown.png-98bdc8f2a4125d73625c4be06ca6ccf5.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Assets/Shadow/Textures/topdown.png"
+dest_files=[ "res://.import/topdown.png-98bdc8f2a4125d73625c4be06ca6ccf5.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/Assets/UI/ControlHints.gd b/mono/2.5d/Assets/UI/ControlHints.gd
new file mode 100644
index 00000000000..ddc11b994be
--- /dev/null
+++ b/mono/2.5d/Assets/UI/ControlHints.gd
@@ -0,0 +1,5 @@
+extends Control
+
+func _process(_delta):
+ if Input.is_action_just_pressed("ToggleControlHints"):
+ visible = !visible
diff --git a/mono/2.5d/Assets/UI/Overlay.tscn b/mono/2.5d/Assets/UI/Overlay.tscn
new file mode 100644
index 00000000000..ac9e384af86
--- /dev/null
+++ b/mono/2.5d/Assets/UI/Overlay.tscn
@@ -0,0 +1,28 @@
+[gd_scene load_steps=2 format=2]
+
+[ext_resource path="res://Assets/UI/ControlHints.gd" type="Script" id=1]
+
+[node name="Overlay" type="CanvasLayer"]
+
+[node name="ControlHints" type="CenterContainer" parent="."]
+anchor_right = 1.0
+margin_bottom = 200.0
+script = ExtResource( 1 )
+
+[node name="Label" type="Label" parent="ControlHints"]
+margin_left = 348.0
+margin_top = 25.0
+margin_right = 1251.0
+margin_bottom = 175.0
+rect_min_size = Vector2( 500, 50 )
+text = "
+Controls: WASD to move, Space to jump, R to reset, Shift to walk, T to toggle isometric controls, C to view cube demo, Tab to toggle hints.
+
+UIOPKL to change view mode. U = Forty Five deg, I = Isometric,
+O = Top Down, J = Front Side, K = Oblique Y, L = Oblique Z
+
+Not every view mode is meant to be good, it's just to showcase what the system can do.
+In actual games, shadows, resizing, parallax, and other hints of depth could be added to make the world seem more 3D.
+"
+align = 1
+valign = 1
diff --git a/mono/2.5d/Assets/UI/OverlayCube.tscn b/mono/2.5d/Assets/UI/OverlayCube.tscn
new file mode 100644
index 00000000000..e93c82be8d1
--- /dev/null
+++ b/mono/2.5d/Assets/UI/OverlayCube.tscn
@@ -0,0 +1,28 @@
+[gd_scene load_steps=2 format=2]
+
+[ext_resource path="res://Assets/UI/ControlHints.gd" type="Script" id=1]
+
+[node name="Overlay" type="CanvasLayer"]
+
+[node name="ControlHints" type="CenterContainer" parent="."]
+anchor_right = 1.0
+margin_bottom = 200.0
+script = ExtResource( 1 )
+
+[node name="Label" type="Label" parent="ControlHints"]
+margin_left = 416.0
+margin_top = 25.0
+margin_right = 1183.0
+margin_bottom = 175.0
+rect_min_size = Vector2( 500, 50 )
+text = "
+Controls: WASDQE to rotate, R to reset, C to return to the world, Tab to toggle hints.
+
+UIOPKL to change view mode. U = Forty Five deg, I = Isometric,
+O = Top Down, K = Oblique Y, L = Oblique Z
+
+Not every view mode is meant to be good, it's just to showcase what the system can do.
+In actual games, shadows, resizing, parallax, and other hints of depth could be added to make the world seem more 3D.
+"
+align = 1
+valign = 1
diff --git a/mono/2.5d/Properties/AssemblyInfo.cs b/mono/2.5d/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000000..fa80bd8babc
--- /dev/null
+++ b/mono/2.5d/Properties/AssemblyInfo.cs
@@ -0,0 +1,25 @@
+using System.Reflection;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle("2.5D Demo (Mono C#)")]
+[assembly: AssemblyDescription("2.5D demo project for Godot, Mono C# version.")]
+[assembly: AssemblyConfiguration("Debug")]
+[assembly: AssemblyCompany("Godot")]
+[assembly: AssemblyProduct("Godot Demo Projects")]
+[assembly: AssemblyCopyright("Copyright © 2019 Godot Contributors")]
+[assembly: AssemblyTrademark("Godot Engine")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
diff --git a/mono/2.5d/README.md b/mono/2.5d/README.md
new file mode 100644
index 00000000000..b7767f714b3
--- /dev/null
+++ b/mono/2.5d/README.md
@@ -0,0 +1,19 @@
+# 2.5D Demo Project (Mono C#)
+
+This demo project is an example of how a 2.5D game could be created in Godot.
+
+Controls: WASD to move, Space to jump, R to reset, and UIOPKL to change view modes.
+
+Note: There is a GDScript version available [here](https://github.com/godotengine/godot-demo-projects/tree/master/misc/2.5d).
+
+## How does it work?
+
+Custom node types are added in a Godot plugin to allow 2.5D objects. Node25D serves as the base for all 2.5D objects; its first child must be a Spatial, which is used to calculate its position. It also adds YSort25D to sort Node25D nodes, and ShadowMath25D for calculating a shadow.
+
+It uses structs called Basis25D and Transform25D to calculate 2D positions from 3D ones. For getting a 3D position, this project uses KinematicBody and StaticBody (3D), but these only exist for math - the camera is 2D and all sprites are 2D. You are able to use any Spatial node for math.
+
+To display the objects, add a Sprite or any other Node2D-derived children to your Node25D objects. Some nodes are unsuitable, such as 2D physics nodes. Keep in mind that the first child must be Spatial-derived for math purposes.
+
+Several view modes are implemented, including top down, front side, 45 degree, isometric, and two oblique modes. To implement a different view angle, all you need to do is create a new Basis25D, use it in all your Node25D transforms, and of course create textures to display that object in 2D.
+
+## Screenshots
diff --git a/mono/2.5d/addons/node25d-cs/Basis25D.cs b/mono/2.5d/addons/node25d-cs/Basis25D.cs
new file mode 100644
index 00000000000..0aeb774f6ef
--- /dev/null
+++ b/mono/2.5d/addons/node25d-cs/Basis25D.cs
@@ -0,0 +1,202 @@
+using Godot;
+using System;
+using System.Runtime.InteropServices;
+
+#if GODOT_REAL_T_IS_DOUBLE
+using real_t = System.Double;
+#else
+using real_t = System.Single;
+#endif
+
+///
+/// Basis25D structure for performing 2.5D transform math.
+/// Note: All code assumes that Y is UP in 3D, and DOWN in 2D.
+/// A top-down view has a Y axis component of (0, 0), with a Z axis component of (0, 1).
+/// For a front side view, Y is (0, -1) and Z is (0, 0).
+/// Remember that Godot's 2D mode has the Y axis pointing DOWN on the screen.
+///
+[Serializable]
+[StructLayout(LayoutKind.Sequential)]
+public struct Basis25D : IEquatable
+{
+ // Also matrix columns, the directions to move on screen for each unit change in 3D.
+ public Vector2 x;
+ public Vector2 y;
+ public Vector2 z;
+
+ // Also matrix rows, the parts of each vector that contribute to moving in a screen direction.
+ // Setting a row to zero means no movement in that direction.
+ public Vector3 Row0
+ {
+ get { return new Vector3(x.x, y.x, z.x); }
+ set
+ {
+ x.x = value.x;
+ y.x = value.y;
+ z.x = value.z;
+ }
+ }
+
+ public Vector3 Row1
+ {
+ get { return new Vector3(x.y, y.y, z.y); }
+ set
+ {
+ x.y = value.x;
+ y.y = value.y;
+ z.y = value.z;
+ }
+ }
+
+ public Vector2 this[int columnIndex]
+ {
+ get
+ {
+ switch (columnIndex)
+ {
+ case 0: return x;
+ case 1: return y;
+ case 2: return z;
+ default: throw new IndexOutOfRangeException();
+ }
+ }
+ set
+ {
+ switch (columnIndex)
+ {
+ case 0: x = value; return;
+ case 1: y = value; return;
+ case 2: z = value; return;
+ default: throw new IndexOutOfRangeException();
+ }
+ }
+ }
+
+ public real_t this[int columnIndex, int rowIndex]
+ {
+ get
+ {
+ return this[columnIndex][rowIndex];
+ }
+ set
+ {
+ Vector2 v = this[columnIndex];
+ v[rowIndex] = value;
+ this[columnIndex] = v;
+ }
+ }
+
+ private static readonly Basis25D _topDown = new Basis25D(1, 0, 0, 0, 0, 1);
+ private static readonly Basis25D _frontSide = new Basis25D(1, 0, 0, -1, 0, 0);
+ private static readonly Basis25D _fortyFive = new Basis25D(1, 0, 0, -0.70710678118f, 0, 0.70710678118f);
+ private static readonly Basis25D _isometric = new Basis25D(0.86602540378f, 0.5f, 0, -1, -0.86602540378f, 0.5f);
+ private static readonly Basis25D _obliqueY = new Basis25D(1, 0, -1, -1, 0, 1);
+ private static readonly Basis25D _obliqueZ = new Basis25D(1, 0, 0, -1, -1, 1);
+
+ public static Basis25D TopDown { get { return _topDown; } }
+ public static Basis25D FrontSide { get { return _frontSide; } }
+ public static Basis25D FortyFive { get { return _fortyFive; } }
+ public static Basis25D Isometric { get { return _isometric; } }
+ public static Basis25D ObliqueY { get { return _obliqueY; } }
+ public static Basis25D ObliqueZ { get { return _obliqueZ; } }
+
+ ///
+ /// Creates a Dimetric Basis25D from the angle between the Y axis and the others.
+ /// Dimetric(Tau/3) or Dimetric(2.09439510239) is the same as Isometric.
+ /// Try to keep this number away from a multiple of Tau/4 (or Pi/2) radians.
+ ///
+ /// The angle, in radians, between the Y axis and the X/Z axes.
+ public static Basis25D Dimetric(real_t angle)
+ {
+ real_t sin = Mathf.Sin(angle);
+ real_t cos = Mathf.Cos(angle);
+ return new Basis25D(sin, -cos, 0, -1, -sin, -cos);
+ }
+
+ // Constructors
+ public Basis25D(Basis25D b)
+ {
+ x = b.x;
+ y = b.y;
+ z = b.z;
+ }
+ public Basis25D(Vector2 xAxis, Vector2 yAxis, Vector2 zAxis)
+ {
+ x = xAxis;
+ y = yAxis;
+ z = zAxis;
+ }
+ public Basis25D(real_t xx, real_t xy, real_t yx, real_t yy, real_t zx, real_t zy)
+ {
+ x = new Vector2(xx, xy);
+ y = new Vector2(yx, yy);
+ z = new Vector2(zx, zy);
+ }
+
+ public static Basis25D operator *(Basis25D b, real_t s)
+ {
+ b.x *= s;
+ b.y *= s;
+ b.z *= s;
+ return b;
+ }
+
+ public static Basis25D operator /(Basis25D b, real_t s)
+ {
+ b.x /= s;
+ b.y /= s;
+ b.z /= s;
+ return b;
+ }
+
+ public static bool operator ==(Basis25D left, Basis25D right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(Basis25D left, Basis25D right)
+ {
+ return !left.Equals(right);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is Basis25D)
+ {
+ return Equals((Basis25D)obj);
+ }
+ return false;
+ }
+
+ public bool Equals(Basis25D other)
+ {
+ return x.Equals(other.x) && y.Equals(other.y) && z.Equals(other.z);
+ }
+
+ public override int GetHashCode()
+ {
+ return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ string s = String.Format("({0}, {1}, {2})", new object[]
+ {
+ x.ToString(),
+ y.ToString(),
+ z.ToString()
+ });
+ return s;
+ }
+
+ public string ToString(string format)
+ {
+ string s = String.Format("({0}, {1}, {2})", new object[]
+ {
+ x.ToString(format),
+ y.ToString(format),
+ z.ToString(format)
+ });
+ return s;
+ }
+}
diff --git a/mono/2.5d/addons/node25d-cs/Node25D.cs b/mono/2.5d/addons/node25d-cs/Node25D.cs
new file mode 100644
index 00000000000..3eea9a68a6c
--- /dev/null
+++ b/mono/2.5d/addons/node25d-cs/Node25D.cs
@@ -0,0 +1,118 @@
+using Godot;
+using System;
+#if REAL_T_IS_DOUBLE
+using real_t = System.Double;
+#else
+using real_t = System.Single;
+#endif
+
+///
+/// This node converts a 3D position to 2D using a 2.5D transformation matrix.
+/// The transformation of its 2D form is controlled by its 3D child.
+///
+[Tool]
+public class Node25D : Node2D, IComparable
+{
+ ///
+ /// The number of 2D units in one 3D unit.
+ ///
+ public const int SCALE = 32;
+
+ private Spatial spatialNode;
+ private Transform25D transform25D;
+
+ public Basis25D Basis25D
+ {
+ get { return transform25D.basis; }
+ }
+
+ public Transform25D Transform25D
+ {
+ get { return transform25D; }
+ }
+
+ public override void _Ready()
+ {
+ Node25DReady();
+ }
+
+ public override void _Process(real_t delta)
+ {
+ Node25DProcess();
+ }
+
+ ///
+ /// Call this method in _Ready, or before you run Node25DProcess.
+ ///
+ protected void Node25DReady()
+ {
+ spatialNode = GetChild(0);
+ transform25D = new Transform25D(Basis25D.FortyFive * SCALE);
+ // Changing the basis here will change the default for all Node25D instances.
+ }
+
+ ///
+ /// Call this method in _Process, or whenever the position of this object changes.
+ ///
+ protected void Node25DProcess()
+ {
+ CheckViewMode();
+ if (spatialNode != null)
+ {
+ transform25D.spatialPosition = spatialNode.Translation;
+ }
+ GlobalPosition = transform25D.FlatPosition;
+ }
+
+ private void CheckViewMode()
+ {
+ if (Input.IsActionJustPressed("TopDownMode"))
+ {
+ transform25D.basis = Basis25D.TopDown * SCALE;
+ }
+ else if (Input.IsActionJustPressed("FrontSideMode"))
+ {
+ transform25D.basis = Basis25D.FrontSide * SCALE;
+ }
+ else if (Input.IsActionJustPressed("FortyFiveMode"))
+ {
+ transform25D.basis = Basis25D.FortyFive * SCALE;
+ }
+ else if (Input.IsActionJustPressed("IsometricMode"))
+ {
+ transform25D.basis = Basis25D.Isometric * SCALE;
+ }
+ else if (Input.IsActionJustPressed("ObliqueYMode"))
+ {
+ transform25D.basis = Basis25D.ObliqueY * SCALE;
+ }
+ else if (Input.IsActionJustPressed("ObliqueZMode"))
+ {
+ transform25D.basis = Basis25D.ObliqueZ * SCALE;
+ }
+ }
+
+ public int CompareTo(object obj)
+ {
+ if (obj is Node25D)
+ {
+ return CompareTo((Node25D)obj);
+ }
+ return 1;
+ }
+
+ public int CompareTo(Node25D other)
+ {
+ real_t yDiff = spatialNode.Translation.y - other.spatialNode.Translation.y;
+ if (yDiff > 0)
+ {
+ return 1;
+ }
+ else if (yDiff < 0)
+ {
+ return -1;
+ }
+ return 0;
+ }
+
+}
diff --git a/mono/2.5d/addons/node25d-cs/ShadowMath25D.cs b/mono/2.5d/addons/node25d-cs/ShadowMath25D.cs
new file mode 100644
index 00000000000..ab719e4f9e2
--- /dev/null
+++ b/mono/2.5d/addons/node25d-cs/ShadowMath25D.cs
@@ -0,0 +1,55 @@
+using Godot;
+using System;
+#if REAL_T_IS_DOUBLE
+using real_t = System.Double;
+#else
+using real_t = System.Single;
+#endif
+
+///
+/// Adds a simple shadow below an object.
+/// Place this ShadowMath25D node as a child of a Shadow25D, which
+/// is below the target object in the scene tree (not as a child).
+///
+[Tool]
+public class ShadowMath25D : KinematicBody
+{
+ ///
+ /// The maximum distance below objects that shadows will appear.
+ ///
+ public real_t shadowLength = 1000;
+ private Node25D shadowRoot;
+ private Spatial targetMath;
+
+ public override void _Ready()
+ {
+ shadowRoot = GetParent();
+ int index = shadowRoot.GetPositionInParent();
+ targetMath = shadowRoot.GetParent().GetChild(index - 1).GetChild(0);
+ }
+
+ public override void _Process(real_t delta)
+ {
+ if (targetMath == null)
+ {
+ if (shadowRoot != null)
+ {
+ shadowRoot.Visible = false;
+ }
+ return; // Shadow is not in a valid place.
+ }
+
+ Translation = targetMath.Translation;
+ var k = MoveAndCollide(Vector3.Down * shadowLength);
+ if (k == null)
+ {
+ shadowRoot.Visible = false;
+ }
+ else
+ {
+ shadowRoot.Visible = true;
+ GlobalTransform = Transform;
+ }
+ }
+
+}
diff --git a/mono/2.5d/addons/node25d-cs/Transform25D.cs b/mono/2.5d/addons/node25d-cs/Transform25D.cs
new file mode 100644
index 00000000000..eb5b977a2ac
--- /dev/null
+++ b/mono/2.5d/addons/node25d-cs/Transform25D.cs
@@ -0,0 +1,126 @@
+using Godot;
+using System;
+using System.Runtime.InteropServices;
+
+///
+/// Calculates the 2D transformation from a 3D position and a Basis25D.
+///
+[Serializable]
+[StructLayout(LayoutKind.Sequential)]
+public struct Transform25D : IEquatable
+{
+ // Public fields store information that is used to calculate the properties.
+
+ ///
+ /// Controls how the 3D position is transformed into 2D.
+ ///
+ public Basis25D basis;
+
+ ///
+ /// The 3D position of the object. Should be updated on every frame before everything else.
+ ///
+ public Vector3 spatialPosition;
+
+ // Public properties calculate on-the-fly.
+
+ ///
+ /// The 2D transformation of this object. Slower than FlatPosition.
+ ///
+ public Transform2D FlatTransform
+ {
+ get
+ {
+ return new Transform2D(0, FlatPosition);
+ }
+ }
+
+ ///
+ /// The 2D position of this object.
+ ///
+ public Vector2 FlatPosition
+ {
+ get
+ {
+ Vector2 pos = spatialPosition.x * basis.x;
+ pos += spatialPosition.y * basis.y;
+ pos += spatialPosition.z * basis.z;
+ return pos;
+ }
+ }
+
+ // Constructors
+ public Transform25D(Transform25D transform25D)
+ {
+ basis = transform25D.basis;
+ spatialPosition = transform25D.spatialPosition;
+ }
+ public Transform25D(Basis25D basis25D)
+ {
+ basis = basis25D;
+ spatialPosition = Vector3.Zero;
+ }
+ public Transform25D(Basis25D basis25D, Vector3 position3D)
+ {
+ basis = basis25D;
+ spatialPosition = position3D;
+ }
+ public Transform25D(Vector2 xAxis, Vector2 yAxis, Vector2 zAxis)
+ {
+ basis = new Basis25D(xAxis, yAxis, zAxis);
+ spatialPosition = Vector3.Zero;
+ }
+ public Transform25D(Vector2 xAxis, Vector2 yAxis, Vector2 zAxis, Vector3 position3D)
+ {
+ basis = new Basis25D(xAxis, yAxis, zAxis);
+ spatialPosition = position3D;
+ }
+
+ public static bool operator ==(Transform25D left, Transform25D right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(Transform25D left, Transform25D right)
+ {
+ return !left.Equals(right);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is Transform25D)
+ {
+ return Equals((Transform25D)obj);
+ }
+ return false;
+ }
+
+ public bool Equals(Transform25D other)
+ {
+ return basis.Equals(other.basis) && spatialPosition.Equals(other.spatialPosition);
+ }
+
+ public override int GetHashCode()
+ {
+ return basis.GetHashCode() ^ spatialPosition.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ string s = String.Format("({0}, {1})", new object[]
+ {
+ basis.ToString(),
+ spatialPosition.ToString()
+ });
+ return s;
+ }
+
+ public string ToString(string format)
+ {
+ string s = String.Format("({0}, {1})", new object[]
+ {
+ basis.ToString(format),
+ spatialPosition.ToString(format)
+ });
+ return s;
+ }
+}
diff --git a/mono/2.5d/addons/node25d-cs/YSort25D.cs b/mono/2.5d/addons/node25d-cs/YSort25D.cs
new file mode 100644
index 00000000000..7f6501402b4
--- /dev/null
+++ b/mono/2.5d/addons/node25d-cs/YSort25D.cs
@@ -0,0 +1,66 @@
+using Godot;
+using System;
+using System.Collections.Generic;
+#if REAL_T_IS_DOUBLE
+using real_t = System.Double;
+#else
+using real_t = System.Single;
+#endif
+
+///
+/// Assigns Z-index values to Node25D children.
+/// This is different from the GDScript version of this project
+/// because the execution order is different and otherwise
+/// sorting is delayed by one frame.
+///
+//[Tool] // Commented out because it sometimes crashes the editor when running the game...
+public class YSort25D : Node2D
+{
+ ///
+ /// Whether or not to automatically call Sort() in _Process().
+ ///
+ [Export]
+ public bool sort_enabled = true;
+
+ public override void _Process(real_t delta)
+ {
+ if (sort_enabled)
+ {
+ Sort();
+ }
+ }
+
+ ///
+ /// Call this method in _Process, or whenever you want to sort children.
+ ///
+ public void Sort()
+ {
+ var children = GetChildren();
+ if (children.Count > 4000)
+ {
+ throw new InvalidOperationException("Max number of YSort25D children is 4000. ");
+ }
+ List node25dChildren = new List();
+
+ foreach (Node n in children)
+ {
+ Node25D m = n as Node25D;
+ if (m != null)
+ {
+ node25dChildren.Add(m);
+ }
+ }
+
+ node25dChildren.Sort();
+
+ int zIndex = -4000;
+ for (int i = 0; i < node25dChildren.Count; i++)
+ {
+ node25dChildren[i].ZIndex = zIndex;
+ zIndex += 2;
+ // Increment by 2 each time, to allow for shadows in-between.
+ // This does mean that we have a limit of 4000 total sorted Node25Ds.
+ }
+ }
+
+}
diff --git a/mono/2.5d/addons/node25d-cs/icons/kinematic_body_25d.png b/mono/2.5d/addons/node25d-cs/icons/kinematic_body_25d.png
new file mode 100644
index 00000000000..f79d49424ca
Binary files /dev/null and b/mono/2.5d/addons/node25d-cs/icons/kinematic_body_25d.png differ
diff --git a/mono/2.5d/addons/node25d-cs/icons/kinematic_body_25d.png.import b/mono/2.5d/addons/node25d-cs/icons/kinematic_body_25d.png.import
new file mode 100644
index 00000000000..56b6b828e0f
--- /dev/null
+++ b/mono/2.5d/addons/node25d-cs/icons/kinematic_body_25d.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/kinematic_body_25d.png-791432e863e44720a1390f5b1fbf09be.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/node25d-cs/icons/kinematic_body_25d.png"
+dest_files=[ "res://.import/kinematic_body_25d.png-791432e863e44720a1390f5b1fbf09be.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/addons/node25d-cs/icons/node25d.png b/mono/2.5d/addons/node25d-cs/icons/node25d.png
new file mode 100644
index 00000000000..633b4c58094
Binary files /dev/null and b/mono/2.5d/addons/node25d-cs/icons/node25d.png differ
diff --git a/mono/2.5d/addons/node25d-cs/icons/node25d.png.import b/mono/2.5d/addons/node25d-cs/icons/node25d.png.import
new file mode 100644
index 00000000000..10f14a9a246
--- /dev/null
+++ b/mono/2.5d/addons/node25d-cs/icons/node25d.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/node25d.png-6fc4dae5b050ca73e9b1b0ec8fc45bb6.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/node25d-cs/icons/node25d.png"
+dest_files=[ "res://.import/node25d.png-6fc4dae5b050ca73e9b1b0ec8fc45bb6.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/addons/node25d-cs/icons/node25d_icon.png b/mono/2.5d/addons/node25d-cs/icons/node25d_icon.png
new file mode 100644
index 00000000000..a4ea1d1e781
Binary files /dev/null and b/mono/2.5d/addons/node25d-cs/icons/node25d_icon.png differ
diff --git a/mono/2.5d/addons/node25d-cs/icons/node25d_icon.png.import b/mono/2.5d/addons/node25d-cs/icons/node25d_icon.png.import
new file mode 100644
index 00000000000..3b5db27f722
--- /dev/null
+++ b/mono/2.5d/addons/node25d-cs/icons/node25d_icon.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/node25d_icon.png-3df13d996db8a3b76f9b9569a0cd86f8.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/node25d-cs/icons/node25d_icon.png"
+dest_files=[ "res://.import/node25d_icon.png-3df13d996db8a3b76f9b9569a0cd86f8.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/addons/node25d-cs/icons/shadowmath25d.png b/mono/2.5d/addons/node25d-cs/icons/shadowmath25d.png
new file mode 100644
index 00000000000..122cfdc7729
Binary files /dev/null and b/mono/2.5d/addons/node25d-cs/icons/shadowmath25d.png differ
diff --git a/mono/2.5d/addons/node25d-cs/icons/shadowmath25d.png.import b/mono/2.5d/addons/node25d-cs/icons/shadowmath25d.png.import
new file mode 100644
index 00000000000..be6e91f0b4e
--- /dev/null
+++ b/mono/2.5d/addons/node25d-cs/icons/shadowmath25d.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/shadowmath25d.png-7732a94e3519eeac452e5bb7c012b68f.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/node25d-cs/icons/shadowmath25d.png"
+dest_files=[ "res://.import/shadowmath25d.png-7732a94e3519eeac452e5bb7c012b68f.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/addons/node25d-cs/icons/shadowmath25d_icon.png b/mono/2.5d/addons/node25d-cs/icons/shadowmath25d_icon.png
new file mode 100644
index 00000000000..27892a61993
Binary files /dev/null and b/mono/2.5d/addons/node25d-cs/icons/shadowmath25d_icon.png differ
diff --git a/mono/2.5d/addons/node25d-cs/icons/shadowmath25d_icon.png.import b/mono/2.5d/addons/node25d-cs/icons/shadowmath25d_icon.png.import
new file mode 100644
index 00000000000..4045ae76bf8
--- /dev/null
+++ b/mono/2.5d/addons/node25d-cs/icons/shadowmath25d_icon.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/shadowmath25d_icon.png-bbfcbb62f2253c270c6bc1b56235332b.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/node25d-cs/icons/shadowmath25d_icon.png"
+dest_files=[ "res://.import/shadowmath25d_icon.png-bbfcbb62f2253c270c6bc1b56235332b.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/addons/node25d-cs/icons/ysort25d.png b/mono/2.5d/addons/node25d-cs/icons/ysort25d.png
new file mode 100644
index 00000000000..7b54e25386b
Binary files /dev/null and b/mono/2.5d/addons/node25d-cs/icons/ysort25d.png differ
diff --git a/mono/2.5d/addons/node25d-cs/icons/ysort25d.png.import b/mono/2.5d/addons/node25d-cs/icons/ysort25d.png.import
new file mode 100644
index 00000000000..4869ecb70b4
--- /dev/null
+++ b/mono/2.5d/addons/node25d-cs/icons/ysort25d.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/ysort25d.png-561827af7f6c1f38c889b0d5109abd0f.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/node25d-cs/icons/ysort25d.png"
+dest_files=[ "res://.import/ysort25d.png-561827af7f6c1f38c889b0d5109abd0f.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/addons/node25d-cs/icons/ysort25d_icon.png b/mono/2.5d/addons/node25d-cs/icons/ysort25d_icon.png
new file mode 100644
index 00000000000..9cfad10f969
Binary files /dev/null and b/mono/2.5d/addons/node25d-cs/icons/ysort25d_icon.png differ
diff --git a/mono/2.5d/addons/node25d-cs/icons/ysort25d_icon.png.import b/mono/2.5d/addons/node25d-cs/icons/ysort25d_icon.png.import
new file mode 100644
index 00000000000..ebb63d6c10a
--- /dev/null
+++ b/mono/2.5d/addons/node25d-cs/icons/ysort25d_icon.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/ysort25d_icon.png-7582239e358c6cacf13d48494a24527f.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/node25d-cs/icons/ysort25d_icon.png"
+dest_files=[ "res://.import/ysort25d_icon.png-7582239e358c6cacf13d48494a24527f.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/addons/node25d-cs/node25d_plugin.gd b/mono/2.5d/addons/node25d-cs/node25d_plugin.gd
new file mode 100644
index 00000000000..a659c9e0d1c
--- /dev/null
+++ b/mono/2.5d/addons/node25d-cs/node25d_plugin.gd
@@ -0,0 +1,14 @@
+tool
+extends EditorPlugin
+
+func _enter_tree():
+ # When this plugin node enters tree, add the custom types
+ add_custom_type("Node25D", "Node2D", preload("Node25D.cs"), preload("icons/node25d_icon.png"))
+ add_custom_type("YSort25D", "Node2D", preload("YSort25D.cs"), preload("icons/ysort25d_icon.png"))
+ add_custom_type("ShadowMath25D", "KinematicBody", preload("ShadowMath25D.cs"), preload("icons/shadowmath25d_icon.png"))
+
+func _exit_tree():
+ # When the plugin node exits the tree, remove the custom types
+ remove_custom_type("ShadowMath25D")
+ remove_custom_type("YSort25D")
+ remove_custom_type("Node25D")
diff --git a/mono/2.5d/addons/node25d-cs/plugin.cfg b/mono/2.5d/addons/node25d-cs/plugin.cfg
new file mode 100644
index 00000000000..74b293d3819
--- /dev/null
+++ b/mono/2.5d/addons/node25d-cs/plugin.cfg
@@ -0,0 +1,7 @@
+[plugin]
+
+name="Node25D (C#)"
+description="Adds Node25D"
+author="Aaron Franke"
+version="1.0"
+script="node25d_plugin.gd"
diff --git a/mono/2.5d/default_env.tres b/mono/2.5d/default_env.tres
new file mode 100644
index 00000000000..20207a4aa2c
--- /dev/null
+++ b/mono/2.5d/default_env.tres
@@ -0,0 +1,7 @@
+[gd_resource type="Environment" load_steps=2 format=2]
+
+[sub_resource type="ProceduralSky" id=1]
+
+[resource]
+background_mode = 2
+background_sky = SubResource( 1 )
diff --git a/mono/2.5d/icon.png b/mono/2.5d/icon.png
new file mode 100644
index 00000000000..d8efa1a0738
Binary files /dev/null and b/mono/2.5d/icon.png differ
diff --git a/mono/2.5d/icon.png.import b/mono/2.5d/icon.png.import
new file mode 100644
index 00000000000..96cbf4629a5
--- /dev/null
+++ b/mono/2.5d/icon.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://icon.png"
+dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=true
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=true
+svg/scale=1.0
diff --git a/mono/2.5d/project.godot b/mono/2.5d/project.godot
new file mode 100644
index 00000000000..9e1c40b3113
--- /dev/null
+++ b/mono/2.5d/project.godot
@@ -0,0 +1,156 @@
+; Engine configuration file.
+; It's best edited using the editor UI and not directly,
+; since the parameters that go here are not all obvious.
+;
+; Format:
+; [section] ; section goes between []
+; param=value ; assign values to parameters
+
+config_version=4
+
+_global_script_classes=[ ]
+_global_script_class_icons={
+
+}
+
+[application]
+
+config/name="2.5D Demo (Mono C#)"
+run/main_scene="res://Assets/DemoScene.tscn"
+config/icon="res://icon.png"
+
+[display]
+
+window/size/width=1600
+window/size/height=900
+
+[editor_plugins]
+
+enabled=PoolStringArray( "node25d-cs" )
+
+[input]
+
+MoveRight={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null)
+ ]
+}
+MoveLeft={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
+ ]
+}
+MoveForward={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
+ ]
+}
+MoveBackward={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
+ ]
+}
+MovementModifier={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777237,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777348,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":1,"pressure":0.0,"pressed":false,"script":null)
+ ]
+}
+Jump={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777350,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
+ ]
+}
+ResetPosition={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":82,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777222,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":3,"pressure":0.0,"pressed":false,"script":null)
+ ]
+}
+FortyFiveMode={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":85,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777354,"unicode":0,"echo":false,"script":null)
+ ]
+}
+IsometricMode={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":73,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777355,"unicode":0,"echo":false,"script":null)
+ ]
+}
+TopDownMode={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":79,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777356,"unicode":0,"echo":false,"script":null)
+ ]
+}
+FrontSideMode={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":74,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777351,"unicode":0,"echo":false,"script":null)
+ ]
+}
+ObliqueYMode={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":75,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777352,"unicode":0,"echo":false,"script":null)
+ ]
+}
+ObliqueZMode={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":76,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777353,"unicode":0,"echo":false,"script":null)
+ ]
+}
+ToggleIsometricControls={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":84,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":2,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777349,"unicode":0,"echo":false,"script":null)
+ ]
+}
+ToggleControlHints={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777218,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777347,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":10,"pressure":0.0,"pressed":false,"script":null)
+ ]
+}
+MoveClockwise={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":69,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777359,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":5,"pressure":0.0,"pressed":false,"script":null)
+ ]
+}
+MoveCounterclockwise={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":81,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777357,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":4,"pressure":0.0,"pressed":false,"script":null)
+ ]
+}
+ViewCubeDemo={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":67,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777358,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
+ ]
+}
+
+[rendering]
+
+environment/default_environment="res://default_env.tres"