Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Bug WorldToScreenPoint gives the same result after moving the camera

Discussion in 'Scripting' started by Develax, Mar 22, 2023.

  1. Develax

    Develax

    Joined:
    Nov 14, 2017
    Posts:
    67
    I'm not sure if this is really a bug or a feature but the thing is that moving the camera doesn't change the result of the WorldToScreenPoint method. The result is changed only in the next frame.

    Code (CSharp):
    1. Vector3 centerPosPx = Cameras.GameCamera.WorldToScreenPoint(Vector3.zero);
    2. Debug.Log($"BEFORE SHIFT: {centerPosPx}");
    3. Camera.transform.position += Vector3.right;
    4. centerPosPx = Cameras.GameCamera.WorldToScreenPoint(Vector3.zero);
    5. Debug.Log($"AFTER SHIFT: {centerPosPx}");
    In this example 'before' and 'after' positions will be the same even though the camera has been moved.

    In my project, when a player drags the game table, I move the camera. Then I need to position some UI appropriately, I do this in the LateUpdate method. As a result, the position of the user interface is always 1 frame behind other objects.
     
  2. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,660
    Tested your code, but the results before and after the shift are different on the same frame (wouldn't make sense for them to be equal, since the camera transform which is used to calculate the world->screen projection has changed)

    Code (CSharp):
    1. // Update is called once per frame
    2. void Update()
    3. {
    4.         if (Input.anyKeyDown)
    5.         {
    6.             Vector3 centerPosPx = Camera.main.WorldToScreenPoint(Vector3.zero);
    7.             Debug.Log($"BEFORE SHIFT: {centerPosPx}");
    8.             Camera.main.transform.position += Vector3.right;
    9.             centerPosPx = Camera.main.WorldToScreenPoint(Vector3.zero);
    10.             Debug.Log($"AFTER SHIFT: {centerPosPx}");
    11.         }
    12. }
    So I suspect the problem lies elsewhere in your project.

    Note your code calls WorldToScreenPoint on one camera (Cameras.GameCamera), and then moves a different one (Camera). I assumed this was a typo and used Camera.main for both in my test. Might this have to do something with the issue?
     
    Bunny83 likes this.
  3. Develax

    Develax

    Joined:
    Nov 14, 2017
    Posts:
    67
    Yes,
    Code (CSharp):
    1. private Camera Camera => Cameras.GameCamera;
    I composed this example from different places because in the original the camera position changes in one component and the UI moves in the other one in LateUpdate.

    You are right, the WorldToScreenPoint method returns a new value after the camera is shifted in the same frame. My expectations that this is the actual problem affected my perception of the log. Now I don't understand at all what the problem with the moving UI lag might be.
     
  4. Develax

    Develax

    Joined:
    Nov 14, 2017
    Posts:
    67
    The problem was that I was setting `_rectTransform.position` to change the UI element position. It seems that it takes 1 frame to recalculate its `anchoredPosition`. But at the same time, if I assign another camera to the canvas with a larger Depth value, the `anchoredPosition` is recalculated in the same frame.

    At the moment I left the canvas on the first camera and assign the `anchoredPosition` value directly.