I’ve been searching for a method to restrict a mouse drag when it collides with another object without using a RigidBody and everything I tried resulted in failure (the block I’m dragging goes straight through the others). I tried with OnCollisionEnter and with a Raycast and both aren’t working… my brain is about to explode. (T_T)
Also, what is the lightest method to do this kind of thing on iPhone ?
If the objects you want to drag can be rigidbodies, move them by setting the velocity, not the position - it allows the object to respect collisions.
The script below picks a rigidbody when the left mouse button is pressed, and drags it while the button is pressed. Instead of setting the object position, the script calculates the difference between mouse and object positions, and apply a proportional velocity to the object. Velocity is limited to maxSpeed to avoid the object to pass through thin objects. speed is a speed factor which controls how fast the rigidbody will follow the mouse pointer.
var speed: float = 5; // speed factor
var maxSpeed: float = 15; // speed limit
private var dragObj: Transform = null;
private var hit: RaycastHit;
private var length: float;
function Update(){
if (Input.GetMouseButton(0)){ // if left mouse button pressed...
// cast a ray from the mouse pointer
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (!dragObj ){ // if nothing picked yet...
// and the ray hit some rigidbody...
if (Physics.Raycast(ray, hit) && hit.rigidbody){
dragObj = hit.transform; // save picked object's transform
length = hit.distance; // get "distance from the mouse pointer"
}
}
else { // if some object was picked...
// calc velocity necessary to follow the mouse pointer
var vel = (ray.GetPoint(length) - dragObj.position) * speed;
// limit max velocity to avoid pass through objects
if (vel.magnitude > maxSpeed) vel *= maxSpeed / vel.magnitude;
// set object velocity
dragObj.rigidbody.velocity = vel;
}
}
else { // no mouse button pressed
dragObj = null; // dragObj free to drag another object
}
}
EDITED: This is a CharacterController version. It uses no gravity, and the objects stay at the position you release them.
var speed: float = 10; // speed
private var dragObj: Transform = null;
private var hit: RaycastHit;
private var length: float;
private var character: CharacterController;
function Update(){
if (Input.GetMouseButton(0)){ // if left mouse button pressed...
// cast a ray from the mouse pointer
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (!dragObj ){ // if nothing picked yet...
// and the ray hit some character...
if (Physics.Raycast(ray, hit)){
character = hit.transform.GetComponent(CharacterController);
if (character){
dragObj = hit.transform; // save picked object's transform
length = hit.distance; // get "distance from the mouse pointer"
}
}
}
else { // if some object was picked...
// calc mouse pointer displacement
var mov = ray.GetPoint(length) - dragObj.position;
// set object velocity
character.Move(mov * speed * Time.deltaTime);
}
}
else { // no mouse button pressed
dragObj = null; // dragObj free to drag another object
}
}