Make items rigid bodies

- Add a new "Item" physics layer
- Models now include their collision shape
- Item "fixes" collision shape node location
- Item initializes some collision properties
- Grid has been turned into a scene
main
copygirl 9 months ago
parent d8a9320098
commit 17da96969a
  1. 2
      assets/models/bolt.bbmodel
  2. 2
      assets/models/bolt.gltf
  3. 2
      assets/models/nail.bbmodel
  4. 2
      assets/models/nail.gltf
  5. 2
      objects/Grid.cs
  6. 22
      objects/Item.cs
  7. 13
      objects/bolt.tscn
  8. 9
      objects/grid.tscn
  9. 12
      objects/nail.tscn
  10. 1
      player/AnimationController.cs
  11. 27
      player/PickupController.cs
  12. 3
      player/player.tscn
  13. 3
      project.godot
  14. 80
      scenes/workshop.tscn
  15. 3
      scripts/globals/PhysicsLayer.cs

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -41,7 +41,7 @@ public partial class Grid : Area3D
if (_shape == null) { if (_shape == null) {
_shape = new BoxShape3D(); _shape = new BoxShape3D();
AddChild(new CollisionShape3D { Shape = _shape }); AddChild(new CollisionShape3D { Shape = _shape }, true);
} }
_shape.Size = new(GridSize.X * StepSize, 0.001f, GridSize.Y * StepSize); _shape.Size = new(GridSize.X * StepSize, 0.001f, GridSize.Y * StepSize);

@ -1,7 +1,27 @@
public partial class Item : StaticBody3D public partial class Item : RigidBody3D
{ {
[Export] public Vector3I Size { get; set; } [Export] public Vector3I Size { get; set; }
public virtual Node3D Model public virtual Node3D Model
=> GetNode<Node3D>("Model"); => GetNode<Node3D>("Model");
public override void _Ready()
{
// TODO: Find a better way to better import models with colliders.
// TODO: Import items dynamically at runtime?
// TODO: Use PostImport tool script?
foreach (var body in FindChildren("*", "StaticBody3D").Cast<StaticBody3D>()) {
foreach (var shape in body.GetChildren().OfType<CollisionShape3D>()) {
body.RemoveChild(shape);
AddChild(shape);
}
body.GetParent().RemoveChild(body);
}
// Set the collision properties here so we don't have to specify them in each item scene separately.
CollisionLayer = (uint)(PhysicsLayer.Item | PhysicsLayer.Interactable);
CollisionMask = (uint)(PhysicsLayer.Static | PhysicsLayer.Dynamic | PhysicsLayer.Player | PhysicsLayer.Item);
Freeze = FindParent("Grid") != null;
}
} }

@ -1,19 +1,10 @@
[gd_scene load_steps=4 format=3 uid="uid://bjgfm5x7a0dab"] [gd_scene load_steps=3 format=3 uid="uid://bjgfm5x7a0dab"]
[ext_resource type="Script" path="res://objects/Item.cs" id="1_43oqr"] [ext_resource type="Script" path="res://objects/Item.cs" id="1_43oqr"]
[ext_resource type="PackedScene" uid="uid://s4esxyuwyet4" path="res://assets/models/bolt.gltf" id="2_3v163"] [ext_resource type="PackedScene" uid="uid://s4esxyuwyet4" path="res://assets/models/bolt.gltf" id="2_3v163"]
[sub_resource type="CylinderShape3D" id="CylinderShape3D_1yi6b"] [node name="Bolt" type="RigidBody3D"]
height = 0.1
radius = 0.025
[node name="Bolt" type="StaticBody3D"]
collision_layer = 9
collision_mask = 0
script = ExtResource("1_43oqr") script = ExtResource("1_43oqr")
Size = Vector3i(1, 2, 1) Size = Vector3i(1, 2, 1)
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("CylinderShape3D_1yi6b")
[node name="Model" parent="." instance=ExtResource("2_3v163")] [node name="Model" parent="." instance=ExtResource("2_3v163")]

