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.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Godot;
|
||||
using Vector2 = Godot.Vector2;
|
||||
using Vector3 = Godot.Vector3;
|
||||
using GoDotLog;
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public class NavigationComponent
|
||||
public class NavigationComponent : Node
|
||||
{
|
||||
public Vector3 currentGoalWorld;
|
||||
public Vector2 currentGoalOffset;
|
||||
public List<Vector2> pathOffsetCoords;
|
||||
public HexCell[] path;
|
||||
public TileWorld TileWorld { set; get; }
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
currentGoalWorld = targetPositionWorld;
|
||||
Vector2 currentPositionOffset = tileWorld.WorldToOffsetCoords(currentPositionWorld);
|
||||
Vector2 currentGoalOffset = tileWorld.WorldToOffsetCoords(targetPositionWorld);
|
||||
_currentGoalWorld = TileWorld.GetTileWorldCenterFromOffset(_pathOffsetCoords[0]);
|
||||
|
||||
HexCell currentCell = new HexCell();
|
||||
currentCell.OffsetCoords = currentPositionOffset;
|
||||
|
||||
HexCell targetCell = new HexCell();
|
||||
targetCell.OffsetCoords = currentGoalOffset;
|
||||
|
||||
path = currentCell.LineTo(targetCell);
|
||||
|
||||
pathOffsetCoords = new List<Vector2>();
|
||||
foreach (HexCell cell in path)
|
||||
{
|
||||
pathOffsetCoords.Append(cell.OffsetCoords);
|
||||
GD.Print("Navigation: at " + _currentGoalWorld + " path length: " +
|
||||
_pathOffsetCoords.Count);
|
||||
}
|
||||
|
||||
currentGoalOffset = pathOffsetCoords[1];
|
||||
|
||||
public void UpdateCurrentGoal(Vector3 currentPositionWorld)
|
||||
{
|
||||
_currentPositionWorld = currentPositionWorld;
|
||||
|
||||
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 Vector3 TargetPosition = Vector3.Zero;
|
||||
|
||||
public NavigationComponent Navigation
|
||||
{
|
||||
get { return _navigationComponent; }
|
||||
}
|
||||
|
||||
// private members
|
||||
private MovableComponent _movable;
|
||||
private Spatial _geometry;
|
||||
|
@ -18,7 +23,9 @@ public class Player : Entity
|
|||
public override void _Ready()
|
||||
{
|
||||
_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);
|
||||
if (_movable != null)
|
||||
|
@ -27,8 +34,6 @@ public class Player : Entity
|
|||
}
|
||||
|
||||
_geometry = (Spatial)FindNode("Geometry", false);
|
||||
|
||||
_worldInfo = (WorldInfoComponent)FindNode("WorldInfo", false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,26 +41,25 @@ public class Player : Entity
|
|||
{
|
||||
base._PhysicsProcess(delta);
|
||||
|
||||
// update navigation target here
|
||||
if (_navigationComponent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// update physics target
|
||||
Vector3 targetPosition =
|
||||
_worldInfo.TileWorld.GetTileWorldCenterFromOffset(_navigationComponent.currentGoalOffset);
|
||||
_navigationComponent.UpdateCurrentGoal(GlobalTranslation);
|
||||
|
||||
// compute physics movement
|
||||
_groundMotion.PhysicsProcess(delta, this, targetPosition, _worldInfo.TileWorld);
|
||||
_groundMotion.PhysicsProcess(delta, this, _navigationComponent.CurrentGoalWorld, _worldInfo.TileWorld);
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
if (_worldInfo != null)
|
||||
|
@ -66,7 +70,6 @@ public class Player : Entity
|
|||
{
|
||||
GD.Print("New offset coord " + new_offset_coord);
|
||||
_offsetCoord = new_offset_coord;
|
||||
|
||||
}
|
||||
|
||||
if (_movable != null)
|
||||
|
|
|
@ -178,8 +178,14 @@ public class AdaptiveWorldStream : Spatial
|
|||
return;
|
||||
}
|
||||
|
||||
_player.TargetPosition = tile.GlobalTranslation;
|
||||
// MovableComponent movableComponent = _player.GetNode<MovableComponent>("Movable");
|
||||
if (_player.Navigation == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_player.Navigation.Plan(_player.GlobalTranslation, tile.GlobalTranslation);
|
||||
|
||||
// MovableComponent movableComponent = _player.GetNode<MovableComponent>("Movable");
|
||||
// if (movableComponent == null)
|
||||
// {
|
||||
// return;
|
||||
|
|
|
@ -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://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://components/MovableComponent.cs" type="Script" id=8]
|
||||
[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]
|
||||
period = 39.6
|
||||
|
@ -29,8 +30,8 @@ albedo_color = Color( 1, 1, 1, 0.156863 )
|
|||
extents = Vector3( 20, 1, 20 )
|
||||
|
||||
[sub_resource type="CapsuleShape" id=7]
|
||||
radius = 0.2
|
||||
height = 0.5
|
||||
radius = 0.4
|
||||
height = 0.2
|
||||
|
||||
[sub_resource type="CapsuleMesh" id=8]
|
||||
radius = 0.2
|
||||
|
@ -62,6 +63,7 @@ mouse_filter = 2
|
|||
margin_right = 40.0
|
||||
margin_bottom = 40.0
|
||||
mouse_filter = 2
|
||||
alignment = 2
|
||||
|
||||
[node name="GridContainer" type="GridContainer" parent="Control/HBoxContainer"]
|
||||
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"]
|
||||
script = ExtResource( 3 )
|
||||
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 Image Heightmap;
|
||||
public Vector2 Size = new Vector2(100, 100);
|
||||
public float HeightScale = 10;
|
||||
public float HeightScale = 5;
|
||||
|
||||
// private members
|
||||
private HexGrid _hexGrid;
|
||||
|
@ -127,10 +127,4 @@ public class TileWorld : Spatial
|
|||
GetHeightAtOffset(offset_coord),
|
||||
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