Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How to get a world position from the center of the screen ?

Discussion in 'Scripting' started by Zirfly, Apr 1, 2018.

  1. Zirfly

    Zirfly

    Joined:
    Nov 22, 2017
    Posts:
    10
    Hello !

    I have a problem : I need to know what is the position, in world coordinates, that the camera is pointing at. I don't really know how to do it, I've seen such things as
    Code (CSharp):
    1. ScreenToWorldPoint()
    , but I don't know how to use it (Why a Vector3 for input ? If we are talking about a screen, shouldn't it be a Vector2 ?)

    I'm thinking about Raycast and stuff but I'm really not familiar with these....

    To be simple : how can I get a world position from the center of the screen ?

    Thank you !
     
  2. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    You are trying to get a point in a 3D 'world'. The screen is 2D. Therefore, it is effectively looking along a given vector. So any point on the screen extends, in theory, along an infinite number of 3D points along that line.

    If you want a world co-ordinate you have to pick a point 'x' distance from the camera to know at which point, in the 3D world space along that line, you wish to know the point of.

    The documentation shows how to take the 3D point at the near clip plane of the main camera view.
     
    Zirfly likes this.
  3. fire7side

    fire7side

    Joined:
    Oct 15, 2012
    Posts:
    1,819
    The center of the screen is Screen.width/2,Screen.height/2.
     
    GoblinGameWorks and Zirfly like this.
  4. Zirfly

    Zirfly

    Joined:
    Nov 22, 2017
    Posts:
    10
    Ok guys thanks for the help I will try :) !
     
  5. Zirfly

    Zirfly

    Joined:
    Nov 22, 2017
    Posts:
    10
    So,

    Code (CSharp):
    1. Vector3 lookAtPosition = cameraTank.ScreenToWorldPoint(new Vector3(Screen.width / 2, Screen.height / 2, cameraTank.nearClipPlane));
    This should theoretically return me the 3D point I'm looking at ? Because when I Debug.Log it, The coordinates does not change much when I'm looking near me/far from me... I am probably missing something but I don't understand... It seems that the coordinates returned are always close to me, as they go higher when I'm displacing the camera.
     
  6. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    You have to choose how far in front of the camera your point would be for the z position.

    What is it you wish to accomplish in the end?
     
    manchinolik likes this.
  7. Zirfly

    Zirfly

    Joined:
    Nov 22, 2017
    Posts:
    10
    It's a tank game. I'm working on the turret, currently. My plan is the following :

    - Get where the camera points
    - Align the turret and gun to this point

    But, well the first part is where I'm stuck...
     
  8. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    So are you saying that you have / want something like this :
    1. A 3D view (or is this 2D top down?).
    2. A terrain (or flat plane?).
    3. A tank.
    4. A 3rd person view (i.e. from outside looking at the tank and its surroundings).
    5. User taps on map (i.e. the screen).
    6. Tank turret rotates to face the targeted point (screen touch point) and fires in that direction.
    Or something else?
     
  9. Zirfly

    Zirfly

    Joined:
    Nov 22, 2017
    Posts:
    10
    1. 3D View : done
    2. Terrain : done
    3. Tank : WIP
    4. 3rd person view : done
    5. Users : todo
    6. Tank turret rotates : WIP, and I'm stuck on this :(
     
  10. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    So maybe something like this? :-
    Code (CSharp):
    1.         var ray = Camera.main.ScreenPointToRay( new Vector2( Screen.height / 2, Screen.width / 2 ));
    2.         RaycastHit hitPoint;
    3.  
    4.         if( Physics.Raycast( ray, out hitPoint, 100.0f ))
    5.             transform.LookAt( hitPoint.point );
     
    Last edited: Apr 2, 2018
  11. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    Caveat: There might not always be a hitpoint if you can see the skybox. But yes, the ray is useful for knowing the direction at least...
     
  12. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    Indeed.

    The code was intended more for illustration to check it was what the OP wanted, but I have amended it to include the check. :)
     
  13. Zirfly

    Zirfly

    Joined:
    Nov 22, 2017
    Posts:
    10
    Thanks man !! It works !!!
     
    Doug_B likes this.
  14. tourajv

    tourajv

    Joined:
    May 8, 2018
    Posts:
    1
    This is great. But I think the height and width should be switched: new Vector2( Screen.width / 2, Screen.height / 2
     
    Doug_B likes this.
  15. MikeTheMonster

    MikeTheMonster

    Joined:
    Sep 20, 2018
    Posts:
    2
    Hey, I know this is very late, but I have a alternative solution for this.
    _____________________________________________________________________________

    var ray = Camera.main.ScreenPointToRay(new Vector2(Screen.width / 2, Screen.height / 2));
    Vector3 lookAt = ray.direction*500f + barrel.position;
    barrel.LookAt(lookAt);

    ______________________________________________________________________________

    The lookAt point is created by finding the direction the camera is facing, increasing that unit Vector by a very large amount and then moving it to the position of the barrel.

    This comes from the equation for lines in R3: point on line = anchor point + direction unit vector * distance from anchor
     
    Last edited: Dec 20, 2019
  16. Wolfzoon

    Wolfzoon

    Joined:
    Dec 4, 2020
    Posts:
    2
    An intriguing alternative, but I don't really get it
    OP wants to
    With your code:
    The tank is at (1,0,1). Camera is at (0,10,0), and looks in northeast direction but very downwards, to (-1,0,1).
    The ray would thus have a direction of (-1,-10,1). lookAt = (-499,-5000,501), so LookAt looks in direction (-1,-10,1) (just as when lookAt would simply be (0,-10,2)), which is also northeast and very downwards.

    But we want the tank to face (-1,0,1), aka a direction of (-1,0,0), west.