i’m sure you have all played it
in oblivion you can basically snatch up an object and toss it around by using the right and left mouse buttons.
my question is, what is the general mechanics of this feature? do you spawn a small invisible sphere which “sticks” the object to your mouse cursor, and the invisible sphere is scripted to copy your every mouselook movement?
or perhaps it is something more elaborate using rays?
I can’t say for sure, but I’d assume they update the object’s position based on relative distance from the camera. This would probably be your friend in such a situation Unity - Scripting API: Camera.ScreenPointToRay .
the trouble with this is that you’d have to write something on top of the physics engine already in place that governs all objects, and probably needs to be a script on all intractable objects.
the invisible sphere thing i was talking about would work WITH the physics engine, but there could be problems pertaining to how colliders work (a collider spawned within a collider? uh oh)
Have you had a look at the Drag Rigidbody script? Its pretty close. There’s a few versions floating around, but just incase you did’nt know where to find one Here u go
var spring = 50.0;
var damper = 5.0;
var drag = 10.0;
var angularDrag = 5.0;
var distance = 0.2;
var attachToCenterOfMass = false;
private var springJoint : SpringJoint;
function Update ()
{
// Make sure the user pressed the mouse down
if (!Input.GetMouseButtonDown (0))
return;
var mainCamera = FindCamera();
// We need to actually hit an object
var hit : RaycastHit;
if (!Physics.Raycast(mainCamera.ScreenPointToRay(Input.mousePosition), hit, 100))
return;
// We need to hit a rigidbody that is not kinematic
if (!hit.rigidbody || hit.rigidbody.isKinematic)
return;
if (!springJoint)
{
var go = new GameObject("Rigidbody dragger");
var body : Rigidbody = go.AddComponent ("Rigidbody") as Rigidbody;
springJoint = go.AddComponent ("SpringJoint");
body.isKinematic = true;
}
springJoint.transform.position = hit.point;
if (attachToCenterOfMass)
{
var anchor = transform.TransformDirection(hit.rigidbody.centerOfMass) + hit.rigidbody.transform.position;
anchor = springJoint.transform.InverseTransformPoint(anchor);
springJoint.anchor = anchor;
}
else
{
springJoint.anchor = Vector3.zero;
}
springJoint.spring = spring;
springJoint.damper = damper;
springJoint.maxDistance = distance;
springJoint.connectedBody = hit.rigidbody;
StartCoroutine ("DragObject", hit.distance);
}
function DragObject (distance : float)
{
var oldDrag = springJoint.connectedBody.drag;
var oldAngularDrag = springJoint.connectedBody.angularDrag;
springJoint.connectedBody.drag = drag;
springJoint.connectedBody.angularDrag = angularDrag;
var mainCamera = FindCamera();
while (Input.GetMouseButton (0))
{
var ray = mainCamera.ScreenPointToRay (Input.mousePosition);
springJoint.transform.position = ray.GetPoint(distance);
yield;
}
if (springJoint.connectedBody)
{
springJoint.connectedBody.drag = oldDrag;
springJoint.connectedBody.angularDrag = oldAngularDrag;
springJoint.connectedBody = null;
}
}
function FindCamera ()
{
if (camera)
return camera;
else
return Camera.main;
}
That rigidbody script looks better than what I had in mind. I would have suggested a Configurable Joint, and setting its Target Position. My idea could get in the way of other uses for the Target Position.
this drag rigidbody script is pretty nice. lots of variables to toy around with
my only complaints are that the object is in a kind of “tagalong” mode with the cursor, instead of staying on the cursor at all times, but this might be more realistic.
also, this is more of an issue on my end, but the grabbing occurs at the mouse pointer, not the center of the screen where the character is looking. so you end up holding the object somewhat off center at all times. But this can be remedied by simply upping mouse sensitivity and tweaking the mouselook script.