I followed the example provided by @Jakob_Unity here: https://forum.unity.com/threads/navmesh-agent-and-smooth-alignment-with-surface-normals.135964/ but it doesn't work. Others in the thread have reported success, so I logged the value of the terrain normal and always got (0, 1, 0) - in other words up. Clearly the mesh doesn't need to rotate if it believes that the terrain beneath it is flat, so I must be doing something wrong. I've attached the code here for convenience. This is day three, and I'm running out of hair to pull out, so any help would be great. Thanks. Code (CSharp): // TerrainMover.cs using UnityEngine; using System.Collections; public class TerrainMover : MonoBehaviour { public Transform target; public Terrain terrain; private NavMeshAgent agent; private Quaternion lookRotation; void Start () { agent = GetComponent<NavMeshAgent>(); //< cache NavMeshAgent component agent.updateRotation = false; //< let us control the rotation explicitly lookRotation = transform.rotation; //< set original rotation } Vector3 GetTerrainNormal () { Vector3 terrainLocalPos = transform.position - terrain.transform.position; Vector2 normalizedPos = new Vector2(terrainLocalPos.x / terrain.terrainData.size.x, terrainLocalPos.z / terrain.terrainData.size.y); return terrain.terrainData.GetInterpolatedNormal(normalizedPos.x, normalizedPos.y); } void Update () { agent.destination = target.position; //< update agent destination Vector3 normal = GetTerrainNormal(); Vector3 direction = agent.steeringTarget - transform.position; direction.y = 0.0f; if(direction.magnitude > 0.1f normal.magnitude > 0.1f) { Quaternion qLook = Quaternion.LookRotation(direction, Vector3.up); Quaternion qNorm = Quaternion.FromToRotation(Vector3.up, normal); lookRotation = qNorm * qLook; } // soften the orientation transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime/0.2f); } }
Should you not use terrain.terrainData.size.z there? Code (csharp): Vector2 normalizedPos = new Vector2(terrainLocalPos.x / terrain.terrainData.size.x, terrainLocalPos.z / terrain.terrainData.size.y);
I thought that I had tried changing y to z and got an error but ... no error now. The only change however is that the mesh oscillates very slightly in the x-axis, even though agent.updateRotation = false. Love VS, BTW
@LennartJohansen That was a good idea; the normal always faces up, which is why the vehicle doesn't conform to the slope. I wonder if the code is reading the elevation from a different part of the map (i.e. always flat). If so, it's not obvious why.