@ -0,0 +1,9 @@
[gd_scene load_steps=2 format=3 uid="uid://54575e3ygpxl"]
[ext_resource type="Script" path="res://objects/Grid.cs" id="1_7yhbt"]
[node name="Grid" type="Area3D"]
collision_layer = 256
collision_mask = 0
monitoring = false
script = ExtResource("1_7yhbt")

@ -1,18 +1,10 @@
[gd_scene load_steps=4 format=3 uid="uid://ccprmftodum0o"] [gd_scene load_steps=3 format=3 uid="uid://ccprmftodum0o"]
[ext_resource type="Script" path="res://objects/Item.cs" id="1_6pcd7"] [ext_resource type="Script" path="res://objects/Item.cs" id="1_6pcd7"]
[ext_resource type="PackedScene" uid="uid://c1fi6jcly6cx2" path="res://assets/models/nail.gltf" id="2_nls7x"] [ext_resource type="PackedScene" uid="uid://c1fi6jcly6cx2" path="res://assets/models/nail.gltf" id="2_nls7x"]
[sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_wqf35"] [node name="Nail" type="RigidBody3D"]
points = PackedVector3Array(-0.025, 0.05, -0.025, 0.025, 0.05, -0.025, 0.025, 0.05, 0.025, -0.025, 0.05, 0.025, 0, -0.05, 0)
[node name="Nail" type="StaticBody3D"]
collision_layer = 9
collision_mask = 0
script = ExtResource("1_6pcd7") script = ExtResource("1_6pcd7")
Size = Vector3i(1, 2, 1) Size = Vector3i(1, 2, 1)
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("ConvexPolygonShape3D_wqf35")
[node name="Model" parent="." instance=ExtResource("2_nls7x")] [node name="Model" parent="." instance=ExtResource("2_nls7x")]

@ -179,6 +179,5 @@ public partial class AnimationController : Node3D
var isHolding = _player.Pickup.HasItemsHeld ? 0.9f : 0.0f; var isHolding = _player.Pickup.HasItemsHeld ? 0.9f : 0.0f;
var prevIsHolding = (float)_animTree.Get(IsHoldingParam); var prevIsHolding = (float)_animTree.Get(IsHoldingParam);
_animTree.Set(IsHoldingParam, Lerp(prevIsHolding, isHolding, 8 * (float)delta)); _animTree.Set(IsHoldingParam, Lerp(prevIsHolding, isHolding, 8 * (float)delta));
// TODO: Bob `PickupController` up and down dependent on animation cycle.
} }
} }

