Search Unity

Scaling with ARFoundation

Discussion in 'Handheld AR' started by tdmowrer, Aug 5, 2018.

  1. tdmowrer

    tdmowrer

    Unity Technologies

    Joined:
    Apr 21, 2017
    Posts:
    490
    We wanted to make scale a first class citizen in ARFoundation, so I'd like to clarify how it works. A basic AR scene has an ARSession and an ARSessionOrigin. The job of the ARSessionOrigin is to transform "session space" (the coordinate system used by the device) into "world space" (a position, rotation, and scale in Unity). The AR camera should be a child of the ARSessionOrigin, so if you want your AR camera to start at a non trivial position in the Unity scene, simply move the session origin to that position. That seems straightforward enough.

    However, you might find scale harder to get your head around. What are we scaling anyway? What does that mean? If I have a single Unity cube in my scene, and I set the scale to something other than (1, 1, 1), what should I expect to happen?

    ScaleCube.gif
    WTF? Why is my cube moving all over the place? Why isn't it scaling?

    The cube is changing apparent size, but also changing apparent position. Imagine if I had two cubes, what would you expect to happen? If both cubes got bigger without moving, then they would overlap. Clearly, they also have to appear to move.

    I say "appear" because we aren't actually scaling the cube; we're scaling session origin. This means scaling the camera's position and also all the trackables, such as planes. The blue plane in the GIF above doesn't appear to move because it and the camera are being scaled together. The end result is that it looks like the entire scene has scaled, when in fact, the session origin (camera + planes) have been scaled by the opposite amount.

    Looking instead at the scene view, we see what's actually happening: the cube doesn't move at all.

    ScaleCube_sceneView.gif

    We're trying to scale the apparent size of the entire scene, so everything will appear to get bigger or smaller and move away from or toward some origin. In fact, the session origin.

    So what should you do? Put the session origin at the "middle" of whatever scene you're trying to scale, and add another GameObject in the hierarchy (between ARSessionOrigin and Camera) to add an additional positional offset to the camera. Wouldn't it be nice if there were a convenience method to achieve this? In fact, there is!

    ARSessionOrigin.MakeContentAppearAt does exactly this. It doesn't move the content; instead it moves the ARSessionOrigin such that the content you specify appears to be the the position you've specified. Example: instead of moving the entire scene 3 meters to the left, move the ARSessionOrigin 3 meters to the right.

    Effectively, this puts the ARSessionOrigin at the "center" of the scene, and then also moves the camera by the opposite amount. The effect is that the origin for which all scaling is done is now well defined and controllable.

    MoveARSessionOrigin.gif
    Here, I've created a GameObject in the center of this complex scene, and asked the ARSessionOrigin to MakeContentAppearAt some point I selected on the plane. On the right, we have the GameView, what you would see on your device. It looks like the scene is moving while the plane remains still. However, the scene view on the left reveals that we're actually moving the session origin around.

    Using this method, scaling the session origin finally does what we want:

    ScaleARSessionOrigin.gif

    The content is "scaled" around a point I've specified.

    And it works for rotation too:

    RotateARSessionOrigin.gif

    Note how the camera effectively orbits the scene, making it look like the content is rotating.

    So why go through all this headache in the first place? Why not just scale the scene and leave the session origin alone? For simple content, like a cube, it's probably much easier just to scale the content. But for complex scenes, like this village, it might be very expensive, or even impossible. Particle effects cannot be trivially scaled. Scaling physics or nav meshes down to be very tiny is a bad idea -- things will start falling through the world, and nav meshes will be too small to work properly. Terrain is static at runtime, and cannot be moved, rotated, or scaled. For these reasons, it's much more effective to scale the camera + trackables, not the scene content.

    Hope that helps clear up some confusion. I'll look for your questions and feedback below!

    -Tim
     
    gxyfred, SpiderJones, andgest and 4 others like this.
  2. Tarrag

    Tarrag

    Joined:
    Nov 7, 2016
    Posts:
    104
    That's rad @timmunity, thanks a bunch , it clarified the concept.

    I didn't get a chance to look further into this but it appears the light/shadows rotate with the ARSessionOriginGO. I have a directional light in the scene.

    MakeContentAppearAt you described worked for me for horizontal planes if I instantiated on a horizontal plane but in this scenario I run into problems when moving the object to/on vertical planes.

    I used MakeContentAppearAt method when I instantiating or moving the object. At instantiation I used

    if (m_SessionOrigin.Raycast(touch.position, s_Hits, TrackableType.PlaneWithinPolygon))
    hitPose = s_Hits[0].pose;
    spawnedObject = Instantiate(m_PlacedPrefab, hitPose.position, hitPose.rotation);
    MakeContentAppearAt(spawnedObject.transform, spawnedObject.transform.position, spawnedObject.transform.rotation);

    When moving an object to a vertical plane after instantiated at a horizontal plane if I used MakeContentAppearAt(spawnedObject.transform, hitPose.position, spawnedObject.transform.rotation); the object sits vertically on a vertical plane. So instead I tried using MakeContentAppearAt(spawnedObject.transform, hitPose.position, hitPose.rotation); However hitPose.rotation changes within a plane so the object jitters when moved and in a vertical plane it does not sit or rotate correctly.

    To avoid the jerky movement I am experimienting by changing the actual rotation of the object to hitPose.rotation when changing plane alignments, use MakeContentAppearAt(spawnedObject.transform, hitPose.position, spawnedObject.transform.rotation); and in the case of vertical planes change the rotation of the ARSessionGO to Quaternion.AngleAxis(rotationSlider.value, Vector3.right); though haven't seen good results.

    Cheers! Sergio
     
  3. rxmarccall

    rxmarccall

    Joined:
    Oct 13, 2011
    Posts:
    299
    @timmunity
    I was just trying to understand this better today! Good timing.

    I wanted to ask if it'd be possible for you to upload / share the project above so we can easily play around with the example project you used above?

    I've been trying to understand how I can manually make a trackable plane in the editor like this to test with.
     
    Last edited: Aug 6, 2018
  4. tdmowrer

    tdmowrer

    Unity Technologies

    Joined:
    Apr 21, 2017
    Posts:
    490
    The lights/shadows don't rotate with the session origin, but they might appear that way, since the camera is orbiting the scene. Depending on the effect you want to achieve, you might want to parent the light to the session origin (so it moves and rotates too).

    You are both spawning an object at the hit point and then also using MakeContentAppearAt to make it appear at the hit point. I suppose that's fine, but it doesn't really matter where you spawn the object in that case, since you're also moving the session origin.

    Sounds like you don't want the vertical orientation. In that case, you can use the variant that doesn't take a rotation. Maybe something like this:

    Code (CSharp):
    1. if (m_SessionOrigin.Raycast(touch.position, s_Hits, TrackableType.PlaneWithinPolygon))
    2. {
    3.   hitPose = s_Hits[0].pose;
    4.   spawnedObject = Instantiate(m_PlacedPrefab);
    5.   m_SessionOrigin.MakeContentAppearAt(spawnedObject.transform, hitPose.position);
    6. }
    If you want to just adjust the rotation later, use the variant that only takes a rotation.
     
  5. tdmowrer

    tdmowrer

    Unity Technologies

    Joined:
    Apr 21, 2017
    Posts:
    490
    I had a feeling that would be one of the first questions :)

    I used a prototype of the simulation package I've mentioned in some other threads. That's not done yet, but it should also work as a standalone sample; I'll look at adding it to the ARFoundation Samples repo.
     
    rxmarccall and wjpeters like this.
  6. Balours

    Balours

    Joined:
    Nov 27, 2013
    Posts:
    42
    Thanks for the explanation @tdmowrer , it's working fine!
    Now my issue, I want to attach an object to the camera that will interact with the scaled objects, for example a stick that will illuminate the objects when touched, but of course if the camera is moved away I lost the interaction. How should I manage the scale of the attached object?
    Thank you!
     
  7. tdmowrer

    tdmowrer

    Unity Technologies

    Joined:
    Apr 21, 2017
    Posts:
    490
    If I understand correctly, you want the "stick" to appear to remain unscaled, that is, not change size with the content. In that case, you can parent it to the ARSessionOrigin. If you also want it to move with the camera (e.g., a fixed stick dangling in front of your head), then you could parent it to the AR Camera.

    Here's what that looks like:
    CameraStick.gif

    And here's my scene hierarchy:

    StickSceneHierarchy.png

    Remember, in this setup, the blue cube is not moving or scaling; it's the plane, camera, and "stick" that get scaled together.
     
  8. Balours

    Balours

    Joined:
    Nov 27, 2013
    Posts:
    42
    Yes that's close to what I want, thanks a lot for the example. However, I would need the stick to stay proportional to the content, is it the case in your example?
     
  9. Tarrag

    Tarrag

    Joined:
    Nov 7, 2016
    Posts:
    104
    Apologies for the late response @tdmowrer , that time of the year :)
    That works, thank you! Cheers, Sergio
     
  10. tdmowrer

    tdmowrer

    Unity Technologies

    Joined:
    Apr 21, 2017
    Posts:
    490
    To stay proportional to the content, the "stick" should be outside of the ARSessionOrigin hierarchy. You could then have a script that places it in front of the camera every frame.
     
  11. Balours

    Balours

    Joined:
    Nov 27, 2013
    Posts:
    42
    That's perfect, and it makes sense. Thank you for your help!
     
  12. HeavyProduction

    HeavyProduction

    Joined:
    Aug 12, 2016
    Posts:
    26
    Any update on the scale project sample?
     
  13. maurogarcia

    maurogarcia

    Joined:
    Nov 6, 2012
    Posts:
    12
    It would be very useful an update of the Sample Project, 'cause still not contain anything about "Scaling".
    Thanks!
     
  14. tonOnWu

    tonOnWu

    Joined:
    Jun 23, 2017
    Posts:
    58
    Hi. We're moving an old version of one of our AR apps, but we really need more examples. Particularly we need a "Scaling" example and how to remove planes and plane's detection once the scene has been set.
     
    hawken and GreeneMachine like this.
  15. tonOnWu

    tonOnWu

    Joined:
    Jun 23, 2017
    Posts:
    58
    Hi everybody. Well, while we wait for an example that explains how to do this, I've been trying to solve it by myself. I'll present what I've done so far. Any helping ideas will be well received.

    First I created a Component call Scaler which was assigned to AR Session Origin. This is the code:

    Code (CSharp):
    1. [RequireComponent(typeof(ARSessionOrigin))]
    2. public class Scaler : MonoBehaviour
    3. {
    4.  
    5.     ARSessionOrigin m_SessionOrigin;
    6.     [SerializeField] GameObject referenceToScale;
    7.  
    8.     void Start()
    9.     {
    10.         m_SessionOrigin = GetComponent<ARSessionOrigin>();
    11.     }
    12.  
    13.     // Method called by a Slider
    14.     public void OnValueChange(float value)
    15.     {
    16.         Debug.Log("New Value: " + value);
    17.         Transform t = gameObject.transform;
    18.  
    19.         m_SessionOrigin.MakeContentAppearAt(referenceToScale.transform, Quaternion.identity);
    20.  
    21.         referenceToScale.transform.localScale = new Vector3(value, value, value);
    22.     }
    23. }
    The method OnValueChange is called by a Slider.

    Now, following what I understand on the first post of this thread, I did set a MiddleReference game object in the hierarchy and has located between the AR Session Origin and AR Camera. This MiddleReference is the "referenceToScale" of the previous code. I'm pretty sure that my error is on the code, but I don't know what it is.

    Attached is the image of the Hierarchy Object's disposition.

    Thanks.
     

    Attached Files:

  16. doelwit

    doelwit

    Joined:
    Apr 5, 2018
    Posts:
    1
    Code (CSharp):
    1.     public void updateSize()
    2.     {
    3.         float val = scaleSlider.value;
    4.      
    5.         m_SessionOrigin.transform.localScale = new Vector3(val, val, val);
    6.      
    7.     }
    8.  
    9.     public void updateRotation()
    10.     {
    11.         float val = rotateSlider.value;
    12.      
    13.         m_SessionOrigin.transform.rotation = Quaternion.Euler(0, val, 0);
    14.  
    15.     }
    these seem to work for me, they are both onvaluechanged listener delegates which I've added to the PlaceOnPlane script
     
    Maarja and real2u like this.
  17. tonOnWu

    tonOnWu

    Joined:
    Jun 23, 2017
    Posts:
    58
    Ok, after a bit more than 24 hours later, I found the solution I want it. Now I'll share it for other people that could have been having the same problem.

    First I created an Empty Object called MiddleReference in the hierarchy and located in a middle position between AR Session Origin and its child AR Camera.

    Then, in the AR Session Origin I placed the components: PlaceOnPlane:

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3. using UnityEngine.EventSystems;
    4. using UnityEngine.Experimental.XR;
    5. using UnityEngine.XR.ARFoundation;
    6.  
    7. [RequireComponent(typeof(ARSessionOrigin), typeof(Scaler))]
    8. public class PlaceOnPlane : MonoBehaviour
    9. {
    10.     ARPlaneManager planeManager;      
    11.     private bool scenesPositionSet = false;     // Indicate that scale scenario and position has been set. If true, the game is ready to start
    12.     private Scaler m_scaler;                      // We'll use this to change the reference for scaling
    13.  
    14.     [SerializeField]
    15.     [Tooltip("Instantiates this prefab on a plane at the touch location.")]
    16.     GameObject m_PlacedPrefab;          // Element to be set on scene. In case of a game, it will be the entire scenario
    17.     public GameObject placedPrefab      // The prefab to instantiate on touch.
    18.     {
    19.         get { return m_PlacedPrefab; }
    20.         set { m_PlacedPrefab = value; }
    21.     }
    22.  
    23.     // The object instantiated as a result of a successful raycast intersection with a plane.
    24.     public GameObject spawnedObject { get; private set; }
    25.  
    26.     ARSessionOrigin m_SessionOrigin;
    27.  
    28.     static List<ARRaycastHit> s_Hits = new List<ARRaycastHit>();
    29.  
    30.     void Awake()
    31.     {
    32.         m_SessionOrigin = GetComponent<ARSessionOrigin>();
    33.         m_scaler = GetComponent<Scaler>();
    34.     }
    35.  
    36.     void Update()
    37.     {
    38.         if (Input.touchCount > 0 && !IsPointerOverUIObject() && !scenesPositionSet)
    39.         {
    40.             Touch touch = Input.GetTouch(0);
    41.  
    42.             if (m_SessionOrigin.Raycast(touch.position, s_Hits, TrackableType.PlaneWithinPolygon))
    43.             {
    44.                 Pose hitPose = s_Hits[0].pose;
    45.  
    46.                 if (spawnedObject == null)
    47.                 {
    48.                     spawnedObject = Instantiate(m_PlacedPrefab, hitPose.position, hitPose.rotation);
    49.                 }
    50.                 else
    51.                 {
    52.                     spawnedObject.transform.position = hitPose.position;
    53.                 }
    54.  
    55.                 // Locating reference on the same position
    56.                 if (m_scaler != null)
    57.                 {
    58.                     m_scaler.referenceToScale.transform.position = hitPose.position;
    59.                 }
    60.                 else
    61.                 {
    62.                     Debug.Log("Error: Scaler has not being initialized");
    63.                 }
    64.             }
    65.         }
    66.     }
    67.  
    68.     // Remove planes, points and set everything
    69.     public void SetScenario()
    70.     {
    71.  
    72.         ARPlaneManager aRPlaneManager = GetComponent<ARPlaneManager>();
    73.         aRPlaneManager.enabled = false;
    74.  
    75.         // Scene position has been set. So it won't be able to move it
    76.         scenesPositionSet = true;
    77.  
    78.         //DisablePlanes();       // Uncomment this if you want to visual remove planes.
    79.  
    80.     }
    81.  
    82.     void OnPositionContent()
    83.     {
    84.         if (Input.touchCount > 0)
    85.         {
    86.             Touch touch = Input.GetTouch(0);
    87.  
    88.             if (m_SessionOrigin.Raycast(touch.position, s_Hits, TrackableType.PlaneWithinPolygon))
    89.             {
    90.                 Pose hitPose = s_Hits[0].pose;
    91.  
    92.                 if (spawnedObject == null)
    93.                 {
    94.                     spawnedObject = Instantiate(m_PlacedPrefab);
    95.                     DisablePlanes();
    96.                 }
    97.                 else
    98.                 {
    99.                     spawnedObject.transform.position = hitPose.position;
    100.                 }
    101.             }
    102.         }
    103.     }
    104.  
    105.     /* Procedure to remove planes from view to the user */
    106.     void DisablePlanes()
    107.     {
    108.         planeManager = GetComponent<ARPlaneManager>();
    109.         List<ARPlane> allPlanes = new List<ARPlane>();
    110.  
    111.         planeManager.GetAllPlanes(allPlanes);
    112.         planeManager.enabled = false;
    113.         foreach (ARPlane plane in allPlanes)
    114.         {
    115.             plane.gameObject.SetActive(false);
    116.         }
    117.     }
    118.  
    119.     /* Procedure to check if has been Tap over an UI object in a Canvas.
    120.      * Returns True if an object in the Canvas has been Tapped. */
    121.     private bool IsPointerOverUIObject()
    122.     {        
    123.         PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current);
    124.         eventDataCurrentPosition.position = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
    125.  
    126.         List<RaycastResult> results = new List<RaycastResult>();
    127.         EventSystem.current.RaycastAll(eventDataCurrentPosition, results);
    128.         return results.Count > 0;
    129.     }
    130.  
    131. }
    132.  
    and the Scaler Component:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. using UnityEngine.Experimental.XR;
    6. using UnityEngine.XR.ARFoundation;
    7.  
    8. [RequireComponent(typeof(ARSessionOrigin))]
    9. public class Scaler : MonoBehaviour {
    10.  
    11.     ARSessionOrigin m_SessionOrigin;
    12.     public GameObject referenceToScale;
    13.  
    14.     /* Next values must be the same min and max values of
    15.      * the Slider to change the scale */
    16.     private float m_maxScaleValue = 10.0f;
    17.     private float m_minScaleValue = 0.0f;
    18.     private float m_defaultScaleValue = 5.0f;
    19.  
    20.     void Awake()
    21.     {
    22.         m_SessionOrigin = GetComponent<ARSessionOrigin>();
    23.     }
    24.  
    25.     // Method called by a Slider
    26.     public void OnValueChange(float value)
    27.     {
    28.         Transform t = gameObject.transform;
    29.  
    30.         m_SessionOrigin.MakeContentAppearAt(
    31.             referenceToScale.transform,
    32.             referenceToScale.transform.position,
    33.             referenceToScale.transform.rotation);
    34.  
    35.         float scaleValue = Mathf.Clamp(value, m_minScaleValue, m_maxScaleValue);
    36.         t.localScale = new Vector3(scaleValue, scaleValue, scaleValue);
    37.     }
    38.  
    39.     private void Start()
    40.     {
    41.         OnValueChange(m_defaultScaleValue);
    42.     }
    43. }
    44.  
    The Scaler component is called by a slider. The ReferenceToScale in the middle object mentioned at the beginning of this thread. But, with this code you can also move the object over an identified plane and then scale the object.

    I attached an image of the setting. I hope more people can use this.
     

    Attached Files:

    Maarja likes this.
  18. Edur-Games

    Edur-Games

    Joined:
    Nov 21, 2017
    Posts:
    44
    For the object scale, using the ARSessionOrigin transform scale already works.

    Scale (50, 50, 50) you're scaling 50 times the smallest object.
    This works well for me. About stabilizing objects once placed needs more debugging
     
  19. hawken

    hawken

    Joined:
    Aug 22, 2013
    Posts:
    475
    heres a script you can put on AR Session Origin to test this out without needing the example scene:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class CameraScaler : MonoBehaviour {
    6.  
    7.     [Range(1f,3f)]
    8.     public float scale;
    9.    
    10.     // Update is called once per frame
    11.     void Update () {
    12.         transform.localScale = new Vector3(scale,scale,scale);
    13.     }
    14. }
     
    Jelmer123 likes this.
  20. real2u

    real2u

    Joined:
    Jun 20, 2018
    Posts:
    13
    Thanks for everything @tdmowrer , I’ve managed to get everything working flawlessly. Both scaling and rotating.

    I was wondering if it’s possible to use a Static Gameobject due to it’s perfomance advantages. I’ve found this post https://blogs.unity3d.com/2017/11/16/dealing-with-scale-in-ar/ in which being Static is mentioned, is it possible to replicate with ARFoundation?

    In my scene instead of using a prefab, I’m using a baked game object and I can move it as a I wish without a problem. But I would love to make it as performatic as possible.

    Best regards,
     
  21. tdmowrer

    tdmowrer

    Unity Technologies

    Joined:
    Apr 21, 2017
    Posts:
    490
    Sure, ARFoundation works in the same way. By scaling the ARSessionOrigin, you are affecting the camera, not your scene's content, so this will work with a static GameObject.
     
  22. Daniel4362

    Daniel4362

    Joined:
    Dec 7, 2017
    Posts:
    4
    Hello,

    I am having trouble scaling content while also using the ARSessionOrigin.MakeContentAppearAt().

    My goal is to get an object floating in the scene and to be able to move it around your space. Right now I use MakeContentAppearAt() to position it 1 meter in front of the camera and I do that while moving around to place it. Then I turn that off to leave it in place. But if I scale the object up or down, next time I use the make content appear at, It resets the camera position (as expected).

    I have really enjoyed using ARFoundation and I know there is a solution, I am just having trouble finding it. Would you have any advice @tdmowrer.

    Here is a video of my goal of movement that I was able to achieve with raw ARKit-Unity-Plugin (this was also scaling the content, which thanks to your talks, I see the major advantages of not doing).



    Thank you for any advice anyone can provide!
     
  23. jorgejaas

    jorgejaas

    Joined:
    May 6, 2018
    Posts:
    3
    Can i to scale with 2 fingers??
     
  24. Daniel4362

    Daniel4362

    Joined:
    Dec 7, 2017
    Posts:
    4
    @jorgejaas Yes, you can achieve scale using two fingers. The solutions above involve using a slider UI component to affect the scale of the ARSessionOrigin. You may, however, use the Unity input system or LeanTouch to read the pinch gesture and use that for affecting the scale of the ARSessionOrigin.
     
  25. jorgejaas

    jorgejaas

    Joined:
    May 6, 2018
    Posts:
    3
    Thank @Daniel4362! Do you have any example code for rotation with 1 finger?
     
  26. andgest

    andgest

    Joined:
    Apr 26, 2018
    Posts:
    26
    Hi
    First thank you @tdmowrer for your post, it help me a lot !

    I have a question about real size on AR, and I can't to find the response.
    I have a cube of 1 meter for each axes.
    I want to see this cube in AR and that cube should appear to exactly one meter size in real life.
    How can I do that to be sure that the position and scale of my ARSessionOrigin is complient to preserve the matching between Unity size unit and AR size unit ?
    I don't want to scale ARSessionOrigin arbitrarily to obtain an aproximatively matching.

    Thank you in advance :)
     
  27. tdmowrer

    tdmowrer

    Unity Technologies

    Joined:
    Apr 21, 2017
    Posts:
    490
    Unity uses meters, so if you have a 1 meter cube and want it to appear as 1 meter in AR, you don't have to do anything. Just make sure your session origin is NOT scaled, i.e., its scale is (1, 1, 1).
     
    andgest, rob_ice and newguy123 like this.
  28. andgest

    andgest

    Joined:
    Apr 26, 2018
    Posts:
    26
    Thank you for your really quick reply ! :)
    Ok I understand the source of my trouble. It's not the ARSessionOrigin scale but the size of my object.
    The cube in my exemple is a .obj added dynamically to my scene with trilib.
    The scale to this .obj is (1, 1, 1) but if I create a cube next to him with scale (1, 1, 1), I can constate that it's absolutely not the same size ^^
    upload_2019-1-16_15-49-52.png
     
  29. tdmowrer

    tdmowrer

    Unity Technologies

    Joined:
    Apr 21, 2017
    Posts:
    490
    Scale is a factor, not an absolute. The chair's final size will be its original dimensions times the scale. That means setting the scale to (1, 1, 1) makes your object its original size. You may be able to adjust the export settings for your chair model to make sure it was created in meter scale.

    If you want to try and determine an appropriate scale at runtime, you would need to know how big the chair is, how big you want it to be, and set your scale to the ratio of the two. One way to do this is to iterate over the mesh renderers in the chair and combine their bounds, or, if the object has a rigid body, you can query the size of the collider.
     
    andgest likes this.
  30. newguy123

    newguy123

    Joined:
    Aug 22, 2018
    Posts:
    154
    How might the code look like for something like this, if I want the placed prefab to autoscale (meaning scale the ARSessionOrigin), and FIT fully within cam view (be fully visible in view), with some breathing space around it?
     
  31. hawken

    hawken

    Joined:
    Aug 22, 2013
    Posts:
    475
    any update on adding this to ARFoundation samples?
     
    newguy123 likes this.
  32. tdmowrer

    tdmowrer

    Unity Technologies

    Joined:
    Apr 21, 2017
    Posts:
    490
    Maarja, dansopanso and newguy123 like this.
  33. Jelmer123

    Jelmer123

    Joined:
    Feb 11, 2019
    Posts:
    33
    I implemented ARSessionOrigin.MakeContentAppearAt in my place script. However, my scene always scales from it root, while I would like it to scale from the location the user is looking at (or as I'm using pinch-to-zoom: actually half ways between the user's two fingers).Should I move that Game object called "make content appear at" to the desired location as a root/pivot point for scaling?
     
    Last edited: Feb 25, 2019
  34. Edur-Games

    Edur-Games

    Joined:
    Nov 21, 2017
    Posts:
    44
    Hello!
    I'm experiencing a problem with placing the content in front of the camera. Compared to other games you need to find a plane to place the content, in my case is usually moved by itself on some occasions, especially when there is not much lighting in the environment.

    Is there any difference in behavior when you anchor a content on a detected plane and when you don't use an anchor and put it in front of your camera?

    I have tried several games that use a plane to place the content:
    (The machines, shadows remain, ARise) and the scene is anchored very well. It does not move even at low illumination. But mine by not using any anchor and being "floating in the air" is very unstable sometimes.

    Any suggestions?
    Thank you!
     
  35. Jelmer123

    Jelmer123

    Joined:
    Feb 11, 2019
    Posts:
    33
    I want to scale my scene based on where the user looks.

    I have this hierarchy
    Screen Shot 2019-03-05 at 17.39.01.png

    I have a raycast from the camera's centre against scene geometry, and place PivotPoint there and then scale the scene. However, this gives very strange results. So, how to scale with a certain location as pivot point?
     
  36. Jelmer123

    Jelmer123

    Joined:
    Feb 11, 2019
    Posts:
    33
    Any ideas? Behaviour of ARFoundation is currently completely weird when trying to set a pivot point for scaling...
     
  37. JoeGrainger

    JoeGrainger

    Joined:
    Oct 20, 2012
    Posts:
    16
    AFAIK I think you're scaling with the wrong hierarchy. You want AR Session Origin to be a child of Pivot Point, as you want to be scaling from the Pivot Point's origin. Right now you are scaling from 0,0,0 as that's where AR Session Origin will be.
     
    Jelmer123 likes this.
  38. Jelmer123

    Jelmer123

    Joined:
    Feb 11, 2019
    Posts:
    33
    Thanks! I will give that a try! :)
     
  39. redagrandrei

    redagrandrei

    Joined:
    Sep 3, 2017
    Posts:
    34
    How can i scale the object so it doesnt go into camera? If the object is big enough now it just scales right into camera
     
  40. Jasr_88

    Jasr_88

    Joined:
    Mar 21, 2016
    Posts:
    3
    Hi, i understant the problem of scaling the object instead of the ARSessionOrigin, but what if i need to Scale/Rotate/Move multiple objects, individually, in the same scene?
     
  41. hawken

    hawken

    Joined:
    Aug 22, 2013
    Posts:
    475
    You can do that too, just do it on a per object basis. Theres only one camera root to scale
     
  42. jogaa

    jogaa

    Joined:
    Aug 15, 2017
    Posts:
    4
    Thanks, @tdmowrer, your post and example scene give a great insight! I tinkered a bit with it. So, when I want to move things individually, I need to place them as transform which is NOT a child of ARSessionOrigin, while all other objects need to be a child so they get transformed & rotated with the Origin? Is that correct?
    Sorry, I don't understand.
     
  43. Tarrag

    Tarrag

    Joined:
    Nov 7, 2016
    Posts:
    104
    Hi @hawken , sorry I don't understand, can you please expand on this - rotate a single object where multiple exist?

    If I add a cube to the arfoundation examples Scale.scene, because the effect of makeappearonplane is to rotate the ARSessionOrigin and not the object, any other content in the scene rotates along with the Content provided by Unity in the scene.

    if (m_SessionOrigin != null)
    m_SessionOrigin.MakeContentAppearAt(content, content.transform.position, m_Rotation); // here content does not include the cube I added to test multiple object rotation

    It works not using MakeContentAppearAt, just with m_RealObjOnPlane.transform.rotation = m_Rotation; but early to tell of unintended behaviour. That's why it'd help if you can shed more light how you rotate multiple objects with MakeContentAppearAt pls :)

    Thank you for your help
     
    Last edited: Jul 4, 2019
  44. hawken

    hawken

    Joined:
    Aug 22, 2013
    Posts:
    475
    rotate:
    • If you need to rotate your entire world and be free of any adverse physics or particle contributions, do it with make content appear at and session origin.
    • If you need to rotate your objects in the world, do it per object with standard methods and disable/local anything you don't want affected by rotation.
    scale:
    • If you need to scale everything in your world to the same scale, without affecting physics, use session origin.
    • If you need to scale objects to various arbitrary sizes, it needs to be done with standard methods, you will need to handle scale related problems on a case by case basis.
     
    Last edited: Jul 8, 2019
  45. tbora

    tbora

    Joined:
    Oct 8, 2012
    Posts:
    1
    Hello, I am using ARFoundation and the Image Tracking example. I have a poster and I want my content to appear exactly on top of the poster. The tracking and appearing of the content works but my scene is too big and it has physic objects so I cant just scale it down. I am using the ARTrackedImageManager script. I tried to work with the localScale of the ARSessionOrigin but it didnt work.
     
  46. jpvanmuijen

    jpvanmuijen

    Joined:
    Aug 23, 2012
    Posts:
    4
    You could try changing the physical size of your image in your Reference Image Library, set it to a higher value than it actually is to make your content appear smaller.