Material 在 Unity3d 中通过光线投射确定子网格
Material determination of submeshes through raycasting in Unity3d
我正在尝试将道具随机放置在网格上。网格有 2 个 materials,我只想将道具放在其中一个 materials 上。我目前正在通过光线投射来执行此操作,确定命中点的 material,如果 material 正确,我会在该点放置一个道具。我遇到 material 被错误确定的问题,我不确定为什么。代码如下。
使用 UnityEngine;
public class BoundingBoxTry : MonoBehaviour {
// Use this for initialization
public MeshFilter meshFilter;
private Renderer rend;
private Mesh mesh;
private Bounds bnds;
private float nextX, nextZ, maxX, minX, maxZ, minZ;
public GameObject rayOrigin;
public GameObject propPreFab;
private MeshCollider thisCollider;
void Start () {
thisCollider = GetComponentInChildren<MeshCollider>();
rend = GetComponentInChildren<Renderer>();
mesh = GetComponentInChildren<MeshFilter>().sharedMesh;
bnds = rend.bounds;
}
void Update () {
nextX = Random.Range(0, bnds.size.x);
nextZ = Random.Range(0, bnds.size.z);
nextX = nextX-bnds.size.x/2;
nextZ = nextZ-bnds.size.z/2;
nextX = bnds.center.x-nextX;
nextZ = bnds.center.z-nextZ;
RaycastHit hit = new RaycastHit();
Vector3 randomCoord = new Vector3(nextX, 0, nextZ);
rayOrigin.transform.position = new Vector3(nextX, 100, nextZ);
bool didHit = Physics.Raycast(rayOrigin.transform.position, -new Vector3(0, 1, 0), out hit);
int vertCounter = 0;
if(didHit && hit.collider == thisCollider){
for (int sMC = 0; sMC < mesh.subMeshCount; sMC++)
{
int[] subMesh = mesh.GetTriangles(sMC);
vertCounter = vertCounter + subMesh.Length;
if(hit.triangleIndex < vertCounter){
if(rend.sharedMaterials[sMC] == rayOrigin.GetComponent<Renderer>().sharedMaterial){
GameObject prop = Instantiate(propPreFab, hit.point, Quaternion.identity);
}
else{
}
}
}
}
}
}
我还附上了一张图片来展示我所看到的行为。
当然,只要我提出并沉思这个问题,我就能弄明白。 Arman 的 link 也很有帮助。我看到的问题是由于我没有完全理解我从 triangleIndex 调用中获得的数据造成的。
调用 triangleIndex 时,您会收到一个顶点索引。要从该顶点命中三角形,您必须将顶点索引乘以 3,然后验证哪个子网格被光线投射命中。
我正在尝试将道具随机放置在网格上。网格有 2 个 materials,我只想将道具放在其中一个 materials 上。我目前正在通过光线投射来执行此操作,确定命中点的 material,如果 material 正确,我会在该点放置一个道具。我遇到 material 被错误确定的问题,我不确定为什么。代码如下。 使用 UnityEngine;
public class BoundingBoxTry : MonoBehaviour {
// Use this for initialization
public MeshFilter meshFilter;
private Renderer rend;
private Mesh mesh;
private Bounds bnds;
private float nextX, nextZ, maxX, minX, maxZ, minZ;
public GameObject rayOrigin;
public GameObject propPreFab;
private MeshCollider thisCollider;
void Start () {
thisCollider = GetComponentInChildren<MeshCollider>();
rend = GetComponentInChildren<Renderer>();
mesh = GetComponentInChildren<MeshFilter>().sharedMesh;
bnds = rend.bounds;
}
void Update () {
nextX = Random.Range(0, bnds.size.x);
nextZ = Random.Range(0, bnds.size.z);
nextX = nextX-bnds.size.x/2;
nextZ = nextZ-bnds.size.z/2;
nextX = bnds.center.x-nextX;
nextZ = bnds.center.z-nextZ;
RaycastHit hit = new RaycastHit();
Vector3 randomCoord = new Vector3(nextX, 0, nextZ);
rayOrigin.transform.position = new Vector3(nextX, 100, nextZ);
bool didHit = Physics.Raycast(rayOrigin.transform.position, -new Vector3(0, 1, 0), out hit);
int vertCounter = 0;
if(didHit && hit.collider == thisCollider){
for (int sMC = 0; sMC < mesh.subMeshCount; sMC++)
{
int[] subMesh = mesh.GetTriangles(sMC);
vertCounter = vertCounter + subMesh.Length;
if(hit.triangleIndex < vertCounter){
if(rend.sharedMaterials[sMC] == rayOrigin.GetComponent<Renderer>().sharedMaterial){
GameObject prop = Instantiate(propPreFab, hit.point, Quaternion.identity);
}
else{
}
}
}
}
}
}
我还附上了一张图片来展示我所看到的行为。
当然,只要我提出并沉思这个问题,我就能弄明白。 Arman 的 link 也很有帮助。我看到的问题是由于我没有完全理解我从 triangleIndex 调用中获得的数据造成的。 调用 triangleIndex 时,您会收到一个顶点索引。要从该顶点命中三角形,您必须将顶点索引乘以 3,然后验证哪个子网格被光线投射命中。