我是Unity 3D的初学者。我正在尝试使用Unity 3D创建一个地球仪,如下所示。我在场景上创建了一个Sphere游戏对象并将半径设置为640.然后,我想在C#脚本中在此Sphere的表面上绘制纬度/经度线(每10度)。
我尝试使用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;
}
}
}
}
这样做的正确方法是什么?
我不想编写自定义着色器(如果可能),因为我一无所知。
答案 0 :(得分:1)
自定义3d对象外观的常用方法是使用着色器。
在您的情况下,您需要一个线框着色器,如果您想控制线数,那么您可能需要自己编写。
另一种解决方案是使用纹理。在统一中,您将拥有许多将在对象上应用纹理的默认材质。您可以应用包含线条的图像纹理。
如果您不想要纹理而只想要线条,则可以使用线条渲染器。 LineRenderer不需要3D对象来工作。你只要给它一些点,它就会用一条线将它们联系起来。 我将如何做到这一点:
如果您的问题是&#34;圆的等式是什么,那么我可以找到正确的x和y坐标?&#34;这是一个计算x和y坐标的简短想法
for(int i =0; i< nbPointsOnTheCircle; ++i)
{
var x = Mathf.Cos(nbPointsOnTheCircle / 360);
var y = Mathf.Sin(nbPointsOnTheCircle / 360);
}
如果您的问题是&#34;如何使用Unity动态分配线条渲染器上的点?&#34;这是一个简短的例子:
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;
}
}
修改强>
每个对象只能有一个。这就是为什么上面的示例仅绘制一个圈。你已经有一个地球控制器,但是这个控制器不能为自己添加许多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,这样每个圆圈都有点不同)