Compare commits

...

7 Commits

Author SHA1 Message Date
Martin Felis 39f20c8e01 Some improvements with path smoothing and interactions. 2023-08-28 18:22:28 +02:00
Martin Felis d61ef6ba45 Prepared UnitTest for StreamContainer. 2023-08-28 14:48:54 +02:00
Martin Felis 53b1f7f414 Use instancing for HexTile3D rendering. 2023-08-28 14:03:02 +02:00
Martin Felis 36306b9e01 Some editor changes... 2023-08-28 14:01:23 +02:00
Martin Felis 64e7db9800 Formatting of Game.cs. 2023-08-28 14:01:09 +02:00
Martin Felis 76a7abf22f Minor cleanup in HexTile3D. 2023-08-28 13:59:39 +02:00
Martin Felis 136de4e246 Tweaked export presets. 2023-08-28 13:58:40 +02:00
11 changed files with 220 additions and 118 deletions

View File

@ -98,6 +98,23 @@ public class NavigationComponent : Spatial
{
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)
{
@ -124,26 +141,34 @@ public class NavigationComponent : Spatial
}
List<HexCell> path = TileWorld.HexGrid.FindPath(fromCell, toCell);
// GD.Print("Planning path and have " + TileWorld.HexGrid.Obstacles.Count + " obstacles:");
// GD.Print(TileWorld.HexGrid.Obstacles);
// foreach (Vector2 coord in TileWorld.HexGrid.Obstacles.Keys)
// {
// HexCell cell = new HexCell(coord);
// GD.Print(" " + cell.OffsetCoords);
// }
// Generate grid navigation points
_planningPathWorldNavigationPoints = new List<NavigationPoint>();
foreach (int index in Enumerable.Range(0, path.Count))
{
// GD.Print("Step " + index + ": " + path[index].OffsetCoords);
_planningPathWorldNavigationPoints.Add(
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);
}
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)
{
Vector2 fromPositionOffset = TileWorld.WorldToOffsetCoords(fromPositionWorld);

View File

@ -11,11 +11,11 @@ public class Player : Entity, IInteractionInterface
{
// public members
[Export] public NodePath TileWorldNode;
public int GoldCount = 0;
public TaskQueueComponent TaskQueueComponent;
public NavigationComponent Navigation
{
get { return _navigationComponent; }
@ -23,7 +23,7 @@ public class Player : Entity, IInteractionInterface
[Signal]
delegate void GoldCountChanged(int goldCount);
// private members
private WorldInfoComponent _worldInfo;
private GroundMotionComponent _groundMotion;
@ -36,6 +36,7 @@ public class Player : Entity, IInteractionInterface
private AnimationTree _animationTree;
private DebugGeometry _debugGeometry;
private InteractionComponent _interactionComponent;
public InteractionComponent InteractionComponent
{
get => _interactionComponent;
@ -50,7 +51,7 @@ public class Player : Entity, IInteractionInterface
_navigationComponent = (NavigationComponent)FindNode("Navigation", false);
_navigationComponent.TileWorld = GetNode<TileWorld>(TileWorldNode);
TaskQueueComponent = new TaskQueueComponent();
_itemAttractorArea = (Area)FindNode("ItemAttractorArea", false);
if (_itemAttractorArea == null)
{
@ -61,7 +62,7 @@ public class Player : Entity, IInteractionInterface
_itemAttractorArea.Connect("body_entered", this, nameof(OnItemAttractorBodyEntered));
_itemAttractorArea.Connect("body_exited", this, nameof(OnItemAttractorBodyExited));
}
_itemPickupArea = (Area)FindNode("ItemPickupArea", false);
if (_itemPickupArea == null)
{
@ -76,9 +77,10 @@ public class Player : Entity, IInteractionInterface
Debug.Assert(_playerAnimationPlayer != null);
_animationTree = GetNode<AnimationTree>("Geometry/AnimationTree");
Debug.Assert(_animationTree != null);
AnimationNodeStateMachinePlayback stateMachine = (AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
AnimationNodeStateMachinePlayback stateMachine =
(AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
stateMachine.Start("Idle");
_toolAttachement = (BoneAttachment)FindNode("ToolAttachement");
if (_toolAttachement == null)
{
@ -97,7 +99,7 @@ public class Player : Entity, IInteractionInterface
{
return;
}
if (TaskQueueComponent != null && TaskQueueComponent.Queue.Count > 0)
{
TaskQueueComponent.Process(this, delta);
@ -109,13 +111,15 @@ public class Player : Entity, IInteractionInterface
if (navigationTask != null && navigationTask.PlanningComplete == false)
{
// _navigationComponent.PlanGridPath(this, GlobalTransform, navigationTask.NavigationPoint);
_navigationComponent.FindPath(this, GlobalTranslation, navigationTask.NavigationPoint.WorldPosition);
_navigationComponent.PlanSmoothedPath(this, GlobalTransform, navigationTask.NavigationPoint);
_navigationComponent.ActivatePlannedPath();
navigationTask.PlanningComplete = true;
}
_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);
}
foreach (Node node in _attractedItemList)
{
if (node is GoldBar)
{
GoldBar bar = (GoldBar)node;
GoldBar bar = (GoldBar)node;
bar.SetTarget(GlobalTransform.origin);
}
}
UpdateDebugGeometry();
}
@ -146,16 +150,15 @@ public class Player : Entity, IInteractionInterface
{
return;
}
_debugGeometry.Clear();
_debugGeometry.GlobalTransform = Transform.Identity;
if (_navigationComponent != null)
{
_navigationComponent.DebugDraw(this, _debugGeometry);
return;
}
}
public void OnItemAttractorBodyEntered(Node node)
@ -163,16 +166,17 @@ public class Player : Entity, IInteractionInterface
GD.Print("Item entered " + node);
_attractedItemList.Add(node);
}
public void OnItemAttractorBodyExited(Node node)
{
GD.Print("Item exited " + node);
if (node is GoldBar)
if (node is GoldBar)
{
GoldBar bar = (GoldBar)node;
bar.UnsetTarget();
}
_attractedItemList.Remove(node);
}
@ -190,7 +194,7 @@ public class Player : Entity, IInteractionInterface
GoldCount++;
EmitSignal("GoldCountChanged", GoldCount);
}
body.QueueFree();
}
@ -200,7 +204,8 @@ public class Player : Entity, IInteractionInterface
if (toolName == "Axe")
{
_toolAttachement.Visible = true;
} else if (toolName == "")
}
else if (toolName == "")
{
_toolAttachement.Visible = false;
}
@ -208,14 +213,16 @@ public class Player : Entity, IInteractionInterface
public void OnInteractionStart()
{
AnimationNodeStateMachinePlayback stateMachine = (AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
AnimationNodeStateMachinePlayback stateMachine =
(AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
Debug.Assert(stateMachine != null);
if (_interactionComponent.TargetEntity is Chest)
{
GD.Print("Player Opening Box");
stateMachine.Travel("Interaction");
} else if (_interactionComponent.TargetEntity is Tree)
}
else if (_interactionComponent.TargetEntity is Tree)
{
GD.Print("Player Chopping Tree");
stateMachine.Travel("Hit");
@ -223,9 +230,10 @@ public class Player : Entity, IInteractionInterface
}
public void OnInteractionEnd()
{
{
GD.Print("Player Stopping Interaction");
AnimationNodeStateMachinePlayback stateMachine = (AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
AnimationNodeStateMachinePlayback stateMachine =
(AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
Debug.Assert(stateMachine != null);
stateMachine.Travel("Idle");
}

View File

@ -1,13 +1,13 @@
[preset.0]
name="JeremiasPirateGame"
name="PirateGame3D"
platform="Android"
runnable=true
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="export/android/JeremiasPirateGame.apk"
export_path="export/PirateGame3D.apk"
script_export_mode=1
script_encryption_key=""
@ -23,12 +23,12 @@ architectures/armeabi-v7a=true
architectures/arm64-v8a=true
architectures/x86=false
architectures/x86_64=false
keystore/debug=""
keystore/debug_user=""
keystore/debug_password=""
keystore/release="/home/martin/love-android.keystore"
keystore/release_user="love-android"
keystore/release_password="Ae$phoi2la"
keystore/debug="/home/martin/projects/GodotComponentTest/android/keystore/debug.keystore"
keystore/debug_user="androiddebugkey"
keystore/debug_password="android"
keystore/release="/home/martin/projects/GodotComponentTest/android/keystore/debug.keystore"
keystore/release_user="androiddebugkey"
keystore/release_password="android"
one_click_deploy/clear_previous_install=true
version/code=1
version/name="1.0"
@ -206,7 +206,7 @@ permissions/write_user_dictionary=false
[preset.1]
name="JeremiasPirateGame"
name="PirateGame3D"
platform="HTML5"
runnable=true
custom_features=""

View File

@ -9,17 +9,17 @@
config_version=4
_global_script_classes=[ {
"base": "Reference",
"base": "Node",
"class": "ClickableComponent",
"language": "GDScript",
"path": "res://components/ClickableComponent.gd"
}, {
"base": "Reference",
"base": "KinematicBody2D",
"class": "CollisionLine",
"language": "GDScript",
"path": "res://utils/CollisionLine.gd"
}, {
"base": "Reference",
"base": "Node",
"class": "ColorComponent",
"language": "GDScript",
"path": "res://components/ColorComponent.gd"
@ -54,7 +54,7 @@ _global_script_classes=[ {
"language": "GDScript",
"path": "res://utils/SpringDamper.gd"
}, {
"base": "Reference",
"base": "Sprite",
"class": "TintedSpriteComponent",
"language": "GDScript",
"path": "res://components/TintedSpriteComponent.gd"

View File

@ -114,7 +114,8 @@ public class Game : Spatial
_streamContainer.Connect("TileHovered", this, nameof(OnTileHovered));
_tileWorld.Connect("WorldGenerated", this, nameof(OnWorldGenerated));
_generateWorldButton.Connect("pressed", this, nameof(OnGenerateButton));
_player.TaskQueueComponent.Connect("StartInteraction", _interactionSystem, nameof(_interactionSystem.OnStartInteraction));
_player.TaskQueueComponent.Connect("StartInteraction", _interactionSystem,
nameof(_interactionSystem.OnStartInteraction));
_player.Connect("GoldCountChanged", this, nameof(OnGoldCountChanged));
// register entity events
@ -259,7 +260,7 @@ public class Game : Spatial
{
_player.InteractionComponent.EmitSignal("InteractionEnd");
}
_player.TaskQueueComponent.Reset();
_player.TaskQueueComponent.Queue.Enqueue(new TaskQueueComponent.NavigationTask(
new NavigationComponent.NavigationPoint(tile.GlobalTranslation)));
@ -273,7 +274,7 @@ public class Game : Spatial
_mouseWorldLabel.Text = highlightTransform.origin.ToString();
_mouseTileOffsetLabel.Text = tile.OffsetCoords.ToString();
_mouseTileCubeLabel.Text = tile.Cell.CubeCoords.ToString();
_player.Navigation.FindPath(_player, _player.GlobalTranslation, tile.GlobalTranslation);
}
@ -303,7 +304,7 @@ public class Game : Spatial
playerStartTransform.basis.Quat());
_goldCountLabel.Text = "0";
foreach (Spatial entity in GetNode("Entities").GetChildren())
{
Transform entityTransform = entity.Transform;
@ -320,14 +321,14 @@ public class Game : Spatial
GD.Print("Using new map. Size: " + (int)_tileWorld.ColormapImage.GetSize().x);
_goldCountLabel.Text = "0";
UpdateWorldTextures();
_streamContainer.OnWorldGenerated();
// Reset player transform to offset 0,0 and at current height
ResetGameState();
// Connect all signals of the generated world
foreach (Node node in _tileWorld.Entities.GetChildren())
{
@ -341,7 +342,7 @@ public class Game : Spatial
private void UpdateWorldTextures()
{
GD.Print("Updating World textures");
ImageTexture newWorldTexture = new ImageTexture();
newWorldTexture.CreateFromImage(_tileWorld.ColormapImage,
(uint)(Texture.FlagsEnum.Mipmaps | Texture.FlagsEnum.Repeat));

View File

@ -70,7 +70,6 @@ align = 2
anims/FlashLabel = SubResource( 25 )
[node name="DebugContainer" type="PanelContainer" parent="."]
visible = false
self_modulate = Color( 1, 1, 1, 0.443137 )
anchor_left = 1.0
anchor_top = 1.0

View File

@ -25,10 +25,6 @@ public class HexTile3D : Spatial
delegate void TileHovered(HexTile3D tile3d);
// other member variables
private SpatialMaterial _undefinedMaterial;
private SpatialMaterial _sandMaterial;
private SpatialMaterial _grassMaterial;
private SpatialMaterial _deepGrassMaterial;
private SpatialMaterial _previousMaterial;
private HexGrid _hexGrid;
@ -52,36 +48,7 @@ public class HexTile3D : Spatial
}
}
private TileType _type;
public TileType Type
{
get { return _type; }
set
{
_type = value;
// switch (_type)
// {
// case TileType.Undefined:
// _mesh.SetSurfaceMaterial(0, _undefinedMaterial);
// break;
// case TileType.Sand:
// _mesh.SetSurfaceMaterial(0, _sandMaterial);
// break;
// case TileType.Grass:
// _mesh.SetSurfaceMaterial(0, _grassMaterial);
// break;
// case TileType.DeepGrass:
// _mesh.SetSurfaceMaterial(0, _deepGrassMaterial);
// break;
// default:
// GD.Print("Invalid tile type: " + value.ToString());
// break;
// }
}
}
public TileType Type { get; set; }
HexTile3D()
{
@ -98,11 +65,6 @@ public class HexTile3D : Spatial
_staticBody.Connect("mouse_entered", this, nameof(OnAreaMouseEntered));
_staticBody.Connect("mouse_exited", this, nameof(OnAreaMouseExited));
_undefinedMaterial = GD.Load<SpatialMaterial>("res://materials/UndefinedTile.tres");
_sandMaterial = GD.Load<SpatialMaterial>("res://materials/SandTile.tres");
_grassMaterial = GD.Load<SpatialMaterial>("res://materials/GrassTile.tres");
_deepGrassMaterial = GD.Load<SpatialMaterial>("res://materials/DeepGrassTile.tres");
Mesh = GetNode<MeshInstance>("Mesh");
Debug.Assert(Mesh != null);

View File

@ -23,6 +23,7 @@ script = ExtResource( 1 )
[node name="Mesh" type="MeshInstance" parent="." groups=["GameGeometry"]]
transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0, -2.5, 0 )
visible = false
mesh = ExtResource( 3 )
material/0 = ExtResource( 2 )
@ -36,7 +37,3 @@ shape = SubResource( 5 )
visible = false
mesh = SubResource( 6 )
material/0 = SubResource( 7 )
[node name="MultiMeshInstance" type="MultiMeshInstance" parent="."]
transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0, -5, 0 )
visible = false

View File

@ -7,11 +7,15 @@ using GoDotLog;
public class StreamContainer : Spatial
{
// readonly variables
private readonly Transform _deactivatedTileTransform = new Transform(Basis.Identity, Vector3.Up * 1000);
// scene nodes
private MeshInstance _bounds;
private Spatial _activeTiles;
private Queue<HexTile3D> _unusedTiles;
private TileWorld _tileWorld;
public TileWorld TileWorld;
private MultiMeshInstance _tileMultiMesh;
// resources
private PackedScene _hexTileScene = GD.Load<PackedScene>("res://scenes/HexTile3D.tscn");
@ -27,12 +31,12 @@ public class StreamContainer : Spatial
delegate void TileHovered(HexTile3D tile3d);
// other members
private Rect2 _worldRect;
private Rect2 _currentOffsetCoordRect;
private Rect2 _oldOffsetCoordRect;
private HexGrid _hexGrid;
private Dictionary<Vector2, HexTile3D> _coordToTile = new Dictionary<Vector2, HexTile3D>();
private Dictionary<Vector2, HexTile3D> _coordToTile = new();
private Dictionary<HexTile3D, int> _tileToInstanceIndex = new();
public List<Vector2> RemovedCoords = new List<Vector2>();
public List<Vector2> AddedCoords = new List<Vector2>();
@ -43,7 +47,7 @@ public class StreamContainer : Spatial
public void SetWorld(TileWorld tileWorld)
{
_tileWorld = tileWorld;
TileWorld = tileWorld;
}
// Called when the node enters the scene tree for the first time.
@ -52,6 +56,14 @@ public class StreamContainer : Spatial
_unusedTiles = new Queue<HexTile3D>();
_bounds = GetNode<MeshInstance>("Bounds");
_activeTiles = GetNode<Spatial>("ActiveTiles");
_tileMultiMesh = GetNode<MultiMeshInstance>("TileMultiMesh");
_tileMultiMesh.Multimesh.InstanceCount = (int)((Dimensions.x + 5) * (Dimensions.y + 5));
_tileMultiMesh.Multimesh.InstanceCount = 1810;
foreach (int i in Enumerable.Range(0, _tileMultiMesh.Multimesh.InstanceCount))
{
_tileMultiMesh.Multimesh.SetInstanceTransform(i, _deactivatedTileTransform);
}
_hexGrid = new HexGrid();
@ -59,7 +71,7 @@ public class StreamContainer : Spatial
boundsTransform = boundsTransform.Scaled(new Vector3(Dimensions.x, 1, Dimensions.y));
_bounds.Transform = boundsTransform;
_tileWorld = GetNode<TileWorld>(World);
TileWorld = GetNode<TileWorld>(World);
}
@ -69,8 +81,7 @@ public class StreamContainer : Spatial
Vector2 bottomLeftCoord = centerPlane - new Vector2(Dimensions.x / 2, Dimensions.y / 2);
Vector2 topRightCoord = centerPlane + new Vector2(Dimensions.x / 2, Dimensions.y / 2);
_worldRect = new Rect2(bottomLeftCoord, Dimensions);
// GD.Print("World rect now: " + _worldRect.ToString() + " center: " + _worldRect.GetCenter());
// y axis needs to be inverted as HexGrid's offset coordinates use the opposite axis direction
@ -78,6 +89,10 @@ public class StreamContainer : Spatial
HexCell topRightCell = _hexGrid.GetHexAt(new Vector2(topRightCoord.x, bottomLeftCoord.y));
_currentOffsetCoordRect = new Rect2(bottomLeftCell.OffsetCoords,
topRightCell.OffsetCoords - bottomLeftCell.OffsetCoords + Vector2.One);
// Vector2 centerOffset = _hexGrid.GetHexAt(centerPlane).OffsetCoords;
// _currentOffsetCoordRect = new Rect2(centerOffset + new Vector2(-Dimensions.x / 2, -Dimensions.y / 2),
// Dimensions);
// GD.Print("Offset rect now: " + _currentOffsetCoordRect.ToString() + " center: " +
// _currentOffsetCoordRect.GetCenter());
@ -140,10 +155,8 @@ public class StreamContainer : Spatial
if (isInOld && !isInCurrent && _coordToTile.Keys.Contains(coord))
{
HexTile3D tile3D = _coordToTile[coord];
tile3D.Type = HexTile3D.TileType.Undefined;
_unusedTiles.Enqueue(tile3D);
_coordToTile.Remove(coord);
RemovedCoords.Add(coord);
OnTileDeactivate(tile3D, coord);
}
}
}
@ -173,11 +186,13 @@ public class StreamContainer : Spatial
{
HexTile3D tile3D = _unusedTiles.Dequeue();
tile3D.OffsetCoords = coord;
tile3D.Type = _tileWorld.GetTileTypeAtOffset(coord);
tile3D.Type = TileWorld.GetTileTypeAtOffset(coord);
Transform tileTransform = tile3D.Transform;
tileTransform.origin.y = _tileWorld.GetHeightAtOffset(coord);
tileTransform.origin.y = TileWorld.GetHeightAtOffset(coord);
tile3D.Transform = tileTransform;
OnTileActivate(tile3D);
_coordToTile[coord] = tile3D;
}
}
@ -202,13 +217,17 @@ public class StreamContainer : Spatial
}
Transform tileTransform = tile3D.Transform;
tileTransform.origin.y = _tileWorld.GetHeightAtOffset(offsetCoords);
tileTransform.origin.y = TileWorld.GetHeightAtOffset(offsetCoords);
tile3D.Transform = tileTransform;
tile3D.Type = _tileWorld.GetTileTypeAtOffset(offsetCoords);
tile3D.Type = TileWorld.GetTileTypeAtOffset(offsetCoords);
_tileToInstanceIndex[tile3D] = _tileToInstanceIndex.Count;
_coordToTile[offsetCoords] = tile3D;
}
OnTileActivate(_coordToTile[offsetCoords]);
return _coordToTile[offsetCoords];
}
@ -231,6 +250,26 @@ public class StreamContainer : Spatial
}
}
public void OnTileActivate(HexTile3D tile3D)
{
int instanceIndex = _tileToInstanceIndex[tile3D];
Transform instanceTransform = new Transform(tile3D.GlobalTransform.basis.Rotated(Vector3.Up, Mathf.Deg2Rad(30)), tile3D.GlobalTransform.origin + Vector3.Up * -2.5f);
_tileMultiMesh.Multimesh.SetInstanceTransform(instanceIndex, instanceTransform);
}
public void OnTileDeactivate(HexTile3D tile3D, Vector2 coord)
{
int instanceIndex = _tileToInstanceIndex[tile3D];
_tileMultiMesh.Multimesh.SetInstanceTransform(instanceIndex, _deactivatedTileTransform);
tile3D.Type = HexTile3D.TileType.Undefined;
_unusedTiles.Enqueue(tile3D);
_coordToTile.Remove(coord);
RemovedCoords.Add(coord);
}
public void OnTileClicked(HexTile3D tile)
{
EmitSignal("TileClicked", tile);
@ -252,8 +291,10 @@ public class StreamContainer : Spatial
}
Transform tileTransform = tile.GlobalTransform;
tileTransform.origin.y = _tileWorld.GetHeightAtOffset(tile.OffsetCoords);
tileTransform.origin.y = TileWorld.GetHeightAtOffset(tile.OffsetCoords);
tile.GlobalTransform = tileTransform;
OnTileActivate(tile);
}
}
}

