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;
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)
{
_currentPositionWorld = currentPositionWorld;
pathOffsetCoords = new List<Vector2>(); Vector2 currentPositionPlane = new Vector2(currentPositionWorld.x, currentPositionWorld.z);
foreach (HexCell cell in path) Vector2 currentGoalPlane = new Vector2(_currentGoalWorld.x, _currentGoalWorld.z);
if (_pathOffsetCoords.Count > 0 &&
(currentPositionPlane - currentGoalPlane).LengthSquared() < Globals.EpsPositionSquared)
{ {
pathOffsetCoords.Append(cell.OffsetCoords); _pathOffsetCoords.RemoveAt(0);
UpdateCurrentGoal();
} }
currentGoalOffset = pathOffsetCoords[1];
} }
} }

View File

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

View File

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

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

View File

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