I’ve searched thoroughly for a solution I can understand, but can’t seem to figure out how to scale the x/y of a cube (collider) to match that of my camera view at runtime. I’m trying to create a trigger boundary that can scale dynamically depending on the device resolution and aspect ratio. Specifically, when an object leaves the screen, destroy it, bring it back, etc. I have this system working now but the trigger is not connected to the screen size or aspect ratio.
Not sure if I should be using ViewportToScreenPoint, WorldToViewportPoint, Frustum or something else. Any help is appreciated!
Here’s what I have now which doesn’t work correctly (the cube collider is made tiny at runtime.)
Code
var pos : Vector3 = camera.main.WorldToViewportPoint (transform.position);
transform.localScale.x = pos.x;
transform.localScale.y = pos.y;
The below script will draw debug lines at points on the camera view frustum. From these points you can determine the size and scale for a box collider. You could also use these points to generate a mesh collider.
In a new scene, attach this script to the camera :
#pragma strict
var theCamera : Camera;
var upperDistance : float = 8.5;
var lowerDistance : float = 12.0;
private var tx : Transform;
function Start()
{
if ( !theCamera )
{
theCamera = Camera.main;
}
tx = theCamera.transform;
}
function Update()
{
FindUpperCorners();
FindLowerCorners();
}
function FindUpperCorners()
{
var corners : Vector3[] = GetCorners( upperDistance );
// for debugging
Debug.DrawLine( corners[0], corners[1], Color.yellow ); // UpperLeft -> UpperRight
Debug.DrawLine( corners[1], corners[3], Color.yellow ); // UpperRight -> LowerRight
Debug.DrawLine( corners[3], corners[2], Color.yellow ); // LowerRight -> LowerLeft
Debug.DrawLine( corners[2], corners[0], Color.yellow ); // LowerLeft -> UpperLeft
}
function FindLowerCorners()
{
var corners : Vector3[] = GetCorners( lowerDistance );
// for debugging
Debug.DrawLine( corners[0], corners[1], Color.red );
Debug.DrawLine( corners[1], corners[3], Color.red );
Debug.DrawLine( corners[3], corners[2], Color.red );
Debug.DrawLine( corners[2], corners[0], Color.red );
}
function GetCorners( distance : float ) : Vector3[]
{
var corners : Vector3[] = new Vector3[ 4 ];
var halfFOV : float = ( theCamera.fieldOfView * 0.5 ) * Mathf.Deg2Rad;
var aspect : float = theCamera.aspect;
var height : float = distance * Mathf.Tan( halfFOV );
var width : float = height * aspect;
// UpperLeft
corners[ 0 ] = tx.position - ( tx.right * width );
corners[ 0 ] += tx.up * height;
corners[ 0 ] += tx.forward * distance;
// UpperRight
corners[ 1 ] = tx.position + ( tx.right * width );
corners[ 1 ] += tx.up * height;
corners[ 1 ] += tx.forward * distance;
// LowerLeft
corners[ 2 ] = tx.position - ( tx.right * width );
corners[ 2 ] -= tx.up * height;
corners[ 2 ] += tx.forward * distance;
// LowerRight
corners[ 3 ] = tx.position + ( tx.right * width );
corners[ 3 ] -= tx.up * height;
corners[ 3 ] += tx.forward * distance;
return corners;
}
You cannot use a box collider to make a collider to fit the shape of the camera view, assuming perspective so it has a frustum shape to it.
The way to do it is if you want poor collider shape just use the box, if you want to make it more to the actual view, you will need to make the frustum yourself and use a mesh collider.
Shouldn’t be hard at all, just make a cube in blender, extrude the top to a point and scale the base vertices and stretch it length wise.
I don’t know if Unity has this model, but you could do some searching. They only provide basic primitives.