点击蓝字关注我哦
微信公众号:独立游戏之路
关注可了解更多的游戏开发知识与技巧。如果有问题或建议,欢迎+V留言;
动态的改变寻路数据
今天,在开发的时候,想到一个问题,游戏场景后来可能会变,但是里面的寻路数据没法和场景数据一起更新下来,按照现在unity的习性,应该是每次烘焙路径信息都会保存在一个同场景名相同的文件夹下,全部打包替换似乎才能完成更新寻路信息.
但是我选中它的时候,却发现,下面可以将它打包成assetbundle,那么这就说明这就是一些数据而已,AI强依赖.发现它的名字叫NavMesh,然后尝试着在脚本中输入NavMesh,然后发现这个需要读取NavMeshData的数据,意外的简单,所以我将这个NavMesh的文件复制到Resources文件夹下,方便加载测试
然后又修改了场景布局,又烘焙了一次,然后同样的复制到Resources文件夹中.
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);
}
然后清除场景中的寻路信息,直接运行,发现可以运行.真的是好简单的方式!
学以致用 一步起飞
动态的改变关照贴图
如果你的项目里面,有两套或者两套以上的贴图,那么你就会需要用代码来切换贴图,但是,贴图和烘焙的寻路差不多,看起来像是和场景强关联的东西,但是事实上,光照贴图就是一张普通的2D贴图.
但是,有一点需要注意的是,光照贴图烘焙好了之后,即使你把它复制/移动到某个位置,然后你再重新烘焙,它还是会覆盖的,所以,我们应该是复制一份光照贴图.放到一个加载的文件夹中.
我就是用了两个文件夹分别 存储了白天的贴图和晚上的贴图.方便看出效果,其实就是有没有平行光的区别.
这是烘焙好的光照贴图,如果场景足够复杂,不会只有这么一点的光照数据.
里面的-0,-1代表就是这种类型的分布在几张贴图中,其实有的场景还会有shadowmash,但是我这里只是简单地搭建了一个简单的:
然后,我们发现里面有个lightingData文件,然后尝试在代码中对它进行一系列的尝试.终于写出如下效果,都是在unity启动的时候动态更换的:
白天:
夜晚:
看起来似乎没有问题,但是有一点需要注意的是,我们点击任何一个带有光照贴图的模型,查看光照贴图的信息:
发现这里还有一些光照数据还没有用到.那么这些数据如果不用的话,然后修改场景并加载光照贴图,也许会出现贴图和场景不吻合的情况.所以,我们需要将这些信息也记录下来.
首先是加载贴图的代码:
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;
}
}
}
然后是记录静态模型中的光照贴图的信息:
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;
}
我将它写成编辑器插件,方便查看生成的信息,当我获取到这些信息之后,就可以在加载贴图的时候再附上去,就避免了一些光照贴图的错乱.
当然,如果需要上传到服务器,就把这些数据当初普通的热更新资源就好.
学以致用 一步起飞
…END…
-
技术群:添加小编微信并备注进群
小编微信:mm1552923
公众号:dotNet编程大全