• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by vmvenkat · Apr 21, 2014 at 05:19 AM · screencalculations

How to calculate screen area coverage of a 3D object

friends i want to know what % of the screen does the object occupy? it's 3d object. help me.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
5
Best Answer

Answer by robertbu · Apr 21, 2014 at 06:08 AM

For a true pixel percentage of an irregular shaped object, you can render the object to a texture against some know background color that would not be in the object. Rendering to a texture can be done in Pro using a RenderTexture. For Unity Free, you wold have to render only the object and a background for a single frame and use Texture2D.ReadPixels() to get the screen pixels. Once you have the texture you can count the number of pixels that are not background and divide the result by the total number of pixels on a screen.

If you can live with an approximation, you can take corners of the bounds of the mesh, convert to world positions (Transform.TransformPoint()), then convert the result to Screen or Viewport points. Taking the minimum and maximum x and y values will give an XY axes aligned bounding rect that can be used to calculate a percentage. Here is an example script:

 #pragma strict
  
 function Update() {
     var p = CalcScreenPercentage();
      Debug.Log("Object uses " + p + " of the screen");
 }
 
 function CalcScreenPercentage() {
 
     var minX = Mathf.Infinity;
     var minY = Mathf.Infinity;
     var maxX = -Mathf.Infinity;
     var maxY = -Mathf.Infinity;
     
     var bounds = GetComponent.<MeshFilter>().mesh.bounds; 
     var v3Center = bounds.center;
     var v3Extents = bounds.extents;
     
     var corners : Vector3[] = new Vector3[8];
 
     corners[0]  = new Vector3(v3Center.x - v3Extents.x, v3Center.y + v3Extents.y, v3Center.z - v3Extents.z);  // Front top left corner
     corners[1]  = new Vector3(v3Center.x + v3Extents.x, v3Center.y + v3Extents.y, v3Center.z - v3Extents.z);  // Front top right corner
     corners[2]  = new Vector3(v3Center.x - v3Extents.x, v3Center.y - v3Extents.y, v3Center.z - v3Extents.z);  // Front bottom left corner
     corners[3]  = new Vector3(v3Center.x + v3Extents.x, v3Center.y - v3Extents.y, v3Center.z - v3Extents.z);  // Front bottom right corner
     corners[4]  = new Vector3(v3Center.x - v3Extents.x, v3Center.y + v3Extents.y, v3Center.z + v3Extents.z);  // Back top left corner
     corners[5]  = new Vector3(v3Center.x + v3Extents.x, v3Center.y + v3Extents.y, v3Center.z + v3Extents.z);  // Back top right corner
     corners[6]  = new Vector3(v3Center.x - v3Extents.x, v3Center.y - v3Extents.y, v3Center.z + v3Extents.z);  // Back bottom left corner
     corners[7]  = new Vector3(v3Center.x + v3Extents.x, v3Center.y - v3Extents.y, v3Center.z + v3Extents.z);  // Back bottom right corner
     
     for (var i = 0; i < corners.Length; i++) {
         var corner = transform.TransformPoint(corners[i]);
         corner = Camera.main.WorldToScreenPoint(corner);
         if (corner.x > maxX) maxX = corner.x;
         if (corner.x < minX) minX = corner.x;
         if (corner.y > maxY) maxY = corner.y;
         if (corner.y < minY) minY = corner.y;
         minX = Mathf.Clamp(minX, 0, Screen.width);
         maxX = Mathf.Clamp(maxX, 0, Screen.width);
          minY = Mathf.Clamp(minY, 0, Screen.height);
         maxY = Mathf.Clamp(maxY, 0, Screen.height);
     }
  
      var width = maxX - minX;
      var height = maxY - minY;
      var area = width * height;
      var percentage = area / (Screen.width * Screen.height) * 100.0;
      return percentage;
 }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image vmvenkat · Apr 21, 2014 at 09:16 AM 0
Share

It's Working fine. Thank

avatar image
1

