我有两个对象,它们之间有一条线,就像这样:
我想用对象的一个起点和鼠标位置作为终点来创建另一条线,但是仍要面对第二个对象,这看起来像第一行填充了鼠标所在的位置,如下所示:
(据我所知)无法在Unity中设置线条渲染器的方向,那么如何实现呢?
连接形状的代码:
public void AddShape(GameObject shape) {
selectedShape = shape;
selectedShapeComp = shape.GetComponent<Shape>();
if (!selectedShapes.Contains(selectedShape) && (selectedShapes.Count == 0 || selectedShape.CompareTag(selectedShapes[0].tag))) {
currentAdjacentShapes = selectedShapeComp.GetAdjacentShapes();
if (selectedShapes.Count == 0 && !selectedShapeComp.key) return; //If it's first and not a key, don't add it
if (selectedShapes.Count == 0 && selectedShapeComp.key) activeKeys++; //If it's first and is a key, continue
FindCurrentlyAdjacentShapes();
if (currentAdjacentShapes != null && !currentAdjacentShapes.Contains(selectedShape)) return; //If it's not adjacent to prevIoUs shape, don't add it
selectedShapes.Add(selectedShape);
MarkShape();
if (selectedShapes.Count > 1 && selectedShapeComp.key) MarkLeftOutShapes();
SelectionLinespawner.instance.SpawnLine();
}
ClearShapesAhead();
CalculateSelectedShapesAmount();
}
private void RemoveShape(int index) {
UnmarkShape(selectedShapes[index]);
selectedShapes.RemoveAt(index);
}
private void ClearShapesAhead() {
for (int i = selectedShapes.Count; i > selectedShapeComp.selectedPos; i--) {
RemoveShape(i - 1);
}
}
private void FindCurrentlyAdjacentShapes() {
if (selectedShapes.Count > 1) {
currentAdjacentShapes = selectedShapes[selectedShapes.Count - 1].GetComponent<Shape>().GetAdjacentShapes();
}
}
private void MarkLeftOutShapes() {
var shapes = new List<GameObject>();
switch (selectedShape.tag) {
case "Diamond":
shapes = LevelLoader.instance.currentLevel.GetAllDiamonds();
break;
case "Triangle":
shapes = LevelLoader.instance.currentLevel.GetAllTriangles();
break;
}
foreach (var shape in shapes) {
if (!selectedShapes.Contains(shape)) {
Debug.Log("Not selected: " + shape.name);
}
}
}
private void MarkShape() {
selectedShape.gameObject.GetComponent<SpriteRenderer>().color = Color.black;
selectedShape.gameObject.GetComponent<Animator>().SetTrigger("select");
selectedShapeComp.selected = true;
selectedShapeComp.selectedPos = selectedShapes.Count;
}
private void UnmarkShape(GameObject shape) {
var shapeComp = shape.GetComponent<Shape>();
shapeComp.selected = true;
shapeComp.selectedPos = 0;
shape.gameObject.GetComponent<SpriteRenderer>().color = Color.white;
}
private void CalculateSelectedShapesAmount() {
switch (selectedShape.tag) {
case "Diamond":
LevelLoader.instance.currentLevel.selectedDiamonds = selectedShapes.Count;
break;
case "Triangle":
LevelLoader.instance.currentLevel.selectedTriangles = selectedShapes.Count;
break;
}
}
private void DrawLines() {
foreach (var shape in LevelLoader.instance.currentLevel.GetAllShapes()) {
var adjacentShapes = shape.GetComponent<Shape>().GetAdjacentShapes();
foreach (var adjacentShape in adjacentShapes) {
var lineClone = Instantiate(line);
lineClone.transform.parent = shape.transform;
var lineComp = lineClone.GetComponent<Line>();
foreach (Transform child in adjacentShape.transform) {
if (child.CompareTag("Line"))
if (child.GetComponent<Line>().origin != adjacentShape)
lineComp.DrawLine(shape, adjacentShape);
}
if (!lineComp.IsDrawn())
Destroy(lineClone);
}
}
}
解决方法:
以下是实现所需内容的步骤:
>在两个对象和相机定义的平面上找到鼠标的世界位置,
>查找从该位置到两个对象之间的直线的最近点,
>从起始对象到最接近的点画一条线
这是可以指导您的代码:
using UnityEngine;
public class Question : MonoBehavIoUr {
public Vector3 startPosition = Vector3.left * 5;
public Vector3 endPosition = Vector3.right * 5;
void OnDrawGizmos() {
Gizmos.color = Color.blue;
Gizmos.DrawCube(startPosition, Vector3.one);
Gizmos.DrawSphere(endPosition, 1);
Gizmos.color = Color.yellow;
Gizmos.DrawLine(startPosition, endPosition);
var mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
var mousePos = mouseRay.GetPoint(Mathf.Abs(Camera.main.transform.position.z));
var pointOnLine = ClosestPointOnLine(startPosition, endPosition, mousePos, true);
Gizmos.color = Color.black;
Gizmos.DrawLine(startPosition, pointOnLine);
}
/// <summary> Returns the point nearest point to the [point] on the line given by start and end points, [linestart] and [lineEnd]</summary>
/// <param name="clampLine"> If true, the returned point will be on the line segment, rather than the line. </param>
public static Vector3 ClosestPointOnLine(Vector3 linestart, Vector3 lineEnd, Vector3 point, bool clampLine = false) {
var dif = lineEnd - linestart;
var direction = Vector3.normalize(dif);
float closestPoint = Vector3.Dot((point - linestart), direction) / dif.magnitude;
if (clampLine)
closestPoint = Mathf.Clamp(closestPoint, 0, 1);
return linestart + (closestPoint * dif);
}
}
要测试此代码,只需将其粘贴到文件中,在场景中创建一个游戏对象,然后将此组件添加到其中.这仅适用于正交摄影机.
ClosestPointOnLine方法可以在许多情况下为您提供帮助,因此我将其记录在案.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。