picking up boxes like in portal

The title is pretty much covers my question. I might have jumped the gun, but I couldn’t find tutorials about it, and I only ended up finding pick-ups when searching the forums.

I basically want the player to be able to carry a box a set distance away from him when he grabs it, but I’m worried I’ll end up getting clipping through objects with the method I’m planning on using, and was wondering if any of you had any good ideas about how to handle this.

you could try creating a spring joint with the position in front of the gun. So that way if you collide with anything in the world terrain, the spring will expand and the object will move off the point. Then you can put a max distance on the spring, so that if you push to far into something, the spring breaks, and connection with the object is lost. Dropping the picked up object on the ground.

Use a separate depth only camera to render picked objects on top of scenery objects, that prevents the player to see it going through level objects.

I have been working on this for awhile and have seem to come up with a pretty decent and working script. It requires you to add a collider to all objects you want to be able to move and you can choose whether to use a rigidbody but i avoid that due to issues with objects colliding with each other weirdly. You can play around with my script due to it not being perfect but as far as i know this is the only one out there which can deal with it and if you find any improvements please PM me so I can include it with my project. Place this script on the weapon you want it to be used by and place a cursor lock script on your graphics child of your FPS player controller. Then you must make a layer called “Moveable” and place this on all objects that you want the script to affect.

var grabbed : Transform;
var grabDistance : float = 10.0f;

var useToggleDrag : boolean; // Didn't know which style you prefer. 

function Update () {
    if (useToggleDrag)
        UpdateToggleDrag();
    else
        UpdateHoldDrag();
}

// Toggles drag with mouse click
function UpdateToggleDrag () {
    if (Input.GetMouseButtonDown(0)) 
        Grab();
    else if (grabbed)
        Drag();
}

// Drags when user holds down button
function UpdateHoldDrag () {
    if (Input.GetMouseButton(0)) 
        if (grabbed)
            Drag();
        else 
            Grab();
    else
        grabbed = null;
}

function Grab() {
    if (grabbed) 
       grabbed = null;
    else {
        var hit : RaycastHit;
        var ray : Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, hit, 10,
        1 << LayerMask.NameToLayer("Moveable")))
                 grabbed = hit.transform;
    }
}

function Drag() {
    var ray : Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    var position : Vector3 = transform.position + transform.forward * grabDistance;
    var plane : Plane = new Plane(-transform.forward, position);
    var distance : float;
    if (plane.Raycast(ray, distance)) {
        grabbed.position = ray.origin + ray.direction * distance;
        grabbed.rotation = transform.rotation;
    }
}

This is a cursor lock script just push escape button to disable it.

function Start ()
{
	// Start out in paused mode in web player
	
	if (Application.platform == RuntimePlatform.OSXWebPlayer ||
	    Application.platform == RuntimePlatform.WindowsWebPlayer)
	{
		SetPause(true);
	}
	else
	{
		SetPause(false);
		Screen.lockCursor = true;
	}
}

function OnApplicationQuit ()
{
	Time.timeScale = 1;
}

function SetPause (pause : boolean)
{
	Input.ResetInputAxes();
	var gos : Object[] = FindObjectsOfType(GameObject);
	for (var go : GameObject in gos)
		go.SendMessage("DidPause", pause, SendMessageOptions.DontRequireReceiver);
	
	transform.position = Vector3.zero;
	
	if (pause)
	{
		Time.timeScale = 0;
		transform.position = Vector3 (.5, .5, 0);
		guiText.anchor = TextAnchor.MiddleCenter;
	}
	else
	{
		guiText.anchor = TextAnchor.UpperLeft;
		transform.position = Vector3(0, 1, 0);
		Time.timeScale = 1;
	}
}

function DidPause (pause : boolean)
{
	if (pause)
	{
	    // Show the button again
	    guiText.enabled = true;
		guiText.text = "Click to start playing";
	}
	else
	{
	    // Disable the button
	    guiText.enabled = true;
	    guiText.text = "Escape to show the cursor";
	}
}

function OnMouseDown ()
{
    // Lock the cursor
    Screen.lockCursor = true;
}

private var wasLocked = false;

function Update ()
{
	if (Input.GetMouseButton(0))
		Screen.lockCursor = true;
	
    // Did we lose cursor locking?
    // eg. because the user pressed escape
    // or because he switched to another application
    // or because some script set Screen.lockCursor = false;
    if (!Screen.lockCursor  wasLocked)
    {
        wasLocked = false;
        SetPause(true);
    }
    // Did we gain cursor locking?
    else if (Screen.lockCursor  !wasLocked)
    {
        wasLocked = true;
        SetPause(false);
    }
}

Sorry, I’ve only been using unity for about 2 months, and I’m not familiar with spring joints. I’ll be looking for information and tutorials on the subject and would appreciate it if you could share some you recommend.

I’ll try out your script, Nate, though I’m not a programmer and unsure if I can even apply it correctly. Still, thanks for sharing! I should be able to figure it out just looking over it now.

I got your grab script to work fine, but not the cursorlock, and since they work together, I’m kind of stuck. The play can also manage to get onto the box and start flying around on it when I have it too close, which is annoying, since i don’t want to have the box too far out, but that’s a minor issue. I don’t know why I’ve delayed adding a cursor lock for this long, either.