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

World to screen point with Canvas set to Scale with screen size

Discussion in 'Scripting' started by ArinFaraj, Mar 24, 2020.

  1. ArinFaraj

    ArinFaraj

    Joined:
    Jan 5, 2014
    Posts:
    13
    hey guys
    tying to make a hit marker popup and i needed to use the world position of the hit and convert it to a point on the canvas but turns out you can't just use screen point when you set the canvas scaling mode to scale with the screen size so i used this and it works,but is there a better way to do it?

    Code (CSharp):
    1. var screenPoint = camera.WorldToScreenPoint(ob.position);
    2. var correctPoint = new Vector2(screenPoint.x / Screen.width * rectTransform.sizeDelta.x,screenPoint.y / Screen.height * rectTransform.sizeDelta.y);
    3. sampleText.rectTransform.anchoredPosition = correctPoint;
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,741
    CanvasScaler has a scaleFactor that you can divide out of your ScreenPosition, and that should give you the right number.
     
    masterton likes this.
  3. ArinFaraj

    ArinFaraj

    Joined:
    Jan 5, 2014
    Posts:
    13
    thats used when you use the constant pixel size scaling mode im using scale with screen so that doesn't work
     
  4. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,256
    I do this with the canvas set to screen space overlay and scaler set to scale with screen size.

    Code (CSharp):
    1. Vector3 pos = Camera.main.WorldToScreenPoint(targetPosition + offset);
    2. uiObj.transform.position = pos;
    I don't bother with the anchors or the RectTransform when dealing with world space/screen space conversions.
     
    sqallpl and Rispat-Momit like this.
  5. ArinFaraj

    ArinFaraj

    Joined:
    Jan 5, 2014
    Posts:
    13
    im using camera screen space so the world position is not working here
     
  6. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,256
    I dug this out of a project that might help, maybe lead you in the right direction.

    Code (CSharp):
    1. public static Vector3 WorldToScreenSpace(Vector3 worldPos, Camera cam, RectTransform area)
    2. {
    3.     Vector3 screenPoint = cam.WorldToScreenPoint(worldPos);
    4.     screenPoint.z = 0;
    5.  
    6.     Vector2 screenPos;
    7.     if (RectTransformUtility.ScreenPointToLocalPointInRectangle(area, screenPoint, cam, out screenPos))
    8.     {
    9.         return screenPos;
    10.     }
    11.  
    12.     return screenPoint;
    13. }
     
  7. ArinFaraj

    ArinFaraj

    Joined:
    Jan 5, 2014
    Posts:
    13
    this works perfectly thanks alot <3
     
  8. Ziplock9000

    Ziplock9000

    Joined:
    Jan 26, 2016
    Posts:
    360
    I thought this might be useful to somebody

    It allows a Screen Space UI element on a "Scale With Screen Size" canvas to follow a World space object with a Y offset that scales to whatever resolution you're using: (Damn's that's a mouthful!)

    The Y offset is a fraction of the screen size.

    Code (CSharp):
    1. public class GUIElementFollowWorldSpaceObject : MonoBehaviour
    2. {
    3.     public Transform FollowThis;
    4.     public float OffsetYScreenFraction;
    5.     private Vector3 pos;
    6.  
    7.     void Update()
    8.     {
    9.         pos = Camera.main.WorldToScreenPoint(FollowThis.position);
    10.         pos.y -= Screen.height * OffsetYScreenFraction;
    11.         this.transform.position = pos;
    12.     }
    13. }
     
    Leo2236, ChGuidi and Bakanovskiy95 like this.
  9. Berno

    Berno

    Joined:
    Oct 29, 2014
    Posts:
    39
    I looked everywhere and tried every solution and this is the only one that worked for me thanks a lot!
     
    restush96 likes this.
  10. Rispat-Momit

    Rispat-Momit

    Joined:
    Feb 14, 2013
    Posts:
    261
    Love you mate!
    Here is a simple code I made based on Chris-Trueman code:

    (Attach this to your UI element) :)

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class UIToWorldSpace : MonoBehaviour {
    6.  
    7.     public Transform Target;
    8.     public Vector3 offset;
    9.  
    10.     void Update () {
    11.  
    12.  
    13.         Vector3 pos = Camera.main.WorldToScreenPoint(Target.position + offset);
    14.  
    15.          transform.position = pos;
    16.     }
    17. }
    18.  
     
    rayD8 likes this.