Answer by OSG · Apr 21, 2014 at 06:25 AM

You can RayCast from different screen points to find one point which is point on your object. Then from that point we can find bounds of the object on the screen moving ray cast vector horizontally and vertically. Code for this:

 using UnityEngine;
 using System.Collections;
 
 public class Example : MonoBehaviour {
     private bool isVisibleFromCamera = false;
     public GameObject anObject;
     private Camera cam;
     private Plane[] planes;
     public float step = 10f;
 
     void Start() {
         cam = Camera.main;
         planes = GeometryUtility.CalculateFrustumPlanes(cam);
     }
     
     void Update() {
         if (GeometryUtility.TestPlanesAABB(planes, anObject.collider.bounds))
             isVisibleFromCamera = true;
         else
             isVisibleFromCamera = false;
     }
     
     float CalculateBounds() {
         if(isVisibleFromCamera) { //is anObject is visible from mainCamera
             Vector2 point = new Vector2(Random.Range(0, Screen.width), Random.Range(0, Screen.height));
             Ray ray = Camera.main.ScreenPointToRay(point);
             RaycastHit hit;
             bool found = false;
             while(!found) { //calculating point of anObject on the screen
                 if (Physics.Raycast(ray, out hit, 100)) {
                     if (hit.collider.gameObject == anObject) 
                         found = true;
                 }
                 else {
                     point = new Vector2(Random.Range(0, Screen.width), Random.Range(0, Screen.height));
                     ray = Camera.main.ScreenPointToRay(point);
                 }
             }
             //now Vector2 point is point of the anObject 
             //time to find screen bounds
 
             float leftBound, rightBound, topBound, bottomBound;
             leftBound = rightBound = point.x;
             topBound = bottomBound = point.y;
             bool boundFound = false;
             while(!boundFound) {
                 boundFound = true;
                 leftBound -= step;
                 point = new Vector2(leftBound, point.y);
                 ray = Camera.main.ScreenPointToRay(point);
                 if (Physics.Raycast(ray, out hit, 100)) {
                     if (hit.collider.gameObject == anObject) 
                         boundFound = false;
                 }
             }
             boundFound = false;
             while(!boundFound) {
                 boundFound = true;
                 rightBound += step;
                 point = new Vector2(rightBound, point.y);
                 ray = Camera.main.ScreenPointToRay(point);
                 if (Physics.Raycast(ray, out hit, 100)) {
                     if (hit.collider.gameObject == anObject) 
                         boundFound = false;
                 }
             }
             boundFound = false;
             while(!boundFound) {
                 boundFound = true;
                 topBound -= step;
                 point = new Vector2(point.x, topBound);
                 ray = Camera.main.ScreenPointToRay(point);
                 if (Physics.Raycast(ray, out hit, 100)) {
                     if (hit.collider.gameObject == anObject) 
                         boundFound = false;
                 }
             }
             boundFound = false;
             while(!boundFound) {
                 boundFound = true;
                 bottomBound += step;
                 point = new Vector2(point.x, bottomBound);
                 ray = Camera.main.ScreenPointToRay(point);
                 if (Physics.Raycast(ray, out hit, 100)) {
                     if (hit.collider.gameObject == anObject) 
                         boundFound = false;
                 }
             }
             //now we have bounds calculated
 
             float screenArea = Screen.width * Screen.height;
         float objectArea = (rightBound - leftBound) * (bottomBound - topBound);
         return objectArea / screenArea * 100;
         } 
     }
 }
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image vmvenkat · Apr 21, 2014 at 08:57 AM 0
Share

sorry it's not work

avatar image OSG · Apr 21, 2014 at 09:26 AM 0
Share

what you did with my script? just copied and pasted in your project without any changes?

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

21 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Take screenshot script doesn't work 1 Answer

ReadPixels Screen is Offset 0 Answers

How to count the number of clones within view? 1 Answer

Screen.width/2 Giving an Incorrect Value 2 Answers

Screen brightness on Android 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges