版本:3.8.5
实现目标:给3d道路生成路边景观花草
在场景下创建一个节点,我这里种植两种花草模型,兰花和菊花,所以分别在节点下另创建两个节点,为了静态合批。
1.将花草模型分别拖入场景中,制作成预制文件。
2.给plant节点绑定一个脚本,用来初始化生成植物。
一般道路是由平面连接成,所以需要先获取道路模型的网格顶点
/**
* 根据 道路路径获取两侧边界点
* @param roadPath
*/
public static getPointByRoad(roadPath: string) {
try {
let road = find(roadPath)
let mesh = CommonUtil.getMeshRendererAdapter(road).mesh
let pos = mesh.renderingSubMeshes[mesh.jointBufferIndices[0]].geometricInfo.positions;
let result = []
let worldMatrix = mat4();
CommonUtil.getMeshRendererAdapter(road).node.getWorldMatrix(worldMatrix);
for (let i = 0; i < pos.length; i += 3) {
//顶点的本地坐标坐标转世界坐标
let position=new Vec3()
Vec3.fromArray(position, pos, i);
let transform = v3();
Vec3.transformMat4(transform, position, worldMatrix);
result.push(transform)
}
return result
} catch (e) {
return []
}
}
如果模型面数比较大,数据就要进行抽稀
public static dataDilution(data=[],deg:number=1){
if(deg<=1||data.length==0){
return data
}
let arr=[]
for(let i=0;i<data.length;i+=deg){
arr.push(data[i])
}
return arr
}
现在就可以在plant脚本上进行创建使用了
initData(){
let arr = RoadsidePlantUtil.getPointByRoad(this.roadPath)
arr = RoadsidePlantUtil.dataDilution(arr,2)
let lanhuag=find(MarryManUtil.housPath + '/luduan/plant/lanhuag')
let juhuag=find(MarryManUtil.housPath + '/luduan/plant/juhuag')
for(let i=0;i<arr.length;i++){
//y值小于-30不进行操作
if(arr[i].y<-30){
continue
}
let tty = Math.random() * 2
if(tty<1){
resources.load('prefab/flower/lanhua', Prefab, (err: any, data) => {
if (!data) {
return
}
let hua = instantiate(data)
hua.parent = lanhuag
hua.setPosition(v3(arr[i].x,arr[i].y,arr[i].z))
})
}else {
resources.load('prefab/flower/juhua', Prefab, (err: any, data) => {
if (!data) {
return
}
let hua = instantiate(data)
hua.parent = juhuag
hua.setPosition(v3(arr[i].x,arr[i].y,arr[i].z))
})
}
}
}
效果如下