@ -4,7 +4,6 @@ public partial class PickupController : Node3D
public bool HasItemsHeld => GetChildCount() > 0; public bool HasItemsHeld => GetChildCount() > 0;
Node3D _placementPreview; Node3D _placementPreview;
[Export] public Camera3D Camera { get; set; }
[Export] public float PickupDistance { get; set; } = 2.0f; [Export] public float PickupDistance { get; set; } = 2.0f;
Player _player; Player _player;
@ -34,13 +33,12 @@ public partial class PickupController : Node3D
// Parent item to the `PickupController`. // Parent item to the `PickupController`.
var prevRot = CurrentItem.GlobalRotation; var prevRot = CurrentItem.GlobalRotation;
CurrentItem.Freeze = true;
SetMeshLayerOutline(CurrentItem.Model, OutlineMode.Disable);
CurrentItem.GetParent().RemoveChild(CurrentItem); CurrentItem.GetParent().RemoveChild(CurrentItem);
AddChild(CurrentItem); AddChild(CurrentItem);
SetMeshLayerOutline(CurrentItem.Model, OutlineMode.Disable);
CurrentItem.Position = Vector3.Zero; CurrentItem.Position = Vector3.Zero;
CurrentItem.GlobalRotation = prevRot; CurrentItem.GlobalRotation = prevRot;
CurrentItem.CollisionLayer &= (uint)~PhysicsLayer.Static;
// CurrentItem.Freeze = true;
GetViewport().SetInputAsHandled(); GetViewport().SetInputAsHandled();
} }
@ -48,14 +46,20 @@ public partial class PickupController : Node3D
if (HasItemsHeld) { if (HasItemsHeld) {
// Parent item back to the world. // Parent item back to the world.
var prevTransform = CurrentItem.GlobalTransform; var prevTransform = CurrentItem.GlobalTransform;
CurrentItem.CollisionLayer |= (uint)PhysicsLayer.Static;
// CurrentItem.Freeze = false;
RemoveChild(CurrentItem); RemoveChild(CurrentItem);
_world.AddChild(CurrentItem); _world.AddChild(CurrentItem);
CurrentItem.GlobalTransform = _placementPreview.Visible if (_placementPreview.Visible) {
? _placementPreview.GlobalTransform CurrentItem.GlobalTransform = _placementPreview.GlobalTransform;
: prevTransform; } else {
CurrentItem.GlobalTransform = prevTransform;
CurrentItem.Freeze = false;
// Throw item forward and up a bit.
var basis = _player.Camera.Camera.GlobalBasis;
var direction = -basis.Z + basis.Y;
CurrentItem.ApplyImpulse(direction * 2);
}
RemoveChild(_placementPreview); RemoveChild(_placementPreview);
_placementPreview.QueueFree(); _placementPreview.QueueFree();
@ -120,9 +124,10 @@ public partial class PickupController : Node3D
RayResult RayToMouseCursor() RayResult RayToMouseCursor()
{ {
var camera = _player.Camera.Camera;
var mouse = GetViewport().GetMousePosition(); var mouse = GetViewport().GetMousePosition();
var from = Camera.ProjectRayOrigin(mouse); var from = camera.ProjectRayOrigin(mouse);
var to = from + Camera.ProjectRayNormal(mouse) * PickupDistance; var to = from + camera.ProjectRayNormal(mouse) * PickupDistance;
var query = PhysicsRayQueryParameters3D.Create(from, to); var query = PhysicsRayQueryParameters3D.Create(from, to);
query.CollisionMask = (uint)PhysicsLayer.Interactable; query.CollisionMask = (uint)PhysicsLayer.Interactable;

@ -1114,7 +1114,6 @@ bone_idx = 16
use_external_skeleton = true use_external_skeleton = true
external_skeleton = NodePath("../../../../../../../Model/Skeleton/Skeleton3D") external_skeleton = NodePath("../../../../../../../Model/Skeleton/Skeleton3D")
[node name="PickupController" type="Node3D" parent="." node_paths=PackedStringArray("Camera")] [node name="PickupController" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, -0.45) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, -0.45)
script = ExtResource("2_ns2pe") script = ExtResource("2_ns2pe")
Camera = NodePath("../AnimationController/Root/LowerBody/UpperBody/Neck/Head/Camera")

@ -86,7 +86,8 @@ interact_place={
3d_physics/layer_1="Static" 3d_physics/layer_1="Static"
3d_physics/layer_2="Dynamic" 3d_physics/layer_2="Dynamic"
3d_physics/layer_3="Player" 3d_physics/layer_3="Player"
3d_physics/layer_4="Interactable" 3d_physics/layer_4="Item"
3d_physics/layer_9="Interactable"
[rendering] [rendering]

@ -1,10 +1,15 @@
[gd_scene load_steps=11 format=3 uid="uid://bwfuet1irfi17"] [gd_scene load_steps=11 format=3 uid="uid://bwfuet1irfi17"]
[ext_resource type="Script" path="res://objects/Grid.cs" id="2_gstd0"]
[ext_resource type="PackedScene" uid="uid://yvy5vvaqgxy8" path="res://objects/crate.tscn" id="2_j6a20"] [ext_resource type="PackedScene" uid="uid://yvy5vvaqgxy8" path="res://objects/crate.tscn" id="2_j6a20"]
[ext_resource type="Texture2D" uid="uid://dts3g3ivc4stn" path="res://assets/palettes/metal.png" id="3_kvstu"] [ext_resource type="Texture2D" uid="uid://dts3g3ivc4stn" path="res://assets/palettes/metal.png" id="3_kvstu"]
[ext_resource type="PackedScene" uid="uid://ccprmftodum0o" path="res://objects/nail.tscn" id="4_6l6v6"] [ext_resource type="PackedScene" uid="uid://ccprmftodum0o" path="res://objects/nail.tscn" id="4_6l6v6"]
[ext_resource type="PackedScene" uid="uid://bjgfm5x7a0dab" path="res://objects/bolt.tscn" id="5_r6ljd"] [ext_resource type="PackedScene" uid="uid://bjgfm5x7a0dab" path="res://objects/bolt.tscn" id="5_r6ljd"]
[ext_resource type="PackedScene" uid="uid://54575e3ygpxl" path="res://objects/grid.tscn" id="6_okibm"]
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_5erfn"]
[sub_resource type="PlaneMesh" id="PlaneMesh_tg4vq"]
size = Vector2(10, 10)
[sub_resource type="BoxShape3D" id="BoxShape3D_vkl3b"] [sub_resource type="BoxShape3D" id="BoxShape3D_vkl3b"]
size = Vector3(2, 0.1, 1) size = Vector3(2, 0.1, 1)
@ -15,50 +20,27 @@ size = Vector3(2, 0.1, 1)
[sub_resource type="BoxMesh" id="BoxMesh_efbik"] [sub_resource type="BoxMesh" id="BoxMesh_efbik"]
size = Vector3(0.1, 0.9, 0.1) size = Vector3(0.1, 0.9, 0.1)
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_5erfn"]
[sub_resource type="PlaneMesh" id="PlaneMesh_tg4vq"]
size = Vector2(10, 10)
[node name="Workshop" type="Node3D"] [node name="Workshop" type="Node3D"]
[node name="Sun" type="DirectionalLight3D" parent="."] [node name="Sun" type="DirectionalLight3D" parent="."]
transform = Transform3D(0.866025, 0, -0.5, 0.25, 0.866025, 0.433013, 0.433013, -0.5, 0.75, 0, 5, 0) transform = Transform3D(0.866025, 0, -0.5, 0.25, 0.866025, 0.433013, 0.433013, -0.5, 0.75, 0, 5, 0)
[node name="Crates" type="Node3D" parent="."] [node name="Floor" type="StaticBody3D" parent="."]
collision_mask = 0
[node name="Crate1" parent="Crates" instance=ExtResource("2_j6a20")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 0.5, -4)
Palette = ExtResource("3_kvstu")
[node name="Crate2" parent="Crates" instance=ExtResource("2_j6a20")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 0.5, 0)
[node name="Crate3" parent="Crates" instance=ExtResource("2_j6a20")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 0.5, 4)
[node name="Crate4" parent="Crates" instance=ExtResource("2_j6a20")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 4)
[node name="Crate5" parent="Crates" instance=ExtResource("2_j6a20")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4, 0.5, 4)
[node name="Crate6" parent="Crates" instance=ExtResource("2_j6a20")] [node name="CollisionShape3D" type="CollisionShape3D" parent="Floor"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4, 0.5, 0) shape = SubResource("WorldBoundaryShape3D_5erfn")
[node name="Crate7" parent="Crates" instance=ExtResource("2_j6a20")] [node name="MeshInstance3D" type="MeshInstance3D" parent="Floor"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4, 0.5, -4) mesh = SubResource("PlaneMesh_tg4vq")
[node name="Table" type="StaticBody3D" parent="."] [node name="Table" type="StaticBody3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -4) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -4)
collision_layer = 2 collision_layer = 2
collision_mask = 0 collision_mask = 0
[node name="Grid" type="Area3D" parent="Table"] [node name="Grid" parent="Table" instance=ExtResource("6_okibm")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
collision_layer = 8
collision_mask = 0
script = ExtResource("2_gstd0")
GridSize = Vector2i(38, 18) GridSize = Vector2i(38, 18)
[node name="Nail" parent="Table/Grid" instance=ExtResource("4_6l6v6")] [node name="Nail" parent="Table/Grid" instance=ExtResource("4_6l6v6")]
@ -74,7 +56,7 @@ transform = Transform3D(-4.37114e-08, -1, -4.37114e-08, 0, -4.37114e-08, 1, -1,
transform = Transform3D(1.31134e-07, 1, 4.37114e-08, 0, -4.37114e-08, 1, 1, -1.31134e-07, -5.73206e-15, -0.75, 0.025, 0.075) transform = Transform3D(1.31134e-07, 1, 4.37114e-08, 0, -4.37114e-08, 1, 1, -1.31134e-07, -5.73206e-15, -0.75, 0.025, 0.075)
[node name="Nail5" parent="Table/Grid" instance=ExtResource("4_6l6v6")] [node name="Nail5" parent="Table/Grid" instance=ExtResource("4_6l6v6")]
transform = Transform3D(-4.37114e-08, -1, -4.37114e-08, 0, -4.37114e-08, 1, -1, 4.37114e-08, 1.91069e-15, -0.75, 0.025, 0.025) transform = Transform3D(-4.37114e-08, -1, -4.37114e-08, 0, -4.37114e-08, 1, -1, 4.37114e-08, 1.91069e-15, -0.75, 0.025, 0.0250001)
[node name="Bolt" parent="Table/Grid" instance=ExtResource("5_r6ljd")] [node name="Bolt" parent="Table/Grid" instance=ExtResource("5_r6ljd")]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.025, 0.025, 0.3) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.025, 0.025, 0.3)
@ -118,11 +100,8 @@ transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 1.5
collision_layer = 2 collision_layer = 2
collision_mask = 0 collision_mask = 0
[node name="Grid" type="Area3D" parent="Table2"] [node name="Grid" parent="Table2" instance=ExtResource("6_okibm")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.0999999, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0)
collision_layer = 8
collision_mask = 0
script = ExtResource("2_gstd0")
GridSize = Vector2i(38, 18) GridSize = Vector2i(38, 18)
[node name="CollisionShape3D" type="CollisionShape3D" parent="Table2"] [node name="CollisionShape3D" type="CollisionShape3D" parent="Table2"]
@ -133,11 +112,26 @@ shape = SubResource("BoxShape3D_vkl3b")
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.0499997, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.0499997, 0)
mesh = SubResource("BoxMesh_548mk") mesh = SubResource("BoxMesh_548mk")
[node name="Floor" type="StaticBody3D" parent="."] [node name="Crates" type="Node3D" parent="."]
collision_mask = 0
[node name="CollisionShape3D" type="CollisionShape3D" parent="Floor"] [node name="Crate1" parent="Crates" instance=ExtResource("2_j6a20")]
shape = SubResource("WorldBoundaryShape3D_5erfn") transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 0.5, -4)
Palette = ExtResource("3_kvstu")
[node name="MeshInstance3D" type="MeshInstance3D" parent="Floor"] [node name="Crate2" parent="Crates" instance=ExtResource("2_j6a20")]
mesh = SubResource("PlaneMesh_tg4vq") transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 0.5, 0)
[node name="Crate3" parent="Crates" instance=ExtResource("2_j6a20")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 0.5, 4)
[node name="Crate4" parent="Crates" instance=ExtResource("2_j6a20")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 4)
[node name="Crate5" parent="Crates" instance=ExtResource("2_j6a20")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4, 0.5, 4)
[node name="Crate6" parent="Crates" instance=ExtResource("2_j6a20")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4, 0.5, 0)
[node name="Crate7" parent="Crates" instance=ExtResource("2_j6a20")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4, 0.5, -4)

@ -3,5 +3,6 @@ public enum PhysicsLayer : uint {
Static = 1 << 0, Static = 1 << 0,
Dynamic = 1 << 1, Dynamic = 1 << 1,
Player = 1 << 2, Player = 1 << 2,
Interactable = 1 << 3, Item = 1 << 3,
Interactable = 1 << 8,
} }

Loading…
Cancel
Save