Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

Question Turn Off MARS Camera

Discussion in 'Unity MARS' started by andysdds, Jan 25, 2021.

  1. andysdds

    andysdds

    Joined:
    Aug 29, 2019
    Posts:
    11
    I am doing some performance improve , turn off the camera if User is using UI . I try to false active of the MARSSession gameobject . but it still running the camera , according to the iPhone green dot . Is there any function in MARS can turn off the camera?
     
  2. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    Hi there! Turning off the physical camera should be pretty straightforward. This doesn't happen automatically when you disable the MARSSession object, but you can write a simple script to call `IUsesSessionControl.PauseSession` to do it.

    I've provided a sample script here which includes methods to pause/resume/reset the session. Hope this helps!
     
  3. andysdds

    andysdds

    Joined:
    Aug 29, 2019
    Posts:
    11
    I try to
    Code (CSharp):
    1. MARSCore.instance.paused = true;
    but the camera still working .
    then I try to
    Code (CSharp):
    1. IUsesSessionControl.PauseSession()
    but the provider is null , interesting thing is it did have a provider in editor .
     
  4. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    Sorry, I should have been more clear. You aren't meant to call `IUsesSessionControl.PauseSession` directly, but rather use it as an extension method on something which implements `IUsesSessionControl`. Then you would call `this.PauseSession()` from that script.

    It's easiest to have this script exist in the scene before it is loaded, in which case MARS takes care of setting the `.provider` property. If you need to create this object in code, it should also implement `IUsesFunctionalityInjection` and call `this.EnsureFunctionalityInjected()` in Awake.
     
  5. andysdds

    andysdds

    Joined:
    Aug 29, 2019
    Posts:
    11
    My MARSession script
    Code (CSharp):
    1.  
    2. public class MARSSession : MonoBehaviour, IUsesFunctionalityInjection
    3. {
    4.         public class Subscriber : IUsesMarkerTracking, IUsesSessionControl
    5.         {
    6.             IProvidesSessionControl IFunctionalitySubscriber<IProvidesSessionControl>.provider { get; set; }
    7.             IProvidesMarkerTracking IFunctionalitySubscriber<IProvidesMarkerTracking>.provider { get; set; }
    8.         }
    9.         public Subscriber m_Subscriber = new Subscriber ();
    10.         void Awake ()
    11.         {
    12.              // some MARSSession thing
    13.              this.InjectFunctionalitySingle (m_Subscriber);
    14.         }
    15. }
    16.  
    My Other Script
    Code (CSharp):
    1.  
    2. public class ARManager : MonoBehaviour
    3. {
    4.        public MARSSession MARS_instance;
    5.  
    6.         public void Disable_Mars ()
    7.         {
    8.              if (MARS_instance.m_Subscriber.HasProvider<IProvidesSessionControl> ()) // return false
    9.                   MARS_instance.m_Subscriber.PauseSession();
    10.              if (MARS_instance.m_Subscriber.HasProvider<IProvidesMarkerTracking> ()) // return true
    11.                   MARS_instance.m_Subscriber.StopTrackingMarkers ();
    12.         }
    13. }
    14.  
    I think I already done what you are saying , or I do it in the wrong way.:eek:
     
  6. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    Kind of :)

    What you posted seems like it _should_ work, but I was talking about having this all be one script. The "Hidden subscriber" pattern used in the example is also a bit more complicated than what you need here. I haven't been able to test this, but the following code should work, as long as you don't call `TogglePaused` until the camera has fully initialized. If you want the app to _start_ with the camera disabled, you can do that by disabling auto-load in XR Management settings. Happy to go into more detail there if that's what you're after.

    Please try this and see if it works for you
    Code (CSharp):
    1. using System;
    2. using Unity.MARS.Providers;
    3. using Unity.MARS.Settings;
    4. using Unity.XRTools.ModuleLoader;
    5. using UnityEngine;
    6.  
    7. namespace Unity.MARS
    8. {
    9.     public class SessionUI : MonoBehaviour, IUsesFunctionalityInjection, IUsesSessionControl
    10.     {
    11.         IProvidesFunctionalityInjection IFunctionalitySubscriber<IProvidesFunctionalityInjection>.provider { get; set; }
    12.         IProvidesSessionControl IFunctionalitySubscriber<IProvidesSessionControl>.provider { get; set; }
    13.  
    14.         void Awake()
    15.         {
    16.             // Only necessary if this script isn't already in the scene when you press Play
    17.             this.EnsureFunctionalityInjected();
    18.         }
    19.  
    20.         public void TogglePaused()
    21.         {
    22.             var marsCore = MARSCore.instance;
    23.             var wasPaused = marsCore.paused;
    24.             marsCore.paused = !wasPaused;
    25.             if (wasPaused)
    26.             {
    27.                 this.ResumeSession();
    28.             }
    29.             else
    30.             {
    31.                 this.PauseSession();
    32.             }
    33.         }
    34.     }
    35. }
    36.  
     
    azevedco likes this.
  7. andysdds

    andysdds

    Joined:
    Aug 29, 2019
    Posts:
    11
    It work !! , Thank you so mush for you help.
     
    jmunozarUTech likes this.
  8. JakeShields

    JakeShields

    Joined:
    Feb 23, 2014
    Posts:
    13
    Hi, I have some questions.

    1) Turning off MARS Camera

    I want to turn off MARS camera in some situation for better performance, but still I want the main camera(under MARS Session)'s transform to be updated by device movement in real world. Is there any way to do this? (because pausing MARS session also stops main camera's transform update)


    2) Scene Evaluation

    I am considering setting Startup Mode to WaitForRequest and call RequestSceneEvaluation with frame update for better sync between AR and in-game update.

    2-1) To do this, calling RequestSceneEvaluation on every frame update is right? or just setting Evaulation Interval to zero will do? (with Startup Mode: Evaluate On Interval)

    2-2) Does main camera(under MARS Session)'s transform update also occur on this Scene Evaluation?

    2-3) Do you remcommend to reduce Evaluation Interval or syncing it with frame update? Will there any performance impact or other issues?
     
    Last edited: Dec 2, 2021
  9. mtschoen

    mtschoen

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    194
    Hi there! Thanks for using MARS :)

    I'll try to answer your questions inline below

    Unfortunately, this isn't really possible, at least not if you want full 6dof tracking. You can disable the `ARCameraBackground` which should get you some GPU performance back, but the phone still needs the camera to be powered on and recording images in order to do SLAM which is responsible for positional tracking.

    It would be possible to use something like the Gyroscope.attitude API (https://docs.unity3d.com/ScriptReference/Gyroscope-attitude.html) to just do 3dof tracking while AR tracking is paused, if that is sufficient.

    I'll answer (2-2) first: the main camera transform update happens every frame. Some other parts of the query pipeline, like updating face poses and landmarks also happen every frame _once the query match has occurred_. Essentially, the evaluation interval only affects the timing of query acquisition and loss. Once a query match is acquired, updates to the data should happen once per frame, regardless of evaluation interval or calls to `RequestSceneEvaluation`.

    Setting scene evaluation to WaitForRequest and calling RequestSceneEvaluation every frame is equivalent to setting the interval to 0 and leaving the default Evaluate On Interval setting at start-up. Because of the pipelined nature of the MARS backend, it is not possible to get matches to happen immediately on the frame that the data is available. There will always be a delay of a few frames depending on what stage of the pipeline is active. It is not possible to run multiple pipeline stages at once.

    Finally, yes there will be a performance impact to setting the evaluation interval to 0 or trying to evaluate every frame. Depending on your use case, this may be acceptable. If you only expect users to scan a small number of surfaces and don't make heavy use of synthetic objects, evaluating every frame may work well. The other thing to keep in mind is that query acquisition causes objects to appear and disappear by default. A slow evaluation interval keeps things from "popping" in and out as matches are acquired and lost due to query constraints. We have found that keeping the evaluation interval a little slower leads to a better user experience. But, of course, your mileage may vary :)

    Hope this helps!
     
    jmunozarUTech likes this.