Simple navigation now working but feels shitty. Keep it for now.

WorldChunkRefactoring
Martin Felis 2023-01-04 21:29:42 +01:00
parent c7349f4cee
commit e3098c65a3
6 changed files with 106 additions and 49 deletions

5
Globals.cs Normal file
View File

@ -0,0 +1,5 @@
public static class Globals
{
public const float EpsPosition = 0.01f;
public const float EpsPositionSquared = 0.01f * 0.01f;
}

View File

@ -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;
GD.Print("Navigation: at " + _currentGoalWorld + " path length: " +
_pathOffsetCoords.Count);
}
HexCell targetCell = new HexCell();
targetCell.OffsetCoords = currentGoalOffset;
path = currentCell.LineTo(targetCell);
pathOffsetCoords = new List<Vector2>();
foreach (HexCell cell in path)
public void UpdateCurrentGoal(Vector3 currentPositionWorld)
{
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();
}
}
}

View File

@ -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)

View File

@ -178,7 +178,13 @@ public class AdaptiveWorldStream : Spatial
return;
}
_player.TargetPosition = tile.GlobalTranslation;
if (_player.Navigation == null)
{
return;
}
_player.Navigation.Plan(_player.GlobalTranslation, tile.GlobalTranslation);
// MovableComponent movableComponent = _player.GetNode<MovableComponent>("Movable");
// if (movableComponent == null)
// {

View File

@ -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="."]

View File

@ -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)
// {
//
// }
}