Some improvements with path smoothing and interactions.
parent
d61ef6ba45
commit
39f20c8e01
|
@ -98,6 +98,23 @@ public class NavigationComponent : Spatial
|
||||||
{
|
{
|
||||||
Debug.Assert(TileWorld != null);
|
Debug.Assert(TileWorld != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void PlanSmoothedPath(KinematicBody body, Transform fromTransformWorld, NavigationPoint navigationPoint)
|
||||||
|
{
|
||||||
|
if (navigationPoint.Flags.HasFlag(NavigationPoint.NavigationFlags.Position)
|
||||||
|
&& navigationPoint.Flags.HasFlag(NavigationPoint.NavigationFlags.Orientation))
|
||||||
|
{
|
||||||
|
FindPath(body, fromTransformWorld.origin, navigationPoint);
|
||||||
|
}
|
||||||
|
else if (navigationPoint.Flags.HasFlag(NavigationPoint.NavigationFlags.Position))
|
||||||
|
{
|
||||||
|
FindPath(body, fromTransformWorld.origin, navigationPoint.WorldPosition);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void FindPath(KinematicBody body, Vector3 fromPositionWorld, Vector3 toPositionWorld)
|
public void FindPath(KinematicBody body, Vector3 fromPositionWorld, Vector3 toPositionWorld)
|
||||||
{
|
{
|
||||||
|
@ -124,26 +141,34 @@ public class NavigationComponent : Spatial
|
||||||
}
|
}
|
||||||
|
|
||||||
List<HexCell> path = TileWorld.HexGrid.FindPath(fromCell, toCell);
|
List<HexCell> path = TileWorld.HexGrid.FindPath(fromCell, toCell);
|
||||||
|
|
||||||
// GD.Print("Planning path and have " + TileWorld.HexGrid.Obstacles.Count + " obstacles:");
|
// Generate grid navigation points
|
||||||
// GD.Print(TileWorld.HexGrid.Obstacles);
|
|
||||||
// foreach (Vector2 coord in TileWorld.HexGrid.Obstacles.Keys)
|
|
||||||
// {
|
|
||||||
// HexCell cell = new HexCell(coord);
|
|
||||||
// GD.Print(" " + cell.OffsetCoords);
|
|
||||||
// }
|
|
||||||
|
|
||||||
_planningPathWorldNavigationPoints = new List<NavigationPoint>();
|
_planningPathWorldNavigationPoints = new List<NavigationPoint>();
|
||||||
foreach (int index in Enumerable.Range(0, path.Count))
|
foreach (int index in Enumerable.Range(0, path.Count))
|
||||||
{
|
{
|
||||||
// GD.Print("Step " + index + ": " + path[index].OffsetCoords);
|
|
||||||
_planningPathWorldNavigationPoints.Add(
|
_planningPathWorldNavigationPoints.Add(
|
||||||
new NavigationPoint(TileWorld.GetHexCenterFromOffset(path[index].OffsetCoords)));
|
new NavigationPoint(TileWorld.GetHexCenterFromOffset(path[index].OffsetCoords)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure the last point coincides with the target position
|
||||||
|
if ((_planningPathWorldNavigationPoints.Last().WorldPosition - toPositionWorld).LengthSquared() <
|
||||||
|
0.5f * 0.5f)
|
||||||
|
{
|
||||||
|
_planningPathWorldNavigationPoints[_planningPathWorldNavigationPoints.Count - 1].WorldPosition = toPositionWorld;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform smoothing
|
||||||
_planningPathSmoothedWorldNavigationPoints = SmoothPath(body, _planningPathWorldNavigationPoints);
|
_planningPathSmoothedWorldNavigationPoints = SmoothPath(body, _planningPathWorldNavigationPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void FindPath(KinematicBody body, Vector3 fromPositionWorld, NavigationPoint navigationPoint)
|
||||||
|
{
|
||||||
|
FindPath(body, fromPositionWorld, navigationPoint.WorldPosition);
|
||||||
|
|
||||||
|
_planningPathWorldNavigationPoints[_planningPathWorldNavigationPoints.Count - 1] = navigationPoint;
|
||||||
|
_planningPathSmoothedWorldNavigationPoints[_planningPathSmoothedWorldNavigationPoints.Count - 1] = navigationPoint;
|
||||||
|
}
|
||||||
|
|
||||||
public void PlanGridPath(KinematicBody body, Vector3 fromPositionWorld, Vector3 toPositionWorld)
|
public void PlanGridPath(KinematicBody body, Vector3 fromPositionWorld, Vector3 toPositionWorld)
|
||||||
{
|
{
|
||||||
Vector2 fromPositionOffset = TileWorld.WorldToOffsetCoords(fromPositionWorld);
|
Vector2 fromPositionOffset = TileWorld.WorldToOffsetCoords(fromPositionWorld);
|
||||||
|
|
|
@ -11,11 +11,11 @@ public class Player : Entity, IInteractionInterface
|
||||||
{
|
{
|
||||||
// public members
|
// public members
|
||||||
[Export] public NodePath TileWorldNode;
|
[Export] public NodePath TileWorldNode;
|
||||||
|
|
||||||
public int GoldCount = 0;
|
public int GoldCount = 0;
|
||||||
|
|
||||||
public TaskQueueComponent TaskQueueComponent;
|
public TaskQueueComponent TaskQueueComponent;
|
||||||
|
|
||||||
public NavigationComponent Navigation
|
public NavigationComponent Navigation
|
||||||
{
|
{
|
||||||
get { return _navigationComponent; }
|
get { return _navigationComponent; }
|
||||||
|
@ -23,7 +23,7 @@ public class Player : Entity, IInteractionInterface
|
||||||
|
|
||||||
[Signal]
|
[Signal]
|
||||||
delegate void GoldCountChanged(int goldCount);
|
delegate void GoldCountChanged(int goldCount);
|
||||||
|
|
||||||
// private members
|
// private members
|
||||||
private WorldInfoComponent _worldInfo;
|
private WorldInfoComponent _worldInfo;
|
||||||
private GroundMotionComponent _groundMotion;
|
private GroundMotionComponent _groundMotion;
|
||||||
|
@ -36,6 +36,7 @@ public class Player : Entity, IInteractionInterface
|
||||||
private AnimationTree _animationTree;
|
private AnimationTree _animationTree;
|
||||||
private DebugGeometry _debugGeometry;
|
private DebugGeometry _debugGeometry;
|
||||||
private InteractionComponent _interactionComponent;
|
private InteractionComponent _interactionComponent;
|
||||||
|
|
||||||
public InteractionComponent InteractionComponent
|
public InteractionComponent InteractionComponent
|
||||||
{
|
{
|
||||||
get => _interactionComponent;
|
get => _interactionComponent;
|
||||||
|
@ -50,7 +51,7 @@ public class Player : Entity, IInteractionInterface
|
||||||
_navigationComponent = (NavigationComponent)FindNode("Navigation", false);
|
_navigationComponent = (NavigationComponent)FindNode("Navigation", false);
|
||||||
_navigationComponent.TileWorld = GetNode<TileWorld>(TileWorldNode);
|
_navigationComponent.TileWorld = GetNode<TileWorld>(TileWorldNode);
|
||||||
TaskQueueComponent = new TaskQueueComponent();
|
TaskQueueComponent = new TaskQueueComponent();
|
||||||
|
|
||||||
_itemAttractorArea = (Area)FindNode("ItemAttractorArea", false);
|
_itemAttractorArea = (Area)FindNode("ItemAttractorArea", false);
|
||||||
if (_itemAttractorArea == null)
|
if (_itemAttractorArea == null)
|
||||||
{
|
{
|
||||||
|
@ -61,7 +62,7 @@ public class Player : Entity, IInteractionInterface
|
||||||
_itemAttractorArea.Connect("body_entered", this, nameof(OnItemAttractorBodyEntered));
|
_itemAttractorArea.Connect("body_entered", this, nameof(OnItemAttractorBodyEntered));
|
||||||
_itemAttractorArea.Connect("body_exited", this, nameof(OnItemAttractorBodyExited));
|
_itemAttractorArea.Connect("body_exited", this, nameof(OnItemAttractorBodyExited));
|
||||||
}
|
}
|
||||||
|
|
||||||
_itemPickupArea = (Area)FindNode("ItemPickupArea", false);
|
_itemPickupArea = (Area)FindNode("ItemPickupArea", false);
|
||||||
if (_itemPickupArea == null)
|
if (_itemPickupArea == null)
|
||||||
{
|
{
|
||||||
|
@ -76,9 +77,10 @@ public class Player : Entity, IInteractionInterface
|
||||||
Debug.Assert(_playerAnimationPlayer != null);
|
Debug.Assert(_playerAnimationPlayer != null);
|
||||||
_animationTree = GetNode<AnimationTree>("Geometry/AnimationTree");
|
_animationTree = GetNode<AnimationTree>("Geometry/AnimationTree");
|
||||||
Debug.Assert(_animationTree != null);
|
Debug.Assert(_animationTree != null);
|
||||||
AnimationNodeStateMachinePlayback stateMachine = (AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
|
AnimationNodeStateMachinePlayback stateMachine =
|
||||||
|
(AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
|
||||||
stateMachine.Start("Idle");
|
stateMachine.Start("Idle");
|
||||||
|
|
||||||
_toolAttachement = (BoneAttachment)FindNode("ToolAttachement");
|
_toolAttachement = (BoneAttachment)FindNode("ToolAttachement");
|
||||||
if (_toolAttachement == null)
|
if (_toolAttachement == null)
|
||||||
{
|
{
|
||||||
|
@ -97,7 +99,7 @@ public class Player : Entity, IInteractionInterface
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TaskQueueComponent != null && TaskQueueComponent.Queue.Count > 0)
|
if (TaskQueueComponent != null && TaskQueueComponent.Queue.Count > 0)
|
||||||
{
|
{
|
||||||
TaskQueueComponent.Process(this, delta);
|
TaskQueueComponent.Process(this, delta);
|
||||||
|
@ -109,13 +111,15 @@ public class Player : Entity, IInteractionInterface
|
||||||
if (navigationTask != null && navigationTask.PlanningComplete == false)
|
if (navigationTask != null && navigationTask.PlanningComplete == false)
|
||||||
{
|
{
|
||||||
// _navigationComponent.PlanGridPath(this, GlobalTransform, navigationTask.NavigationPoint);
|
// _navigationComponent.PlanGridPath(this, GlobalTransform, navigationTask.NavigationPoint);
|
||||||
_navigationComponent.FindPath(this, GlobalTranslation, navigationTask.NavigationPoint.WorldPosition);
|
_navigationComponent.PlanSmoothedPath(this, GlobalTransform, navigationTask.NavigationPoint);
|
||||||
|
|
||||||
_navigationComponent.ActivatePlannedPath();
|
_navigationComponent.ActivatePlannedPath();
|
||||||
navigationTask.PlanningComplete = true;
|
navigationTask.PlanningComplete = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_navigationComponent.UpdateCurrentGoal(GlobalTransform);
|
_navigationComponent.UpdateCurrentGoal(GlobalTransform);
|
||||||
_groundMotion.PhysicsProcess(delta, this, _navigationComponent.CurrentGoalPositionWorld, _navigationComponent.CurrentGoalOrientationWorld, _worldInfo.TileWorld);
|
_groundMotion.PhysicsProcess(delta, this, _navigationComponent.CurrentGoalPositionWorld,
|
||||||
|
_navigationComponent.CurrentGoalOrientationWorld, _worldInfo.TileWorld);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,16 +131,16 @@ public class Player : Entity, IInteractionInterface
|
||||||
{
|
{
|
||||||
_navigationComponent.UpdateCurrentGoal(GlobalTransform);
|
_navigationComponent.UpdateCurrentGoal(GlobalTransform);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Node node in _attractedItemList)
|
foreach (Node node in _attractedItemList)
|
||||||
{
|
{
|
||||||
if (node is GoldBar)
|
if (node is GoldBar)
|
||||||
{
|
{
|
||||||
GoldBar bar = (GoldBar)node;
|
GoldBar bar = (GoldBar)node;
|
||||||
bar.SetTarget(GlobalTransform.origin);
|
bar.SetTarget(GlobalTransform.origin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateDebugGeometry();
|
UpdateDebugGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,16 +150,15 @@ public class Player : Entity, IInteractionInterface
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_debugGeometry.Clear();
|
_debugGeometry.Clear();
|
||||||
_debugGeometry.GlobalTransform = Transform.Identity;
|
_debugGeometry.GlobalTransform = Transform.Identity;
|
||||||
|
|
||||||
if (_navigationComponent != null)
|
if (_navigationComponent != null)
|
||||||
{
|
{
|
||||||
_navigationComponent.DebugDraw(this, _debugGeometry);
|
_navigationComponent.DebugDraw(this, _debugGeometry);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnItemAttractorBodyEntered(Node node)
|
public void OnItemAttractorBodyEntered(Node node)
|
||||||
|
@ -163,16 +166,17 @@ public class Player : Entity, IInteractionInterface
|
||||||
GD.Print("Item entered " + node);
|
GD.Print("Item entered " + node);
|
||||||
_attractedItemList.Add(node);
|
_attractedItemList.Add(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnItemAttractorBodyExited(Node node)
|
public void OnItemAttractorBodyExited(Node node)
|
||||||
{
|
{
|
||||||
GD.Print("Item exited " + node);
|
GD.Print("Item exited " + node);
|
||||||
|
|
||||||
if (node is GoldBar)
|
if (node is GoldBar)
|
||||||
{
|
{
|
||||||
GoldBar bar = (GoldBar)node;
|
GoldBar bar = (GoldBar)node;
|
||||||
bar.UnsetTarget();
|
bar.UnsetTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
_attractedItemList.Remove(node);
|
_attractedItemList.Remove(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +194,7 @@ public class Player : Entity, IInteractionInterface
|
||||||
GoldCount++;
|
GoldCount++;
|
||||||
EmitSignal("GoldCountChanged", GoldCount);
|
EmitSignal("GoldCountChanged", GoldCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
body.QueueFree();
|
body.QueueFree();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +204,8 @@ public class Player : Entity, IInteractionInterface
|
||||||
if (toolName == "Axe")
|
if (toolName == "Axe")
|
||||||
{
|
{
|
||||||
_toolAttachement.Visible = true;
|
_toolAttachement.Visible = true;
|
||||||
} else if (toolName == "")
|
}
|
||||||
|
else if (toolName == "")
|
||||||
{
|
{
|
||||||
_toolAttachement.Visible = false;
|
_toolAttachement.Visible = false;
|
||||||
}
|
}
|
||||||
|
@ -208,14 +213,16 @@ public class Player : Entity, IInteractionInterface
|
||||||
|
|
||||||
public void OnInteractionStart()
|
public void OnInteractionStart()
|
||||||
{
|
{
|
||||||
AnimationNodeStateMachinePlayback stateMachine = (AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
|
AnimationNodeStateMachinePlayback stateMachine =
|
||||||
|
(AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
|
||||||
Debug.Assert(stateMachine != null);
|
Debug.Assert(stateMachine != null);
|
||||||
|
|
||||||
if (_interactionComponent.TargetEntity is Chest)
|
if (_interactionComponent.TargetEntity is Chest)
|
||||||
{
|
{
|
||||||
GD.Print("Player Opening Box");
|
GD.Print("Player Opening Box");
|
||||||
stateMachine.Travel("Interaction");
|
stateMachine.Travel("Interaction");
|
||||||
} else if (_interactionComponent.TargetEntity is Tree)
|
}
|
||||||
|
else if (_interactionComponent.TargetEntity is Tree)
|
||||||
{
|
{
|
||||||
GD.Print("Player Chopping Tree");
|
GD.Print("Player Chopping Tree");
|
||||||
stateMachine.Travel("Hit");
|
stateMachine.Travel("Hit");
|
||||||
|
@ -223,9 +230,10 @@ public class Player : Entity, IInteractionInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnInteractionEnd()
|
public void OnInteractionEnd()
|
||||||
{
|
{
|
||||||
GD.Print("Player Stopping Interaction");
|
GD.Print("Player Stopping Interaction");
|
||||||
AnimationNodeStateMachinePlayback stateMachine = (AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
|
AnimationNodeStateMachinePlayback stateMachine =
|
||||||
|
(AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
|
||||||
Debug.Assert(stateMachine != null);
|
Debug.Assert(stateMachine != null);
|
||||||
stateMachine.Travel("Idle");
|
stateMachine.Travel("Idle");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue