Skip to content

Instantly share code, notes, and snippets.

@kurtdekker
Created June 13, 2026 15:20
Show Gist options
  • Select an option

  • Save kurtdekker/254996b7fbde7d0e61d09309b686c134 to your computer and use it in GitHub Desktop.

Select an option

Save kurtdekker/254996b7fbde7d0e61d09309b686c134 to your computer and use it in GitHub Desktop.
ultra simple Gravity Gun
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// @kurtdekker - gravity gun attachment
//
// We presume you attached this to a new GameObject parented to a
// camera that looks where you want to fire the gravity gun.
//
// This only scans for things with a Grippable Component on them.
//
// Press Y to yoink / let go of things with the gravity gun
//
// Press T to throw it if you're carrying it
//
public class GravityGunAccessory : MonoBehaviour
{
[Header("Where in front of you the load tries to be:")]
public Vector3 GripAhead = new Vector3(1, 1, 4);
[Header("We won't consider beyond this range:")]
public float GripDistance = 10;
// non-null means you're gripping
Grippable current;
// desired point in space ahead of you for carrying the object
Vector3 center => transform.position + transform.rotation * GripAhead;
void GripToggle( bool fling = false)
{
if (current)
{
current.rb.useGravity = true;
if (fling)
{
// pure forward
Vector3 tossDirection = transform.forward;
// up a bit
tossDirection.y += 0.2f;
// scale
tossDirection *= 30;
// by adding, you can whip it to one side by spinning
current.rb.velocity += tossDirection;
}
// let go / drop!
current = null;
}
else
{
// TODO: feel free to implement your own object finder here.
var grippables = FindObjectsOfType<Grippable>();
float bestDistance = 0;
Grippable best = null;
foreach( var grippable in grippables)
{
float distance = Vector3.Distance(grippable.transform.position, center);
if (distance < GripDistance)
{
if (best == null || distance < bestDistance)
{
best = grippable;
bestDistance = distance;
}
}
}
if (best)
{
current = best;
}
}
}
void UpdateCheckGrip()
{
bool toggleGrip = false;
bool fling = false;
// check your inputs here...
if (Input.GetKeyDown(KeyCode.Y))
{
toggleGrip = true;
}
if (Input.GetKeyDown(KeyCode.T))
{
toggleGrip = true;
fling = true;
}
if (toggleGrip)
{
GripToggle(fling);
}
}
void Update()
{
UpdateCheckGrip();
}
private void FixedUpdate()
{
if (current)
{
float dt = Time.deltaTime;
// we want to hold the object here
Vector3 target = center;
// error term
Vector3 delta = target - current.transform.position;
Vector3 direction = delta.normalized;
float distance = delta.magnitude;
Rigidbody rb = current.rb;
rb.useGravity = false;
float mass = rb.mass;
Vector3 velocity = rb.velocity;
// tuning: velocity damping
float velocityDamping = 10.0f;
velocity -= velocity * velocityDamping * dt;
rb.velocity = velocity;
// tuning: force scaling
float forceScale = 140.0f;
Vector3 force = direction * distance * forceScale;
rb.AddForce(force * mass);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// tags an object as something you can grip
//
// put one of these on things you want to carry
[RequireComponent(typeof(Rigidbody))]
public class Grippable : MonoBehaviour
{
public Rigidbody rb => GetComponent<Rigidbody>();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment