Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Keeping an object in the same place on the screen as you rotate the camera only works with Y=0

Discussion in 'Editor & General Support' started by valter-home, Dec 1, 2023.

  1. valter-home

    valter-home

    Joined:
    Sep 22, 2015
    Posts:
    103
    In my Editor I place sprites or 3D objects on a new plane that I build with:

    Code (CSharp):
    1. myNewPlane = new Plane(Vector3.up, new Vector3(0.0f, 0.0f, 0.0f));
    Then, again using my Editor controls, I rotate the camera.
    I need my objects to always remain in the same position on the screen. To achieve this I perform the following steps:
    I store the position of objects with:

    Code (CSharp):
    1. storeObjectPosition =  myCam.WorldToScreenPoint(myObject.transform.position);
    I rotate the camera.
    I restore the position of the object with:

    Code (CSharp):
    1. Ray ray = myCam.ScreenPointToRay(storeObjectPosition);
    2. if (myNewPlane.Raycast(ray, out enter)) {
    3.     myObject.transform.position = ray.GetPoint(enter);
    4. }
    The code works well, inside a for loop I iterate all the objects in the scene.
    The problem occurs if I move the object on the Y axis. The object remains in its apparent position, but the code shown above moves its Y axis to zero rather than keeping it at the set value.
    This is obvious, because the new plane is positioned at 0.0f on all three axes.
    So I thought about moving it to the Y axis of the object I'm restoring, like this:

    Code (CSharp):
    1. myNewPlane = new Plane(Vector3.up, new Vector3(0.0f, *Y_of_object*, 0.0f));
    2. Ray ray = myCam.ScreenPointToRay(storeObjectPosition);
    3. if (myNewPlane.Raycast(ray, out enter)) {
    4.     myObject.transform.position = ray.GetPoint(enter);
    5. }
    6.  
    But despite this, the object is always repositioned with Y = 0.
    Can you figure out what I'm missing?


     
  2. valter-home

    valter-home

    Joined:
    Sep 22, 2015
    Posts:
    103
    No, I have to make a correction, it seems to work.
    For brevity I reported the code above, but in reality I create the new Plane by calling a function in another part of the code. This would seem to be the problem. If instead I create the new Plane immediately before doing the raycast (as in the code above), it works.
    Is it possible that the function is not executed before the raycast?
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,263
    Make sure you're making the Plane() correctly. It is a constructor that takes two Vector3 arguments. I recommend ALWAYS using named arguments for Plane():

    Code (csharp):
    1. myNewPlane = new Plane( inNormal: Vector3.up, inPoint: new Vector3(0.0f, *Y_of_object*, 0.0f));
    Otherwise you risk mixing it up in your code in some places.
     
    valter-home likes this.
  4. valter-home

    valter-home

    Joined:
    Sep 22, 2015
    Posts:
    103
    Thanks, I will follow your advice even though I checked thoroughly and the code is correct. For an unknown reason I have to build the plane immediately before the Raycast, otherwise it doesn't work. I realize that without seeing the entire code you can't do miracles.

    I still need your clarification, if you have time.
    The code posted above works fine in perspective mode, but objects do not maintain their position in orthographic mode if I change its Y axis. It would appear that code myNewPlane = new Plane(Vector3.up, new Vector3(0.0f, *Y_of_object*, 0.0f)); in orthographic mode doesn't work.The Plane construction mode is the same, I use the new Plane with inNormal = Vector3.up.

    Do you have any idea?
     
    Last edited: Dec 3, 2023
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,263
    The only thing I can think of is that since your plane is facing flat upwards, if your camera is ortho and facing horizontally (default cam orientation), then obviously no ray cast from it could ever hit the plane.

    Are you at least pointing the ortho camera downwards a bit so it can hit the plane?

    Otherwise you're going to have to tease apart the parts:

    - the ray from the camera (is it reasonable?) (this seems the most likely to be incorrect)

    - the hitpoint of ray to plane

    - try making another ray and just zap it at the plane, see what results you get.

    There's gonna be some silly little bug somewhere, there always is. I'm the king of silly little bugs so I know. :)
     
  6. valter-home

    valter-home

    Joined:
    Sep 22, 2015
    Posts:
    103
    It's a doubt I've asked myself too, but something doesn't sound right to me.
    Let's talk in orthographic mode as it works well in perspective.
    If I place the objects with the Y axis equal to the new Plane, the above code works fine (but I don't need myNewPlane = new Plane(Vector3.up, new Vector3(0.0f, *Y_of_object*, 0.0f)); ). Again, if I change the Y axis of the new Plane and place the same objects on top of it, it still works. So it always works, even in orthographic mode.
    But if I move one of the objects on the Y axis, let's say the new Plane is positioned with Y = 1 and I move the object with Y = 2, while still using myNewPlane = new Plane(Vector3.up, new Vector3(0.0f, *Y_of_object *, 0.0f)); it does not work.

    I'll do some testing as you suggest.