本次試驗還是想實現水平方向對模型加面,上一篇是相對原始的切割算法,本次想利用已有的切割插件,來實現一個水平面直接對模型進行切割加面。
Mesh切割插件介紹
關於模型切割,自己用過的比較好用的插件有兩個,一個是EsySlice,Gitbub上的非常好用的切割插件,支持使用一個平面對任意的convex Mesh 進行切割,基於C#實現,附上鍊接地址和例子,有興趣的可以學習下。
Github - EsySlice
Github - EsySliceExample
另一個是Mesh Slicer,也是一個不錯的網格模型切片插件,支持帶有碰撞器的切片網格,同時還支持蒙皮網格等優化功能。UnityAssetStore有售,各大unity論壇也有介紹,感興趣的同學也可以學習。
實驗操作
這次使用的是EsySlice,導入框架和例子可以學習切割模型的源碼,然後稍加變通,即可對模型進行水平切割加面操作。話不多說,試驗如下:
using EzySlice;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SliceTest : MonoBehaviour
{
/// <summary>
/// 場景內新建的水平Plane
/// </summary>
public Transform panelSliceTrm;
/// <summary>
/// 切割模型時切割面的材質
/// </summary>
public Material crossMaterial;
void Start()
{
MeshSubdivide(gameObject);
}
private GameObject MeshSubdivide(GameObject modelObj)
{
Vector3 foodPos = modelObj.transform.position;
Transform parentTrm = modelObj.transform.parent;
float minH = 1.352f; //選定可以切割到模型的最低高度
float maxH = 3f; //選定可以切割到模型的最高高度
float space = 0.1f; //水平高度的切割間距
float y = maxH;
while (y > minH)
{
panelSliceTrm.position = new Vector3(panelSliceTrm.position.x, y, panelSliceTrm.position.z);
y -= space;
SlicedHull hull = SliceObject(modelObj, crossMaterial);
if (hull != null)
{
GameObject hullObj = hull.CreateUpperHull(modelObj, crossMaterial);
hullObj.transform.SetParent(parentTrm);
hullObj.transform.position = foodPos;
Destroy(modelObj);
modelObj = hullObj;
}
}
return modelObj;
}
/// <summary>
/// 切割模型
/// </summary>
/// <param name="obj"></param>
/// <param name="crossSectionMaterial"></param>
/// <returns></returns>
public SlicedHull SliceObject(GameObject obj, Material crossSectionMaterial = null)
{
// slice the provided object using the transforms of this object
return obj.Slice(panelSliceTrm.position, panelSliceTrm.up, crossSectionMaterial);
}
}
實驗結果如圖:
基於模型切割實現的方法,可以更加靈活地針對各種不同類型的模型進行水平方向的加面,當模型不規則時是可行的實現方式。