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="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"]
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_mask = 7
lock_rotation = true
@ -31,6 +42,7 @@ BlockMaterial = ExtResource("2_1s35y")
BlockHoverMaterial = ExtResource("3_m64id")
BlockGhostMaterial = ExtResource("4_twdnh")
Orbit = NodePath("Orbit")
Plane = NodePath("Plane")
InteractName = "build"
[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"]
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"]

View File

@ -5,6 +5,8 @@ namespace Gmtk24 {
public partial class Orbit : Node3D {
[Signal]
public delegate void BlockReleaseEventHandler(BuildingBlock block, uint blockReleaseTypeUint);
[Signal]
public delegate void DraggingHeldBlockEventHandler(BuildingBlock block);
[Export(PropertyHint.Range, "0,10,0.1")]
public float MaxCameraDistance = 1f;
@ -19,6 +21,8 @@ namespace Gmtk24 {
public BuildingBlock HeldBlock { private set; get; }
[Export]
public float RotateAmt = (float)(Math.PI / 12);
[Export]
public float DragDistanceTreshold = 500f;
[Export]
public bool IsEnabled { private set; get; } = false;
@ -28,6 +32,10 @@ namespace Gmtk24 {
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.
public override void _Ready() {
}
@ -35,8 +43,18 @@ namespace Gmtk24 {
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta) {
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);
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) {
@ -76,9 +94,14 @@ namespace Gmtk24 {
EmitSignal(SignalName.BlockRelease, HeldBlock, (uint)BlockReleaseType.Throw);
HeldBlock = null;
}
if (@event.IsActionPressed("place_block")) {
EmitSignal(SignalName.BlockRelease, HeldBlock, (uint)BlockReleaseType.Place);
HeldBlock = null;
if (@event.IsAction("place_block")) {
if (@event.IsPressed()) {
PlacingBlock = true;
PlacingMouse = Camera.GetViewport().GetMousePosition();
} else if (PlacingBlock) {
EmitSignal(SignalName.BlockRelease, HeldBlock, (uint)BlockReleaseType.Place);
HeldBlock = null;
}
}
if (@event.IsActionPressed("rotate_block_right")) {
@ -94,6 +117,8 @@ namespace Gmtk24 {
if (HeldBlock != null)
return false; // TODO
PlacingBlock = false;
HeldBlock = block;
bool wasPlaced = HeldBlock.Mode == BuildingBlock.BlockMode.Placed;
var oldLocalRot = HeldBlock.Quaternion;

View File

@ -8,7 +8,7 @@ namespace Gmtk24 {
[Export(PropertyHint.NodeType, "FuncGodotMap")]
public Node3D TrenchbroomMap;
[ExportCategory("SpawnOptions")]
[ExportCategory("Spawn Options")]
[Export]
public float RelativeScale = 0.05f;
[Export]
@ -17,7 +17,9 @@ namespace Gmtk24 {
public uint BlockMask;
[Export(PropertyHint.LayersAvoidance)]
public uint GhostOnlyMask = 0b100000;
[ExportCategory("BlockMaterials")]
[Export(PropertyHint.LayersAvoidance)]
public uint PlaneOnlyLayer = 0b1000000;
[ExportCategory("Block Materials")]
[Export]
public ShaderMaterial BlockMaterial;
[Export]
@ -25,10 +27,14 @@ namespace Gmtk24 {
[Export]
public ShaderMaterial BlockGhostMaterial;
[ExportCategory("Scene Items")]
[Export]
public Orbit Orbit;
[Export]
public StaticBody3D Plane;
public BuildingBlock GhostBlock;
private Vector3 GhostBlockNormal;
// Called when the node enters the scene tree for the first time.
public override void _Ready() {
@ -40,6 +46,11 @@ namespace Gmtk24 {
SpawnBlocks(SpawnPos);
Orbit.BlockRelease += OnBlockRelease;
Orbit.DraggingHeldBlock += OnBlockDrag;
Plane.CollisionLayer = PlaneOnlyLayer;
Plane.CollisionMask = PlaneOnlyLayer;
DisablePlane();
}
public void SpawnBlocks(Vector3 position) {
@ -70,11 +81,14 @@ namespace Gmtk24 {
}
public override void _Process(double delta) {
GhostBlockNormal = Vector3.Up;
if (GhostBlock != null) {
var res = Util.RaycastFromMouse(Orbit.Camera, 0b10100);
var res = Util.RaycastFromMouse(Orbit.Camera, 0b10100 | PlaneOnlyLayer);
if (res is RaycastResult results) {
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);
LocalPos += offset;
}
@ -107,6 +121,7 @@ namespace Gmtk24 {
Hud.InteractionPaused = false;
BlockReleaseType type = (BlockReleaseType)typeUint;
DisablePlane();
block.Reparent(this);
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;
}
}
}