View File

@ -1,6 +1,7 @@
[gd_scene load_steps=5 format=2]
[gd_scene load_steps=7 format=2]
[ext_resource path="res://scenes/StreamContainer.cs" type="Script" id=1]
[ext_resource path="res://assets/Environment/HexTileMesh.tres" type="CylinderMesh" id=2]
[sub_resource type="CubeMesh" id=1]
size = Vector3( 1, 1, 1 )
@ -12,6 +13,11 @@ albedo_color = Color( 1, 1, 1, 0.156863 )
[sub_resource type="BoxShape" id=9]
extents = Vector3( 20, 1, 20 )
[sub_resource type="MultiMesh" id=10]
color_format = 2
transform_format = 1
mesh = ExtResource( 2 )
[node name="StreamContainer" type="Spatial"]
transform = Transform( 1, 0, 0, 0, 1, 2.98023e-08, 0, -2.98023e-08, 1, 0, 0, -4.76837e-07 )
script = ExtResource( 1 )
@ -32,3 +38,6 @@ material/0 = SubResource( 2 )
[node name="CollisionShape" type="CollisionShape" parent="Area"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0 )
shape = SubResource( 9 )
[node name="TileMultiMesh" type="MultiMeshInstance" parent="."]
multimesh = SubResource( 10 )

