gpt4 book ai didi

c# - 如何在 Unity 3D 中的球体表面绘制纬度/经度线?

转载 作者:行者123 更新时间:2023-11-30 17:31:13 25 4
gpt4 key购买 nike

我是 Unity 3D 的初学者。我正在尝试使用 Unity 3D 创建一个地球仪,如下所示。我在场景中创建了一个 Sphere 游戏对象,并将半径设置为 640。然后,我想用 C# 脚本在这个 Sphere 的表面上绘制纬度/经度线(每 10 度)。

enter image description here

我尝试使用 LineRender 绘制每条纬度/经度线,但没有成功。我的代码:

public class EarthController : MonoBehaviour {
private float _radius = 0;
// Use this for initialization
void Start () {
_radius = gameObject.transform.localScale.x;
DrawLatLongLines();
}

// Update is called once per frame
void Update()
{
}

private void DrawLatLongLines()
{
float thetaStep = 0.0001F;
int size = (int)((2.0 * Mathf.PI) / thetaStep);

// draw lat lines
for (int latDeg = 0; latDeg < 90; latDeg += 10)
{
// throw error here.
// seems I cannot add more than one component per type
LineRenderer latLineNorth = gameObject.AddComponent<LineRenderer>();
latLineNorth.startColor = new Color(255, 0, 0);
latLineNorth.endColor = latLineNorth.startColor;
latLineNorth.startWidth = 0.2F;
latLineNorth.endWidth = 0.2F;
latLineNorth.positionCount = size;

LineRenderer latLineSouth = Object.Instantiate<LineRenderer>(latLineNorth);

float theta = 0;
var r = _radius * Mathf.Cos(Mathf.Deg2Rad * latDeg);
var z = _radius * Mathf.Sin(Mathf.Deg2Rad * latDeg);
for (int i = 0; i < size; i++)
{
var x = r * Mathf.Sin(theta);
var y = r * Mathf.Cos(theta);

Vector3 pos = new Vector3(x, y, z);
latLineNorth.SetPosition(i, pos);

pos.z = -z;
latLineSouth.SetPosition(i, pos);

theta += thetaStep;
}
}
}
}

正确的做法是什么?

我不想编写自定义着色器(如果可能的话),因为我对此一无所知。

最佳答案

自定义 3d 对象外观的常用方法是使用着色器。

在你的情况下,你需要一个线框着色器,如果你想控制线的数量,那么你可能必须自己编写它。

另一种解决方案是使用纹理。在 unity 中,您将拥有许多默认 Material ,这些 Material 将在您的对象上应用纹理。您可以应用包含线条的图像纹理。

如果您不想要纹理而只想要线条,您可以使用线条渲染器。 LineRenderer 不需要 3D 对象即可工作。你只要给它一些点,它就会用一条线把它们连接起来。以下是我的做法:

  • 使用线渲染器创建对象并输入创建线渲染器的点圆圈(您可以在 c# 中动态执行或在编辑器中手动执行线渲染器)。
  • 将其存储为预制件(可选)并将其复制到您的场景中(复制粘贴。每复制一个新行
  • 只需修改线条的旋转、比例和位置可以重建一个球体

如果您的问题是“圆的方程是什么,以便我可以找到合适的 x 和 y 坐标?”这是一个计算 x 和 y 坐标的简短想法

for(int i =0; i< nbPointsOnTheCircle; ++i)
{
var x = Mathf.Cos(nbPointsOnTheCircle / 360);
var y = Mathf.Sin(nbPointsOnTheCircle / 360);
}

如果您的问题是“如何使用 Unity 在线渲染器上动态分配点?”这是一个简短的例子:

public class Circle : MonoBehavior
{
private void Start()
{
Vector3[] circlePoints = computePoints(); // a function that compute points of a circle
var lineRenderer = GetComponent<LineRenderer>();
linerenderer.Positions = circlePoints;
}
}

编辑

每个对象只能有一个。这就是为什么上面的例子只画了一个一个圆。你已经有了一个地球 Controller ,但是这个 Controller 不能给它自己添加很多 LineRenderes。相反,这个想法是地球对象有一个脚本来执行如下操作:

private void Start()
{
for(int i=0; i<nbLines;++i)
{
GameObject go = new GameObject();
go.AddComponent<LineRenderer>();
go.AddCOmponent<Circle>();
go.transform.SetParent = transform;
go.name = "Circle" + i;
}
}

然后你会看到在你的场景中创建了几个对象,每个对象都有一个 LineRenderer 和一个 Circle 组件

从那里你应该能够做你想做的事(例如,将参数传递给 Circle 这样每个 Circle 都有点不同)

关于c# - 如何在 Unity 3D 中的球体表面绘制纬度/经度线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48278527/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com