Dynamically change pathfinding data and dynamically change lightmaps

Dynamically change pathfinding data

Today, when I was developing, I thought of a problem. The game scene may change later, but the pathfinding data inside cannot be updated together with the scene data. According to the current habit of unity, it should be that every time the baking path information is saved in a Under the same folder with the same scene name, it seems that all packages and replacements can complete the update of pathfinding information.

insert image description here

But when I selected it, I found that it can be packaged into an assetbundle below, so this means that this is just some data, and AI is strongly dependent. I found that its name is NavMesh, and then tried to enter NavMesh in the script, and found This needs to read the data of NavMeshData, which is surprisingly simple, so I copied the NavMesh file to the Resources folder for easy loading and testing

insert image description here

Then I modified the scene layout, baked it again, and copied it to the Resources folder in the same way.

public NavMeshData meshData;
public Transform endPoint;
public NavMeshAgent player;

// Start is called before the first frame update
void Start()
{ 
  meshData = Resources.Load<NavMeshData>("NavMeshDataNum1");
  NavMesh.AddNavMeshData(meshData); 
}

Then clear the pathfinding information in the scene, run it directly, and find that it can run. It is really a simple way!


Dynamically change the care map

If there are two or more sets of textures in your project, then you will need to use code to switch textures. However, textures are similar to baked pathfinding. They seem to be strongly related to the scene, but in fact Above, a lightmap is just a normal 2D texture.

However, one thing to note is that after the light map is baked, even if you copy/move it to a certain position, and then you bake it again, it will still be overwritten, so we should copy a light map .into a loaded folder.

insert image description here

I just used two folders to store the textures during the day and the textures at night. It is convenient to see the effect, in fact, it is the difference between whether there is parallel light or not.

This is a baked light map. If the scene is complex enough, there will not be only such a little light data.

insert image description here

The -0, -1 in it means that this type of distribution is distributed in several maps. In fact, some scenes will have shadowmash, but I just simply built a simple one here:

insert image description here

Then, we found a lightingData file inside, and then tried a series of attempts to it in the code. Finally, the following effects were written, which were dynamically replaced when unity started:

daytime:

insert image description here

night:

insert image description here

It seems that there is no problem, but one thing to note is that we click on any model with a light map to view the information of the light map:

insert image description here

It is found that there are still some lighting data that have not been used yet. If these data are not used, then modify the scene and load the light map, there may be situations where the map does not match the scene. Therefore, we need to record this information.

The first is the code to load the texture:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class test_Loadmap_nav : MonoBehaviour
{ 
    LightmapData[] lightmaps;  
    int count = 2;

    // Start is called before the first frame update
    void Start()
    {
        Texture2D[] lightmapLight = new Texture2D[count];
        Texture2D[] lightmapDir = new Texture2D[count]; 
        lightmaps = new LightmapData[count];
        for (int i = 0; i < count; i++)
        {

            lightmapLight[i] = Resources.Load<Texture2D>
("LightingData/test_Night/Lightmap-" + i.ToString() + "_comp_light");

            lightmapDir[i] = Resources.Load<Texture2D>
("LightingData/test_Night/Lightmap-" + i.ToString() + "_comp_dir");

            LightmapData lightmapData = new LightmapData();

            lightmapData.lightmapColor = lightmapLight[i];
            lightmapData.lightmapDir = lightmapDir[i]; 
            lightmaps[i] = lightmapData;
        }
        LightmapSettings.lightmaps = lightmaps;


    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            Texture2D[] lightmapLight = new Texture2D[count];
            Texture2D[] lightmapDir = new Texture2D[count];
            lightmaps = new LightmapData[count];
            for (int i = 0; i < count; i++)
            { 
                lightmapLight[i] = Resources.Load<Texture2D>
("LightingData/test_Night/Lightmap-" + i.ToString() + "_comp_light"); 
                lightmapDir[i] = Resources.Load<Texture2D>
("LightingData/test_Night/Lightmap-" + i.ToString() + "_comp_dir"); 
                LightmapData lightmapData = new LightmapData(); 
                lightmapData.lightmapColor = lightmapLight[i];
                lightmapData.lightmapDir = lightmapDir[i]; 
                lightmaps[i] = lightmapData;
            }
            LightmapSettings.lightmaps = lightmaps;
        }
        if (Input.GetKeyDown(KeyCode.B))
        {
            Texture2D[] lightmapLight = new Texture2D[count];
            Texture2D[] lightmapDir = new Texture2D[count];
            lightmaps = new LightmapData[count];
            for (int i = 0; i < count; i++)
            {

                lightmapLight[i] = Resources.Load<Texture2D>
("LightingData/test_Day/Lightmap-" + i.ToString() + "_comp_light"); 
                lightmapDir[i] = Resources.Load<Texture2D>
("LightingData/test_Day/Lightmap-" + i.ToString() + "_comp_dir"); 
                LightmapData lightmapData = new LightmapData(); 
                lightmapData.lightmapColor = lightmapLight[i];
                lightmapData.lightmapDir = lightmapDir[i]; 
                lightmaps[i] = lightmapData;
            }
            LightmapSettings.lightmaps = lightmaps;
        }
    }
}

Then record the lightmap information in the static model:

using Newtonsoft.Json;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class RecordLightMapInfo : Editor
{
    [MenuItem("记录场景中的光照信息/开始生成json文件", false, 150)]
    public static void CreateLightmapJson()
    {

        GameObject Ground = null;

        int lightmapIndex = 1;
        float lightmapScale = 1;
        Vector4 lightmapScaleOffect;




        foreach (GameObject  item in Resources .
FindObjectsOfTypeAll(typeof (GameObject)))
        {
            if (item.name.Equals("Ground"))
            {
                Ground = item;
            }
        }


        Root root = new Root();
        root.lightmapEles = new List<LightmapEle>();
        foreach (Transform item in Ground .transform .
GetComponentsInChildren<Transform>(true ))
        {
            MeshRenderer renderer=  item.GetComponent<MeshRenderer>();

            LightmapEle lightmapEle = new LightmapEle
            {
                lightmapIndex = renderer.lightmapIndex,
                lightmapScale = renderer.scaleInLightmap,
                x = renderer.lightmapScaleOffset.x,
                y = renderer.lightmapScaleOffset.y,
                z = renderer.lightmapScaleOffset.z,
                w = renderer.lightmapScaleOffset.w
            };
            root.lightmapEles.Add(lightmapEle);
        }

        //foreach (var item in root .lightmapEles)
        //{
        //    Debug.Log(item.lightmapIndex);
        //    Debug.Log(item.lightmapScale);
        //    Debug.Log(item.lightmapScaleOffect);
        //}

        try
        {
          string s =  JsonConvert.SerializeObject(root);

            Debug.Log(s); 
        }
        catch (System.Exception)
        {

            throw;
        }
    }
}

[SerializeField]
public class Root
{
   public List<LightmapEle> lightmapEles;
}

[SerializeField]
public class LightmapEle
{
    public int lightmapIndex;
    public float lightmapScale;
    //由于不支持V4类型的,所以将拆分为4个
    public float x;
    public float y;
    public float z;
    public float w;
}

I wrote it as an editor plug-in, which is convenient for viewing the generated information. After I get the information, I can attach it when loading the texture, which avoids some lightmap confusion.

Of course, if you need to upload to the server, just use these data as ordinary hot update resources.

Guess you like

Origin blog.csdn.net/weixin_41590778/article/details/130214260