Simple navigation now working but feels shitty. Keep it for now.
parent
c7349f4cee
commit
e3098c65a3
|
@ -0,0 +1,5 @@
|
||||||
|
public static class Globals
|
||||||
|
{
|
||||||
|
public const float EpsPosition = 0.01f;
|
||||||
|
public const float EpsPositionSquared = 0.01f * 0.01f;
|
||||||
|
}
|
|
@ -1,47 +1,89 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Godot;
|
using Godot;
|
||||||
using Vector2 = Godot.Vector2;
|
using Vector2 = Godot.Vector2;
|
||||||
using Vector3 = Godot.Vector3;
|
using Vector3 = Godot.Vector3;
|
||||||
|
using GoDotLog;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class NavigationComponent
|
public class NavigationComponent : Node
|
||||||
{
|
{
|
||||||
public Vector3 currentGoalWorld;
|
public TileWorld TileWorld { set; get; }
|
||||||
public Vector2 currentGoalOffset;
|
|
||||||
public List<Vector2> pathOffsetCoords;
|
|
||||||
public HexCell[] path;
|
|
||||||
|
|
||||||
private HexGrid _hexGrid;
|
public Vector3 CurrentGoalWorld => _currentGoalWorld;
|
||||||
|
|
||||||
public void Plan(Vector3 currentPositionWorld, Vector3 targetPositionWorld, TileWorld tileWorld)
|
private Vector3 _currentGoalWorld = Vector3.Zero;
|
||||||
|
private Vector2 _currentGoalPlane = Vector2.Zero;
|
||||||
|
private Vector2 _currentGoalOffset = Vector2.Zero;
|
||||||
|
private Vector3 _currentPositionWorld = Vector3.Zero;
|
||||||
|
|
||||||
|
private List<Vector2> _pathOffsetCoords;
|
||||||
|
private HexCell[] _path;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
if ((targetPositionWorld - currentGoalWorld).LengthSquared() < 0.01)
|
base._Ready();
|
||||||
|
_pathOffsetCoords = new List<Vector2>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _Process(float delta)
|
||||||
|
{
|
||||||
|
Debug.Assert(TileWorld != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Plan(Vector3 fromPositionWorld, Vector3 toPositionWorld)
|
||||||
|
{
|
||||||
|
Vector2 fromPositionOffset = TileWorld.WorldToOffsetCoords(fromPositionWorld);
|
||||||
|
Vector2 toPositionOffset = TileWorld.WorldToOffsetCoords(toPositionWorld);
|
||||||
|
|
||||||
|
HexCell fromCell = new HexCell();
|
||||||
|
fromCell.OffsetCoords = fromPositionOffset;
|
||||||
|
|
||||||
|
HexCell toCell = new HexCell();
|
||||||
|
toCell.OffsetCoords = toPositionOffset;
|
||||||
|
|
||||||
|
_path = fromCell.LineTo(toCell);
|
||||||
|
Debug.Assert(_path.Length > 0);
|
||||||
|
|
||||||
|
_pathOffsetCoords = new List<Vector2>();
|
||||||
|
foreach (int index in Enumerable.Range(1, _path.Length - 1))
|
||||||
|
{
|
||||||
|
_pathOffsetCoords.Add(_path[index].OffsetCoords);
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateCurrentGoal();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateCurrentGoal()
|
||||||
|
{
|
||||||
|
if (_pathOffsetCoords.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentGoalWorld = targetPositionWorld;
|
_currentGoalWorld = TileWorld.GetTileWorldCenterFromOffset(_pathOffsetCoords[0]);
|
||||||
Vector2 currentPositionOffset = tileWorld.WorldToOffsetCoords(currentPositionWorld);
|
|
||||||
Vector2 currentGoalOffset = tileWorld.WorldToOffsetCoords(targetPositionWorld);
|
|
||||||
|
|
||||||
HexCell currentCell = new HexCell();
|
GD.Print("Navigation: at " + _currentGoalWorld + " path length: " +
|
||||||
currentCell.OffsetCoords = currentPositionOffset;
|
_pathOffsetCoords.Count);
|
||||||
|
}
|
||||||
|
|
||||||
HexCell targetCell = new HexCell();
|
|
||||||
targetCell.OffsetCoords = currentGoalOffset;
|
|
||||||
|
|
||||||
path = currentCell.LineTo(targetCell);
|
public void UpdateCurrentGoal(Vector3 currentPositionWorld)
|
||||||
|
|
||||||
pathOffsetCoords = new List<Vector2>();
|
|
||||||
foreach (HexCell cell in path)
|
|
||||||
{
|
{
|
||||||
pathOffsetCoords.Append(cell.OffsetCoords);
|
_currentPositionWorld = currentPositionWorld;
|
||||||
}
|
|
||||||
|
|
||||||
currentGoalOffset = pathOffsetCoords[1];
|
Vector2 currentPositionPlane = new Vector2(currentPositionWorld.x, currentPositionWorld.z);
|
||||||
|
Vector2 currentGoalPlane = new Vector2(_currentGoalWorld.x, _currentGoalWorld.z);
|
||||||
|
if (_pathOffsetCoords.Count > 0 &&
|
||||||
|
(currentPositionPlane - currentGoalPlane).LengthSquared() < Globals.EpsPositionSquared)
|
||||||
|
{
|
||||||
|
_pathOffsetCoords.RemoveAt(0);
|
||||||
|
UpdateCurrentGoal();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,6 +6,11 @@ public class Player : Entity
|
||||||
// public members
|
// public members
|
||||||
public Vector3 TargetPosition = Vector3.Zero;
|
public Vector3 TargetPosition = Vector3.Zero;
|
||||||
|
|
||||||
|
public NavigationComponent Navigation
|
||||||
|
{
|
||||||
|
get { return _navigationComponent; }
|
||||||
|
}
|
||||||
|
|
||||||
// private members
|
// private members
|
||||||
private MovableComponent _movable;
|
private MovableComponent _movable;
|
||||||
private Spatial _geometry;
|
private Spatial _geometry;
|
||||||
|
@ -18,7 +23,9 @@ public class Player : Entity
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
_groundMotion = new GroundMotionComponent();
|
_groundMotion = new GroundMotionComponent();
|
||||||
_navigationComponent = new NavigationComponent();
|
_worldInfo = (WorldInfoComponent)FindNode("WorldInfo", false);
|
||||||
|
_navigationComponent = (NavigationComponent)FindNode("Navigation", false);
|
||||||
|
_navigationComponent.TileWorld = _worldInfo.TileWorld;
|
||||||
|
|
||||||
_movable = (MovableComponent)FindNode("Movable", false);
|
_movable = (MovableComponent)FindNode("Movable", false);
|
||||||
if (_movable != null)
|
if (_movable != null)
|
||||||
|
@ -27,8 +34,6 @@ public class Player : Entity
|
||||||
}
|
}
|
||||||
|
|
||||||
_geometry = (Spatial)FindNode("Geometry", false);
|
_geometry = (Spatial)FindNode("Geometry", false);
|
||||||
|
|
||||||
_worldInfo = (WorldInfoComponent)FindNode("WorldInfo", false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,26 +41,25 @@ public class Player : Entity
|
||||||
{
|
{
|
||||||
base._PhysicsProcess(delta);
|
base._PhysicsProcess(delta);
|
||||||
|
|
||||||
// update navigation target here
|
if (_navigationComponent == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// update physics target
|
_navigationComponent.UpdateCurrentGoal(GlobalTranslation);
|
||||||
Vector3 targetPosition =
|
|
||||||
_worldInfo.TileWorld.GetTileWorldCenterFromOffset(_navigationComponent.currentGoalOffset);
|
|
||||||
|
|
||||||
// compute physics movement
|
_groundMotion.PhysicsProcess(delta, this, _navigationComponent.CurrentGoalWorld, _worldInfo.TileWorld);
|
||||||
_groundMotion.PhysicsProcess(delta, this, targetPosition, _worldInfo.TileWorld);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void _Process(float delta)
|
public override void _Process(float delta)
|
||||||
{
|
{
|
||||||
if ((_navigationComponent.currentGoalWorld - TargetPosition).LengthSquared() > 0.01)
|
if (_navigationComponent != null)
|
||||||
{
|
{
|
||||||
_navigationComponent.Plan(GlobalTransform.origin, TargetPosition, _worldInfo.TileWorld);
|
_navigationComponent.UpdateCurrentGoal(GlobalTranslation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void OnPositionUpdated(Vector3 newPosition)
|
public void OnPositionUpdated(Vector3 newPosition)
|
||||||
{
|
{
|
||||||
if (_worldInfo != null)
|
if (_worldInfo != null)
|
||||||
|
@ -66,7 +70,6 @@ public class Player : Entity
|
||||||
{
|
{
|
||||||
GD.Print("New offset coord " + new_offset_coord);
|
GD.Print("New offset coord " + new_offset_coord);
|
||||||
_offsetCoord = new_offset_coord;
|
_offsetCoord = new_offset_coord;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_movable != null)
|
if (_movable != null)
|
||||||
|
|
|
@ -178,7 +178,13 @@ public class AdaptiveWorldStream : Spatial
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_player.TargetPosition = tile.GlobalTranslation;
|
if (_player.Navigation == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_player.Navigation.Plan(_player.GlobalTranslation, tile.GlobalTranslation);
|
||||||
|
|
||||||
// MovableComponent movableComponent = _player.GetNode<MovableComponent>("Movable");
|
// MovableComponent movableComponent = _player.GetNode<MovableComponent>("Movable");
|
||||||
// if (movableComponent == null)
|
// if (movableComponent == null)
|
||||||
// {
|
// {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
[gd_scene load_steps=17 format=2]
|
[gd_scene load_steps=18 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://scenes/AdaptiveWorldStream.cs" type="Script" id=1]
|
[ext_resource path="res://scenes/AdaptiveWorldStream.cs" type="Script" id=1]
|
||||||
[ext_resource path="res://assets/CreatusPiratePack/characters/Pirate1final_0.01.glb" type="PackedScene" id=2]
|
[ext_resource path="res://assets/CreatusPiratePack/characters/Pirate1final_0.01.glb" type="PackedScene" id=2]
|
||||||
|
@ -9,6 +9,7 @@
|
||||||
[ext_resource path="res://utils/TileHighlight.tscn" type="PackedScene" id=7]
|
[ext_resource path="res://utils/TileHighlight.tscn" type="PackedScene" id=7]
|
||||||
[ext_resource path="res://components/MovableComponent.cs" type="Script" id=8]
|
[ext_resource path="res://components/MovableComponent.cs" type="Script" id=8]
|
||||||
[ext_resource path="res://scenes/TileWorld.cs" type="Script" id=9]
|
[ext_resource path="res://scenes/TileWorld.cs" type="Script" id=9]
|
||||||
|
[ext_resource path="res://components/NavigationComponent.cs" type="Script" id=10]
|
||||||
|
|
||||||
[sub_resource type="OpenSimplexNoise" id=10]
|
[sub_resource type="OpenSimplexNoise" id=10]
|
||||||
period = 39.6
|
period = 39.6
|
||||||
|
@ -29,8 +30,8 @@ albedo_color = Color( 1, 1, 1, 0.156863 )
|
||||||
extents = Vector3( 20, 1, 20 )
|
extents = Vector3( 20, 1, 20 )
|
||||||
|
|
||||||
[sub_resource type="CapsuleShape" id=7]
|
[sub_resource type="CapsuleShape" id=7]
|
||||||
radius = 0.2
|
radius = 0.4
|
||||||
height = 0.5
|
height = 0.2
|
||||||
|
|
||||||
[sub_resource type="CapsuleMesh" id=8]
|
[sub_resource type="CapsuleMesh" id=8]
|
||||||
radius = 0.2
|
radius = 0.2
|
||||||
|
@ -62,6 +63,7 @@ mouse_filter = 2
|
||||||
margin_right = 40.0
|
margin_right = 40.0
|
||||||
margin_bottom = 40.0
|
margin_bottom = 40.0
|
||||||
mouse_filter = 2
|
mouse_filter = 2
|
||||||
|
alignment = 2
|
||||||
|
|
||||||
[node name="GridContainer" type="GridContainer" parent="Control/HBoxContainer"]
|
[node name="GridContainer" type="GridContainer" parent="Control/HBoxContainer"]
|
||||||
margin_right = 127.0
|
margin_right = 127.0
|
||||||
|
@ -244,3 +246,8 @@ transform = Transform( 0.4, 0, 0, 0, 0.4, 0, 0, 0, 0.4, 0, 0, 0 )
|
||||||
[node name="WorldInfo" type="Node" parent="Player"]
|
[node name="WorldInfo" type="Node" parent="Player"]
|
||||||
script = ExtResource( 3 )
|
script = ExtResource( 3 )
|
||||||
World = NodePath("../../TileWorld")
|
World = NodePath("../../TileWorld")
|
||||||
|
|
||||||
|
[node name="Navigation" type="Node" parent="Player"]
|
||||||
|
script = ExtResource( 10 )
|
||||||
|
|
||||||
|
[node name="Entities" type="Spatial" parent="."]
|
||||||
|
|
|
@ -11,7 +11,7 @@ public class TileWorld : Spatial
|
||||||
// public members
|
// public members
|
||||||
public Image Heightmap;
|
public Image Heightmap;
|
||||||
public Vector2 Size = new Vector2(100, 100);
|
public Vector2 Size = new Vector2(100, 100);
|
||||||
public float HeightScale = 10;
|
public float HeightScale = 5;
|
||||||
|
|
||||||
// private members
|
// private members
|
||||||
private HexGrid _hexGrid;
|
private HexGrid _hexGrid;
|
||||||
|
@ -127,10 +127,4 @@ public class TileWorld : Spatial
|
||||||
GetHeightAtOffset(offset_coord),
|
GetHeightAtOffset(offset_coord),
|
||||||
tileCenter.y);
|
tileCenter.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
||||||
// public override void _Process(float delta)
|
|
||||||
// {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue