Search Unity

Keep the sprite size the same regardless of camera distance in perspective

Discussion in '2D' started by TheCelt, Apr 9, 2016.

Thread Status:
Not open for further replies.
  1. TheCelt

    TheCelt

    Joined:
    Feb 27, 2013
    Posts:
    742
    Hello

    I have a 2D sprite in my game world that is rendered with a perspective camera. The sprite's information is like this:



    So i want to create a script that maintains the size of the sprite as it is currently regardless of how close or far away the camera is from it.

    Before you suggest, no i don't want an orthographic camera due to other reasons i have, and that i kinda want to understand how to do it this way so i can apply it to other things later too like 3D objects.

    So my confusion here is:

    Do i put a resize script on my gameObjects that i want to have a fixed size regardless of camera distance, OR do i put a script on say the camera and iterate all gameObjects i want to resize?

    And, what would i need to do in order to adjust it's size and its collider? It's mainly the maths i don't understand. If the camera moves closer by two units, is that sprite going to show 2 times bigger? Because currently it doesn't seem to be ... and thats why i don't understand the maths involved for such a thing its real confusing.
     
    Last edited: Apr 10, 2016
  2. DeveshPandey

    DeveshPandey

    Joined:
    Sep 30, 2012
    Posts:
    221
    Looking for same solution, any updates on this?
     
  3. Unitobinator

    Unitobinator

    Joined:
    Oct 15, 2015
    Posts:
    2
    This is kinda a dead thread but without an answer, so I'm going to try and give my thoughts on this.

    1. You said that you don't want to use an orthographic camera but it would be possible to use one and only let it render the sprites having equal sizes, using layer masks. Occlusion would be a little tricky. For sprites, however, I do believe this to be the best solution. This could be a starting point: https://blog.theknightsofunity.com/using-multiple-unity-cameras-why-this-may-be-important/
    2. If you really do want to resize things, e.g. due to collision and stuff, I think the best way to go about, is to attach a resize script to every object you want to resize. Resizing is not a behaviour of the camera but of the thing. The camera renders and doesn't resize but it would work either way and that's, to some extend, a matter of personal preference. The math that is involved here is called "Intercept theorem": https://en.wikipedia.org/wiki/Intercept_theorem. Applying this theorem to each and every point of the to be rescaled objects would produce the nicest results but it could already be enough to only apply it to their scale values.
    3. An, as I think, quite elegant but probably overkill solution would be to write your own renderer, as Unity's camera kinda makes everything orthographic but with perspective taken into account and then renders that. So if you prevent it from taking perspective into account for your rescaled objects, this would be an idea as well. I'm saying it honestly, I couldn't do this but maybe you do.
    4. The last idea that I have is to, if occlusion is not wanted, to screen space as a UI element. If it is wanted, you could do some clever tricks by checking whether the object would be occluded by something in world space and then dynamically not render that part/clear that part with something transparent.
    But these are just my two cents. I hope, I can help someone with this.
     
  4. cdr9042

    cdr9042

    Joined:
    Apr 22, 2018
    Posts:
    173
    I have this solution to scale object in the far background (mountain, cloud...) in a 2D platformer game:
    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. public class PerspectiveDistanceObject : MonoBehaviour
    6. {
    7.     [SerializeField] float scale = 2f;
    8.     [SerializeField] Transform targetTransform;
    9.     Camera m_Camera;
    10.     Vector3 originalPosition;
    11.     bool updatedPosition;
    12.  
    13.     private void Start()
    14.     {
    15.         originalPosition = transform.position;
    16.         m_Camera = Camera.main;
    17.         if (targetTransform == null) { targetTransform = transform; }
    18.         UpdatePosition();
    19.     }
    20.  
    21.     private void UpdatePosition()
    22.     {
    23.         float camDistance = -m_Camera.transform.position.z;
    24.         //move object farther based on desired scale
    25.         float additionalDistance = camDistance * (scale - 1);
    26.         targetTransform.position = new Vector3(targetTransform.position.x, targetTransform.position.y, additionalDistance);
    27.         targetTransform.localScale = targetTransform.localScale * scale;
    28.         updatedPosition = true;
    29.     }
    30. }
    31.  
    Add the component to the object that will be scaled.

    After running UpdatePosition(), the object will be scaled to the wanted value (default 2) and its distance will be set so that it looks the same on the camera as if its scale was 1x.

    This code assumed the camera wants to focus on objects with position.z == 0 and the camera's position.z is the distance from the camera to the target objects
     
    cj-currie likes this.
  5. MiniDannenBerg

    MiniDannenBerg

    Joined:
    May 23, 2023
    Posts:
    5
    Thanks for the code
     
  6. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,491
    Please use the Like button to show appreciation rather than necroing threads from 2016.

    Thanks.
     
Thread Status:
Not open for further replies.