HookShot, that is. I haven’t checked if HookShot is owned by Nintendo or if I should use a different name. Well the visuals aren’t that import right now. What’s important is that you click, and you move. Great stuff.
I threw this together in my spare time over the course of a couple days. I’d probably want the player to be pulled to the center of the two hook locations when they’re both active.
Oh i also implemented this so that the hookshots are modular. You could theoretically have as many hooks as you’d like
So maybe press and release isn’t the right way to do it. Maybe press and then press again to release that same one.
Then you could have 4 hooks with varying attributes bound to ‘QWER’ like a MOBA.
The hooks themselves have two parts; the main hook that moves through space, and a script for the rigidbody “Tip” of the hook, which overrides the _IntegrateForces
function from Godot. It looks at whatever it’s made contact with and checks whether it’s an active target or just an obstacle.
using Godot;
public partial class Hook : RigidBody3D
{
public override void _IntegrateForces(PhysicsDirectBodyState3D state){
for (var i = 0; i < state.GetContactCount(); i++){
var obj = state.GetContactColliderObject(i) as Node3D;
var Body = obj as CollisionObject3D;
var Map = obj as GridMap;
uint layer = 0;
if(Body != null) layer |= Body.CollisionLayer;
if(Map != null) layer |= Map.CollisionLayer;
var Hook = GetParent() as HookShot;
if((layer & 10) != 0 && Hook.Firing && !Hook.Player.Collisions.Contains(obj)){
Hook.Firing = false;
Hook.Retracting = true;
GD.Print($"{obj.Name}");
if((layer & 8) != 0 && Hook.Released ){
Hook.ContactPoint = state.GetContactLocalPosition(i);
Hook.HookedTarget = obj;
Hook.Collisions.Add(obj);
Hook.Player.Collisions.Add(obj);
Hook.Connected = true;
Hook.Released = false;
}
}
}
}
}
As of right now, the style of movement is pretty static. I’m trying to decide whether I want to make it more fast paced, or keep it slow and methodical like it is now.
The current iteration does lend itself to being a lot slower.
The hookshots are rendered using a portal shader, so only stuff inside the box gets rendered. I have a feeling this will be useful in future projects.
shader_type spatial;
render_mode depth_prepass_alpha,cull_disabled;
uniform bool masked = false;//set to true if passing thru a portal
uniform vec3 Portal_Global_Origin;
uniform vec3 Portal_Size;
uniform vec3 Portal_Rotation;
uniform sampler2D object_texture;
varying float y_f;
varying vec3 world_position;
void vertex() {
if(masked){
world_position = VERTEX;
}
}
void fragment() {
if(masked){
ALPHA_SCISSOR_THRESHOLD = 2.0; // Hide everything
vec3 offset = world_position - Portal_Global_Origin;
if(offset.x < Portal_Size.x && offset.x > -Portal_Size.x){
if(offset.y < Portal_Size.y && offset.y > -Portal_Size.y){
if(offset.z < Portal_Size.z && offset.z > -Portal_Size.z){
ALPHA_SCISSOR_THRESHOLD = 0.0; // If we're inside the Portal, show the object
}
}
}
}
ALBEDO = texture(object_texture, UV).rgb; // Get the texture color
}