Effect:
Early preparation: The character can walk on the drawn Berlin noise map because of the use of the Dynamic baked map plug-in
Mount the LocalNavMeshBuilder script in the plug-in for the character:
Add the NavMeshSourceTag script in the code for the Berlin noise map:
Implementation:
Three types of movement of characters:
Create a character and mount the following script.
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; public class PlayerMove : MonoBehaviour { public ETC m_ETC; [Header("Movement Speed")] public float m_MoveSpeed; [Header("Rotation Speed")] public float m_RotateSpeed; [Header("Minimap Arrow")] public RectTransform arrowImg; void Update() { //The mini map arrow points in the same direction as the character's true direction arrowImg.localEulerAngles = Vector3.back * gameObject.transform.eulerAngles.y; #region Ray detection movement if (Input.GetMouseButtonDown(1)) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out RaycastHit hit)) { if (hit.collider.CompareTag("PerlinMap")) { transform.GetComponent<NavMeshAgent>().SetDestination(hit.point); } } } #endregion #region Joystick movement float h = m_ETC.GetAxis("Horizontal"); float v = m_ETC.GetAxis("Vertical"); Vector3 dir = new Vector3(h, 0, v); if (dir!=Vector3.zero) { //Joystick combined with navigation transform.GetComponent<NavMeshAgent>().SetDestination(dir + transform.position); //Just the joystick //transform.LookAt(dir + transform.position); //transform.Translate(Vector3.forward * Time.deltaTime * 5); } #endregion #region WASD mobile transform.Translate(Vector3.forward*Input.GetAxis("Vertical")*Time.deltaTime*m_MoveSpeed); transform.Rotate(Vector3.up,Input.GetAxis("Horizontal") * Time.deltaTime * m_RotateSpeed); #endregion } }
Map Berlin:
Create an empty object and mount the following script.
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; /// <summary> /// Draw Berlin noise map /// </summary> public class PerlinNoiseMap : MonoBehaviour { [Header("Noise intensity")] public float noisily; [Header("map length")] public int mapWidth; [Header("Map Width")] public int mapHeight; [Header("Underlying Color")] public Color downColor; [Header("upper color")] public Color upColor; [Header("Minimap")] public Image miniMap; public GameObject player; private void Start() { VertexHelper vh = new VertexHelper(); Texture2D texture = new Texture2D(mapWidth, mapHeight); for (int x = 0; x < mapWidth; x + + ) { for (int z = 0; z < mapHeight; z + + ) { float y = Mathf.PerlinNoise(x * noisily * 0.1f, z * noisily * 0.1f);//It is a plane effect without multiplying by coefficients //UV coordinates do not count the outermost layer float uvx = (float)x / (mapWidth - 1); float uvy = (float)z / (mapHeight - 1); Color color = Color.Lerp(downColor, upColor, y); texture.SetPixel(x, z, color); vh.AddVert(new Vector3(x, y * noisily, z), color, new Vector2(uvx, uvy)); if (x < mapWidth - 1 & amp; & amp; z < mapHeight - 1) { vh.AddTriangle(x * mapHeight + z, x * mapHeight + z + 1, (x + 1) * mapHeight + z); vh.AddTriangle((x + 1) * mapHeight + z, x * mapHeight + z + 1, (x + 1) * mapHeight + z + 1); } } } texture.Apply(); Mesh mesh = new Mesh(); vh.FillMesh(mesh); gameObject.AddComponent<MeshFilter>().mesh = mesh; gameObject.AddComponent<MeshCollider>().sharedMesh = mesh; gameObject.AddComponent<MeshRenderer>().material.mainTexture = texture; //Plug-in implementation, adding the NavMeshSourceTag component allows players to navigate on the Berlin noise map gameObject.AddComponent<NavMeshSourceTag>(); //Mini map material assignment Material m = new Material(Shader.Find("UI/Default")); m.mainTexture = texture; miniMap.material = m; } private void Update() { //Scroll wheel controls field of view if (Input.GetAxis("Mouse ScrollWheel") != 0 & amp; & amp; transform.localScale.x + Input.GetAxis("Mouse ScrollWheel") >= 1) { miniMap.transform.localScale + = Vector3.one * Input.GetAxis("Mouse ScrollWheel"); } else if (Input.GetAxis("Mouse ScrollWheel") != 0 & amp; & amp; transform.localScale.x + Input.GetAxis("Mouse ScrollWheel") <= 1) { miniMap.transform.localScale + = Vector3.one * Input.GetAxis("Mouse ScrollWheel"); } //Reset the minimap anchor point with the character as the center //Situation 1: The character is generated in the lower left corner of the map miniMap.rectTransform.pivot = new Vector2(player.transform.position.x / mapWidth, player.transform.position.z / mapHeight); //Situation 2: The character is generated in the center of the map //miniMap.rectTransform.pivot = new Vector2((mapWidth / 2 + player.transform.position.x) / mapWidth , (mapHeight / 2 + player.transform.position.z) / mapHeight); } }
The character is generated in the lower left corner of the map (situation 1 described in the above code):
The character is generated in the center of the map (situation 2 described in the above code):