Improved socket script and added hologram logic to show preview of where the pickupable will attach. Also added lock and key meshes.
This commit is contained in:
+10
-4
@@ -14,6 +14,7 @@ class_name Pickupable
|
||||
@export var maxDistance: float = 4.0
|
||||
@export var body: RigidBody3D
|
||||
@export var snapAnchor: Marker3D
|
||||
@export var visualMeshNode: MeshInstance3D
|
||||
|
||||
@export_range(0.01, 1000.0, 0.01) var bodyMass: float = 1.0
|
||||
|
||||
@@ -43,7 +44,15 @@ func beginInteract(player, hitPosition: Vector3):
|
||||
func updateInteract(player):
|
||||
if !dragging:
|
||||
return
|
||||
|
||||
|
||||
if Input.is_action_just_pressed("action") and currentSocket != null:
|
||||
if currentSocket.attachedObject == self:
|
||||
currentSocket.detachObject()
|
||||
else:
|
||||
if currentSocket.attachObject(self):
|
||||
endInteract(player)
|
||||
return
|
||||
|
||||
body.sleeping = false
|
||||
|
||||
# Toggle rotation mode
|
||||
@@ -117,9 +126,6 @@ func endInteract(player):
|
||||
rotating = false
|
||||
player.setMouseFactors(1.0, 1.0)
|
||||
playerRef = null
|
||||
|
||||
if currentSocket != null and currentSocket.isInRange(self):
|
||||
currentSocket.snapObject(self)
|
||||
|
||||
func throw():
|
||||
if !dragging:
|
||||
|
||||
+61
-35
@@ -5,68 +5,94 @@ extends Node3D
|
||||
@export var snapArea: Area3D
|
||||
@export var snapDistance: float = 0.5
|
||||
@export var lockOnSnap: bool = true
|
||||
@export var hologramMaterial: Material
|
||||
|
||||
var hologramInstance: MeshInstance3D
|
||||
var candidate: Pickupable = null
|
||||
var snappedObject: Pickupable = null
|
||||
var attachedObject: Pickupable = null
|
||||
|
||||
func _ready() -> void:
|
||||
if snapArea:
|
||||
snapArea.body_entered.connect(onBodyEntered)
|
||||
snapArea.body_exited.connect(onBodyExited)
|
||||
|
||||
hologramInstance = MeshInstance3D.new()
|
||||
hologramInstance.top_level = true
|
||||
hologramInstance.visible = false
|
||||
|
||||
if hologramMaterial:
|
||||
hologramInstance.material_override = hologramMaterial
|
||||
|
||||
add_child(hologramInstance)
|
||||
|
||||
func isInRange(object: Pickupable) -> bool:
|
||||
if object == null:
|
||||
func canAttach(object: Pickupable) -> bool:
|
||||
if attachedObject != null:
|
||||
return false
|
||||
|
||||
if object.snapAnchor == null:
|
||||
if object == null or object.snapAnchor == null:
|
||||
return false
|
||||
|
||||
var distance := object.snapAnchor.global_position.distance_to(
|
||||
snapPoint.global_position
|
||||
)
|
||||
|
||||
var distance := object.snapAnchor.global_position.distance_to(snapPoint.global_position)
|
||||
return distance <= snapDistance
|
||||
|
||||
func attachObject(object: Pickupable) -> bool:
|
||||
if not canAttach(object):
|
||||
return false
|
||||
|
||||
var targetTransform := getSnapTransform(object)
|
||||
var body := object.body
|
||||
body.linear_velocity = Vector3.ZERO
|
||||
body.angular_velocity = Vector3.ZERO
|
||||
body.global_transform = targetTransform
|
||||
|
||||
if lockOnSnap:
|
||||
body.freeze = true
|
||||
|
||||
attachedObject = object
|
||||
candidate = null
|
||||
object.currentSocket = self
|
||||
|
||||
if hologramInstance:
|
||||
hologramInstance.visible = false
|
||||
|
||||
return true
|
||||
|
||||
func detachObject() -> void:
|
||||
if attachedObject == null:
|
||||
return
|
||||
|
||||
var body := attachedObject.body
|
||||
if lockOnSnap:
|
||||
body.freeze = false
|
||||
|
||||
attachedObject.currentSocket = null
|
||||
attachedObject = null
|
||||
|
||||
func getSnapTransform(object: Pickupable) -> Transform3D:
|
||||
var objectTransform := object.body.global_transform
|
||||
var anchorTransform := object.snapAnchor.global_transform
|
||||
|
||||
# Where is the SnapAnchor relative to the Rigidbody?
|
||||
var anchorOffset := objectTransform.affine_inverse() * anchorTransform
|
||||
|
||||
# We want the SnapAnchor to have exactly the same
|
||||
# transform as the Socket's SnapPoint.
|
||||
return snapPoint.global_transform * anchorOffset.affine_inverse()
|
||||
|
||||
func snapObject(object: Pickupable):
|
||||
if not isInRange(object):
|
||||
return
|
||||
|
||||
var targetTransform := getSnapTransform(object)
|
||||
|
||||
var body := object.body
|
||||
|
||||
body.linear_velocity = Vector3.ZERO
|
||||
body.angular_velocity = Vector3.ZERO
|
||||
|
||||
body.global_transform = targetTransform
|
||||
|
||||
if lockOnSnap:
|
||||
body.freeze = true
|
||||
|
||||
snappedObject = object
|
||||
candidate = null
|
||||
|
||||
func onBodyEntered(body: Node3D):
|
||||
if attachedObject != null: return
|
||||
if body is RigidBody3D and body.get_parent() is Pickupable:
|
||||
var pickup = body.get_parent() as Pickupable
|
||||
pickup.currentSocket = self
|
||||
candidate = pickup
|
||||
|
||||
if pickup.visualMeshNode and pickup.visualMeshNode.mesh:
|
||||
hologramInstance.mesh = pickup.visualMeshNode.mesh
|
||||
var targetBodyTransform = getSnapTransform(pickup)
|
||||
var meshLocalTranform = pickup.body.global_transform.affine_inverse() * pickup.visualMeshNode.global_transform
|
||||
hologramInstance.global_transform = targetBodyTransform * meshLocalTranform
|
||||
hologramInstance.visible = true
|
||||
|
||||
func onBodyExited(body: Node3D):
|
||||
if body is RigidBody3D and body.get_parent() is Pickupable:
|
||||
var pickup = body.get_parent() as Pickupable
|
||||
if pickup.currentSocket == self:
|
||||
if pickup.currentSocket == self and attachedObject != pickup:
|
||||
pickup.currentSocket = null
|
||||
if candidate == pickup:
|
||||
candidate = null
|
||||
|
||||
if hologramInstance:
|
||||
hologramInstance.visible = false
|
||||
|
||||
Reference in New Issue
Block a user