# How to Add Physics to a Meshed Scene Source: https://www.nianticspatial.com/docs/nsdk/how-to/ar/meshing/meshing_physics_real_world/ ### Platform: unity This how-to covers: - Adding dynamic meshing to a scene with the default manager; - How to create a prefab for meshing; - Interacting with mesh physics; - Making the mesh invisible. (image: Launching Spheres in the Real World) (image: Falling Objects on the Gandhi Statue) ## Prerequisites You will need a Unity project with NSDK installed and a set-up basic AR scene. For more information, see [Set up the Niantic SDK for Unity](https://www.nianticspatial.com/docs/nsdk/setup/#set-up-the-niantic-sdk-for-unity) and [Set up a basic AR scene](https://www.nianticspatial.com/docs/nsdk/setup/#set-up-a-basic-ar-scene). ## Creating the Mesh To create a mesh prefab: 1. Add an AR Mesh Manager to the XROrigin: 1. In the **Hierarchy**, right-click on the `XROrigin`, then select **Create Empty** to add an empty `GameObject` to it. Name the new object **MeshManager**. 2. In the **Hierarchy**, select **MeshManager**, then, in the **Inspector** window, click **Add Component** and add an **ARMeshManager** Component to it. > **Caution:** > > Be cautious when adding the `ARMeshManager` Component to GameObjects that parent a camera. The `ARMeshManager` will automatically increase the scale of the GameObject it's attached to. This can misalign the scale of the real and virtual worlds, breaking occlusions and the perceived distances of objects. 1. Repeat this process, but add a **Nsdk Meshing Extension** Component instead. (image: The Unity UI showing the added components) 2. Add an AR Occlusion Manager: 1. In the **Hierarchy**, expand the `XROrigin` and **Camera Offset**, then select the **Main Camera** object. Then, in the **Inspector**, click **Add Component** and add an `AROcclusionManager`. 2. Set the **Occlusion Preference Mode** to **No Occlusion**. (image: The AR Occlusion Manager with No Occlusion set) 3. Prepare the mesh for conversion to prefab: 1. In the **Hierarchy**, right click and create an Empty `GameObject` in the main scene. Name it **MeshChunk**. 2. In the **Inspector** window, add three Components to **MeshChunk**; a **Mesh Filter** to hold geographic information, a **Mesh Renderer** to display the mesh (if desired), and a **Mesh Collider** to provide physics. 3. In the **Mesh Renderer** Component, expand the **Materials** drop-down, then click the circle button to open the **Select Material** window and pick a **Default Material** to add to it. (image: Create a MeshChunk game object like so) > **Caution:** > > **Attention!** > > **Unity 6** users will need to to upgrade the **Default Material** used in the **MeshChunk** to work with the **Universal Render Pipeline (URP)**. > > This can be done by double-clicking on the **Default Material** after it's added to the **MeshChunk**'s **Mesh Renderer**, then on the top menu go to **Edit** -> **Rendering** -> **Materials** and convert the **Material** to **URP**. 4. Convert the mesh into a prefab and assign it: 1. Drag **MeshChunk** from the **Hierarchy** to the **Assets** window, converting it into a prefab. 2. Delete the **MeshChunk** `GameObject` from the scene. 3. Select **MeshManager** from the **Hierarchy**, then drag the **MeshChunk** prefab to the **Mesh Prefab** slot in the **Inspector**. (image: Create a MeshChunk prefab and add it to the ARMeshManager) 5. Test it out: 1. Build to device or press play in the editor. A mesh overlay should appear on screen. (image: Mesh overlay with playback) ## Testing Mesh Physics Because the mesh has a **Mesh Collider**, the mesh will respond to any object using standard Unity physics collision. For example, the mesh can provide collision for creatures walking on meshed surfaces or inform game entities when they have bumped into walls. This exercise demonstrates this by allowing the player to shoot spheres into the scene and see them bounce off of the mesh. To add physics to the mesh: 1. Create a physics prefab and add rigid body collision to it: 1. In the **Hierarchy**, right click, then mouse over **3D Object** and select **Sphere**. Name it **LauncherSphere**. 2. Select **LauncherSphere** in the **Hierarchy**, then add a **RigidBody** Component to it in the **Inspector**. 3. Still in the **Inspector**, make **LauncherSphere** smaller by setting its scale in the **Transform** Component to (0.2, 0.2, 0.2). 4. Drag **LauncherSphere** to the **Assets** window to make it into a prefab, then delete it from the scene. 2. Create a script to launch spheres: 1. In the **Assets** window, right-click, then mouse over **Create** and choose **C # Script**. Name the new script **Launcher**. 2. Add the **Launcher** code to your script: #### Click to expand the Launcher code ```csharp using UnityEngine; public class Launcher : MonoBehaviour { public Rigidbody _prefabWithRigidbody; void Update() { #if UNITY_EDITOR if(Input.GetMouseButtonDown(0)) #else if (Input.touchCount > 0) #endif { // spawn in front of at the camera var pos = Camera.main.transform.position; var forw = Camera.main.transform.forward; var thing = Instantiate(_prefabWithRigidbody, pos+(forw*0.4f), Quaternion.identity); thing.AddForce(forw * 200.0f); } } } ``` 3. Make a `GameObject` to run the script: 1. In the **Hierarchy**, right-click in your Scene, then choose **Create Empty**. Name it **LauncherScript**, then drag and drop the **Launcher** script onto it from the **Assets** directory. 2. Select **LauncherScript** from the **Hierarchy**, then, in the **Inspector**, assign **LauncherSphere** as the **Prefab** variable. 4. Build to device and test! You should be able to tap anywhere on screen and shoot a sphere that bounces off of surfaces. (image: Launching Spheres in the Real World) ## Making the Mesh Invisible The simplest way to make the mesh invisible is to tell Unity not to render it. Delete the **Mesh Renderer** from the prefab and Unity will no longer be able to draw it, but this also means the mesh cannot provide occlusion and shadows in the scene. #### Built-in Render Pipeline To keep this functionality, NSDK provides a shader called `InvisibleMeshWithShadows` that will receive light and draw shadows without rendering the mesh directly. To add an invisibility shader to the mesh: 1. If you don't have a copy of the `InvisibleMeshWithShadows` shader in your project, download it from our GitHub repository [here](https://github.com/nianticspatial/nsdk-samples-csharp/blob/main/NsdkSamples/Assets/Samples/NavigationMesh/Shaders/InvisibleMeshWithShadows.shader) and add it to your project. 2. Right-click in the **Assets** window, then mouse over **Create** and select **Material**. Name it **InvisibleShader**. 3. Add the `InvisibleMeshWithShadows` shader to **InvisibleShader**: 1. In the **Assets** window, select the Material. 2. In the **Inspector** window, click the **Shader** dropdown, search for `InvisibleMeshWithShadows`, and select it. 4. Add **InvisibleShader** to the **Mesh Renderer** in the prefab: 1. Select your **MeshChunk** object in the **Hierarchy**. 2. In the **Inspector** window, find the **Mesh Renderer** component and click the **Materials** menu to expand it. 3. Add **InvisibleShader** as the Material by clicking the circle and searching for **InvisibleShader** or dragging and dropping **Invisible Shader** to the element box. #### Universal Render Pipeline To keep this functionality, NSDK provides two Shader Graph assets available for download from our GitHub repository [here](https://github.com/nianticspatial/nsdk-samples-csharp/blob/main/NsdkSamples/Assets/Samples/Common/Shaders/URPGraphShaders). 1. Import [`MainLight.shadersubgraph`](https://github.com/nianticspatial/nsdk-samples-csharp/blob/main/NsdkSamples/Assets/Samples/Common/Shaders/URPGraphShaders/MainLight.shadersubgraph) 2. Import [`TransparentWithShadow.shadergraph`](https://github.com/nianticspatial/nsdk-samples-csharp/blob/main/NsdkSamples/Assets/Samples/Common/Shaders/URPGraphShaders/TransparentWithShadow.shadergraph) > **Note:** > > Here, we've aligned the `Directional Light` in the scene to match the real world. Look into [`ARLightEstimation`](https://docs.unity3d.com/Packages/com.unity.xr.arfoundation@6.0/api/UnityEngine.XR.ARFoundation.ARLightEstimationData.html) from AR Foundation to set up realistic lighting in your project. (image: Invisible mesh with moving shadows) ## Custom Mesh Texturing While this how-to will not cover them, there are other ways to leverage mesh textures for AR development. Two examples follow: - A custom mesh renderer (as used in the [Meshing sample scenes](https://github.com/nianticspatial/nsdk-samples-csharp/tree/main/NsdkSamples/Assets/Samples/Meshing)) could display normals to see triangle facing directions while debugging. - By default, the mesh renderer does not create a UV surface map, but using tri-planar projection when generating the mesh can create a UV map of the world space. The example shader can for mesh texturing can be found [here](https://github.com/nianticspatial/nsdk-samples-csharp/tree/main/NsdkSamples/Assets/Samples/Meshing/Shaders) (image: Blue Mesh over the Gandhi Statue) (image: Custom shader to texture meshes at different normals) ## More Information - For more details on how this works, see [Meshing](https://www.nianticspatial.com/docs/nsdk/features/meshing/).