From 385ed555052c3516a6b41394ac28384ff88f75dd Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Wed, 28 Dec 2022 21:57:34 +0100 Subject: [PATCH] Started refactoring entity movement and structure. --- components/GroundMotionComponent.cs | 28 ++++++++++++++++++++++++ components/MovableComponent.cs | 13 +++++------ entities/Entity.cs | 20 +++++++++++++++++ entities/Player.cs | 26 +++++++++++++++++----- scenes/AdaptiveWorldStream.cs | 15 +++++++------ scenes/AdaptiveWorldStream.tscn | 4 ++-- scenes/HexTile3D.cs | 10 ++++----- scenes/HexTile3D.tscn | 8 +++---- scenes/TileWorld.cs | 2 +- utils/SpringDamper.cs | 34 +++++++++++++++++++++++++++++ 10 files changed, 128 insertions(+), 32 deletions(-) create mode 100644 components/GroundMotionComponent.cs create mode 100644 entities/Entity.cs diff --git a/components/GroundMotionComponent.cs b/components/GroundMotionComponent.cs new file mode 100644 index 0000000..1637d20 --- /dev/null +++ b/components/GroundMotionComponent.cs @@ -0,0 +1,28 @@ +using Godot; +using System; + +/// +/// +public class GroundMotionComponent +{ + public float MaxSpeed = 3; + + public void Process(float delta, Entity entity, Vector3 target_position) + { + Vector3 direction_xy = new Vector3(target_position.x - entity.GlobalTranslation.x, + 0, + target_position.z - entity.GlobalTranslation.z); + + Vector3 new_velocity = direction_xy.Normalized() * MaxSpeed; + new_velocity.y = entity.Velocity.y - 9.81f * delta; + + if (direction_xy.LengthSquared() > 0.01) + { + entity.Velocity = entity.MoveAndSlide(new_velocity); + } + else + { + entity.Velocity = Vector3.Up * -9.81f * delta; + } + } +} \ No newline at end of file diff --git a/components/MovableComponent.cs b/components/MovableComponent.cs index 4934c09..c5521c3 100644 --- a/components/MovableComponent.cs +++ b/components/MovableComponent.cs @@ -40,10 +40,6 @@ public class MovableComponent : Node targetDir = targetError.Normalized(); targetAngle = new Vector3(0, 0, 1).SignedAngleTo(targetDir, Vector3.Up); - if (currentAngle < Mathf.Pi && targetAngle > Mathf.Pi) - { - } - if (targetAngle - currentAngle > Mathf.Pi) { currentAngle += 2 * Mathf.Pi; @@ -69,13 +65,16 @@ public class MovableComponent : Node && (targetPosition - currentPosition).LengthSquared() > 0.01) { var springDamperResult = - _positionSpringDamper.CalcClampedSpeed(currentPosition, currentVelocity, targetPosition, delta, + _positionSpringDamper.CalcClampedSpeedXZ(currentPosition, currentVelocity, targetPosition, delta, maxSpeed); currentPosition = springDamperResult.Item1; currentVelocity = springDamperResult.Item2; - - EmitSignal("PositionUpdated", currentPosition); + } + currentVelocity.y = currentVelocity.y - 9.81f * delta; + currentPosition.y = currentPosition.y + currentVelocity.y * delta; + + EmitSignal("PositionUpdated", currentPosition); } } \ No newline at end of file diff --git a/entities/Entity.cs b/entities/Entity.cs new file mode 100644 index 0000000..14871f2 --- /dev/null +++ b/entities/Entity.cs @@ -0,0 +1,20 @@ +using Godot; +using System; + +public class Entity : KinematicBody +{ + public Vector3 Position = Vector3.Zero; + public Quat Orientation = Quat.Identity; + + public Vector3 Velocity = Vector3.Zero; + public float RotationalVelocity = 0; + + public override void _Ready() + { + } + + public override void _Process(float _delta) + { + Velocity = MoveAndSlide(Velocity); + } +} \ No newline at end of file diff --git a/entities/Player.cs b/entities/Player.cs index cc6645b..f025d37 100644 --- a/entities/Player.cs +++ b/entities/Player.cs @@ -1,21 +1,26 @@ using Godot; using System; -public class Player : KinematicBody +public class Player : Entity { - // other members + // public members + public Vector3 TargetPosition = Vector3.Zero; + + // private members private MovableComponent _movable; private Spatial _geometry; private WorldInfoComponent _worldInfo; private Vector2 _offsetCoord = Vector2.Zero; + private GroundMotionComponent _groundMotion; // Called when the node enters the scene tree for the first time. public override void _Ready() { + _groundMotion = new GroundMotionComponent(); + _movable = (MovableComponent)FindNode("Movable", false); if (_movable != null) { - _movable.Connect("PositionUpdated", this, nameof(OnPositionUpdated)); _movable.Connect("OrientationUpdated", this, nameof(OnOrientationUpdated)); } @@ -24,11 +29,19 @@ public class Player : KinematicBody _worldInfo = (WorldInfoComponent)FindNode("WorldInfo", false); } + + public override void _Process(float _delta) + { + base._Process(_delta); + _groundMotion.Process(_delta, this, TargetPosition); + } + public void OnPositionUpdated(Vector3 newPosition) { if (_worldInfo != null) { Vector2 new_offset_coord = _worldInfo.TileWorld.WorldToOffsetCoords(newPosition); + float tile_height = _worldInfo.TileWorld.GetHeightAtOffset(new_offset_coord); if (_offsetCoord != new_offset_coord) { GD.Print("New offset coord " + new_offset_coord); @@ -38,8 +51,11 @@ public class Player : KinematicBody if (_movable != null) { - _movable.targetPosition.y = _worldInfo.TileWorld.GetHeightAtOffset(new_offset_coord); - + if (_movable.currentPosition.y < tile_height) + { + _movable.currentPosition.y = tile_height; + _movable.currentVelocity.y = 0; + } } } diff --git a/scenes/AdaptiveWorldStream.cs b/scenes/AdaptiveWorldStream.cs index 78f12f5..f6f9bbb 100644 --- a/scenes/AdaptiveWorldStream.cs +++ b/scenes/AdaptiveWorldStream.cs @@ -178,13 +178,14 @@ public class AdaptiveWorldStream : Spatial return; } - MovableComponent movableComponent = _player.GetNode("Movable"); - if (movableComponent == null) - { - return; - } - - movableComponent.targetPosition = tile.Transform.origin; + _player.TargetPosition = tile.GlobalTranslation; +// MovableComponent movableComponent = _player.GetNode("Movable"); +// if (movableComponent == null) +// { +// return; +// } +// +// movableComponent.targetPosition = tile.Transform.origin; } diff --git a/scenes/AdaptiveWorldStream.tscn b/scenes/AdaptiveWorldStream.tscn index ad1a282..68eb5a5 100644 --- a/scenes/AdaptiveWorldStream.tscn +++ b/scenes/AdaptiveWorldStream.tscn @@ -21,7 +21,7 @@ albedo_color = Color( 1, 1, 1, 0.156863 ) extents = Vector3( 20, 1, 20 ) [sub_resource type="CapsuleShape" id=7] -radius = 0.2 +radius = 0.475 height = 0.5 [sub_resource type="CapsuleMesh" id=8] @@ -221,13 +221,13 @@ script = ExtResource( 6 ) [node name="MeshInstance" type="MeshInstance" parent="Player"] transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0.5, 0 ) -visible = false mesh = SubResource( 8 ) [node name="Movable" type="Node" parent="Player"] script = ExtResource( 8 ) [node name="Geometry" type="Spatial" parent="Player"] +visible = false [node name="Pirate1final_001" parent="Player/Geometry" instance=ExtResource( 2 )] transform = Transform( 0.4, 0, 0, 0, 0.4, 0, 0, 0, 0.4, 0, 0, 0 ) diff --git a/scenes/HexTile3D.cs b/scenes/HexTile3D.cs index c01ed82..05e9fb8 100644 --- a/scenes/HexTile3D.cs +++ b/scenes/HexTile3D.cs @@ -14,7 +14,7 @@ public class HexTile3D : Spatial // scene nodes private MeshInstance _mesh; - private Area _area; + private StaticBody _staticBody; // signals [Signal] @@ -87,11 +87,11 @@ public class HexTile3D : Spatial public override void _Ready() { _mesh = GetNode("Mesh"); - _area = GetNode("Mesh/Area"); + _staticBody = GetNode("StaticBody"); - _area.Connect("input_event", this, nameof(OnAreaInputEvent)); - _area.Connect("mouse_entered", this, nameof(OnAreaMouseEntered)); - _area.Connect("mouse_exited", this, nameof(OnAreaMouseExited)); + _staticBody.Connect("input_event", this, nameof(OnAreaInputEvent)); + _staticBody.Connect("mouse_entered", this, nameof(OnAreaMouseEntered)); + _staticBody.Connect("mouse_exited", this, nameof(OnAreaMouseExited)); _undefinedMaterial = GD.Load("res://materials/UndefinedTile.tres"); _sandMaterial = GD.Load("res://materials/SandTile.tres"); diff --git a/scenes/HexTile3D.tscn b/scenes/HexTile3D.tscn index c35f63f..1bca594 100644 --- a/scenes/HexTile3D.tscn +++ b/scenes/HexTile3D.tscn @@ -22,10 +22,8 @@ transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0, -5, mesh = SubResource( 6 ) material/0 = ExtResource( 2 ) -[node name="Area" type="Area" parent="Mesh"] -monitoring = false -monitorable = false +[node name="StaticBody" type="StaticBody" parent="."] -[node name="CollisionShape" type="CollisionShape" parent="Mesh/Area"] -transform = Transform( 1, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0 ) +[node name="CollisionShape" type="CollisionShape" parent="StaticBody"] +transform = Transform( -4.37114e-08, 0, 1, 0, 10, 0, -1, 0, -4.37114e-08, 0, -5, 0 ) shape = SubResource( 5 ) diff --git a/scenes/TileWorld.cs b/scenes/TileWorld.cs index 34d5b05..3a4231c 100644 --- a/scenes/TileWorld.cs +++ b/scenes/TileWorld.cs @@ -105,7 +105,7 @@ public class TileWorld : Spatial { if (!IsOffsetCoordValid(offset_coord)) { - return -0.1f; + return 0; } return Heightmap.GetPixel((int)offset_coord.x, (int)offset_coord.y).r * HeightScale - HeightScale * 0.5f ; diff --git a/utils/SpringDamper.cs b/utils/SpringDamper.cs index dc84d24..0dacb83 100644 --- a/utils/SpringDamper.cs +++ b/utils/SpringDamper.cs @@ -60,4 +60,38 @@ public class SpringDamper return (x_new, vel_new); } + + public (Vector3, Vector3) CalcClampedSpeedXZ(Vector3 x, Vector3 v, Vector3 xt, float h, float speedMax) + { + var result_x = Calc(x.x, v.x, xt.x, h); + var result_z = Calc(x.z, v.z, xt.z, h); + + Vector3 x_new = x; + Vector3 v_new = v; + + x_new.x = result_x.Item1; + v_new.x = result_x.Item2; + + x_new.z = result_z.Item1; + v_new.z = result_z.Item2; + + Vector3 result_v_xz = new Vector3( + (result_x.Item1 - x.x) / h, + 0, + (result_z.Item1 - x.z) / h); + + float speed_new = result_v_xz.Length(); + + if (speed_new > speedMax) + { + result_v_xz = (result_v_xz) / speed_new * speedMax; + x_new.x = x.x + result_v_xz.x * h; + x_new.z = x.z + result_v_xz.z * h; + } + + v.x = result_v_xz.x; + v.z = result_v_xz.z; + + return (x_new, v_new); + } } \ No newline at end of file