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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Sprite Overlay Question

Discussion in 'Scripting' started by jarden, Feb 14, 2017.

  1. jarden

    jarden

    Joined:
    Mar 29, 2011
    Posts:
    74
    Hi, I am trying to get a sprite over my gameobject positioned how it would look with no sprite. I managed to get it to work with a orthogonal camera.

    With a perspective camera, I don't know how far to make the z axis before I transform it. 2.6 seems to work but I'd like to know the math.

    a is the rect I used to capture a screenshot of the object
    Code (CSharp):
    1. spritego.transform.position = Camera.main.ScreenToWorldPoint(new Vector3(a.position.x, Screen.height - a.position.y, 2.6f));
    So my question is why does 2.6 work as the z? Thanks.
     
  2. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    I'm having a hard time understanding what the line even means? You have a gameobject with no sprite, and you have a second GO with a sprite your trying to position in the world closer to the camera "in front" of it?

    Anyway not sure what your trying to do, but here's how ScreenToWorldPoint works and understanding that might help with your problem. In WorldSpace we have 3 dimensions out there. x, y (generally left/right and up/down in relation to the camera) and z a distance away from the camera. With all sorts of maths we can squish all these points in space to a single 2D plane (your screen) that only has x,y points. Now of this means there is a whole line of points that squish down into a single point on the screen. The graphics engine figures out which one of those would have been in front and only displays that one.

    So going backwards, if we are taking a single x,y point and putting it back into the world, we have an infinite line to choose from. You supply the Z -Axis co-ordinate of how far away from the camera that point should be stuck at. In perspective world if your twice as big as me, but i'm twice as close as you.. i'll look exactly the same size. So some combination of that is why 2.6 is working for you. Maybe your objects are the same size, so the object your covering is 2.6 units from the camera. Or its 50% bigger and sitting at 3.9.. etc.
     
    Last edited: Feb 14, 2017
  3. SarfaraazAlladin

    SarfaraazAlladin

    Joined:
    Dec 20, 2013
    Posts:
    280
    Building on @takatok's answer, what you could do is Vector3.Distance between the target game object's position and the camera's position.
     
  4. jarden

    jarden

    Joined:
    Mar 29, 2011
    Posts:
    74
    Its not the distance, it works no matter how far it is from camera. Here's my code. Line 82 is where 2.6 is. It takes a screenshot on a second camera on layer 8:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class getobjectss : MonoBehaviour
    5. {
    6.     public GameObject target;
    7.     private RenderTexture rt;
    8.     public Camera cam;
    9.  
    10.     void Start()
    11.     {
    12.         rt = new RenderTexture(Screen.width,Screen.height,24,RenderTextureFormat.ARGB32,RenderTextureReadWrite.Linear);
    13.     }
    14.  
    15.     void Update()
    16.     {
    17.         if (Input.GetKeyDown(KeyCode.Space))
    18.         {
    19.             StartCoroutine(thisone());
    20.         }
    21.     }
    22.  
    23.     public IEnumerator thisone()
    24.     {
    25.         yield return new WaitForEndOfFrame();
    26.         target.layer = 8;
    27.  
    28.         Rect a = GUIRectWithObject(target);
    29.         a = new Rect((int)a.position.x-5, (int)a.position.y-5, (int)a.width+10, (int)a.height+10);
    30.         if (a.xMin < 0)
    31.         {
    32.             a.xMin = 0;
    33.         }
    34.         if (a.xMax > Screen.width)
    35.         {
    36.             a.xMax = Screen.width;
    37.         }
    38.         if (a.yMin < 0)
    39.         {
    40.             a.yMin = 0;
    41.         }
    42.         if (a.yMax > Screen.height)
    43.         {
    44.             a.yMax = Screen.height;
    45.         }
    46.         //Debug.Log(a.xMin + ", "+a.xMax+", "+ a.yMin + ", "+ a.yMax);
    47.         //Debug.Log(a.width + ", " + a.height);
    48.         //Debug.Log(a.position);
    49.         cam.targetTexture = rt;
    50.         RenderTexture.active = rt;
    51.         cam.Render();
    52.         Texture2D screenShot = new Texture2D((int)a.width, (int)a.height, TextureFormat.ARGB32, false, true);
    53.         screenShot.ReadPixels(a, 0, 0, false);
    54.         //byte[] bytes = screenShot.EncodeToPNG();
    55.         //string filename = Application.dataPath + "/_SCap/tredg.png";
    56.         //System.IO.File.WriteAllBytes(filename, bytes);
    57.         RenderTexture.active = null;
    58.         cam.targetTexture = null;
    59.         target.layer = 0;
    60.  
    61.         screenShot.filterMode = FilterMode.Point;
    62.         screenShot.Apply();
    63.  
    64.         if (Camera.main.orthographic == true)
    65.         {
    66.             Sprite mySprite = Sprite.Create(screenShot, new Rect(0.0f, 0.0f, screenShot.width, screenShot.height), new Vector2(0f, 1f), 100.0f, 0, SpriteMeshType.FullRect);
    67.             GameObject go = new GameObject("test");
    68.             SpriteRenderer sr = go.AddComponent<SpriteRenderer>() as SpriteRenderer;
    69.             //sr.color = new Color(0.9f, 0.9f, 0.9f, 1.0f);
    70.             sr.sprite = mySprite;
    71.             go.transform.rotation = Camera.main.transform.rotation;
    72.             go.transform.position = Camera.main.ScreenToWorldPoint(new Vector3(a.position.x, Screen.height - a.position.y, 5));
    73.         }
    74.         else
    75.         {
    76.             Sprite mySprite = Sprite.Create(screenShot, new Rect(0.0f, 0.0f, screenShot.width, screenShot.height), new Vector2(0f, 1f), 100.0f, 0, SpriteMeshType.FullRect);
    77.             GameObject go = new GameObject("test");
    78.             SpriteRenderer sr = go.AddComponent<SpriteRenderer>() as SpriteRenderer;
    79.             //sr.color = new Color(0.9f, 0.9f, 0.9f, 1.0f);
    80.             sr.sprite = mySprite;
    81.             go.transform.rotation = Camera.main.transform.rotation;
    82.             go.transform.position = Camera.main.ScreenToWorldPoint(new Vector3(a.position.x, Screen.height - a.position.y, 2.6f));
    83.         }
    84.     }
    85.  
    86.   public static Rect GUIRectWithObject(GameObject go)
    87.     {
    88.         Vector3 cen = go.GetComponent<Renderer>().bounds.center;
    89.         Vector3 ext = go.GetComponent<Renderer>().bounds.extents;
    90.  
    91.         Vector2[] extentPoints = new Vector2[8]
    92.          {
    93.                WorldToGUIPoint(new Vector3(cen.x-ext.x, cen.y-ext.y, cen.z-ext.z)),
    94.                WorldToGUIPoint(new Vector3(cen.x+ext.x, cen.y-ext.y, cen.z-ext.z)),
    95.                WorldToGUIPoint(new Vector3(cen.x-ext.x, cen.y-ext.y, cen.z+ext.z)),
    96.                WorldToGUIPoint(new Vector3(cen.x+ext.x, cen.y-ext.y, cen.z+ext.z)),
    97.                WorldToGUIPoint(new Vector3(cen.x-ext.x, cen.y+ext.y, cen.z-ext.z)),
    98.                WorldToGUIPoint(new Vector3(cen.x+ext.x, cen.y+ext.y, cen.z-ext.z)),
    99.                WorldToGUIPoint(new Vector3(cen.x-ext.x, cen.y+ext.y, cen.z+ext.z)),
    100.                WorldToGUIPoint(new Vector3(cen.x+ext.x, cen.y+ext.y, cen.z+ext.z))
    101.          };
    102.         Vector2 min = extentPoints[0];
    103.         Vector2 max = extentPoints[0];
    104.         foreach (Vector2 v in extentPoints)
    105.         {
    106.             min = Vector2.Min(min, v);
    107.             max = Vector2.Max(max, v);
    108.         }
    109.         return new Rect(min.x, min.y, max.x - min.x, max.y - min.y);
    110.     }
    111.  
    112.     public static Vector2 WorldToGUIPoint(Vector3 world)
    113.     {
    114.         Vector2 screenPoint = Camera.main.WorldToScreenPoint(world);
    115.         screenPoint.y = (float)Screen.height - screenPoint.y;
    116.         return screenPoint;
    117.     }
    118. }