Vastly improved interactivity, wired up some animations.
parent
2663b469fc
commit
c982ec783c
|
@ -19,6 +19,18 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="entities\Axe.gd" />
|
||||
<Content Include="entities\Axe.tscn" />
|
||||
<Content Include="entities\Chest.tscn" />
|
||||
<Content Include="entities\GoldBar.tscn" />
|
||||
<Content Include="entities\Player3D.tscn" />
|
||||
<Content Include="entities\PlayerEntity.gd" />
|
||||
<Content Include="entities\PlayerEntity.tscn" />
|
||||
<Content Include="entities\SimpleEntity.gd" />
|
||||
<Content Include="entities\SimpleEntity.tscn" />
|
||||
<Content Include="entities\Tree.tscn" />
|
||||
<Content Include="entities\WanderingEntity.gd" />
|
||||
<Content Include="entities\WanderingEntity.tscn" />
|
||||
<Content Include="scenes\Tests\HexTile3DMaterialAssign.tscn" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,17 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://assets/Characters/Pirate.glb" type="PackedScene" id=1]
|
||||
[ext_resource path="res://assets/Objects/toolAxe.tscn" type="PackedScene" id=2]
|
||||
|
||||
[node name="Pirate" instance=ExtResource( 1 )]
|
||||
transform = Transform( 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0 )
|
||||
|
||||
[node name="ToolAttachement" type="BoneAttachment" parent="Armature/Skeleton" index="5"]
|
||||
transform = Transform( 1, 8.68458e-08, -1.04308e-07, 1.74623e-07, -1, -1.30385e-07, 1.41561e-07, 1.50874e-07, -1, -0.72, 0.45, 3.28113e-08 )
|
||||
visible = false
|
||||
bone_name = "HandTip.R"
|
||||
|
||||
[node name="Tool" type="Spatial" parent="Armature/Skeleton/ToolAttachement" index="0"]
|
||||
transform = Transform( -1.12419e-14, 8.74228e-08, -2, 2, -8.74228e-08, -1.39841e-13, -8.74228e-08, -2, -8.74228e-08, 2.38419e-07, -0.151768, 0.615043 )
|
||||
|
||||
[node name="toolAxe" parent="Armature/Skeleton/ToolAttachement/Tool" index="0" instance=ExtResource( 2 )]
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,18 +0,0 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://assets/KenneySurvivalKit/Models/tree.glb" type="PackedScene" id=1]
|
||||
|
||||
[sub_resource type="CapsuleShape" id=1]
|
||||
radius = 0.329139
|
||||
height = 0.936801
|
||||
|
||||
[node name="tree" instance=ExtResource( 1 )]
|
||||
|
||||
[node name="tree" parent="." index="0"]
|
||||
transform = Transform( 1.5, 0, 0, 0, 1, 0, 0, 0, 1.5, 0, 0, 0 )
|
||||
|
||||
[node name="StaticBody" type="StaticBody" parent="." index="1"]
|
||||
|
||||
[node name="CollisionShape" type="CollisionShape" parent="StaticBody" index="0"]
|
||||
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0.519998, 0 )
|
||||
shape = SubResource( 1 )
|
|
@ -5,4 +5,4 @@
|
|||
[node name="toolAxe" instance=ExtResource( 1 )]
|
||||
|
||||
[node name="toolAxe" parent="." index="0"]
|
||||
transform = Transform( 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0 )
|
||||
transform = Transform( 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0 )
|
||||
|
|
|
@ -2,11 +2,20 @@ using Godot;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using GodotComponentTest.entities;
|
||||
using Object = Godot.Object;
|
||||
|
||||
public class TaskQueueComponent : Component
|
||||
{
|
||||
public abstract class Task
|
||||
[Signal]
|
||||
delegate void StartInteraction(Entity entity, Entity targetEntity);
|
||||
|
||||
public abstract class Task : Object
|
||||
{
|
||||
/// <summary>
|
||||
/// Executes a Task on the specified entity.
|
||||
/// </summary>
|
||||
/// <returns>true when the Task is complete, false otherwise</returns>
|
||||
public abstract bool PerformTask(Entity entity, float delta);
|
||||
}
|
||||
|
||||
|
@ -36,13 +45,6 @@ public class TaskQueueComponent : Component
|
|||
|
||||
public override bool PerformTask(Entity entity, float delta)
|
||||
{
|
||||
GD.Print("Interaction of " + entity + " with " + TargetEntity);
|
||||
|
||||
if (TargetEntity is Chest)
|
||||
{
|
||||
Chest chest = (Chest)TargetEntity;
|
||||
chest.OnInteract();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +54,7 @@ public class TaskQueueComponent : Component
|
|||
public TaskQueueComponent()
|
||||
{
|
||||
Queue = new Queue<Task>();
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
|
@ -67,25 +70,23 @@ public class TaskQueueComponent : Component
|
|||
return;
|
||||
}
|
||||
|
||||
Task currentTask = Queue.Peek();
|
||||
while (currentTask.PerformTask(entity, delta))
|
||||
do
|
||||
{
|
||||
Queue.Dequeue();
|
||||
if (Queue.Count == 0)
|
||||
Task currentTask = Queue.Peek();
|
||||
InteractionTask interactionTask = currentTask as InteractionTask;
|
||||
if (interactionTask != null)
|
||||
{
|
||||
EmitSignal("StartInteraction", entity, interactionTask.TargetEntity);
|
||||
}
|
||||
|
||||
if (currentTask.PerformTask(entity, delta))
|
||||
{
|
||||
Queue.Dequeue();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
currentTask = Queue.Peek();
|
||||
if (currentTask is NavigationTask)
|
||||
{
|
||||
NavigationTask navigationTask = (NavigationTask)currentTask;
|
||||
if (navigationTask != null && navigationTask.NavigationPoint.Flags ==
|
||||
NavigationComponent.NavigationPoint.NavigationFlags.Orientation)
|
||||
{
|
||||
GD.Print("Current task is orientation task!");
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (Queue.Count > 0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
using Godot;
|
||||
using System;
|
||||
|
||||
public class Axe : StaticBody
|
||||
{
|
||||
// Called when the node enters the scene tree for the first time.
|
||||
public override void _Ready()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
extends StaticBody
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
|
@ -0,0 +1,20 @@
|
|||
[gd_scene load_steps=4 format=2]
|
||||
|
||||
[ext_resource path="res://assets/Objects/toolAxe.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://entities/Axe.cs" type="Script" id=2]
|
||||
|
||||
[sub_resource type="CylinderShape" id=1]
|
||||
height = 0.846435
|
||||
radius = 0.687167
|
||||
|
||||
[node name="Axe" type="StaticBody"]
|
||||
collision_layer = 9
|
||||
collision_mask = 0
|
||||
script = ExtResource( 2 )
|
||||
|
||||
[node name="CollisionShape" type="CollisionShape" parent="."]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.428358, 0 )
|
||||
shape = SubResource( 1 )
|
||||
|
||||
[node name="toolAxe" parent="." instance=ExtResource( 1 )]
|
||||
transform = Transform( 0.707107, 0.707107, -3.09086e-08, 4.37114e-08, 1.91069e-15, 1, 0.707107, -0.707107, -3.09086e-08, -0.323064, 0.0760467, 0.348457 )
|
|
@ -1,8 +1,9 @@
|
|||
using Godot;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using GodotComponentTest.entities;
|
||||
|
||||
public class Chest : Entity
|
||||
public class Chest : Entity, IInteractionInterface
|
||||
{
|
||||
// resources
|
||||
private PackedScene _goldBarScene = GD.Load<PackedScene>("res://entities/GoldBar.tscn");
|
||||
|
@ -15,6 +16,7 @@ public class Chest : Entity
|
|||
|
||||
public LidState State = LidState.Closed;
|
||||
public bool IsMouseOver = false;
|
||||
|
||||
private MeshInstance _mesh;
|
||||
private AnimationPlayer _animationPlayer;
|
||||
|
||||
|
@ -27,7 +29,7 @@ public class Chest : Entity
|
|||
// Called when the node enters the scene tree for the first time.
|
||||
public override void _Ready()
|
||||
{
|
||||
_mesh = GetNode<MeshInstance>("Armature/Skeleton/Chest");
|
||||
_mesh = GetNode<MeshInstance>("Geometry/Skeleton/Chest");
|
||||
_animationPlayer = GetNode<AnimationPlayer>("AnimationPlayer");
|
||||
|
||||
Connect("input_event", this, nameof(OnAreaInputEvent));
|
||||
|
@ -67,7 +69,7 @@ public class Chest : Entity
|
|||
}
|
||||
|
||||
|
||||
public void OnInteract()
|
||||
public void OnInteractionStart()
|
||||
{
|
||||
_animationPlayer.Stop();
|
||||
|
||||
|
@ -83,6 +85,12 @@ public class Chest : Entity
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public void OnInteractionEnd()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnChestOpened()
|
||||
{
|
||||
GD.Print("Chest now opened!");
|
||||
|
|
|
@ -45,14 +45,14 @@ bind/1/pose = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.693102, -1.13623, -1.5266
|
|||
resource_name = "ChestOpen"
|
||||
length = 0.333333
|
||||
tracks/0/type = "transform"
|
||||
tracks/0/path = NodePath("Armature/Skeleton:Lid")
|
||||
tracks/0/path = NodePath("Geometry/Skeleton:Lid")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/keys = PoolRealArray( 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0.0666667, 1, 0, 0, 0, 0, 0, -0.079364, 0.996846, 1, 1, 1, 0.133333, 1, 0, 0, 0, 0, 0, -0.489957, 0.871747, 1, 1, 1, 0.2, 1, 0, 0, 0, 0, 0, -0.855809, 0.517292, 1, 1, 1, 0.266667, 1, 2.37487e-08, 0, 0, 4.03449e-08, -3.99897e-08, 0.919654, -0.39273, 1, 1, 1, 0.333333, 1, 0, 0, 0, -1.45046e-08, 1.43769e-08, -0.808978, 0.587839, 1, 1, 1 )
|
||||
tracks/1/type = "transform"
|
||||
tracks/1/path = NodePath("Armature/Skeleton:Body")
|
||||
tracks/1/path = NodePath("Geometry/Skeleton:Body")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/imported = false
|
||||
|
@ -83,10 +83,10 @@ extents = Vector3( 0.19, 0.19, 0.332 )
|
|||
[node name="Chest" type="KinematicBody"]
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="Armature" type="Spatial" parent="."]
|
||||
[node name="Geometry" type="Spatial" parent="."]
|
||||
transform = Transform( -0.259808, 0, 0.15, 0, 0.3, 0, -0.15, 0, -0.259808, 0, 0, 0 )
|
||||
|
||||
[node name="Skeleton" type="Skeleton" parent="Armature"]
|
||||
[node name="Skeleton" type="Skeleton" parent="Geometry"]
|
||||
bones/0/name = "Body"
|
||||
bones/0/parent = -1
|
||||
bones/0/rest = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.697618, -0.0422799, -5.68067e-09 )
|
||||
|
@ -98,15 +98,13 @@ bones/1/rest = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.00451577, 1.17851, 1.583
|
|||
bones/1/enabled = true
|
||||
bones/1/bound_children = [ ]
|
||||
|
||||
[node name="Chest" type="MeshInstance" parent="Armature/Skeleton"]
|
||||
[node name="Chest" type="MeshInstance" parent="Geometry/Skeleton"]
|
||||
mesh = SubResource( 12 )
|
||||
skin = SubResource( 13 )
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
anims/ChestOpen = SubResource( 3 )
|
||||
|
||||
[node name="State" type="Node" parent="."]
|
||||
|
||||
[node name="MountPoint" type="Spatial" parent="."]
|
||||
transform = Transform( -0.524001, 0, -0.851718, 0, 1, 0, 0.851718, 0, -0.524001, 0.717306, 0, 0.400936 )
|
||||
|
||||
|
|
|
@ -42,16 +42,16 @@ public class GoldBar : KinematicBody
|
|||
}
|
||||
else
|
||||
{
|
||||
if (Mathf.Abs(Transform.origin.y) < 0.01)
|
||||
{
|
||||
// apply damping when on ground
|
||||
velocity = velocity - velocity.Normalized() * 0.9f * delta;
|
||||
}
|
||||
|
||||
velocity.y = velocity.y - 9.81f * delta;
|
||||
}
|
||||
|
||||
velocity = MoveAndSlide(velocity);
|
||||
velocity = MoveAndSlide(velocity, Vector3.Up);
|
||||
|
||||
if (IsOnFloor() || Mathf.Abs(Transform.origin.y) < 0.01)
|
||||
{
|
||||
// apply damping when on ground
|
||||
velocity = velocity - velocity.Normalized() * 0.9f * delta;
|
||||
}
|
||||
|
||||
if (velocity.LengthSquared() < 0.01)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
namespace GodotComponentTest.entities;
|
||||
|
||||
public interface IInteractionInterface
|
||||
{
|
||||
void OnInteractionStart();
|
||||
void OnInteractionEnd();
|
||||
}
|
|
@ -1,12 +1,15 @@
|
|||
using Godot;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using GodotComponentTest.entities;
|
||||
|
||||
public class Player : Entity
|
||||
public class Player : Entity, IInteractionInterface
|
||||
{
|
||||
// public members
|
||||
public Vector3 TargetPosition = Vector3.Zero;
|
||||
public int goldCount = 0;
|
||||
|
||||
public TaskQueueComponent TaskQueueComponent;
|
||||
|
||||
|
@ -15,6 +18,9 @@ public class Player : Entity
|
|||
get { return _navigationComponent; }
|
||||
}
|
||||
|
||||
[Signal]
|
||||
delegate void GoldCountChanged(int goldCount);
|
||||
|
||||
// private members
|
||||
private WorldInfoComponent _worldInfo;
|
||||
private GroundMotionComponent _groundMotion;
|
||||
|
@ -22,6 +28,8 @@ public class Player : Entity
|
|||
private Area _itemAttractorArea;
|
||||
private Area _itemPickupArea;
|
||||
private List<Node> _attractedItemList = new List<Node>();
|
||||
private BoneAttachment _toolAttachement;
|
||||
private AnimationPlayer _playerAnimationPlayer;
|
||||
|
||||
// Called when the node enters the scene tree for the first time.
|
||||
public override void _Ready()
|
||||
|
@ -53,6 +61,14 @@ public class Player : Entity
|
|||
_itemPickupArea.Connect("body_entered", this, nameof(OnItemPickupAreaBodyEntered));
|
||||
}
|
||||
|
||||
_playerAnimationPlayer = (AnimationPlayer)GetNode<AnimationPlayer>("Geometry/AnimationPlayer");
|
||||
Debug.Assert(_playerAnimationPlayer != null);
|
||||
|
||||
_toolAttachement = (BoneAttachment)FindNode("ToolAttachement");
|
||||
if (_toolAttachement == null)
|
||||
{
|
||||
GD.PushWarning("No ToolAttachement found!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -94,9 +110,9 @@ public class Player : Entity
|
|||
|
||||
foreach (Node node in _attractedItemList)
|
||||
{
|
||||
GoldBar bar = (GoldBar)node;
|
||||
if (bar != null)
|
||||
if (node is GoldBar)
|
||||
{
|
||||
GoldBar bar = (GoldBar)node;
|
||||
bar.SetTarget(GlobalTransform.origin);
|
||||
}
|
||||
}
|
||||
|
@ -111,9 +127,10 @@ public class Player : Entity
|
|||
public void OnItemAttractorBodyExited(Node node)
|
||||
{
|
||||
GD.Print("Item exited " + node);
|
||||
GoldBar bar = (GoldBar)node;
|
||||
if (bar != null)
|
||||
|
||||
if (node is GoldBar)
|
||||
{
|
||||
GoldBar bar = (GoldBar)node;
|
||||
bar.UnsetTarget();
|
||||
}
|
||||
_attractedItemList.Remove(node);
|
||||
|
@ -121,11 +138,44 @@ public class Player : Entity
|
|||
|
||||
public void OnItemPickupAreaBodyEntered(Node body)
|
||||
{
|
||||
GD.Print("Picking up item: " + body);
|
||||
GD.Print("Picking up item: " + body.Name);
|
||||
|
||||
if (body is Axe)
|
||||
{
|
||||
SetActiveTool("Axe");
|
||||
}
|
||||
|
||||
if (body is GoldBar)
|
||||
{
|
||||
GoldBar bar = (GoldBar)body;
|
||||
bar.QueueFree();
|
||||
goldCount++;
|
||||
EmitSignal("GoldCountChanged", goldCount);
|
||||
}
|
||||
|
||||
body.QueueFree();
|
||||
}
|
||||
|
||||
public void SetActiveTool(String toolName)
|
||||
{
|
||||
Debug.Assert(_toolAttachement != null);
|
||||
if (toolName == "Axe")
|
||||
{
|
||||
_toolAttachement.Visible = true;
|
||||
} else if (toolName == "")
|
||||
{
|
||||
_toolAttachement.Visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnInteractionStart()
|
||||
{
|
||||
GD.Print("Player Starting Interaction");
|
||||
_playerAnimationPlayer.CurrentAnimation = "Hit-loop";
|
||||
_playerAnimationPlayer.Play();
|
||||
}
|
||||
|
||||
public void OnInteractionEnd()
|
||||
{
|
||||
GD.Print("Player Stopping Interaction");
|
||||
_playerAnimationPlayer.CurrentAnimation = "Idle-loop";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
using Godot;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using GodotComponentTest.entities;
|
||||
|
||||
public class Tree : StaticBody, IInteractionInterface
|
||||
{
|
||||
[Export] public float ChopDuration = 2;
|
||||
public bool IsMouseOver = false;
|
||||
|
||||
private MeshInstance _geometry;
|
||||
private AnimationPlayer _animationPlayer;
|
||||
private float _health = 100;
|
||||
private bool _isBeingChopped = false;
|
||||
|
||||
[Signal]
|
||||
delegate void EntityClicked(Entity entity);
|
||||
|
||||
// Called when the node enters the scene tree for the first time.
|
||||
public override void _Ready()
|
||||
{
|
||||
_geometry = GetNode<MeshInstance>("Geometry");
|
||||
Debug.Assert(_geometry != null);
|
||||
_animationPlayer = GetNode<AnimationPlayer>("AnimationPlayer");
|
||||
Debug.Assert(_animationPlayer != null);
|
||||
|
||||
Connect("input_event", this, nameof(OnAreaInputEvent));
|
||||
Connect("mouse_entered", this, nameof(OnAreaMouseEntered));
|
||||
Connect("mouse_exited", this, nameof(OnAreaMouseExited));
|
||||
}
|
||||
|
||||
|
||||
public override void _Process(float delta)
|
||||
{
|
||||
base._Process(delta);
|
||||
|
||||
if (_isBeingChopped)
|
||||
{
|
||||
_health = Math.Max(0, _health - delta * 100 / ChopDuration);
|
||||
}
|
||||
|
||||
if (_health == 0)
|
||||
{
|
||||
QueueFree();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnAreaInputEvent(Node camera, InputEvent inputEvent, Vector3 position, Vector3 normal,
|
||||
int shapeIndex)
|
||||
{
|
||||
if (IsMouseOver && inputEvent is InputEventMouseButton)
|
||||
{
|
||||
InputEventMouseButton mouseButtonEvent = (InputEventMouseButton)inputEvent;
|
||||
if (mouseButtonEvent.ButtonIndex == 1 && mouseButtonEvent.Pressed)
|
||||
{
|
||||
EmitSignal("EntityClicked", this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void OnAreaMouseEntered()
|
||||
{
|
||||
IsMouseOver = true;
|
||||
SpatialMaterial overrideMaterial = new SpatialMaterial();
|
||||
overrideMaterial.AlbedoColor = new Color(1, 0, 0);
|
||||
_geometry.MaterialOverride = overrideMaterial;
|
||||
}
|
||||
|
||||
|
||||
public void OnAreaMouseExited()
|
||||
{
|
||||
IsMouseOver = false;
|
||||
_geometry.MaterialOverride = null;
|
||||
}
|
||||
|
||||
|
||||
public void OnInteractionStart()
|
||||
{
|
||||
GD.Print("Starting tree animationplayer");
|
||||
_animationPlayer.CurrentAnimation = "TreeShake";
|
||||
_animationPlayer.Play();
|
||||
_isBeingChopped = true;
|
||||
}
|
||||
|
||||
public void OnInteractionEnd()
|
||||
{
|
||||
_animationPlayer.Stop();
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -17,6 +17,8 @@ public class Game : Spatial
|
|||
private TextureRect _worldTextureRect;
|
||||
private TextureRect _heightTextureRect;
|
||||
private Button _generateWorldButton;
|
||||
private Control _gameUI;
|
||||
private Label _goldCountLabel;
|
||||
|
||||
// scene nodes
|
||||
private Spatial _tileHighlight;
|
||||
|
@ -25,7 +27,6 @@ public class Game : Spatial
|
|||
private Area _streamContainerArea;
|
||||
private Spatial _streamContainerActiveTiles;
|
||||
private Player _player;
|
||||
private Chest _chest;
|
||||
private TileWorld _tileWorld;
|
||||
private Camera _camera;
|
||||
|
||||
|
@ -39,13 +40,14 @@ public class Game : Spatial
|
|||
private HexCell _currentTile;
|
||||
private Vector3 _cameraOffset;
|
||||
private ImageTexture _blackWhitePatternTexture;
|
||||
private InteractionSystem _interactionSystem;
|
||||
|
||||
// Called when the node enters the scene tree for the first time.
|
||||
public override void _Ready()
|
||||
{
|
||||
// debugStatsContainer
|
||||
Container debugStatsContainer = (Container) FindNode("DebugStatsContainer");
|
||||
|
||||
Container debugStatsContainer = (Container)FindNode("DebugStatsContainer");
|
||||
|
||||
_framesPerSecondLabel = debugStatsContainer.GetNode<Label>("fps_label");
|
||||
_tileLabel = debugStatsContainer.GetNode<Label>("tile_label");
|
||||
_tileOffsetLabel = debugStatsContainer.GetNode<Label>("tile_offset_label");
|
||||
|
@ -60,17 +62,19 @@ public class Game : Spatial
|
|||
_worldTextureRect = worldGeneratorContainer.GetNode<TextureRect>("WorldTextureRect");
|
||||
_heightTextureRect = worldGeneratorContainer.GetNode<TextureRect>("HeightTextureRect");
|
||||
_generateWorldButton = worldGeneratorContainer.GetNode<Button>("WorldGenerateButton");
|
||||
_gameUI = (Control)FindNode("GameUI");
|
||||
_goldCountLabel = _gameUI.GetNode<Label>("GoldCount");
|
||||
Debug.Assert(_goldCountLabel != null);
|
||||
|
||||
// scene nodes
|
||||
_tileHighlight = GetNode<Spatial>("TileHighlight");
|
||||
_mouseTileHighlight = GetNode<Spatial>("MouseTileHighlight");
|
||||
|
||||
|
||||
_streamContainer = (StreamContainer)FindNode("StreamContainer");
|
||||
_streamContainerArea = _streamContainer.GetNode<Area>("Area");
|
||||
_streamContainerActiveTiles = _streamContainer.GetNode<Spatial>("ActiveTiles");
|
||||
|
||||
|
||||
_player = GetNode<Player>("Player");
|
||||
_chest = GetNode<Chest>("Entities/Chest");
|
||||
_tileWorld = GetNode<TileWorld>("TileWorld");
|
||||
_camera = (Camera)FindNode("Camera");
|
||||
_cameraOffset = _camera.GlobalTranslation - _player.GlobalTranslation;
|
||||
|
@ -78,7 +82,7 @@ public class Game : Spatial
|
|||
// populate UI values
|
||||
Slider generatorWorldSizeSlider = worldGeneratorContainer.GetNode<Slider>("HBoxContainer/WorldSizeSlider");
|
||||
generatorWorldSizeSlider.Value = _tileWorld.Size;
|
||||
|
||||
|
||||
Debug.Assert(_tileWorld != null);
|
||||
|
||||
// resources
|
||||
|
@ -89,12 +93,14 @@ public class Game : Spatial
|
|||
_blackWhitePatternTexture = new ImageTexture();
|
||||
Image image = new Image();
|
||||
image.Load("assets/4x4checker.png");
|
||||
_blackWhitePatternTexture.CreateFromImage(image, (uint) (Texture.FlagsEnum.Mipmaps | Texture.FlagsEnum.Repeat));
|
||||
_blackWhitePatternTexture.CreateFromImage(image, (uint)(Texture.FlagsEnum.Mipmaps | Texture.FlagsEnum.Repeat));
|
||||
|
||||
// other members
|
||||
_lastTile = new HexCell();
|
||||
_currentTile = new HexCell();
|
||||
_hexGrid = new HexGrid();
|
||||
_interactionSystem = GetNode<InteractionSystem>("InteractionSystem");
|
||||
Debug.Assert(_interactionSystem != null);
|
||||
|
||||
// update data
|
||||
_worldTextureRect.RectSize = Vector2.One * _tileWorld.Size;
|
||||
|
@ -106,12 +112,13 @@ 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.Connect("GoldCountChanged", this, nameof(OnGoldCountChanged));
|
||||
|
||||
// register entity events
|
||||
Array entityNodes = FindNode("Entities").GetChildren();
|
||||
foreach (Node node in entityNodes)
|
||||
foreach (Node node in GetNode("Entities").GetChildren())
|
||||
{
|
||||
if (node is Chest)
|
||||
if (node.HasSignal("EntityClicked"))
|
||||
{
|
||||
node.Connect("EntityClicked", this, nameof(OnEntityClicked));
|
||||
}
|
||||
|
@ -157,9 +164,9 @@ public class Game : Spatial
|
|||
Vector3 cameraNormal = _camera.ProjectRayNormal(_camera.GetViewport().Size * 0.5f);
|
||||
Vector3 cameraPosition = _camera.ProjectRayOrigin(_camera.GetViewport().Size * 0.5f);
|
||||
Vector3 cameraDir = cameraNormal - cameraPosition;
|
||||
|
||||
|
||||
Vector3 centerCoord;
|
||||
|
||||
|
||||
if (Mathf.Abs(cameraDir.y) > Globals.EpsPosition)
|
||||
{
|
||||
centerCoord = cameraPosition + cameraNormal * (-cameraPosition.y / cameraNormal.y);
|
||||
|
@ -169,7 +176,7 @@ public class Game : Spatial
|
|||
centerCoord = _camera.GlobalTranslation;
|
||||
centerCoord.y = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
_currentTile = _hexGrid.GetHexAt(new Vector2(centerCoord.x, centerCoord.z));
|
||||
|
||||
|
@ -215,10 +222,11 @@ public class Game : Spatial
|
|||
GD.PrintErr("Could not find WorldSizeSlider!");
|
||||
return;
|
||||
}
|
||||
|
||||
_tileWorld.Seed = _tileWorld.Seed + 1;
|
||||
_tileWorld.Generate((int)worldSizeSlider.Value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void OnAreaInputEvent(Node camera, InputEvent inputEvent, Vector3 position, Vector3 normal,
|
||||
int shapeIndex)
|
||||
|
@ -280,8 +288,9 @@ public class Game : Spatial
|
|||
playerStartTransform.origin.y = height;
|
||||
_player.Transform = playerStartTransform;
|
||||
_player.TaskQueueComponent.Reset();
|
||||
_player.Navigation.PlanDirectPath(playerStartTransform.origin, playerStartTransform.origin, playerStartTransform.basis.Quat());
|
||||
|
||||
_player.Navigation.PlanDirectPath(playerStartTransform.origin, playerStartTransform.origin,
|
||||
playerStartTransform.basis.Quat());
|
||||
|
||||
foreach (Spatial entity in GetNode("Entities").GetChildren())
|
||||
{
|
||||
Transform entityTransform = entity.Transform;
|
||||
|
@ -296,20 +305,39 @@ public class Game : Spatial
|
|||
public void OnWorldGenerated()
|
||||
{
|
||||
GD.Print("Using new map. Size: " + (int)_tileWorld.Colormap.GetSize().x);
|
||||
|
||||
_goldCountLabel.Text = "0";
|
||||
|
||||
ImageTexture newWorldTexture = new ImageTexture();
|
||||
newWorldTexture.CreateFromImage(_tileWorld.Colormap, (uint) (Texture.FlagsEnum.Mipmaps | Texture.FlagsEnum.Repeat));
|
||||
newWorldTexture.CreateFromImage(_tileWorld.Colormap,
|
||||
(uint)(Texture.FlagsEnum.Mipmaps | Texture.FlagsEnum.Repeat));
|
||||
_worldTextureRect.Texture = newWorldTexture;
|
||||
_tileMaterial.SetShaderParam("MapAlbedoTexture", newWorldTexture);
|
||||
_tileMaterial.SetShaderParam("TextureSize", (int)_tileWorld.Colormap.GetSize().x);
|
||||
|
||||
ImageTexture newHeightTexture = new ImageTexture();
|
||||
newHeightTexture.CreateFromImage(_tileWorld.Heightmap, (uint) (Texture.FlagsEnum.Mipmaps | Texture.FlagsEnum.Repeat));
|
||||
newHeightTexture.CreateFromImage(_tileWorld.Heightmap,
|
||||
(uint)(Texture.FlagsEnum.Mipmaps | Texture.FlagsEnum.Repeat));
|
||||
_heightTextureRect.Texture = newHeightTexture;
|
||||
|
||||
|
||||
_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())
|
||||
{
|
||||
if (node.HasSignal("EntityClicked"))
|
||||
{
|
||||
node.Connect("EntityClicked", this, nameof(OnEntityClicked));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void OnGoldCountChanged(int goldCount)
|
||||
{
|
||||
_goldCountLabel.Text = goldCount.ToString();
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=20 format=2]
|
||||
[gd_scene load_steps=21 format=2]
|
||||
|
||||
[ext_resource path="res://scenes/StreamContainer.cs" type="Script" id=1]
|
||||
[ext_resource path="res://components/NavigationComponent.cs" type="Script" id=2]
|
||||
|
@ -10,9 +10,10 @@
|
|||
[ext_resource path="res://scenes/TileWorld.tscn" type="PackedScene" id=8]
|
||||
[ext_resource path="res://scenes/Game.cs" type="Script" id=9]
|
||||
[ext_resource path="res://scenes/DebugCamera.gd" type="Script" id=10]
|
||||
[ext_resource path="res://assets/CreatusPiratePack/Models/Characters/gltf/Pirate1final.glb" type="PackedScene" id=11]
|
||||
[ext_resource path="res://assets/Characters/Pirate.tscn" type="PackedScene" id=11]
|
||||
[ext_resource path="res://ui/WorldGeneratorUI.gd" type="Script" id=12]
|
||||
[ext_resource path="res://assets/Objects/toolAxe.tscn" type="PackedScene" id=13]
|
||||
[ext_resource path="res://entities/Axe.tscn" type="PackedScene" id=14]
|
||||
[ext_resource path="res://systems/InteractionSystem.cs" type="Script" id=15]
|
||||
|
||||
[sub_resource type="CubeMesh" id=1]
|
||||
size = Vector3( 1, 1, 1 )
|
||||
|
@ -47,6 +48,30 @@ transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0 )
|
|||
[node name="TileWorld" parent="." instance=ExtResource( 8 )]
|
||||
Size = 32
|
||||
|
||||
[node name="GameUI" type="HBoxContainer" parent="."]
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
margin_left = -40.0
|
||||
margin_right = -10.0
|
||||
margin_bottom = 40.0
|
||||
grow_horizontal = 0
|
||||
alignment = 2
|
||||
|
||||
[node name="GoldLabel" type="Label" parent="GameUI"]
|
||||
margin_top = 13.0
|
||||
margin_right = 30.0
|
||||
margin_bottom = 27.0
|
||||
text = "Gold"
|
||||
|
||||
[node name="GoldCount" type="Label" parent="GameUI"]
|
||||
margin_left = 34.0
|
||||
margin_top = 13.0
|
||||
margin_right = 84.0
|
||||
margin_bottom = 27.0
|
||||
rect_min_size = Vector2( 50, 0 )
|
||||
text = "0"
|
||||
align = 2
|
||||
|
||||
[node name="DebugContainer" type="PanelContainer" parent="."]
|
||||
visible = false
|
||||
self_modulate = Color( 1, 1, 1, 0.443137 )
|
||||
|
@ -272,6 +297,9 @@ current = true
|
|||
fov = 60.0
|
||||
script = ExtResource( 10 )
|
||||
|
||||
[node name="InteractionSystem" type="Node" parent="."]
|
||||
script = ExtResource( 15 )
|
||||
|
||||
[node name="Player" type="KinematicBody" parent="."]
|
||||
collision_mask = 0
|
||||
axis_lock_motion_y = true
|
||||
|
@ -284,11 +312,6 @@ shape = SubResource( 7 )
|
|||
|
||||
[node name="Movable" parent="Player" instance=ExtResource( 4 )]
|
||||
|
||||
[node name="Geometry" type="Spatial" parent="Player"]
|
||||
transform = Transform( 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0 )
|
||||
|
||||
[node name="Pirate1final" parent="Player/Geometry" instance=ExtResource( 11 )]
|
||||
|
||||
[node name="WorldInfo" type="Node" parent="Player"]
|
||||
script = ExtResource( 6 )
|
||||
World = NodePath("../../TileWorld")
|
||||
|
@ -313,6 +336,8 @@ monitorable = false
|
|||
[node name="CollisionShape" type="CollisionShape" parent="Player/ItemPickupArea"]
|
||||
shape = SubResource( 23 )
|
||||
|
||||
[node name="Geometry" parent="Player" instance=ExtResource( 11 )]
|
||||
|
||||
[node name="Entities" type="Spatial" parent="."]
|
||||
|
||||
[node name="Chest" parent="Entities" instance=ExtResource( 7 )]
|
||||
|
@ -324,8 +349,9 @@ transform = Transform( 0.550568, 0, -0.83479, 0, 1, 0, 0.83479, 0, 0.550568, 4.8
|
|||
[node name="Chest2" parent="Entities" instance=ExtResource( 7 )]
|
||||
transform = Transform( 0.793576, 0, -0.608471, 0, 1, 0, 0.608471, 0, 0.793576, 2.79265, 0, -5.36551 )
|
||||
|
||||
[node name="toolAxe" parent="Entities" instance=ExtResource( 13 )]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 1.81635, 0, 0 )
|
||||
[node name="Axe" parent="Entities" instance=ExtResource( 14 )]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 1.79762, 0, 0 )
|
||||
input_ray_pickable = false
|
||||
|
||||
[connection signal="value_changed" from="Generator Container/WorldGeneratorContainer/HBoxContainer/WorldSizeSlider" to="Generator Container/WorldGeneratorContainer" method="_on_HSlider_value_changed"]
|
||||
|
||||
|
|
|
@ -226,13 +226,13 @@ public class StreamContainer : Spatial
|
|||
|
||||
public void OnTileClicked(HexTile3D tile)
|
||||
{
|
||||
GD.Print("Clicked on Tile at " + tile.OffsetCoords);
|
||||
// GD.Print("Clicked on Tile at " + tile.OffsetCoords);
|
||||
EmitSignal("TileClicked", tile);
|
||||
}
|
||||
|
||||
public void OnTileHovered(HexTile3D tile)
|
||||
{
|
||||
GD.Print("Hovered on Tile at " + tile.OffsetCoords);
|
||||
// GD.Print("Hovered on Tile at " + tile.OffsetCoords);
|
||||
EmitSignal("TileHovered", tile);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ public class TileWorld : Spatial
|
|||
public Image Heightmap;
|
||||
public Image Colormap;
|
||||
public int Seed = 0;
|
||||
public Spatial Entities;
|
||||
|
||||
// private members
|
||||
private HexGrid _hexGrid;
|
||||
|
@ -84,6 +85,7 @@ public class TileWorld : Spatial
|
|||
}
|
||||
|
||||
_environmentNode = GetNode<Spatial>("Environment");
|
||||
Entities = GetNode<Spatial>("Entities");
|
||||
|
||||
Generate(Size);
|
||||
}
|
||||
|
@ -161,6 +163,11 @@ public class TileWorld : Spatial
|
|||
{
|
||||
child.QueueFree();
|
||||
}
|
||||
|
||||
foreach (Node child in Entities.GetChildren())
|
||||
{
|
||||
child.QueueFree();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnHeightMapChanged()
|
||||
|
@ -231,7 +238,7 @@ public class TileWorld : Spatial
|
|||
Spatial treeAsset = SelectAsset(offsetCoord, _treeAssets, environmentRandom, 0.10);
|
||||
if (treeAsset != null)
|
||||
{
|
||||
_environmentNode.AddChild(treeAsset);
|
||||
Entities.AddChild(treeAsset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
[ext_resource path="res://assets/Environment/rockC.tscn" type="PackedScene" id=6]
|
||||
[ext_resource path="res://assets/Environment/rockA.tscn" type="PackedScene" id=7]
|
||||
[ext_resource path="res://assets/Environment/grassLarge.tscn" type="PackedScene" id=8]
|
||||
[ext_resource path="res://assets/Environment/tree.tscn" type="PackedScene" id=9]
|
||||
[ext_resource path="res://entities/Tree.tscn" type="PackedScene" id=9]
|
||||
|
||||
[node name="TileWorld" type="Spatial"]
|
||||
script = ExtResource( 1 )
|
||||
|
@ -70,3 +70,5 @@ visible = false
|
|||
[node name="tree" parent="Assets/Trees" instance=ExtResource( 9 )]
|
||||
|
||||
[node name="Environment" type="Spatial" parent="."]
|
||||
|
||||
[node name="Entities" type="Spatial" parent="."]
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
using Godot;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Godot.Collections;
|
||||
using GodotComponentTest.entities;
|
||||
using Array = System.Array;
|
||||
using NodePair = System.Tuple<Godot.Node, Godot.Node>;
|
||||
|
||||
public class InteractionSystem : Node
|
||||
{
|
||||
private List<NodePair> _interactionPairs;
|
||||
|
||||
// Called when the node enters the scene tree for the first time.
|
||||
public override void _Ready()
|
||||
{
|
||||
_interactionPairs = new List<NodePair>();
|
||||
}
|
||||
|
||||
|
||||
public override void _Process(float delta)
|
||||
{
|
||||
base._Process(delta);
|
||||
|
||||
List<NodePair> invalidInteractionPairs = new List<NodePair>();
|
||||
|
||||
foreach (Tuple<Node, Node> pair in _interactionPairs)
|
||||
{
|
||||
Node nodeA = pair.Item1;
|
||||
Node nodeB = pair.Item2;
|
||||
|
||||
if (nodeA == null || nodeA.IsQueuedForDeletion() || nodeB == null || nodeB.IsQueuedForDeletion()) {
|
||||
invalidInteractionPairs.Add(pair);
|
||||
}
|
||||
|
||||
if (nodeA == null || nodeA.IsQueuedForDeletion())
|
||||
{
|
||||
IInteractionInterface interactableB = nodeB as IInteractionInterface;
|
||||
if (interactableB != null)
|
||||
{
|
||||
interactableB.OnInteractionEnd();
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeB == null || nodeB.IsQueuedForDeletion())
|
||||
{
|
||||
IInteractionInterface interactableA = nodeA as IInteractionInterface;
|
||||
if (interactableA != null)
|
||||
{
|
||||
interactableA.OnInteractionEnd();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
foreach (NodePair pair in invalidInteractionPairs)
|
||||
{
|
||||
_interactionPairs.Remove(pair);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnStartInteraction(Node nodeA, Node nodeB)
|
||||
{
|
||||
IInteractionInterface interactableA = nodeA as IInteractionInterface;
|
||||
if (interactableA != null)
|
||||
{
|
||||
interactableA.OnInteractionStart();
|
||||
}
|
||||
|
||||
IInteractionInterface interactableB = nodeB as IInteractionInterface;
|
||||
if (interactableB != null)
|
||||
{
|
||||
interactableB.OnInteractionStart();
|
||||
}
|
||||
|
||||
NodePair pair = new NodePair(nodeA, nodeB);
|
||||
_interactionPairs.Add(new NodePair(nodeA, nodeB));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue