- Home /
Checking Player's distance to an Object
Hello. I am using a script which lets me grab and carry Objects around.
But the problem is, I can grab it anywhere, and that is not what I want.
Could someone help me out and tell me how could I check the Player's distance to an Object, not allowing Player to grab the Object from too far. I apologize, English is not my first language.
Anyway, this is the code I am using.
private var pickObj: Transform = null; private var hit: RaycastHit; private var dist: float; private var newPos: Vector3;
function Update(){
if (Input.GetMouseButton(0)){ // if left button creates a ray from the mouse
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (!pickObj){ // if nothing picked yet...
if (Physics.Raycast(ray, hit) && hit.transform.tag == "Pick"){
// if it's a rigidbody, zero its physics velocity
if (hit.rigidbody) hit.rigidbody.velocity = Vector3.zero;
pickObj = hit.transform; // now there's an object picked
// remember its distance from the camera
dist = Vector3.Distance(pickObj.position, Camera.main.transform.position);
}
}
else { // if object already picked...
newPos = ray.GetPoint(dist); // transport the object
pickObj.position = newPos; // to the mouse position
}
}
else { // when button released free pickObj
pickObj = null;
}
}
Also, if you know how to prevent the Object going through walls, could you tell me how? Thanks in advance.
Answer by thellama · Jul 28, 2012 at 06:21 PM
Notice I added a distance float and check between the object and the camera on your third if statement. Just adjust the distance float and it will check the distance and see if the object is within your grabbable distance!
var pickObj: Transform = null;
private var hit: RaycastHit;
private var dist: float;
private var newPos: Vector3;
var distance : float = 5;
function Update(){
if (Input.GetMouseButton(0)){ // if left button creates a ray from the mouse
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (!pickObj){ // if nothing picked yet...
if (Physics.Raycast(ray, hit) && hit.transform.tag == "Pick" && Vector3.Distance(Camera.main.transform.position, hit.transform.position) < distance){
// if it's a rigidbody, zero its physics velocity
if (hit.rigidbody) hit.rigidbody.velocity = Vector3.zero;
pickObj = hit.transform; // now there's an object picked
// remember its distance from the camera
dist = Vector3.Distance(pickObj.position, Camera.main.transform.position);
}
}
else { // if object already picked...
newPos = ray.GetPoint(dist); // transport the object
hit.rigidbody.MovePosition(newPos); // to the mouse position
}
}
else { // when button released free pickObj
pickObj = null;
}
}
Also note I changed
pickObj.position = newPos; // to the mouse position
To
hit.rigidbody.MovePosition(newPos);
This is so it will use the rigidbody and collider to check it's position in space against other colliders. Not 100% accurate but it works.
I believe Aldo's solution below should allow for that, by using parenting method the object retains its normal collision
Answer by aldonaletto · Jul 28, 2012 at 08:47 PM
There's a new version of this script, and it uses a grabRange parameter to define the max distance. It also has pickPos, which sets the object position relative to the character. When an object inside grabRange is clicked, it's rigidbody.velocity is controlled in order to bring it to pickPos. Since the object must have a rigidbody, the script adds one to the object if there's none, removing it when the object is released:
var grabRange: float = 2; var pickPos: Vector3 = Vector3 (0, 0.5, 1.1); var force: float = 30;
private var pickObj: Transform = null; private var rBody: Rigidbody; private var hadRBody: boolean; private var freezeRot: boolean;
function Update(){
if (Input.GetMouseButtonDown(0)){ // if left button pressed...
var hit: RaycastHit;
var ray = Camera.main.ScreenPointToRay(Input.mousePosition); // create a ray from the mouse pointer
// if object "Pick" clicked, and inside grabRange...
if (Physics.Raycast(ray, hit) && hit.transform.tag == "Pick" && hit.distance < grabRange){
pickObj = hit.transform; // save the object's transform...
pickObj.parent = transform; // child it to the player...
rBody = pickObj.rigidbody; // and get its rigidbody, if any
if (rBody){ // if already had a rigidbody...
freezeRot = rBody.freezeRotation; // save its freezeRotation property
hadRBody = true;
} else { // if no rigidbody, add one:
rBody = pickObj.gameObject.AddComponent(Rigidbody);
hadRBody = false;
}
rBody.freezeRotation =true; // disable physical rotations
}
}
if (Input.GetMouseButtonUp(0) && pickObj){
if (hadRBody){ // if already had a rigidbody...
rBody.freezeRotation = freezeRot; // restore freezeRotation
} else { // if not, destroy the added rigidbody:
Destroy(rBody);
}
pickObj.parent = null; // unchild the object...
pickObj = null; // and signal that's nothing is picked anymore
}
}
function FixedUpdate(){ if (pickObj){ var error = transform.TransformPoint(pickPos) - pickObj.position; rBody.velocity = force error; } } EDITED:* There was some variable declarations missing at the top - answer fixed (again...)
No matter what I try, I still get loads of errors. I tried adding this to the original and using this itself, but neither of those ways worked. I tried adding variables but I still got errors. If you can help me, thanks in advance.
add these lines at the top:
private var pickObj: Transform;
private var rBody : Rigidbody;
var grabRange = 2.0;
var pickPos : Vector3;
if there are still errors after that, what are they?
$$anonymous$$ Identifier: 'force'
I have no idea what should I do. Any help?
hmm, not sure what the value should be.. but add this line at the top:
var force = 1.0;
not entirely sure what that part does..
Dear God! Due to some mysterious reason, the first lines of this script disappeared! It's fixed now (@Seth Bergman almost guessed the missing lines...)