diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index d21e59f..453ec94 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -9,7 +9,7 @@ ] }, "unofficial.Urho3DNet.Editor": { - "version": "0.3.7.733", + "version": "0.3.7.738", "commands": [ "rbfx" ] diff --git a/Content/Common/Data/Objects/Tile.prefab b/Content/Common/Data/Objects/Tile.prefab index e33f284..7bd6345 100644 --- a/Content/Common/Data/Objects/Tile.prefab +++ b/Content/Common/Data/Objects/Tile.prefab @@ -50,6 +50,111 @@ }, { "_typeName": "RigidBody" + }, + { + "_typeName": "Tile", + "attributes": [ + { + "name": "Link", + "type": "Int", + "value": 1 + }, + { + "name": "LinkSource", + "type": "Int", + "value": 2 + }, + { + "name": "LinkTarget", + "type": "Int", + "value": 3 + } + ] + } + ], + "nodes": [ + { + "_id": 1, + "attributes": [ + { + "name": "Is Enabled", + "type": "Bool", + "value": false + }, + { + "name": "Name", + "type": "String", + "value": "Link" + } + ], + "components": [ + { + "_typeName": "AnimatedModel", + "attributes": [ + { + "name": "Model", + "type": "ResourceRef", + "value": "Model;Models/Link.mdl" + }, + { + "name": "Material", + "type": "ResourceRefList", + "value": "Material;Materials/White.material" + }, + { + "name": "Bone Animation Enabled", + "type": "VariantVector", + "value": [ + { + "type": "Bool", + "value": true + }, + { + "type": "Bool", + "value": true + }, + { + "type": "Bool", + "value": true + } + ] + } + ] + } + ], + "nodes": [ + { + "attributes": [ + { + "name": "Name", + "type": "String", + "value": "Root" + } + ], + "nodes": [ + { + "_id": 2, + "attributes": [ + { + "name": "Name", + "type": "String", + "value": "A" + } + ] + }, + { + "_id": 3, + "attributes": [ + { + "name": "Name", + "type": "String", + "value": "B" + } + ] + } + ] + } + ] } ] }, diff --git a/Content/Common/Data/Scenes/Scene.scene b/Content/Common/Data/Scenes/Scene.scene index 1c4f362..970c866 100644 --- a/Content/Common/Data/Scenes/Scene.scene +++ b/Content/Common/Data/Scenes/Scene.scene @@ -1,8 +1,8 @@ - - + + diff --git a/Directory.Build.props b/Directory.Build.props index 537dd06..b17188e 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - 0.3.7.733 + 0.3.7.738 \ No newline at end of file diff --git a/RbfxTemplate/GameState.cs b/RbfxTemplate/GameState.cs index ea6f534..4ef381a 100644 --- a/RbfxTemplate/GameState.cs +++ b/RbfxTemplate/GameState.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.IO; +using RbfxTemplate.GameStates; using Urho3DNet; namespace RbfxTemplate @@ -14,13 +15,37 @@ public sealed class GameState : RmlUIStateBase private readonly Viewport _viewport; private Dictionary _tileMaterials = new Dictionary(); - private readonly Node _link; + + private PickSate _pickSate; + private DragSate _dragSate; + private StateBase _state; + + public StateBase State + { + get + { + return _state; + } + set + { + if (_state != value) + { + _state?.Deactivate(); + _state = value; + _state?.Activate(); + } + } + } + + private PhysicsRaycastResult _raycastResult; public GameState(UrhoPluginApplication app) : base(app, "UI/GameScreen.rml") { MouseMode = MouseMode.MmFree; IsMouseVisible = true; + _raycastResult = new PhysicsRaycastResult(); + _app = app; _scene = Context.CreateObject(); _scene.Ptr.LoadXML("Scenes/Scene.scene"); @@ -41,23 +66,25 @@ public GameState(UrhoPluginApplication app) : base(app, "UI/GameScreen.rml") Context.ResourceCache.GetResource("Materials/Emoji/" + matName); } - _link = _scene.Ptr.GetChild("Link", true); - Vector3 pos = Vector3.Zero; + var tilePrefab = Context.ResourceCache.GetResource("Objects/Tile.prefab"); foreach (var tileMaterial in _tileMaterials) { - var tile = _scene.Ptr.CreateChild(); - var prefabReference = tile.CreateComponent(); - prefabReference.SetPrefab(Context.ResourceCache.GetResource("Objects/Tile.prefab")); - prefabReference.Inline(PrefabInlineFlag.None); + var tile = _scene.Ptr.InstantiatePrefab(tilePrefab); + //var prefabReference = tile.CreateComponent(); + //prefabReference.SetPrefab(); + //prefabReference.Inline(PrefabInlineFlag.None); var model = tile.GetComponent(true); model.SetMaterial(tileMaterial.Value); tile.Position = pos; pos += Vector3.Forward; } - Deactivate(); + _pickSate = new PickSate(this); + _dragSate = new DragSate(this); + State = _pickSate; + Deactivate(); } public override void OnDataModelInitialized(GameRmlUIComponent component) @@ -72,6 +99,10 @@ public override void Activate(StringVariantMap bundle) SubscribeToEvent(E.MouseButtonUp, HandleMouseUp); SubscribeToEvent(E.MouseMove, HandleMouseMove); + SubscribeToEvent(E.TouchBegin, HandleTouchBegin); + SubscribeToEvent(E.TouchEnd, HandleTouchEnd); + SubscribeToEvent(E.TouchMove, HandleTouchMove); + _scene.Ptr.IsUpdateEnabled = true; @@ -79,32 +110,54 @@ public override void Activate(StringVariantMap bundle) base.Activate(bundle); } - private void HandleMouseMove(StringHash arg1, VariantMap arg2) + private void HandleTouchBegin(VariantMap args) { - if (!_link.IsEnabled) - return; + var touchId = args[E.TouchBegin.TouchID].Int; + var x = args[E.TouchBegin.X].Int; + var y = args[E.TouchBegin.Y].Int; + _state.HandleTouchBegin(touchId, new IntVector2(x,y)); + } - var x = arg2[E.MouseMove.X].Int; - var y = arg2[E.MouseMove.Y].Int; - var ray = _viewport.GetScreenRay(x, y); - var normal = Vector3.Up; - var d = normal.DotProduct(ray.Direction); - float t = -(normal.DotProduct(ray.Origin) + 0.0f) / d; - var a = _link.GetChild("A", true); - var b = _link.GetChild("B", true); - b.Position = ray.Origin + ray.Direction * t; - a.LookAt(b.Position); - b.LookAt(a.Position); + private void HandleTouchEnd(VariantMap args) + { + var touchId = args[E.TouchEnd.TouchID].Int; + var x = args[E.TouchEnd.X].Int; + var y = args[E.TouchEnd.Y].Int; + _state.HandleTouchEnd(touchId, new IntVector2(x, y)); } - private void HandleMouseUp(StringHash arg1, VariantMap arg2) + private void HandleTouchMove(VariantMap args) { - _link.IsEnabled = false; + var touchId = args[E.TouchMove.TouchID].Int; + var x = args[E.TouchMove.X].Int; + var y = args[E.TouchMove.Y].Int; + _state.HandleTouchMove(touchId, new IntVector2(x, y)); } - private void HandleMouseDown(StringHash arg1, VariantMap arg2) + private void HandleMouseMove(VariantMap args) { - _link.IsEnabled = true; + var buttons = args[E.MouseMove.Buttons].Int; + var qualifiers = args[E.MouseMove.Qualifiers].Int; + var x = args[E.MouseMove.X].Int; + var y = args[E.MouseMove.Y].Int; + _state.HandleMouseMove(new IntVector2(x, y), buttons, qualifiers); + + } + + private void HandleMouseUp(StringHash arg1, VariantMap args) + { + var buttons = args[E.MouseButtonUp.Buttons].Int; + var qualifiers = args[E.MouseButtonUp.Qualifiers].Int; + var button = args[E.MouseButtonUp.Button].Int; + _state.HandleMouseUp(button, Context.Input.MousePosition, buttons, qualifiers); + } + + private void HandleMouseDown(StringHash arg1, VariantMap args) + { + var buttons = args[E.MouseButtonDown.Buttons].Int; + var qualifiers = args[E.MouseButtonDown.Qualifiers].Int; + var button = args[E.MouseButtonDown.Button].Int; + _state.HandleMouseDown(button, Context.Input.MousePosition, buttons, qualifiers); } public override void Deactivate() @@ -132,5 +185,33 @@ private void HandleKeyUp(VariantMap args) return; } } + public Ray GetScreenRay(IntVector2 inputMousePosition) + { + return _viewport.GetScreenRay(inputMousePosition.X, inputMousePosition.Y); + } + + public Tile PickTile(IntVector2 inputMousePosition) + { + var ray = GetScreenRay(inputMousePosition); + var physics = _scene.Ptr.GetComponent(); + physics.RaycastSingle(_raycastResult, ray, 100); + if (_raycastResult.Body != null) + { + return _raycastResult.Body.Node.GetComponent() ?? _raycastResult.Body.Node.GetParentComponent(true); + } + return null; + } + + public void DragTile(Tile tile, int? touchId) + { + _dragSate.TrackTile(tile, touchId); + State = _dragSate; + + } + + public void LinkTiles(Tile pickTile) + { + State = _pickSate; + } } } \ No newline at end of file diff --git a/RbfxTemplate/GameStates/DragSate.cs b/RbfxTemplate/GameStates/DragSate.cs new file mode 100644 index 0000000..86c883b --- /dev/null +++ b/RbfxTemplate/GameStates/DragSate.cs @@ -0,0 +1,70 @@ +using Urho3DNet; + +namespace RbfxTemplate.GameStates +{ + public class DragSate : StateBase + { + private Tile _tile; + private int? _touchId; + + public DragSate(GameState game) : base(game) + { + } + + public void TrackTile(Tile tile, int? touchId) + { + _tile = tile; + _touchId = touchId; + } + + public override void Activate() + { + _tile.Link.IsEnabled = true; + base.Activate(); + } + + public override void Deactivate() + { + base.Deactivate(); + } + + public override void HandleMouseMove(IntVector2 intVector2, int buttons, int qualifiers) + { + if (_touchId.HasValue) { return; } + + MoveLink(intVector2); + } + + private void MoveLink(IntVector2 intVector2) + { + var ray = Game.GetScreenRay(intVector2); + var normal = Vector3.Up; + var d = normal.DotProduct(ray.Direction); + float t = -(normal.DotProduct(ray.Origin) + 0.0f) / d; + _tile.LinkTarget.WorldPosition = ray.Origin + ray.Direction * t; + _tile.LinkSource.LookAt(_tile.LinkTarget.WorldPosition); + _tile.LinkTarget.LookAt(_tile.LinkSource.WorldPosition); + } + + public override void HandleMouseUp(int button, IntVector2 inputMousePosition, int buttons, int qualifiers) + { + if (_touchId.HasValue) { return; } + + Game.LinkTiles(Game.PickTile(inputMousePosition)); + } + + public override void HandleTouchMove(int touchId, IntVector2 intVector2) + { + if (_touchId != touchId) { return; } + + MoveLink(intVector2); + } + + public override void HandleTouchEnd(int touchId, IntVector2 intVector2) + { + if (_touchId != touchId) { return; } + + Game.LinkTiles(Game.PickTile(intVector2)); + } + } +} \ No newline at end of file diff --git a/RbfxTemplate/GameStates/PickSate.cs b/RbfxTemplate/GameStates/PickSate.cs new file mode 100644 index 0000000..6517609 --- /dev/null +++ b/RbfxTemplate/GameStates/PickSate.cs @@ -0,0 +1,34 @@ +using Urho3DNet; + +namespace RbfxTemplate.GameStates +{ + public class PickSate: StateBase + { + public PickSate(GameState game) : base(game) + { + } + + public override void HandleMouseDown(int button, IntVector2 inputMousePosition, int buttons, int qualifiers) + { + if (button != 1) + { + return; + } + + var tile = Game.PickTile(inputMousePosition); + if (tile != null) + { + Game.DragTile(tile, null); + } + } + + public override void HandleTouchBegin(int touchId, IntVector2 touchPosition) + { + var tile = Game.PickTile(touchPosition); + if (tile != null) + { + Game.DragTile(tile, touchId); + } + } + } +} \ No newline at end of file diff --git a/RbfxTemplate/GameStates/StateBase.cs b/RbfxTemplate/GameStates/StateBase.cs new file mode 100644 index 0000000..ffc81ae --- /dev/null +++ b/RbfxTemplate/GameStates/StateBase.cs @@ -0,0 +1,56 @@ +using Urho3DNet; + +namespace RbfxTemplate.GameStates +{ + public abstract class StateBase + { + private readonly GameState _game; + + public GameState Game => _game; + + public StateBase(GameState game) + { + _game = game; + } + + public virtual void HandleTouchBegin(int touchId, IntVector2 intVector2) + { + + } + + public virtual void HandleTouchMove(int touchId, IntVector2 intVector2) + { + + } + + public virtual void HandleTouchEnd(int touchId, IntVector2 intVector2) + { + + } + + public virtual void HandleMouseMove(IntVector2 intVector2, int buttons, int qualifiers) + { + + } + + public virtual void HandleMouseDown(int button, IntVector2 inputMousePosition, int buttons, int qualifiers) + { + + } + + public virtual void HandleMouseUp(int button, IntVector2 inputMousePosition, int buttons, int qualifiers) + { + + } + + public virtual void Activate() + { + + } + + public virtual void Deactivate() + { + + } + } +} diff --git a/RbfxTemplate/RbfxTemplate.csproj b/RbfxTemplate/RbfxTemplate.csproj index a5e6fca..fd9cf3f 100644 --- a/RbfxTemplate/RbfxTemplate.csproj +++ b/RbfxTemplate/RbfxTemplate.csproj @@ -13,7 +13,7 @@ - + diff --git a/RbfxTemplate/Tile.cs b/RbfxTemplate/Tile.cs index 0080c0e..aa75656 100644 --- a/RbfxTemplate/Tile.cs +++ b/RbfxTemplate/Tile.cs @@ -2,12 +2,35 @@ namespace RbfxTemplate { - [ObjectFactory] + [ObjectFactory(Category = "Component/Game")] [Preserve(AllMembers = true)] public sealed class Tile : Component { + [Urho3DNet.SerializeField(Mode = AttributeMode.AmDefault | AttributeMode.AmNodeid, Name = "Link")] + private int _linkId; + + [Urho3DNet.SerializeField(Mode = AttributeMode.AmDefault | AttributeMode.AmNodeid, Name = "LinkSource")] + private int _linkSource; + + [Urho3DNet.SerializeField(Mode = AttributeMode.AmDefault | AttributeMode.AmNodeid, Name = "LinkTarget")] + private int _linkTarget; + + public Node Link { get; set; } + + public Node LinkSource { get; set; } + + public Node LinkTarget { get; set; } + public Tile(Context context) : base(context) { } + + public override void ApplyAttributes() + { + Link = Scene.GetNode((uint)_linkId); + LinkSource = Scene.GetNode((uint)_linkSource); + LinkTarget = Scene.GetNode((uint)_linkTarget); + base.ApplyAttributes(); + } } } \ No newline at end of file diff --git a/RbfxTemplate/UrhoApplication.cs b/RbfxTemplate/UrhoApplication.cs index bf29c08..aa7b55e 100644 --- a/RbfxTemplate/UrhoApplication.cs +++ b/RbfxTemplate/UrhoApplication.cs @@ -41,8 +41,7 @@ public override void Setup() EngineParameters[Urho3D.EpOrientations] = "LandscapeLeft LandscapeRight Portrait"; // Run shaders via SpirV-Cross to eliminate potential driver bugs - EngineParameters[Urho3D.EpShaderPolicyGlsl] = 0; - EngineParameters[Urho3D.EpShaderPolicyHlsl] = 2; + //EngineParameters[Urho3D.EpShaderPolicy] = 0; // Enable this if you need to debug translated shaders. //EngineParameters[Urho3D.EpShaderLogSources] = true;