Swapping between front facing and back facing camera at runtime

I’ve been looking into how to swap between the front facing and back facing camera with unity MARS and I haven’t been able to find a concrete solution.

Some resources suggest that I have to be swapping the CameraFacingDirection to User from World, but this isn’t as cut and dry as it is in ARFoundation as the MARSSession tends to override this based on the requirements it generates based on whats in the scene.

Is there any way to swap between the front facing and back facing camera on an IOS device during runtime?

Hi, you can switch the camera by using the API IUsesCameraTexture.RequestCameraFacingDirection

If you add a MonoBehaviour to your scene that implements IUsesCameraTexture, you can call this.RequestCameraFacingDirection in the behavior. This only works if you are using AR Foundation 4 or later.

Thanks for your reply!

So I have tried a similar approach to the one you described above by using a mono behavior that implements several of the subscriber classes but I always end up with the same result: a null reference for the obj that is being used in the method of these classes.

My code is setup as follows:

using Unity.MARS.Data;
using Unity.MARS.Providers;
using Unity.XRTools.ModuleLoader;
using UnityEngine;

public class SwitchCameraController : MonoBehaviour,  IUsesCameraTexture
{
    IProvidesCameraTexture IFunctionalitySubscriber<IProvidesCameraTexture>.provider { get; set; }

    public void SwitchCamera()
    {
        var currentDirection = this.GetCameraFacingDirection();
        var requestUserDirection = currentDirection == CameraFacingDirection.World;
        var requestedDirection = requestUserDirection
            ? CameraFacingDirection.User
            : CameraFacingDirection.World;

        this.RequestCameraFacingDirection(requestedDirection);
    }
}

When I make a call to switch camera I get a null reference error for on this.GetCameraFacingDirection, IUsesCameraTexture.cs line 24.

The method in question:

        /// <summary>
        /// Get the current facing direction of the camera used to supply the texture
        /// </summary>
        public static CameraFacingDirection GetCameraFacingDirection(this IUsesCameraTexture obj)
        {
            return obj.provider.CameraFacingDirection;
        }

I’m curious if I am missing something when it comes to properly establishing functionality within these subscriber classes, do I have to inject functionality as is done similarly in the MARSSession.cs? Let me know when you have a chance!

1 Like

Hi, you also need to implement IUsesFunctionalityInjection
and call this.EnsureFunctionalityInjected();on Awake

Thanks for this! That solved my issues of null references but now I have another question about the MARS Session and how it affects the camera facing direction.

Using the same code above, with the addition of the explicit functionality injection, I am able to call the switchCamera method and request what should be the opposite of the current camera facing direction, but what happens is it stays the same.

Using some logs to check the current camera facing direction and that which is being requested throughout the method call I see that I start out as world, requested is updated to user, and finally after the request is made my camera direction is still world.

I noticed in the RequestCameraFacingDirection method of IUsesCameraTexture the comment for the method states that it changes to the requested facing direction “if possible.” I’m curious if my request does not fit in the realm of possibility for the method, though It does explicitly say if it does or not.

Is there something I have to do to ensure my use of the method is correct? Or is this related to what exists in the scene (I noticed that the MARS Session requirements for camera facing direction change depending on what types of AR things exist in the scene)?

bump

eddersook, Just checking some basic things, which version of AR Foundation are you using?, same for MARS, ARKit ARCore etc.

Currently using the following versions:

AR Foundation: 4.1.7
ARCore: 4.1.7
ARKit: 4.1.7
Unity MARS: 1.3.1
Unity: 2020.3.12f

Hi @eddersook , thanks for providing this info. I tested requesting camera facing with this setup and did not have any issues. Can you try using the attached scene and script?

7555138–934216–DynamicCameraFacingTest.zip (6.04 KB)

Hi @amydigiov_Unity I tried to implement your script with Unity Mars and it worked perfectly in switching between the front and rear camera! I just have a big issue concerning the Image tracking :frowning: Indeed I’m trying to activate the front camera of my Android device to track an Image Marker. But when I add the Image Marker to my Scene, I’m no longer able to switch between the two cameras… It’s like the camera is blocked in the rear mode (I think it is relate to the Marker condition that “overrides” the camerafacingdirection).

Do you have any suggestion to solve this issue? I’ve tried many solutions but none worked
Thank you so much for any help:)

Hi @amydigiov_Unity , thanks for giving me this test package. I assume on your end when you click the buttons it swaps and updates the text above, but for myself in my project as well as a completely fresh project with only the MARS installer and the same package versions of AR Foundation, etc provided above I get stuck on the world facing direction.

https://drive.google.com/file/d/1wZXsOQkrxvYYup5pGFzWr87ywvU1TswG/view?usp=sharing here’s a link to a screen recording showing what I see. This is exactly the same behavior on my iPhone.

any ideas what the differences could be?

Hey @eddersook , the issue is that image tracking isn’t available on ARCore (or ARKit) using the front camera. ARCore/Kit support various configurations of which features can operate simultaneously, and image tracking and activating the user-facing camera are always mutually exclusive. Check out this Unite video, namely around the 12 minute mark, where Todd talks about configuration management. Note that for any configuration that supports image markers, the user-facing camera is not supported.

Out of curiosity, what is the use case you’re trying to build that needs user-facing image tracking?

Hi @Jono_Unity ! I think you’re getting me mixed up with @ above. @ them here so they can see your response!

My concern is primarily with getting my IOS device to swap between front and back facing cameras. I tried the solutions provided given the package versions and Unity version given above within my existing project and also in a completely fresh project with only the provided solution and the newest version of MARS, all of which left me unsuccessful in swapping between the user and world facing cameras on IOS.

The consistent experience I have both in editor and on device, within my current project as well as the fresh project, is that no matter what camera facing direction I request, it will always remain the world camera facing direction.

I have provided a video in my previous response that shows the perspective I see in editor and on device using the provided scene and script from @amydigiov_Unity