You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
86 lines
2.8 KiB
GDScript
86 lines
2.8 KiB
GDScript
2 years ago
|
extends Spatial
|
||
|
|
||
|
export(NodePath) var LookAtTarget setget _set_lookAtTarget_path
|
||
|
|
||
|
### Railgun turret entity controller
|
||
|
|
||
|
|
||
|
onready var skeleton = $Armature/Skeleton
|
||
|
onready var turret_yaw_bone = skeleton.find_bone("turret head")
|
||
|
onready var turret_pitch_bone = skeleton.find_bone("vertical joint")
|
||
|
onready var vert_eyes = $VertEyes
|
||
|
onready var turret_eyes = $Armature/Skeleton/turretAttachement/TurretEyes
|
||
|
|
||
|
var first_call: bool = true
|
||
|
var target: Position3D
|
||
|
|
||
|
#var additional_rotation = Vector3(90, 0, 0)
|
||
|
|
||
|
func _set_lookAtTarget_path(new_value):
|
||
|
# Because get_node doesn't work in the first call, we just want to assign instead.
|
||
|
# This is to get around a issue with NodePaths exposed to the editor.
|
||
|
if first_call:
|
||
|
LookAtTarget = new_value
|
||
|
return
|
||
|
|
||
|
# Assign skeleton_path to whatever value is passed.
|
||
|
LookAtTarget = new_value
|
||
|
|
||
|
if LookAtTarget == null:
|
||
|
return
|
||
|
|
||
|
# Get the node at that location, if there is one.
|
||
|
var temp = get_node(LookAtTarget)
|
||
|
if temp != null:
|
||
|
if temp is Position3D:
|
||
|
target = get_node(LookAtTarget)
|
||
|
return
|
||
|
else:
|
||
|
print("Railgun.gd: Got invalid LookAtTarget: ", LookAtTarget)
|
||
|
return
|
||
|
else:
|
||
|
print("Railgun.gd: Got no LookAtTarget: ", LookAtTarget)
|
||
|
|
||
|
func _ready():
|
||
|
pass # configuring skeletonIK
|
||
|
|
||
|
|
||
|
func _process(delta):
|
||
|
# Calculating the two points where the vertical joint should point to to aim at the target
|
||
|
"""
|
||
|
var T = target.transform.origin
|
||
|
var C = skeleton.get_bone_global_pose(turret_pitch_bone).origin # Vector3 root of the pitch bone
|
||
|
|
||
|
var radius_C = (skeleton.get_bone_global_pose(turret_yaw_bone).origin - C).length()
|
||
|
var normal_C = (T-C).normalized()
|
||
|
|
||
|
var normal_C_angle = acos(Vector3(0, normal_C.y, normal_C.z).dot(normal_C)) # to transform the T point into a 2D plane and THEN do 2D circle intersection
|
||
|
|
||
|
var radius_T = (T - C).length() # length of CT which will be the radius of the circle around T"""
|
||
|
if first_call:
|
||
|
first_call = false
|
||
|
if target == null:
|
||
|
_set_lookAtTarget_path(LookAtTarget)
|
||
|
|
||
|
var turret_height_diff = (turret_eyes.global_transform.origin - vert_eyes.global_transform.origin)
|
||
|
|
||
|
vert_eyes.look_at((target.global_transform.origin-turret_height_diff), Vector3.UP)
|
||
|
skeleton.set_bone_pose(turret_pitch_bone, Basis(Vector3.RIGHT, -1*vert_eyes.rotation.x))
|
||
|
|
||
|
var vert_bone_direction = skeleton.get_bone_pose(turret_pitch_bone) * Vector3.UP
|
||
|
|
||
|
var target_pos = skeleton.global_transform.xform_inv(target.global_transform.origin)
|
||
|
|
||
|
var rest = skeleton.get_bone_global_pose(turret_yaw_bone)
|
||
|
rest = rest.looking_at(target_pos, vert_bone_direction)
|
||
|
|
||
|
# Get the rotation euler of the bone and of this node.
|
||
|
#var rest_euler = rest.basis.get_euler()
|
||
|
|
||
|
# Apply additional rotation stored in additional_rotation to the bone.
|
||
|
|
||
|
# Make a new basis with the, potentially, changed euler angles.
|
||
|
#rest.basis = Basis(rest_euler)
|
||
|
|
||
|
skeleton.set_bone_global_pose_override(turret_yaw_bone, rest, 1, true)
|