Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • 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
0
Question by banana111 · Nov 04, 2018 at 06:07 PM · raycastingmain camerafield of viewfrustum

How to get where my camera borders a plane

Hello, I have a game where I need to know the x values of where my camera is bordering a plane which is my background. To achieve this I used the following code: cam.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, System.Math.Abs(transform.transform.position.z))); This worked perfectly until I implemented the feature of random camera rotation. Now I am trying to get the x values based on the current angel. I have 2 ideas of how to achieve this. The first one is by using rays. I am new to ray casting and don't know how to send a ray from my cameras vertices or my cameras frustum's vertices (a frustum is a shape that the field of view casts https://docs.unity3d.com/Manual/UnderstandingFrustum.html). the second method I thought about is to use a simple tan=a/b (function) a being the border on the right and b being transform.postion.z, but to do this I need to know the x and y angel of my field of view or my "Frustum" if you will. I have tried many methods to get this angel. In the unity manual, it says that you have to use the screens Aspect ratio. Which makes a lot of sense but I tried it and couldn't seem to figure out how I must multiply it (I have tried multiplying the angel itself and also the result from the Tan function. Neither has worked)

Long story short, I would like to know how to get the rays that my field of view casts, or the angel that my field of view has.

I hope someone can help me, Thanks in advance.

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

1 Reply

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

Answer by banana111 · Nov 07, 2018 at 05:42 PM

Hello, I have figured it out. I kind of reverse engineered it in a way. So I'm still looking for a better answer, but if any one else has this problem here is my solution. FIrs of I found this code in the manual

  Vector3[] frustumCorners = new Vector3[4];
             camera.CalculateFrustumCorners(new Rect(0, 0, 1, 1), camera.farClipPlane, Camera.MonoOrStereoscopicEye.Mono, frustumCorners);

it creates a vector variable at the end of your cameras field of view corners. then I created a new vector 3 from my camera's position to one of the corners (I chose 2 since all of it's values are positive you can choose which ever one you like (that's not higher then 4 lol)). with this code: Vector3 big_vector=frustumCorners[2]-transform.position;

then I used an Atan function to get the angel by dividing the big vectors (the vector from the camera/this object to one of the corners of the camera ) x value with its z value (). with this code:

 angel = (float)(System.Math.Atan(big_vector.x / big_vector.z));

then I calculated the x right and left borders on my plane (my plane is a z value of 0) and the y up and down values of the plane (I calculated separately for right and left and up and down since my camera is rotated) I did this by multiplying the tan function with the transform.position.z since this is where my camera is located and since my plane is on a z of 0 the length form my camera to the plane is the same as my cameras z position. here is the how I did it(screen_x borders is a float array of 2 items declared over the start function the same goes for the y ones):

     //these are the x values
     screen_x_borders[0] = (float)System.Math.Tan(angel+transform.rotation.y) * System.Math.Abs(transform.position.z)+transform.position.x;
     
             screen_x_borders[1] = (float)System.Math.Tan(-angel+transform.rotation.y) * System.Math.Abs(transform.position.z) + transform.position.x;
 
 
 //these are the y values: 
 
 angel = (float)(System.Math.Atan(big_vector.y / big_vector.z));
 
         screen_y_borders[0] = (float)System.Math.Tan(angel) * System.Math.Abs(transform.position.z + transform.rotation.x) + transform.position.y;
 
         screen_y_borders[1] = (float)System.Math.Tan(-angel) * System.Math.Abs(transform.position.z + transform.rotation.x) + transform.position.y;


when calculating the y values I calculated a new angel as you can see. this is basically it but for easier usage in other scripts I stored the borders length/distance from each other into a Vector 2 and then also calculated a Vector2 offset so when I use the code in other scripts I can just say for example if( border.x + offset < this position){ do something }

the border lengths (screen_border is a public variable ):

 screen_borders.x = screen_x_borders[0] - screen_x_borders[1];
 
 screen_borders.y = screen_y_borders[0] - screen_y_borders[1];

the offset(is also a public Vector 2 ):

    border_offset = new Vector2(screen_x_borders[0]-screen_borders.x/2 ,screen_y_borders[0] - screen_borders.y / 2 - transform.position.y );

I subtracted the y position of my camera from the offset since my camera is moving in the y position all the time and I will subtract it when I need to call it in other scripts rather then doing it here every frame for eg. : if( screen_borders.y+border_offset < this position){ do something } the whole code :

 public GameObject object_;
 
 public Vector3[] frustumCorners;
 public Vector3 big_vector;
 public float angel;
 public float[] screen_x_borders = new float[2];
 public float[] screen_y_borders = new float[2];
 public Vector2 screen_borders;
 public Vector2 border_offset;
 void Start() {
     var camera = GetComponent<Camera>();
     Vector3[] frustumCorners = new Vector3[4];
     camera.CalculateFrustumCorners(new Rect(0, 0, 1, 1), camera.farClipPlane, Camera.MonoOrStereoscopicEye.Mono, frustumCorners);
 
     Vector3 big_vector=frustumCorners[2]-transform.position;
 
     angel = (float)(System.Math.Atan(big_vector.x / big_vector.z));
 
     Debug.Log("angel1: " + (-angel  * 180 / System.Math.PI));
     Debug.Log("angel2: " + transform.rotation.eulerAngles.y );
     Debug.Log("angel3: " + (angel + transform.rotation.y) * 180 / System.Math.PI);
 
 
     Vector2 cur_object_angels = new Vector2(0,0);
     cur_object_angels.y = (transform.rotation.eulerAngles.y > 180) ? transform.rotation.eulerAngles.y - 360 : transform.rotation.eulerAngles.y;
     cur_object_angels.x = (transform.rotation.eulerAngles.x > 180) ? transform.rotation.eulerAngles.x - 360 : cur_object_angels.x;
     cur_object_angels *= (float)System.Math.PI / 180;
 
     screen_x_borders[0] = (float)System.Math.Tan(angel + cur_object_angels.y) * System.Math.Abs(transform.position.z)+transform.position.x;
 
     screen_x_borders[1] = (float)System.Math.Tan(-angel + cur_object_angels.y) * System.Math.Abs(transform.position.z) + transform.position.x;
 
     screen_borders.x = screen_x_borders[0] - screen_x_borders[1];
 
 
     angel = (float)(System.Math.Atan(big_vector.y / big_vector.z));
 
     screen_y_borders[0] = (float)System.Math.Tan(angel + cur_object_angels.x) * System.Math.Abs(transform.position.z + transform.rotation.x) + transform.position.y;
 
     screen_y_borders[1] = (float)System.Math.Tan(-angel + cur_object_angels.x) * System.Math.Abs(transform.position.z + transform.rotation.x) + transform.position.y;
 
     screen_borders.y = screen_y_borders[0] - screen_y_borders[1];
 
     border_offset = new Vector2(screen_x_borders[0]-screen_borders.x/2 ,screen_y_borders[0] - screen_borders.y / 2 - transform.position.y );
 
     screen_borders /= 2;
     
     object_.transform.position = new Vector3(screen_borders.x+border_offset.x, screen_borders.y+border_offset.y+transform.position.y, 0);
 }

At the end, I have an object_ Gameobject variable which I have to test if the code worked and my corners are like they are supposed to be.

I know this was long but I wanted to explain my train of taught behind it since the code is very specific for my example of a camera moving in the y position. I hope this helps someone I was stumped on this problem for about 4-5 days I think. By posting this I can say that my problem is finally ...over.

Comment
Add comment · 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

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.

Follow this Question

Answers Answers and Comments

99 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 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 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 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 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

How can I tell the user can see an object, from any angle? 1 Answer

how can i instantiate a GameObject in mouse position and in a special distance from the camera? 2 Answers

Help with Raycast C# 0 Answers

Obstacle avoidance 1 Answer

C# RayCast Fire Cooldown DeltaTime Help 1 Answer


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