Skip to content

Instantly share code, notes, and snippets.

@GammaGames
Created May 13, 2022 13:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GammaGames/bc92c2d4c9d0c59b7a9aad45d457d316 to your computer and use it in GitHub Desktop.
Save GammaGames/bc92c2d4c9d0c59b7a9aad45d457d316 to your computer and use it in GitHub Desktop.
Simple “yanking” implementation of a grappling hook for VR in Godot
extends "res://Tools/UsableObject.gd"
var using = false
onready var ray = $Raycast
onready var hook = $Hook
onready var rope = $Rope
onready var laser = $Laser
onready var indicator = $Indicator
onready var initial_transform = transform
var hook_body = null
var start_origin = null
var target = null
var player = null
func _ready():
laser.clear()
laser.begin(1)
laser.add_vertex(ray.transform.origin)
laser.add_vertex(ray.cast_to)
laser.end()
func _physics_process(state):
if using and target:
var target_velocity = target - global_transform.origin
var offset = start_origin - get_parent().get_parent().transform.origin
player.apply_impulse(Vector3.ZERO, target_velocity.normalized() * 0.5 * offset.length())
elif player:
if ray.is_colliding():
indicator.get_surface_material(0).albedo_color = Color.webgreen
else:
indicator.get_surface_material(0).albedo_color = Color.red
func pick_up(by):
.pick_up(by)
player = get_parent().player
ray.enabled = true
laser.visible = true
indicator.visible = true
func let_go(impulse=Vector3.ZERO):
player = null
unuse()
laser.visible = false
.let_go(impulse)
transform = initial_transform
mode = RigidBody.MODE_STATIC
indicator.visible = false
ray.enabled = false
func use(by):
using = true
ray.force_raycast_update()
if ray.is_colliding():
hook_body = ray.get_collider()
start_origin = get_parent().get_parent().transform.origin
target = ray.get_collision_point()
hook.visible = true
laser.visible = false
remove_child(hook)
hook_body.add_child(hook)
hook.global_transform.origin = target
rope.enabled = true
func unuse():
using = false
rope.enabled = false
hook.visible = false
laser.visible = true
if hook_body:
hook_body.remove_child(hook)
add_child(hook)
hook_body = null
target = null
[gd_scene load_steps=12 format=2]
[ext_resource path="res://Tools/UsableObject.tscn" type="PackedScene" id=1]
[ext_resource path="res://Objects/Grapple.gd" type="Script" id=2]
[ext_resource path="res://Assets/Models/AssetForge/grapple.obj" type="ArrayMesh" id=3]
[ext_resource path="res://Objects/Rope.gd" type="Script" id=4]
[sub_resource type="CylinderShape" id=10]
radius = 0.1
height = 0.3
[sub_resource type="SpatialMaterial" id=4]
albedo_color = Color( 0.278431, 0.278431, 0.278431, 1 )
metallic = 0.47
roughness = 0.63
[sub_resource type="SphereMesh" id=5]
material = SubResource( 4 )
radius = 0.05
height = 0.1
radial_segments = 8
rings = 8
[sub_resource type="SpatialMaterial" id=6]
flags_transparent = true
albedo_color = Color( 1, 0, 0, 0.501961 )
[sub_resource type="SpatialMaterial" id=7]
albedo_color = Color( 0, 0, 0, 1 )
metallic_specular = 0.0
[sub_resource type="PlaneMesh" id=8]
size = Vector2( 0.03, 0.01 )
[sub_resource type="SpatialMaterial" id=9]
resource_local_to_scene = true
albedo_color = Color( 1, 0, 0, 1 )
[node name="Grapple" instance=ExtResource( 1 )]
script = ExtResource( 2 )
[node name="CollisionShape" parent="." index="0"]
transform = Transform( 1, 0, 0, 0, -4.37114e-008, -1, 0, 1, -4.37114e-008, 0, 0, 0.0321951 )
shape = SubResource( 10 )
[node name="grapple" type="MeshInstance" parent="." index="1"]
transform = Transform( 0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, -0.034271, 0.0126667, -0.0675699 )
mesh = ExtResource( 3 )
material/0 = null
material/1 = null
material/2 = null
material/3 = null
material/4 = null
material/5 = null
material/6 = null
material/7 = null
material/8 = null
material/9 = null
material/10 = null
material/11 = null
material/12 = null
material/13 = null
material/14 = null
material/15 = null
material/16 = null
material/17 = null
[node name="Raycast" type="RayCast" parent="." index="2"]
cast_to = Vector3( 0, 0, -35 )
collision_mask = 10
[node name="Hook" type="MeshInstance" parent="." index="3"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.06 )
visible = false
mesh = SubResource( 5 )
material/0 = null
[node name="Laser" type="ImmediateGeometry" parent="." index="4"]
visible = false
material_override = SubResource( 6 )
[node name="Rope" type="ImmediateGeometry" parent="." index="5"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.06 )
material_override = SubResource( 7 )
script = ExtResource( 4 )
start_node = NodePath("..")
end_node = NodePath("../Hook")
[node name="Indicator" type="MeshInstance" parent="." index="6"]
transform = Transform( 1, 0, 0, 0, -4.37114e-008, -1, 0, 1, -4.37114e-008, 0.00157227, 0.0612243, 0.00321842 )
mesh = SubResource( 8 )
material/0 = SubResource( 9 )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment