-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement camera cache utility class #852
Conversation
Camera.main calls a FindByTag on the whole scene to return the reference everytime. Cache the reference to the main camera instead and provide a method to overwrite it if necessary
Both GetHorizontalFieldOfViewRadians and IsInFov use Camera.main to get the reference to the main camera in their calculations. Set the old methods obsolte and move them into new camera extensions
Most scripts are simple replacement. Some scripts cache the reference themselves: ScaleByDistance, MoveWithObject
@Zod-, |
/// </summary> | ||
/// <param name="newMain">New main camera to cache</param> | ||
/// <returns></returns> | ||
private static Camera CacheMain(Camera newMain) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The class name already tells us its the CameraCache, so maybe name this method something like SetMain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realized the same and renamed it in a later commit to CameraCache.Refresh(camera)
. How do you like that one? Maybe another suggestion?
(I also totally forgot to change the automatically generated private to public which i fixed in the same commit)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good!
I noticed there's places where we are caching our cached camera, when we can now just use a direct call to the CachedCamera.main
public static bool IsInFOV(this Camera camera, Vector3 position) | ||
{ | ||
float verticalFovHalf = camera.fieldOfView / 2; | ||
float horizontalFovHalf = camera.GetHorizontalFieldOfViewRadians() * Mathf.Rad2Deg / 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: * 0.5f
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed this, also added it to GetHorizontalFieldOfViewRadians
@@ -100,16 +101,17 @@ private void Update() | |||
} | |||
else | |||
{ | |||
Camera mainCamera = CameraCache.main; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why cache again?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really for caching but I'm just used to have a local reference when I use something more than once. Using the full call to reference it every time and sometimes even twice in the same line can make the code quite a bit longer. I could change it back in cases where it's not as bad.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO calling it directly actually helps legibility, even if it's just a bit longer. Less Spaghetti.
Not that performance is an issue here, but local references do add to the heap (albeit negligible now days). Not a big deal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll change it back in cases like this where there are fewer calls
/// <summary> | ||
/// Returns a cached reference to the main camera and uses Camera.main if it hasn't been cached yet. | ||
/// </summary> | ||
public static Camera main |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: public variables should be PascalCase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although this is very optional because it's following the same pattern as unity to get the main camera. Less work to refactor, but maybe making it PascalCase will show there's a difference between usages?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had the same in mind to keep it the same as the unity call. But that's a good point to see a larger difference. One could mistake CameraCache.main
for Camera.main
when skimming over the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed it to PascalCase
Altough it seemed to make sense first to keep it the same as the unity api but to make a clearer difference between the two rename: main > Main.
@@ -61,7 +61,8 @@ private enum FrustumPlanes | |||
|
|||
private void Start() | |||
{ | |||
Depth = Mathf.Clamp(Depth, Camera.main.nearClipPlane, Camera.main.farClipPlane); | |||
Camera mainCamera = CameraCache.main; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We cache here, then again on line 104.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see, it's needed because it's the update. Please disregard comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Should I still change the local variable caches or is it ok? |
I think it's okay, not a big deal. I'll leave that up to you. |
@@ -93,26 +92,23 @@ private void Start() | |||
// Update the direction indicator's position and orientation every frame. | |||
private void Update() | |||
{ | |||
// No object to track? | |||
if (TargetObject == null || pointer == null) | |||
if (!HasObjectsToTrack()) return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit braces { return; }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -0,0 +1,30 @@ | |||
using UnityEngine; | |||
|
|||
namespace HoloToolkit.Unity |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the CameraCache be in the HoloToolkit.Unity.Input namespace? That is where our other camera related stuff lives right now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's fine, and the class should also include the license info in header.
@@ -0,0 +1,36 @@ | |||
using UnityEngine; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit License header
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the changes. Approved
@keveleigh, same here. Workaround I found is assigning the gaze transform manually. Use the camera prefab you've got in your scene. |
I'm not getting any errors. How are you guys testing? Nevermind, There it showed up |
Could be 2017.2 specific? |
@StephenHodgson Sweet, thanks for the workaround! @jessemcculloch I pulled master, loaded in Unity 2017.1.0f3, opened the InputTapTest scene, and hit the Play button. |
For some reason it doesn't seem to like if (GazeTransform == null)
{
GazeTransform = CameraCache.Main.transform;
}
else
{
GazeTransform = GazeTransform;
} |
Sometimes null coalescing doesn't work for components in Unity for some reason. It's hit or miss. I think it's because even when a field is null, Unity still assigns an object that's still technically null to |
@Zod- I was just writing up the same finding :) Unity overrides == for GameObjects, which doesn't appear to play nicely with ??. From that blog post:
|
Sorry about that I've fixed it in #864 |
Fixes #848
This adds a new Utility class that allows the use a cached reference to the main camera via
CameraCache.main
. Additionally, a method to refresh the reference is provided withCameraCache.Refresh(camera)
. On the first call where the cached camera is null,Refresh(Camera.main)
is called to initialize. Should I add this to documentation somewhere? What do you think of the names?I moved
MathUtils.GetHorizontalFieldOfViewRadians
andMathUtils.IsInFov
to a newCameraExtensions
since they were both relying on and usingCamera.main
. Both Methods are not marked as obsolete and use the new extension with the cached camera instead. There was another method inUtils.MoveObjectInFrontOfUser
that also uses the camera but I didn't move that one into Camera because I thought it didn't fit as well. But maybecamera.MoveObjectInFront
might not be so bad.Most scripts were simple replacements from
Camera.main
toCameraCache.main
where I also added a local variable in some cases where it's used more than once.2 Scripts cache the reference to the camera once on start:
ScaleByDistance
,MoveWithObject
. Not sure how to deal with those. Maybe do it like the GazeManager that checks for the GazeTransform on every update?Lastly
GestureInteractiveData
does this:I changed it to use
CameraCache
but wasn't comfortable to just completely remove it and use local variables where it's used.