先看圖: 編程
原理很簡單,就是編寫代碼時費腦.... 數組
簡單看了一下官方實例工程bootcamp中的Decal System,也是相似這種原理(Decal System更加複雜些,經過2次剔除三角形,而且切割三角型來生成一個新的面,一兩句說不清,有興趣的朋友能夠看看《遊戲編程精粹2》中操做幾何體那一章,如出一轍),經過複製一部分目標對象的網格,貼上圖,再將這個有新網格的對象做爲目標對象的child。只不過官方的計算速度快得多得多,這個至於爲何還在研究中...下圖爲使用bootcamp中的Decal System效果 函數
代碼: 測試
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Decaller : MonoBehaviour {
// Use this for initialization
public Vector3 size = new Vector3(1,1,1);//包圍盒尺寸
public Vector3 center = Vector3.zero;//包圍盒中心座標
private Bounds bounds;//包圍盒對象
public GameObject target;//目標對象變量
private Mesh targetMesh;//目標對象的網格
private List<Vector3> vertices;//頂點數組
private List<int> triangles;//三角形索引數組 this
void BoundsCapture()//主要功能就在這個函數中
{
//思路:
//1.找出包圍盒包含的三角形
//2.將這些三角形使用的頂點加入vertices數組,並構建triangles數組,最後將這些東西賦值給新的網格
for(int i =0;i<targetMesh.triangles.Length;i+=3)
{
int containCount = 0;
for(int j =0;j<3;j++)
{
if(bounds.Contains( targetMesh.vertices[targetMesh.triangles[i+j]] ) )
{
containCount++;
}
else
{
containCount--;
}
if(containCount == 3)//當前三角形三個頂點都被包圍才加入數組
{
for( int k = 0 ;k<3 ;k++ )//加入當前測試經過的三個頂點
{ spa
//若是頂點已存在當前頂點數組中時再也不添加
if(!vertices.Contains(targetMesh.vertices[targetMesh.triangles[i+k]]))
vertices.Add(targetMesh.vertices[targetMesh.triangles[i+k]]);
orm
//將目標頂點在當前vertices數組中的索引值加入triangles數組
triangles.Add(vertices.IndexOf(targetMesh.vertices[targetMesh.triangles[i+k]]));
}
}
}
}
//能最少組成一個三角形時才生成新對象
if(vertices.Count>=3 & triangles.Count>0)
{
GameObject newGO = new GameObject();
newGO.AddComponent<MeshFilter>();
newGO.AddComponent<MeshRenderer>();
newGO.GetComponent<MeshFilter>().mesh.vertices = vertices.ToArray();
newGO.GetComponent<MeshFilter>().mesh.triangles = triangles.ToArray();
newGO.GetComponent<MeshFilter>().mesh.RecalculateNormals();
newGO.GetComponent<MeshFilter>().mesh.RecalculateBounds();
vertices.Clear();
triangles.Clear();
}
}
void UpdateBounds()//更新包圍盒位置信息
{
bounds.center = transform.position;
}
//--------------------------------------------
void Start ()
{
center = transform.position;
bounds = new Bounds(center,size);
vertices = new List<Vector3>();
triangles = new List<int>();
if(target!=null)
targetMesh = target.GetComponent<MeshFilter>().mesh;
}
// Update is called once per frame
void Update ()
{
UpdateBounds();
if(Input.GetButtonDown("Jump"))//按下空格鍵就執行復制
{
BoundsCapture();
}
} 對象
ps.因爲每次執行時都要遍歷整個對象網格的全部頂點,因此效率可想而知....歡迎各位指教! 索引