在 Unity 中生成"ramp"对象的算法



我正在为我的A级计算机科学项目在Unity中创建一个基本的模拟器。目前,用户可以通过选择关联的工具并单击并拖动来确定盒子的两个相对角,从而确定其尺寸来绘制框(板条箱(对象。

该框由单个预制件组成,该预制件被实例化并相应地更改其大小。它的代码如下:

void Start () {
boxAnim = boxButton.GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{   
//sets the mouseDown and mouseHeld bools and the mouse position Vector3
mouseDown = Input.GetMouseButtonDown(0);
mouseHeld = Input.GetMouseButton(0);
mousePosition = Input.mousePosition;
//checks if the user has started to draw
if (mouseDown && !draw)
{
draw = true;
originalMousePosition = mousePosition;
}
//checking if the user has released the mouse
if (draw && !mouseHeld)
{
finalMousePosition = mousePosition;
draw = false;
if (boxAnim.GetBool("Pressed") == true) //if the box draw button is pressed
{
boxDraw(originalMousePosition, finalMousePosition); //draws crate
}
}
}
void boxDraw(Vector3 start, Vector3 end)
{
//asigns world coordinates for the start and end mouse positions
worldStart = Camera.main.ScreenToWorldPoint(start);
worldEnd = Camera.main.ScreenToWorldPoint(end);
if (worldStart.y >= -3.2f && worldEnd.y >= -3.2f)
{ 
//determines the size of box to be drawn
boxSize.x = Mathf.Abs(worldStart.x - worldEnd.x);
boxSize.y = Mathf.Abs(worldStart.y - worldEnd.y);
//crate sprite is 175px wide, 175/50 = 3.5 (50px per unit) so the scale factor must be the size, divided by 3.5
boxScaleFactor.x = boxSize.x / 3.5f;
boxScaleFactor.y = boxSize.y / 3.5f;
//initial scale of the box is 1 (this isn't necessary but makes reading program easier)
boxScale.x = 1 * boxScaleFactor.x;
boxScale.y = 1 * boxScaleFactor.y;
//creates a new crate under the name newBox and alters its size
GameObject newBox = Instantiate(box, normalCoords(start, end), box.transform.rotation) as GameObject;
newBox.transform.localScale = boxScale;
}
}
Vector3 normalCoords(Vector3 start, Vector3 end)
{
//takes start and end coordinates as position coordinates and returns a world coordinate coordinate for the box
if(end.x > start.x)
{
start.x = start.x + (Mathf.Abs(start.x - end.x) / 2f);
}
else
{
start.x = start.x - (Mathf.Abs(start.x - end.x) / 2f);
}
if(end.y > start.y)
{
start.y = start.y + (Mathf.Abs(start.y - end.y) / 2f);
}
else
{
start.y = start.y - (Mathf.Abs(start.y - end.y) / 2f);
}
start = Camera.main.ScreenToWorldPoint(new Vector3(start.x, start.y, 0f));
return start;
}

以类似的方式,我希望能够创建一个"渐变"对象,以便用户可以单击并拖动以确定基本宽度,然后再次单击以确定仰角/高度的角度,(坡道将始终是一个直角三角形。问题在于,我希望将坡道作为我创建的精灵,而不仅仅是基本的块颜色。然而,单个精灵只有一个仰角,任何变换都无法改变这一点(据我所知(。显然,我不想为每个角度创建不同的精灵,那么我能做些什么吗?

我在想的解决方案是,如果有某种功能可以让我改变代码中矢量图像的节点,但我很确定这不存在。

编辑:只是为了澄清这是一个2D环境,代码包括Vector3s,因为这是我习惯的

你提到了精灵,它是一个2D对象(嗯,它实际上非常像一个算作3D的Quad(,但你在问题的其他部分和代码中引用了完整的3D,我认为这让人们感到困惑,因为为精灵创建纹理是一个非常不同的问题。我假设你错误地提到了精灵,你实际上想要一个 3D 对象(无论如何,Unity 在内部大部分时间都是 3D(,如果你愿意,它只能有一面

您可以从代码创建 3D 形状没有问题,尽管您确实需要熟悉 Mesh 类,并且掌握动态创建三角形需要一些练习

这里有几个很好的起点

https://docs.unity3d.com/Manual/Example-CreatingaBillboardPlane.html https://docs.unity3d.com/ScriptReference/Mesh.html

我可以使用网格和多边形碰撞体来解决部分问题。我现在有一个函数,它将创建一个具有给定宽度和高度的直角三角形和一个三角形形状的碰撞器:

using UnityEngine;
using System.Collections;
public class createMesh : MonoBehaviour {
public float width = 5f;
public float height = 5f;
public PolygonCollider2D polyCollider;
void Start()
{
polyCollider = GetComponent<PolygonCollider2D>();
}
// Update is called once per frame
void Update () {
TriangleMesh(width, height);
}
void TriangleMesh(float width, float height)
{
MeshFilter mf = GetComponent<MeshFilter>();
Mesh mesh = new Mesh();
mf.mesh = mesh;
//Verticies
Vector3[] verticies = new Vector3[3]
{
new Vector3(0,0,0), new Vector3(width, 0, 0), new Vector3(0, 
height, 0)
};
//Triangles
int[] tri = new int[3];
tri[0] = 0;
tri[1] = 2;
tri[2] = 1;
//normals
Vector3[] normals = new Vector3[3];
normals[0] = -Vector3.forward;
normals[1] = -Vector3.forward;
normals[2] = -Vector3.forward;
//UVs
Vector2[] uv = new Vector2[3];
uv[0] = new Vector2(0, 0);
uv[0] = new Vector2(1, 0);
uv[0] = new Vector2(0, 1);
//initialise
mesh.vertices = verticies;
mesh.triangles = tri;
mesh.normals = normals;
mesh.uv = uv;
//setting up collider
polyCollider.pathCount = 1;
Vector2[] path = new Vector2[3]
{
new Vector2(0,0), new Vector2(0, height), new Vector2(width, 0)
};
polyCollider.SetPath(0, path);
}
}

我只需要将这个函数放入与我的代码非常相似的代码中,以便用户可以指定宽度和高度。

最新更新