【问题标题】:How to show vertices on a cube when selected in Unity (during runtime)?在 Unity 中选择时(运行时)如何在立方体上显示顶点?
【发布时间】:2015-10-28 16:57:26
【问题描述】:

我正在尝试编写一个脚本,使立方体变为蓝色,并在运行时选择时在其上显示立方体的顶点。所以基本上当点击时,它会显示所有顶点,然后允许用户选择立方体的不同顶点。

这是我目前所拥有的,基本上只是将立方体变成蓝色。如何将立方体的顶点显示为球体?我希望以后能够选择这些顶点。

using UnityEngine;
using System.Collections;

public class Cube : MonoBehaviour {
    void OnMouseDown() {
        Renderer rend = GetComponent<Renderer>();
        rend.material.color = Color.blue;
        //insert method to display vertices
    }
}

【问题讨论】:

  • 你是如何找到你的“立方体”的顶点的?你用什么作为“球体”? Unity 原语?
  • @LOLslowSTi 我还没有找到顶点,我假设它们在某种数组中作为立方体的属性。我想使用统一原语作为球体。 (我是统一的新手,所以我可能说错了,指出我在哪里看的正确方向将不胜感激)
  • 什么是“立方体”,它也是原始的吗?
  • 是的,它也是一个原始的
  • 您可以使用 GetComponent().mesh.vertices (docs.unity3d.com/ScriptReference/Mesh-vertices.html) 获取模型顶点的 Vector3s 数组。 “显示顶点”有非常广泛的解释。您是否正在考虑编写一些着色器代码来渲染模型的线框,每个顶点周围都有一个填充颜色的圆圈?用鼠标“选择顶点”可以通过光线投射(在一个顶点上射击,你给它周围有一个小的圆形对撞机)或编写自定义代码来根据 x/y 鼠标坐标选择东西来完成。

标签: c# unity3d cube vertices


【解决方案1】:

由于立方体和球体都是基元:

你会发现这样的顶点(假设cube 是GameObject):

Vector3[] vertices = cube.GetComponent<MeshFilter>().mesh.vertices;

然后创建你的球体(需要using System.Linq):

GameObject[] spheres = vertices.Select(vert =>
{
    GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere)
    sphere.transform.position = vert;
    return sphere;
})
.ToArray();

更新:好的,我现在看到你的顶点太多的问题,这就是我会做的,我会亲自将阈值设为你的球体的半径,这样一旦球体开始重叠,它们就会变成一个:

float threshold = 0.1f;

public void CreateSpheres()
{
    List<GameObject> spheres = new List<GameObject>();
    foreach (Vector3 vert in vertices)
    {
        if (spheres.Any(sph => (sph.transform.position - vert) < threshold)) continue;

        GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere)
        sphere.transform.position = vert;
        spheres.Add(sphere);
    }
}

【讨论】:

  • 我没有变量cube 作为GameObject 我不知道该怎么做。我尝试像这样定义多维数据集:GameObject cube = this.gameObject; 但是当我写Vector3[] vertices = cube.GetComponent&lt;MeshFilter&gt;().mesh.vertices; 时,我收到错误无法在类型Unity.Engine.MeshFilter 和Unity.Engine.Vector3[ ] 之间隐式转换
  • 如果您在 MonoBehaviour 中输入此内容,那么您必须像这样写 gameObject 而不是 cube:gameObject.GetComponent&lt;MeshFilter&gt;().mesh.vertices; 应该可以工作。
  • 这行得通,但是 vertices.Select 给了我一个错误类型参数,用于 Visual Studio 中的方法“Enumerable.Select 无法从用法中推断”。在 Unity 中,出现此错误“错误 CS1643:并非所有代码路径都以“System.Func”类型的匿名方法返回值
  • 发现错误,已更新。不知道我是怎么错过那个退货声明的。
【解决方案2】:

无法使 Select Function 像上一个示例中所示那样工作。如另一个答案中所述,使用GetComponent&lt;MeshFilter&gt;.mesh.vertices; 找到了坐标。

void OnMouseDown() {
    Renderer rend = GetComponent<Renderer>();
    rend.material.color = Color.blue;
    Vector3[] vertices = GetComponent<MeshFilter>().mesh.vertices;
    Vector3[] verts = removeDuplicates(vertices);
    drawSpheres(verts);
}

顶点数组包含 24 个元素,原因显示为here。因此编写了函数 removeDuplicates 来去除重复的顶点。该函数如下图所示:

Vector3[] removeDuplicates(Vector3[] dupArray) {

    Vector3[] newArray = new Vector3[8];  //change 8 to a variable dependent on shape
    bool isDup = false;
    int newArrayIndex = 0;
    for (int i = 0; i < dupArray.Length; i++) {
        for (int j = 0; j < newArray.Length; j++) {
            if (dupArray[i] == newArray[j]) {
                isDup = true;
            }
        }
        if (!isDup) {
            newArray[newArrayIndex] = dupArray[i];
            newArrayIndex++;
            isDup = false;
        }
    }
    return newArray;
}

最后,使用此处显示的 drawSpheres 函数使用新的 verts 数组绘制球体:

void drawSpheres(Vector3[] verts) {
    GameObject[] Spheres = new GameObject[verts.Length];
    for (int i = 0; i < verts.Length; i++) {
        Spheres[i] = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        Spheres[i].transform.position = verts[i];
        Spheres[i].transform.localScale -= new Vector3(0.8F, 0.8F, 0.8F);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    • 2021-03-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2023-04-09
    相关资源
    最近更新 更多