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. Dismiss Notice

How can I limit a frustum I'm using for detection?

Discussion in 'Scripting' started by Reverend-Speed, Oct 29, 2021.

  1. Reverend-Speed

    Reverend-Speed

    Joined:
    Mar 28, 2011
    Posts:
    284
    I'm currently trying to detect if a character enters / exits a smaller (ie. shorter) frustum than my camera frustum in Fixed Camera gameplay.

    I'm not using OnBecameVisible as I'm basically looking at making a fixed camera system like Alone in the Dark - so there's going to be multiple cameras being switched on or off (actually, probably one camera that moves between positions). In that instance, if the camera is off or not present at the space the character is moving into, that makes OnBecameVisible unhelpful, afaik.

    I was using GeometryUtility.CalculateFrustumPlanes and GeometryUtility.TestPlanesAABB fairly successfully, but I've run into a problem. The back plane of the camera frustum is too far away to make the frustum check worthwhile, and I'm a bit confused about the math of bringing it closer to the near plane for the check (I'd prefer not changing the actual camera frustum).

    I'd do a squared distance check but that won't reliably cover the geometry of the frustum (the radius would over or undershoot the planes). I'm seriously considering doing some kind of secondary boxcast or overlap check but my gut is telling me I should be able to check it in one. Indeed, I'm already checking it in one, I just have too big a frustum! It's possible that Cinemachine would have some tools that could help, but I'd really like to solve this issue! I feel I'm really close...!

    I tried manually changing the distance value of the sixth plane (planes[5]) from CalculateFrustumPlanes with the intention of feeding that back into TestPlanesAABB but it doesn't seem to have any effect on the detection.

    In addition, I'm having trouble visualizing the placement of the back plane - I'm currently using this code...

    planes = GeometryUtility.CalculateFrustumPlanes(Camera.main);

    planes[5].distance = distFromCamera;
    farPlaneDistance = planes[5].distance;
    p.transform.rotation = Quaternion.FromToRotation(Vector3.up, planes[5].normal);
    p.transform.position = Camera.main.transform.position + (-planes[5].normal * distFromCamera);
    //p.transform.position = Camera.main.transform.position + (-planes[5].normal);

    ...but - clearly I'm changing the position of the gameObject plane for visualization rather than the actual main plane. (Ultimately I'd change this to a Gizmo or what have you, but this is just for testing)

    Any advice would be appreciated!

    LATER:
    Currently trying to find the camera bounds using CalculateFrustumCorners, with the intention of putting them into Matrix4x4.Frustum via WorldToViewportPoint (modifying the far plane) and then using that in CalculateFrustumPlanes... and THEN using that in TestPlanesAABB.

    Unfortunately, I can't seem to get useful Vector3s out of CalculateFrustumCorners (just a collection of Vector3.zeros).

    Feeling very lost here.

    EVEN LATER:
    So, I've figured out how to use Matrix4x4.Frustum to create a frustum, which I can build out of planes (using CalculateFrustumPlanes and code from the Unity Docs). The near and far planes can be set manually...

    Code (CSharp):
    1. public Matrix4x4 manualFrustum;
    2.     public float manualFrustumNear = 1.0f;
    3.     public float manualFrustumFar = 4.0f;
    4.     public Plane[] manualFrustumPlanes;
    5.  
    6.     void Start()
    7.     {
    8.         manualFrustum = Matrix4x4.Frustum(0, 1, 0, 1, manualFrustumNear, manualFrustumFar);
    9.    
    10.         manualFrustumPlanes = GeometryUtility.CalculateFrustumPlanes(manualFrustum);
    11.  
    12.         // Create a "Plane" GameObject aligned to each of the calculated planes
    13.         for (int i = 0; i < 6; ++i)
    14.         {
    15.             GameObject p = GameObject.CreatePrimitive(PrimitiveType.Plane);
    16.             p.name = "Plane " + i.ToString();
    17.             p.transform.position = -manualFrustumPlanes[i].normal * manualFrustumPlanes[i].distance;
    18.             p.transform.rotation = Quaternion.FromToRotation(Vector3.up, manualFrustumPlanes[i].normal);
    19.         }
    20.     }
    The issue NOW is how to set the orientation and position of the Frustum (NOT the plane game objects created above for visualisation). This is tough as, on its own, a Frustum doesn't seem to have those attributes. Hmm. More questions...!

    LATER LATER LATER...

    So, there's https://docs.unity3d.com/ScriptReference/Matrix4x4.Rotate.html and this https://docs.unity3d.com/ScriptReference/Matrix4x4.Translate.html , but these seem to create matrices rather than perform an operation on an existing Matrix. Where on earth are the functions I need...
     
    Last edited: Oct 30, 2021
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,528
    I'm trying to figure out where physics is involved here because it's on the physics sub-forum. All I see is camera/math/script stuff.

    It seems like this post would be better moved to the scripting forum where you'd like get more eyes on it? I can do that for you if you wish.
     
  3. Reverend-Speed

    Reverend-Speed

    Joined:
    Mar 28, 2011
    Posts:
    284
    My intention was to place the post in 'Physics' as it related to detecting things (ala colliders, triggers, casts, bounds etc). On mature reflection, yeah, that's dumb - it should go in the scripting forum! If you can migrate that I'd appreciate it.

    Cheers man!
     
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,528
    Not a problem at all and it's often a little ambiguous as to where things should be asked. It's not a problem being here but you might be more likely to get answers elsewhere. A link stays here even if I move it to scripting though so you'll get it in both places for a while.
     
    Reverend-Speed likes this.