NavigationComponent can handle position and orientation targets.
parent
14e5d47d91
commit
716654a6fd
32
Game.gd
32
Game.gd
|
@ -1,32 +0,0 @@
|
|||
extends Node2D
|
||||
|
||||
|
||||
onready var SimpleEntity = preload("res://entities/SimpleEntity.tscn")
|
||||
onready var WanderingEntity = preload("res://entities/WanderingEntity.tscn")
|
||||
onready var player_movable_target_label = $UI/PlayerMovableTarget
|
||||
onready var player = $PlayerEntity
|
||||
onready var entities = $Entities
|
||||
|
||||
signal world_location_clicked
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass
|
||||
|
||||
|
||||
func _process(delta):
|
||||
player_movable_target_label.text = str(player.movable_component.target)
|
||||
|
||||
|
||||
func _on_AddEntityButton_pressed():
|
||||
var entity_instance = SimpleEntity.instance()
|
||||
var viewport_rect = get_viewport_rect()
|
||||
entity_instance.transform.origin = Vector2(randf() * viewport_rect.size[0], randf() * viewport_rect.size[1])
|
||||
entities.add_child(entity_instance)
|
||||
|
||||
func _on_AddWanderingEntity_pressed():
|
||||
var entity_instance = WanderingEntity.instance()
|
||||
var viewport_rect = get_viewport_rect()
|
||||
entity_instance.transform.origin = Vector2(randf() * viewport_rect.size[0], randf() * viewport_rect.size[1])
|
||||
entities.add_child(entity_instance)
|
||||
entity_instance.set_target(Vector2(randf() * viewport_rect.size[0], randf() * viewport_rect.size[1]))
|
131
Game.tscn
131
Game.tscn
|
@ -1,131 +0,0 @@
|
|||
[gd_scene load_steps=10 format=2]
|
||||
|
||||
[ext_resource path="res://entities/SimpleEntity.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://entities/PlayerEntity.tscn" type="PackedScene" id=2]
|
||||
[ext_resource path="res://assets/white.png" type="Texture" id=3]
|
||||
[ext_resource path="res://materials/PhysicsObjects.tres" type="Material" id=4]
|
||||
[ext_resource path="res://utils/CollisionLine.gd" type="Script" id=5]
|
||||
[ext_resource path="res://Game.gd" type="Script" id=6]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id=1]
|
||||
extents = Vector2( 57.5347, 51.5794 )
|
||||
|
||||
[sub_resource type="RectangleShape2D" id=2]
|
||||
|
||||
[sub_resource type="SegmentShape2D" id=3]
|
||||
a = Vector2( 37, 302 )
|
||||
b = Vector2( 34, 570 )
|
||||
|
||||
[node name="Game" type="Node2D"]
|
||||
script = ExtResource( 6 )
|
||||
|
||||
[node name="Control" type="HBoxContainer" parent="."]
|
||||
margin_left = 30.0
|
||||
margin_top = 30.0
|
||||
margin_right = 40.0
|
||||
margin_bottom = 40.0
|
||||
|
||||
[node name="AddEntityButton" type="Button" parent="Control"]
|
||||
margin_right = 77.0
|
||||
margin_bottom = 20.0
|
||||
text = "Add Entity"
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="AddWanderingEntity" type="Button" parent="Control"]
|
||||
margin_left = 81.0
|
||||
margin_right = 190.0
|
||||
margin_bottom = 20.0
|
||||
text = "Add Wandering"
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="Entities" type="Node2D" parent="."]
|
||||
|
||||
[node name="SimpleEntity" parent="Entities" instance=ExtResource( 1 )]
|
||||
position = Vector2( 360, 118 )
|
||||
|
||||
[node name="SimpleEntity2" parent="Entities" instance=ExtResource( 1 )]
|
||||
position = Vector2( 157, 306 )
|
||||
|
||||
[node name="PlayerEntity" parent="." instance=ExtResource( 2 )]
|
||||
|
||||
[node name="World" type="Node2D" parent="."]
|
||||
|
||||
[node name="Wall" type="KinematicBody2D" parent="World"]
|
||||
position = Vector2( 582, 817 )
|
||||
scale = Vector2( 7.56, 1 )
|
||||
__meta__ = {
|
||||
"_edit_group_": true
|
||||
}
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="World/Wall"]
|
||||
material = ExtResource( 4 )
|
||||
position = Vector2( 0.965286, 0.579379 )
|
||||
scale = Vector2( 115, 104 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="World/Wall"]
|
||||
position = Vector2( 0.465286, 0.57938 )
|
||||
z_as_relative = false
|
||||
shape = SubResource( 1 )
|
||||
|
||||
[node name="RigidBody2D" type="RigidBody2D" parent="World"]
|
||||
position = Vector2( 649, 227 )
|
||||
__meta__ = {
|
||||
"_edit_group_": true
|
||||
}
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="World/RigidBody2D"]
|
||||
rotation = -0.432491
|
||||
scale = Vector2( 11.5039, 4.3795 )
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="World/RigidBody2D/CollisionShape2D"]
|
||||
material = ExtResource( 4 )
|
||||
use_parent_material = true
|
||||
scale = Vector2( 20.002, 19.4893 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="Wall2" type="KinematicBody2D" parent="World"]
|
||||
position = Vector2( 896, 386 )
|
||||
scale = Vector2( 7.56, 1 )
|
||||
__meta__ = {
|
||||
"_edit_group_": true
|
||||
}
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="World/Wall2"]
|
||||
material = ExtResource( 4 )
|
||||
position = Vector2( 0.965286, 0.579379 )
|
||||
scale = Vector2( 115, 104 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="World/Wall2"]
|
||||
position = Vector2( 0.465286, 0.57938 )
|
||||
z_as_relative = false
|
||||
shape = SubResource( 1 )
|
||||
|
||||
[node name="CollisionLine" type="KinematicBody2D" parent="World"]
|
||||
position = Vector2( 221, 205 )
|
||||
script = ExtResource( 5 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="World/CollisionLine"]
|
||||
shape = SubResource( 3 )
|
||||
|
||||
[node name="UI" type="CanvasLayer" parent="."]
|
||||
|
||||
[node name="PlayerMovableTarget" type="Label" parent="UI"]
|
||||
margin_right = 40.0
|
||||
margin_bottom = 14.0
|
||||
text = "Blaaa"
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[connection signal="pressed" from="Control/AddEntityButton" to="." method="_on_AddEntityButton_pressed"]
|
||||
[connection signal="pressed" from="Control/AddWanderingEntity" to="." method="_on_AddWanderingEntity_pressed"]
|
||||
|
||||
[editable path="Entities/SimpleEntity"]
|
||||
[editable path="Entities/SimpleEntity2"]
|
|
@ -1,5 +1,9 @@
|
|||
using System;
|
||||
|
||||
public static class Globals
|
||||
{
|
||||
public const float EpsPosition = 0.01f;
|
||||
public const float EpsPositionSquared = 0.01f * 0.01f;
|
||||
public const float EpsPositionSquared = EpsPosition * EpsPosition;
|
||||
public const float EpsRadians = 0.1f * Godot.Mathf.Pi / 180f;
|
||||
public const float EpsRadiansSquared = EpsRadians * EpsRadians;
|
||||
}
|
|
@ -13,4 +13,8 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Chickensoft.GoDotTest" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="LocalSystems" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
using Godot;
|
||||
|
||||
public class Component : Node
|
||||
{
|
||||
|
||||
}
|
|
@ -6,12 +6,14 @@ using Vector3 = Godot.Vector3;
|
|||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public class GroundMotionComponent
|
||||
public class GroundMotionComponent : Component
|
||||
{
|
||||
public float Accel = 50;
|
||||
public float Damping = 0.2f;
|
||||
public float MaxSpeed = 8;
|
||||
|
||||
public float RotationSpeedRadPerSecond = 270 * Mathf.Pi / 180;
|
||||
|
||||
|
||||
private void CalcPlaneVelocity(float delta, Entity entity, Vector3 targetPosition)
|
||||
{
|
||||
|
@ -19,13 +21,14 @@ public class GroundMotionComponent
|
|||
targetPosition.z - entity.GlobalTranslation.z);
|
||||
float targetDistance = planeTargetVector.Length();
|
||||
Vector2 planeTargetDirection = planeTargetVector / targetDistance;
|
||||
Vector2 planeOrientation = new Vector2(entity.GlobalTransform.basis.z[0], entity.GlobalTransform.basis.z[2]);
|
||||
|
||||
Vector2 planeVelocity = new Vector2(entity.Velocity.x, entity.Velocity.z);
|
||||
// GD.Print("-- Step: distance: " + targetDistance + " dir: " + planeTargetDirection + " speed: " + planeVelocity.Length() + " vel dir: " + planeVelocity.Normalized());
|
||||
planeVelocity -= planeVelocity * Damping;
|
||||
// GD.Print(" damp : speed: " + planeVelocity.Length() + " vel dir: " + planeVelocity.Normalized());
|
||||
|
||||
if (targetDistance < 0.01)
|
||||
if (targetDistance < 0.01 || planeOrientation.Dot(planeTargetDirection) < 0.9)
|
||||
{
|
||||
planeVelocity = Vector2.Zero;
|
||||
} else {
|
||||
|
@ -79,15 +82,46 @@ public class GroundMotionComponent
|
|||
}
|
||||
|
||||
|
||||
public void PhysicsProcess(float delta, Entity entity, Vector3 targetPosition, TileWorld tileWorld)
|
||||
public void PhysicsProcess(float delta, Entity entity, Vector3 targetPosition, Quat targetOrientation, TileWorld tileWorld)
|
||||
{
|
||||
CalcAndApplyOrientation(delta, entity, targetPosition, targetOrientation);
|
||||
CalcPlaneVelocity(delta, entity, targetPosition);
|
||||
|
||||
CalcVerticalVelocity(delta, entity, tileWorld);
|
||||
|
||||
Vector3 prePhysicsVelocity = entity.Velocity;
|
||||
entity.Velocity = entity.MoveAndSlide(entity.Velocity);
|
||||
|
||||
//GD.Print("Pre : speed: " + prePhysicsVelocity.Length() + " Velocity: " + prePhysicsVelocity);
|
||||
//GD.Print("Post: speed: " + entity.Velocity.Length() + " Velocity: " + entity.Velocity);
|
||||
}
|
||||
|
||||
private void CalcAndApplyOrientation(float delta, Entity entity, Vector3 targetPosition, Quat targetOrientation)
|
||||
{
|
||||
Vector3 direction_to_target = targetPosition - entity.GlobalTranslation;
|
||||
|
||||
if (direction_to_target.LengthSquared() > Globals.EpsPositionSquared)
|
||||
{
|
||||
direction_to_target = direction_to_target.Normalized();
|
||||
Vector3 localXAxis = Vector3.Up.Cross(direction_to_target);
|
||||
targetOrientation = new Basis(localXAxis, Vector3.Up, direction_to_target).Quat().Normalized();
|
||||
}
|
||||
|
||||
float orientationErrorRadians = entity.GlobalTransform.basis.Quat().AngleTo(targetOrientation);
|
||||
if (orientationErrorRadians > 0)
|
||||
{
|
||||
Transform entityTransform = entity.Transform;
|
||||
if (orientationErrorRadians < RotationSpeedRadPerSecond * delta)
|
||||
{
|
||||
entityTransform.basis = new Basis(targetOrientation);
|
||||
}
|
||||
else if (orientationErrorRadians > 0f)
|
||||
{
|
||||
Quat entityRotation = new Quat(entityTransform.basis);
|
||||
float slerpWeight = RotationSpeedRadPerSecond / (orientationErrorRadians / delta);
|
||||
entityRotation = entityRotation.Slerp(targetOrientation, slerpWeight);
|
||||
entityTransform.basis = new Basis(entityRotation);
|
||||
}
|
||||
|
||||
entity.Transform = entityTransform;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
using Godot;
|
||||
using System;
|
||||
|
||||
public class MovableComponent : Node
|
||||
public class MovableComponent : Component
|
||||
{
|
||||
public Vector3 targetPosition = Vector3.Zero;
|
||||
public Vector3 currentPosition = Vector3.Zero;
|
||||
|
@ -58,7 +58,7 @@ public class MovableComponent : Node
|
|||
currentAngle = springDamperResult.Item1;
|
||||
currentAngularVelocity = springDamperResult.Item2;
|
||||
|
||||
EmitSignal("OrientationUpdated", this.currentAngle);
|
||||
// EmitSignal("OrientationUpdated", this.currentAngle);
|
||||
}
|
||||
|
||||
if ((Mathf.Abs(currentAngularVelocity) < 5 && Mathf.Abs(targetAngle - currentAngle) < 0.3)
|
||||
|
|
|
@ -12,22 +12,48 @@ using GoDotLog;
|
|||
/// </summary>
|
||||
public class NavigationComponent : Node
|
||||
{
|
||||
public class NavigationPoint
|
||||
{
|
||||
[Flags]
|
||||
public enum NavigationFlags
|
||||
{
|
||||
Position = 1,
|
||||
Orientation = 2
|
||||
}
|
||||
|
||||
public Vector3 WorldPosition = Vector3.Zero;
|
||||
public Quat WorldOrientation = Quat.Identity;
|
||||
public NavigationFlags Flags = NavigationFlags.Position | NavigationFlags.Orientation;
|
||||
|
||||
public NavigationPoint(Vector3 worldPosition)
|
||||
{
|
||||
WorldPosition = worldPosition;
|
||||
Flags = NavigationFlags.Position;
|
||||
}
|
||||
|
||||
public NavigationPoint(Quat worldOrientation)
|
||||
{
|
||||
WorldOrientation = worldOrientation;
|
||||
Flags = NavigationFlags.Orientation;
|
||||
}
|
||||
}
|
||||
|
||||
public TileWorld TileWorld { set; get; }
|
||||
|
||||
public Vector3 CurrentGoalWorld => _currentGoalWorld;
|
||||
public Vector3 CurrentGoalPositionWorld => _currentGoalPositionWorld;
|
||||
public Quat CurrentGoalOrientationWorld => _currentGoalOrientationWorld;
|
||||
|
||||
private Vector3 _currentGoalWorld = Vector3.Zero;
|
||||
private Vector2 _currentGoalPlane = Vector2.Zero;
|
||||
private Vector2 _currentGoalOffset = Vector2.Zero;
|
||||
private Vector3 _currentPositionWorld = Vector3.Zero;
|
||||
private NavigationPoint _currentGoal;
|
||||
private Vector3 _currentGoalPositionWorld = Vector3.Zero;
|
||||
private Quat _currentGoalOrientationWorld = Quat.Identity;
|
||||
|
||||
private List<Vector2> _pathOffsetCoords;
|
||||
private List<NavigationPoint> _pathWorldNavigationPoints;
|
||||
private HexCell[] _path;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
base._Ready();
|
||||
_pathOffsetCoords = new List<Vector2>();
|
||||
_pathWorldNavigationPoints = new List<NavigationPoint>();
|
||||
}
|
||||
|
||||
public override void _Process(float delta)
|
||||
|
@ -50,39 +76,103 @@ public class NavigationComponent : Node
|
|||
_path = fromCell.LineTo(toCell);
|
||||
Debug.Assert(_path.Length > 0);
|
||||
|
||||
_pathOffsetCoords = new List<Vector2>();
|
||||
_pathWorldNavigationPoints = new List<NavigationPoint>();
|
||||
foreach (int index in Enumerable.Range(1, _path.Length - 1))
|
||||
{
|
||||
_pathOffsetCoords.Add(_path[index].OffsetCoords);
|
||||
_pathWorldNavigationPoints.Add(
|
||||
new NavigationPoint(TileWorld.GetTileWorldCenterFromOffset(_path[index].OffsetCoords)));
|
||||
}
|
||||
|
||||
if ((toPositionWorld - TileWorld.GetTileWorldCenterFromOffset(toCell.OffsetCoords)).LengthSquared() >
|
||||
Globals.EpsPositionSquared)
|
||||
{
|
||||
_pathWorldNavigationPoints.Add(new NavigationPoint(toPositionWorld));
|
||||
}
|
||||
|
||||
UpdateCurrentGoal();
|
||||
}
|
||||
|
||||
|
||||
public void Plan(Vector3 fromPositionWorld, Vector3 toPositionWorld, Quat toWorldOrientation)
|
||||
{
|
||||
Plan(fromPositionWorld, toPositionWorld);
|
||||
|
||||
_pathWorldNavigationPoints.Add(new NavigationPoint(toWorldOrientation));
|
||||
}
|
||||
|
||||
|
||||
private void UpdateCurrentGoal()
|
||||
{
|
||||
if (_pathOffsetCoords.Count == 0)
|
||||
if (_pathWorldNavigationPoints.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_currentGoalWorld = TileWorld.GetTileWorldCenterFromOffset(_pathOffsetCoords[0]);
|
||||
_currentGoal = _pathWorldNavigationPoints[0];
|
||||
|
||||
GD.Print("Navigation: at " + _currentGoalWorld + " path length: " +
|
||||
_pathOffsetCoords.Count);
|
||||
GD.Print("Navigation Goal: pos " + _currentGoal.WorldPosition + " " + " rot: " + _currentGoal.WorldOrientation +
|
||||
" flags: " + _currentGoal.Flags + " path length: " +
|
||||
_pathWorldNavigationPoints.Count);
|
||||
}
|
||||
|
||||
|
||||
public void UpdateCurrentGoal(Vector3 currentPositionWorld)
|
||||
public void UpdateCurrentGoal(Transform currentTransformWorld)
|
||||
{
|
||||
_currentPositionWorld = currentPositionWorld;
|
||||
if (_pathWorldNavigationPoints.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currentGoal.Flags.HasFlag(NavigationPoint.NavigationFlags.Position))
|
||||
{
|
||||
_currentGoalPositionWorld = _pathWorldNavigationPoints[0].WorldPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentGoalPositionWorld = currentTransformWorld.origin;
|
||||
}
|
||||
|
||||
if (_currentGoal.Flags.HasFlag(NavigationPoint.NavigationFlags.Orientation))
|
||||
{
|
||||
_currentGoalOrientationWorld = _currentGoal.WorldOrientation;
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentGoalOrientationWorld = currentTransformWorld.basis.Quat();
|
||||
}
|
||||
|
||||
Vector3 currentPositionWorld = currentTransformWorld.origin;
|
||||
Quat currentOrientationWorld = currentTransformWorld.basis.Quat();
|
||||
|
||||
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)
|
||||
Vector2 currentGoalPlane = new Vector2(_currentGoal.WorldPosition.x, _currentGoal.WorldPosition.z);
|
||||
|
||||
bool goalReached = false;
|
||||
float positionErrorSquared = (currentPositionPlane - currentGoalPlane).LengthSquared();
|
||||
float orientationError = _currentGoalOrientationWorld.AngleTo(currentOrientationWorld);
|
||||
|
||||
if (_currentGoal.Flags.HasFlag(NavigationPoint.NavigationFlags.Position)
|
||||
&& _currentGoal.Flags.HasFlag(NavigationPoint.NavigationFlags.Orientation)
|
||||
&& positionErrorSquared < Globals.EpsPositionSquared
|
||||
&& orientationError < Globals.EpsRadians)
|
||||
{
|
||||
_pathOffsetCoords.RemoveAt(0);
|
||||
goalReached = true;
|
||||
}
|
||||
else if (_currentGoal.Flags.HasFlag(NavigationPoint.NavigationFlags.Position) &&
|
||||
positionErrorSquared < Globals.EpsPositionSquared)
|
||||
{
|
||||
goalReached = true;
|
||||
}
|
||||
else if (_currentGoal.Flags.HasFlag(NavigationPoint.NavigationFlags.Orientation) &&
|
||||
orientationError < Globals.EpsRadians)
|
||||
|
||||
{
|
||||
goalReached = true;
|
||||
}
|
||||
|
||||
if (goalReached)
|
||||
{
|
||||
_pathWorldNavigationPoints.RemoveAt(0);
|
||||
UpdateCurrentGoal();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
using Godot;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
public class TaskQueueComponent : Component
|
||||
{
|
||||
public class Task
|
||||
{
|
||||
}
|
||||
|
||||
public class NavigationTask : Task
|
||||
{
|
||||
[Flags] public enum Flags
|
||||
{
|
||||
Position = 1,
|
||||
Orientation = 2
|
||||
}
|
||||
|
||||
public Vector3 TargetPositionWorld = Vector3.Zero;
|
||||
public Quat TargetOrientationWorld = Quat.Identity;
|
||||
public Flags NavigationFlags = Flags.Position | Flags.Orientation;
|
||||
}
|
||||
|
||||
public class InteractionTask : Task
|
||||
{
|
||||
public Entity TargetEntity;
|
||||
}
|
||||
|
||||
public Queue<Task> Queue;
|
||||
|
||||
public TaskQueueComponent()
|
||||
{
|
||||
Queue = new Queue<Task>();
|
||||
Reset();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Queue.Clear();
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
using Godot;
|
||||
using System;
|
||||
|
||||
public class WorldInfoComponent : Node
|
||||
public class WorldInfoComponent : Component
|
||||
{
|
||||
[Export] public NodePath World;
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
@startuml
|
||||
'https://plantuml.com/class-diagram
|
||||
|
||||
class Entity
|
||||
Entity *-- Component
|
||||
|
||||
Entity : update()
|
||||
Entity : Component[] mComponents
|
||||
Entity : LocalSystem[] mSystems;
|
||||
|
||||
class Component3 {
|
||||
void update()
|
||||
int counter
|
||||
}
|
||||
note right of Entity::update
|
||||
lel
|
||||
end note
|
||||
|
||||
@enduml
|
|
@ -51,9 +51,4 @@ public class Chest : Entity
|
|||
IsMouseOver = false;
|
||||
_mesh.MaterialOverride = null;
|
||||
}
|
||||
// // Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
// public override void _Process(float delta)
|
||||
// {
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://assets/Objects/chest.glb" type="PackedScene" id=1]
|
||||
[ext_resource path="res://entities/Chest.cs" type="Script" id=2]
|
||||
|
||||
[node name="Chest" instance=ExtResource( 1 )]
|
||||
script = ExtResource( 2 )
|
||||
|
||||
[node name="Armature" parent="." index="2"]
|
||||
transform = Transform( -0.259808, 0, 0.15, 0, 0.3, 0, -0.15, 0, -0.259808, 0, 0, 0 )
|
|
@ -0,0 +1,33 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
namespace GodotComponentTest.entities;
|
||||
|
||||
public class Flower : Entity
|
||||
{
|
||||
public override void _Ready()
|
||||
{
|
||||
Array<Node> children = new Array<Node>();
|
||||
GetAllChildren(this, ref children);
|
||||
|
||||
foreach (Node child in children)
|
||||
{
|
||||
if (child is ClickableComponent)
|
||||
{
|
||||
GD.Print("Found Clickable Component!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GetAllChildren(Node childNode, ref Array<Node> childList)
|
||||
{
|
||||
var children = childNode.GetChildren();
|
||||
foreach (Node child in children)
|
||||
{
|
||||
childList.Add(child);
|
||||
GetAllChildren(child, ref childList);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,8 @@ public class Player : Entity
|
|||
// public members
|
||||
public Vector3 TargetPosition = Vector3.Zero;
|
||||
|
||||
public TaskQueueComponent TaskQueueComponent;
|
||||
|
||||
public NavigationComponent Navigation
|
||||
{
|
||||
get { return _navigationComponent; }
|
||||
|
@ -15,7 +17,6 @@ public class Player : Entity
|
|||
private MovableComponent _movable;
|
||||
private Spatial _geometry;
|
||||
private WorldInfoComponent _worldInfo;
|
||||
private Vector2 _offsetCoord = Vector2.Zero;
|
||||
private GroundMotionComponent _groundMotion;
|
||||
private NavigationComponent _navigationComponent;
|
||||
|
||||
|
@ -26,6 +27,7 @@ public class Player : Entity
|
|||
_worldInfo = (WorldInfoComponent)FindNode("WorldInfo", false);
|
||||
_navigationComponent = (NavigationComponent)FindNode("Navigation", false);
|
||||
_navigationComponent.TileWorld = _worldInfo.TileWorld;
|
||||
TaskQueueComponent = new TaskQueueComponent();
|
||||
|
||||
_movable = (MovableComponent)FindNode("Movable", false);
|
||||
if (_movable != null)
|
||||
|
@ -46,9 +48,18 @@ public class Player : Entity
|
|||
return;
|
||||
}
|
||||
|
||||
_navigationComponent.UpdateCurrentGoal(GlobalTranslation);
|
||||
if (TaskQueueComponent != null && TaskQueueComponent.Queue.Count > 0)
|
||||
{
|
||||
var currentTask = TaskQueueComponent.Queue.Peek();
|
||||
if (currentTask is TaskQueueComponent.NavigationTask)
|
||||
{
|
||||
TaskQueueComponent.NavigationTask navigationTask = (TaskQueueComponent.NavigationTask)TaskQueueComponent.Queue.Dequeue();
|
||||
|
||||
_groundMotion.PhysicsProcess(delta, this, _navigationComponent.CurrentGoalWorld, _worldInfo.TileWorld);
|
||||
}
|
||||
}
|
||||
|
||||
_navigationComponent.UpdateCurrentGoal(GlobalTransform);
|
||||
_groundMotion.PhysicsProcess(delta, this, _navigationComponent.CurrentGoalPositionWorld, _navigationComponent.CurrentGoalOrientationWorld, _worldInfo.TileWorld);
|
||||
}
|
||||
|
||||
|
||||
|
@ -56,11 +67,12 @@ public class Player : Entity
|
|||
{
|
||||
if (_navigationComponent != null)
|
||||
{
|
||||
_navigationComponent.UpdateCurrentGoal(GlobalTranslation);
|
||||
}
|
||||
_navigationComponent.UpdateCurrentGoal(GlobalTransform);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void OnOrientationUpdated(float newOrientation)
|
||||
{
|
||||
_geometry.Transform = new Transform(new Quat(Vector3.Up, newOrientation), Vector3.Zero);
|
||||
|
|
|
@ -75,7 +75,7 @@ _global_script_class_icons={
|
|||
[application]
|
||||
|
||||
config/name="i3sc1 GodotComponentTest"
|
||||
run/main_scene="res://scenes/AdaptiveWorldStream.tscn"
|
||||
run/main_scene="res://scenes/Game.tscn"
|
||||
config/icon="res://icon.png"
|
||||
|
||||
[display]
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
[gd_scene load_steps=27 format=2]
|
||||
[gd_scene load_steps=26 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]
|
||||
[ext_resource path="res://components/WorldInfoComponent.cs" type="Script" id=3]
|
||||
[ext_resource path="res://scenes/StreamContainer.cs" type="Script" id=4]
|
||||
|
@ -104,7 +103,6 @@ tracks/1/keys = PoolRealArray( 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0.133333, 1,
|
|||
extents = Vector3( 0.2, 0.2, 0.332224 )
|
||||
|
||||
[node name="AdaptiveWorldStream" type="Spatial"]
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="TileHighlight" parent="." instance=ExtResource( 7 )]
|
||||
visible = false
|
||||
|
|
|
@ -6,7 +6,7 @@ using GoDotLog;
|
|||
using Dictionary = Godot.Collections.Dictionary;
|
||||
using Array = Godot.Collections.Array;
|
||||
|
||||
public class AdaptiveWorldStream : Spatial
|
||||
public class Game : Spatial
|
||||
{
|
||||
// ui elements
|
||||
private Label _framesPerSecondLabel;
|
||||
|
@ -59,7 +59,7 @@ public class AdaptiveWorldStream : Spatial
|
|||
_streamContainerArea = GetNode<Area>("StreamContainer/Area");
|
||||
_streamContainerActiveTiles = GetNode<Spatial>("StreamContainer/ActiveTiles");
|
||||
_player = GetNode<Player>("Player");
|
||||
_chest = GetNode<Chest>("Chest");
|
||||
_chest = GetNode<Chest>("Entities/Chest");
|
||||
_tileWorld = GetNode<TileWorld>("TileWorld");
|
||||
|
||||
Debug.Assert(_tileWorld != null);
|
||||
|
@ -193,6 +193,13 @@ public class AdaptiveWorldStream : Spatial
|
|||
public void OnEntityClicked(Entity entity)
|
||||
{
|
||||
GD.Print("Clicked on entity at " + entity.GlobalTranslation);
|
||||
|
||||
Spatial mountPoint = (Spatial)entity.FindNode("MountPoint");
|
||||
if (mountPoint != null)
|
||||
{
|
||||
GD.Print("Mount point!");
|
||||
_player.Navigation.Plan(_player.GlobalTranslation, mountPoint.GlobalTranslation, mountPoint.GlobalTransform.basis.Quat());
|
||||
}
|
||||
}
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,12 @@
|
|||
public class LookupWorldSystem : IWorldSystemInterface
|
||||
{
|
||||
public void RegisterEntityComponent(Entity entity, Component component)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void Update(float delta)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
public interface IWorldSystemInterface
|
||||
{
|
||||
void RegisterEntityComponent(Entity entity, Component component);
|
||||
void Update(float delta);
|
||||
}
|
Loading…
Reference in New Issue