I got an unity project where object is meant to be moving with mouse cursor. The object moves fine, but when the object is still, it starts to float towards the camera that Ray-casts. I would like that the object doesn't float towards camera.
I couldn't find any reason for objects behavior.
I just ran into this issue myself, and after getting on some Unity discords, someone else explained it to me:
Why It Happens
The reason this happens is because your Raycast is constantly casting a ray onto GameObjects in the scene, including the GameObject you're moving, so even though you're not moving the mouse, it's constantly casting through itself, moving itself closer and closer to the camera.
You can solve this in two different ways. The first way is probably better.
First Way
You need to add a LayerMask
to your entire movable surface that your object can move on. So if you have a ping pong paddle and a table, add a LayerMask of Movable
onto the ping pong table surface.
Then, make sure that your 3D object DOES NOT have that LayerMask.
Then, in your Script, add a public LayerMask
variable, and add it to your Raycast:
public LayerMask layerMask;
private void Update() {
Ray rayOrigin = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(rayOrigin, out RaycastHit hit, layerMask)) {
transform.position = hit.point;
}
}
To explain this, the LayerMask
forces the Raycast to only cast on a specific Layer of gameObjects, so it's essentially ignoring your movable 3D object.
Second Way
Another way is to force the Y
coordinate of transform.position
to stay at a specific level, but that's only really useful if you don't require vertical movement, so take this with a grain of salt.
According to the docs, RaycastHit.point
is a Vector3, so you can just use the X
and Z
coordinates:
Ray rayOrigin = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(rayOrigin, out RaycastHit hit)) {
transform.position = new Vector3(hit.point.x, transform.position.y, hit.point.z);
}
However, this doesn't really solve the underlying issue, so it's probably better to just use the first method.