Characters walking on Berlin noise map

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):