View File

@ -0,0 +1,60 @@
using System;
using Godot;
using GodotComponentTest.utils;
using GoDotTest;
using Xunit;
namespace GodotComponentTest.tests;
public class StreamContainerTests : TestClass
{
private Node _testScene = null;
private TileWorld _tileWorld;
private StreamContainer _streamContainer;
private PackedScene _tileWorldScene = GD.Load<PackedScene>("res://scenes/TileWorld.tscn");
private PackedScene _streamContainerScene = GD.Load<PackedScene>("res://scenes/StreamContainer.tscn");
public StreamContainerTests(Node testScene) : base(testScene)
{
_testScene = testScene;
}
[Setup]
public void Setup()
{
_tileWorld = (TileWorld) _tileWorldScene.Instance();
_tileWorld.HexGrid = new HexGrid();
_testScene.AddChild(_tileWorld);
_streamContainer = (StreamContainer) _streamContainerScene.Instance();
foreach (Node node in _testScene.GetChildren())
{
if (node is TileWorld)
{
_streamContainer.World = node.GetPath();
}
}
_testScene.AddChild(_streamContainer);
}
[Cleanup]
public void Cleanup()
{
foreach (Node node in _testScene.GetChildren())
{
node.QueueFree();
}
_streamContainer.QueueFree();
_tileWorld.QueueFree();
}
[Test]
public void Plane2DDistSimple()
{
// _streamContainer.UpdateRects(new Vector2(0, 0));
// _streamContainer.UpdateRects(new Vector2(1, 0));
}
}