Add plane for placing blocks in hard places

This commit is contained in:
Sofia 2024-08-20 16:16:57 +03:00
parent e20c07cf84
commit 5cb1777149
3 changed files with 90 additions and 10 deletions

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=11 format=3 uid="uid://d02cqylu3xwos"] [gd_scene load_steps=14 format=3 uid="uid://d02cqylu3xwos"]
[ext_resource type="PackedScene" uid="uid://diwlyi146eroa" path="res://models/table.fbx" id="1_1soa3"] [ext_resource type="PackedScene" uid="uid://diwlyi146eroa" path="res://models/table.fbx" id="1_1soa3"]
[ext_resource type="Script" path="res://scripts/Table.cs" id="1_cb7s1"] [ext_resource type="Script" path="res://scripts/Table.cs" id="1_cb7s1"]
@ -19,7 +19,18 @@ size = Vector3(5, 5, 5)
[sub_resource type="BoxShape3D" id="BoxShape3D_3kmm7"] [sub_resource type="BoxShape3D" id="BoxShape3D_3kmm7"]
size = Vector3(1.3, 0.2, 2.4) size = Vector3(1.3, 0.2, 2.4)
[node name="table" type="RigidBody3D" node_paths=PackedStringArray("SpawnPoint", "Orbit")] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_sxhnw"]
transparency = 1
albedo_color = Color(1, 0.364706, 1, 0.219608)
[sub_resource type="PlaneMesh" id="PlaneMesh_8p75w"]
material = SubResource("StandardMaterial3D_sxhnw")
size = Vector2(5, 5)
[sub_resource type="BoxShape3D" id="BoxShape3D_1n3ll"]
size = Vector3(5, 0.001, 5)
[node name="table" type="RigidBody3D" node_paths=PackedStringArray("SpawnPoint", "Orbit", "Plane")]
collision_layer = 7 collision_layer = 7
collision_mask = 7 collision_mask = 7
lock_rotation = true lock_rotation = true
@ -31,6 +42,7 @@ BlockMaterial = ExtResource("2_1s35y")
BlockHoverMaterial = ExtResource("3_m64id") BlockHoverMaterial = ExtResource("3_m64id")
BlockGhostMaterial = ExtResource("4_twdnh") BlockGhostMaterial = ExtResource("4_twdnh")
Orbit = NodePath("Orbit") Orbit = NodePath("Orbit")
Plane = NodePath("Plane")
InteractName = "build" InteractName = "build"
[node name="table" parent="." instance=ExtResource("1_1soa3")] [node name="table" parent="." instance=ExtResource("1_1soa3")]
@ -102,4 +114,16 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1)
[node name="OrbitHand" type="Node3D" parent="Orbit/OrbitCamera"] [node name="OrbitHand" type="Node3D" parent="Orbit/OrbitCamera"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.3, -0.1, -0.26) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.3, -0.1, -0.26)
[node name="Plane" type="StaticBody3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.37762, 0)
collision_layer = 16
collision_mask = 16
[node name="MeshInstance3D" type="MeshInstance3D" parent="Plane"]
mesh = SubResource("PlaneMesh_8p75w")
skeleton = NodePath("../..")
[node name="CollisionShape3D" type="CollisionShape3D" parent="Plane"]
shape = SubResource("BoxShape3D_1n3ll")
[connection signal="Interacted" from="." to="." method="Interact"] [connection signal="Interacted" from="." to="." method="Interact"]

View File

@ -5,6 +5,8 @@ namespace Gmtk24 {
public partial class Orbit : Node3D { public partial class Orbit : Node3D {
[Signal] [Signal]
public delegate void BlockReleaseEventHandler(BuildingBlock block, uint blockReleaseTypeUint); public delegate void BlockReleaseEventHandler(BuildingBlock block, uint blockReleaseTypeUint);
[Signal]
public delegate void DraggingHeldBlockEventHandler(BuildingBlock block);
[Export(PropertyHint.Range, "0,10,0.1")] [Export(PropertyHint.Range, "0,10,0.1")]
public float MaxCameraDistance = 1f; public float MaxCameraDistance = 1f;
@ -19,6 +21,8 @@ namespace Gmtk24 {
public BuildingBlock HeldBlock { private set; get; } public BuildingBlock HeldBlock { private set; get; }
[Export] [Export]
public float RotateAmt = (float)(Math.PI / 12); public float RotateAmt = (float)(Math.PI / 12);
[Export]
public float DragDistanceTreshold = 500f;
[Export] [Export]
public bool IsEnabled { private set; get; } = false; public bool IsEnabled { private set; get; } = false;
@ -28,6 +32,10 @@ namespace Gmtk24 {
private RandomNumberGenerator RNG = new RandomNumberGenerator(); private RandomNumberGenerator RNG = new RandomNumberGenerator();
private bool PlacingBlock = false;
private Vector2 PlacingMouse = Vector2.Zero;
private bool Dragging = false;
// Called when the node enters the scene tree for the first time. // Called when the node enters the scene tree for the first time.
public override void _Ready() { public override void _Ready() {
} }
@ -35,8 +43,18 @@ namespace Gmtk24 {
// Called every frame. 'delta' is the elapsed time since the previous frame. // Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta) { public override void _Process(double delta) {
Quaternion = new Quaternion(Vector3.Up, CurrentYaw) * new Quaternion(Vector3.Right, CurrentPitch); Quaternion = new Quaternion(Vector3.Up, CurrentYaw) * new Quaternion(Vector3.Right, CurrentPitch);
if (HeldBlock != null) if (HeldBlock != null) {
HeldBlock.Position = HeldBlock.Position.Lerp(Vector3.Zero, 0.2f); HeldBlock.Position = HeldBlock.Position.Lerp(Vector3.Zero, 0.2f);
if (PlacingBlock) {
var distance = Camera.GetViewport().GetMousePosition().DistanceSquaredTo(PlacingMouse);
if (distance >= DragDistanceTreshold && !Dragging) {
Dragging = true;
EmitSignal(SignalName.DraggingHeldBlock, HeldBlock);
}
} else {
Dragging = false;
}
}
} }
public void SetEnabled(bool enabled) { public void SetEnabled(bool enabled) {
@ -76,10 +94,15 @@ namespace Gmtk24 {
EmitSignal(SignalName.BlockRelease, HeldBlock, (uint)BlockReleaseType.Throw); EmitSignal(SignalName.BlockRelease, HeldBlock, (uint)BlockReleaseType.Throw);
HeldBlock = null; HeldBlock = null;
} }
if (@event.IsActionPressed("place_block")) { if (@event.IsAction("place_block")) {
if (@event.IsPressed()) {
PlacingBlock = true;
PlacingMouse = Camera.GetViewport().GetMousePosition();
} else if (PlacingBlock) {
EmitSignal(SignalName.BlockRelease, HeldBlock, (uint)BlockReleaseType.Place); EmitSignal(SignalName.BlockRelease, HeldBlock, (uint)BlockReleaseType.Place);
HeldBlock = null; HeldBlock = null;
} }
}
if (@event.IsActionPressed("rotate_block_right")) { if (@event.IsActionPressed("rotate_block_right")) {
HeldBlock.RotateY(RotateAmt); HeldBlock.RotateY(RotateAmt);
@ -94,6 +117,8 @@ namespace Gmtk24 {
if (HeldBlock != null) if (HeldBlock != null)
return false; // TODO return false; // TODO
PlacingBlock = false;
HeldBlock = block; HeldBlock = block;
bool wasPlaced = HeldBlock.Mode == BuildingBlock.BlockMode.Placed; bool wasPlaced = HeldBlock.Mode == BuildingBlock.BlockMode.Placed;
var oldLocalRot = HeldBlock.Quaternion; var oldLocalRot = HeldBlock.Quaternion;

View File

@ -17,6 +17,8 @@ namespace Gmtk24 {
public uint BlockMask; public uint BlockMask;
[Export(PropertyHint.LayersAvoidance)] [Export(PropertyHint.LayersAvoidance)]
public uint GhostOnlyMask = 0b100000; public uint GhostOnlyMask = 0b100000;
[Export(PropertyHint.LayersAvoidance)]
public uint PlaneOnlyLayer = 0b1000000;
[ExportCategory("Block Materials")] [ExportCategory("Block Materials")]
[Export] [Export]
public ShaderMaterial BlockMaterial; public ShaderMaterial BlockMaterial;
@ -25,10 +27,14 @@ namespace Gmtk24 {
[Export] [Export]
public ShaderMaterial BlockGhostMaterial; public ShaderMaterial BlockGhostMaterial;
[ExportCategory("Scene Items")]
[Export] [Export]
public Orbit Orbit; public Orbit Orbit;
[Export]
public StaticBody3D Plane;
public BuildingBlock GhostBlock; public BuildingBlock GhostBlock;
private Vector3 GhostBlockNormal;
// Called when the node enters the scene tree for the first time. // Called when the node enters the scene tree for the first time.
public override void _Ready() { public override void _Ready() {
@ -40,6 +46,11 @@ namespace Gmtk24 {
SpawnBlocks(SpawnPos); SpawnBlocks(SpawnPos);
Orbit.BlockRelease += OnBlockRelease; Orbit.BlockRelease += OnBlockRelease;
Orbit.DraggingHeldBlock += OnBlockDrag;
Plane.CollisionLayer = PlaneOnlyLayer;
Plane.CollisionMask = PlaneOnlyLayer;
DisablePlane();
} }
public void SpawnBlocks(Vector3 position) { public void SpawnBlocks(Vector3 position) {
@ -70,11 +81,14 @@ namespace Gmtk24 {
} }
public override void _Process(double delta) { public override void _Process(double delta) {
GhostBlockNormal = Vector3.Up;
if (GhostBlock != null) { if (GhostBlock != null) {
var res = Util.RaycastFromMouse(Orbit.Camera, 0b10100); var res = Util.RaycastFromMouse(Orbit.Camera, 0b10100 | PlaneOnlyLayer);
if (res is RaycastResult results) { if (res is RaycastResult results) {
Vector3 LocalPos = results.Position - GlobalPosition; Vector3 LocalPos = results.Position - GlobalPosition;
if (results.Collider is BuildingBlock) { if (results.Collider is BuildingBlock || results.Collider == Plane) {
GhostBlockNormal = results.Normal;
Vector3 offset = GhostBlock.OffsetFrom(results.Normal, GhostOnlyMask); Vector3 offset = GhostBlock.OffsetFrom(results.Normal, GhostOnlyMask);
LocalPos += offset; LocalPos += offset;
} }
@ -107,6 +121,7 @@ namespace Gmtk24 {
Hud.InteractionPaused = false; Hud.InteractionPaused = false;
BlockReleaseType type = (BlockReleaseType)typeUint; BlockReleaseType type = (BlockReleaseType)typeUint;
DisablePlane();
block.Reparent(this); block.Reparent(this);
switch (type) { switch (type) {
@ -138,5 +153,21 @@ namespace Gmtk24 {
} }
} }
private void OnBlockDrag(BuildingBlock _) {
var offset = GhostBlock.OffsetFrom(GhostBlockNormal);
EnablePlane(GhostBlock.Position - offset, new Quaternion(Vector3.Up, GhostBlockNormal));
}
private void EnablePlane(Vector3 pos, Quaternion rot) {
Plane.Visible = true;
Plane.ProcessMode = ProcessModeEnum.Pausable;
Plane.Position = pos;
Plane.Quaternion = rot;
}
private void DisablePlane() {
Plane.Visible = false;
Plane.ProcessMode = ProcessModeEnum.Disabled;
}
} }
} }