unity 编辑器二次开发,在场景中创建一个空物体,该物体上挂载一个脚本,该脚本在设置面板上要有一个按钮,名字叫“生成路径点”,点击后在场景中该节点下生成一个球,可重复点击,在scene场景点击某个球右键后出现一个linerender,起始点是该球,终点在鼠标位置,当鼠标点击其他球体后linerender终点放到此球上
时间: 2023-11-30 09:03:27 浏览: 163
首先,创建一个空物体并挂载脚本的代码如下:
```C#
using UnityEngine;
public class PathPointGenerator : MonoBehaviour
{
public GameObject pathPointPrefab; // 路径点预制体
public void GeneratePathPoint()
{
Instantiate(pathPointPrefab, transform.position, Quaternion.identity, transform);
}
}
```
这里定义了一个公共变量 `pathPointPrefab`,用于存储路径点的预制体。在 `GeneratePathPoint()` 方法中,我们使用 `Instantiate()` 函数在当前空物体的位置生成一个路径点。
接下来,我们需要在设置面板上添加一个按钮。可以在脚本的 `OnInspectorGUI()` 方法中添加一个 `GUILayout.Button()`,代码如下:
```C#
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(PathPointGenerator))]
public class PathPointGeneratorEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
PathPointGenerator pathPointGenerator = (PathPointGenerator)target;
if (GUILayout.Button("Generate Path Point"))
{
pathPointGenerator.GeneratePathPoint();
}
}
}
```
这里使用了 `CustomEditor` 特性来自定义脚本的 Inspector 界面。在 `OnInspectorGUI()` 方法中,我们将目标对象转换为 `PathPointGenerator` 类型,并添加一个“生成路径点”的按钮。点击按钮后,调用 `GeneratePathPoint()` 方法生成路径点。
现在,我们需要实现在场景中点击某个路径点,绘制一条从该路径点到鼠标位置的线段。可以在路径点的脚本中添加一个 `OnMouseDown()` 方法,代码如下:
```C#
using UnityEngine;
public class PathPoint : MonoBehaviour
{
public Material lineMaterial; // 线段材质
public float lineWidth = 0.1f; // 线段宽度
private bool isDrawing = false; // 是否正在绘制
private void OnMouseDown()
{
if (!isDrawing)
{
isDrawing = true;
Camera camera = Camera.main;
Vector3 mousePosition = Input.mousePosition;
mousePosition.z = -camera.transform.position.z;
Vector3 endPosition = camera.ScreenToWorldPoint(mousePosition);
GameObject line = new GameObject("Line");
line.transform.SetParent(transform.parent);
LineRenderer lineRenderer = line.AddComponent<LineRenderer>();
lineRenderer.material = lineMaterial;
lineRenderer.startWidth = lineRenderer.endWidth = lineWidth;
lineRenderer.SetPositions(new Vector3[] { transform.position, endPosition });
}
}
private void OnMouseUp()
{
isDrawing = false;
}
}
```
在 `OnMouseDown()` 方法中,首先判断是否正在绘制。如果没有正在绘制,就根据鼠标位置计算终点位置,并用 `GameObject` 创建一个新的线段,设置其起始点为当前路径点,终点为鼠标位置,并将其添加一个 `LineRenderer` 组件。在 `OnMouseUp()` 方法中,将 `isDrawing` 设为 `false`,表示绘制结束。
最后,我们需要实现在点击其他路径点后,将线段的终点移动到点击的路径点上。可以在绘制线段的脚本中添加一个公共方法 `SetEndPosition()`,用于设置线段的终点,代码如下:
```C#
using UnityEngine;
public class LineGenerator : MonoBehaviour
{
public void SetEndPosition(Vector3 endPosition)
{
LineRenderer lineRenderer = GetComponent<LineRenderer>();
lineRenderer.SetPosition(1, endPosition);
}
}
```
在路径点的脚本中,我们需要获取所有路径点,并在 `OnMouseDown()` 方法中遍历所有路径点,找到与当前路径点距离最近的路径点,并调用其 `LineGenerator` 组件的 `SetEndPosition()` 方法,代码如下:
```C#
using UnityEngine;
public class PathPoint : MonoBehaviour
{
public Material lineMaterial; // 线段材质
public float lineWidth = 0.1f; // 线段宽度
private bool isDrawing = false; // 是否正在绘制
private void OnMouseDown()
{
if (!isDrawing)
{
isDrawing = true;
Camera camera = Camera.main;
Vector3 mousePosition = Input.mousePosition;
mousePosition.z = -camera.transform.position.z;
Vector3 endPosition = camera.ScreenToWorldPoint(mousePosition);
GameObject line = new GameObject("Line");
line.transform.SetParent(transform.parent);
LineRenderer lineRenderer = line.AddComponent<LineRenderer>();
lineRenderer.material = lineMaterial;
lineRenderer.startWidth = lineRenderer.endWidth = lineWidth;
lineRenderer.SetPositions(new Vector3[] { transform.position, endPosition });
foreach (Transform child in transform.parent)
{
if (child != transform && child.GetComponent<LineGenerator>() != null)
{
float distance = Vector3.Distance(child.position, transform.position);
if (distance < 1 && distance < Vector3.Distance(endPosition, transform.position))
{
child.GetComponent<LineGenerator>().SetEndPosition(transform.position);
}
}
}
}
}
private void OnMouseUp()
{
isDrawing = false;
}
}
```
在遍历所有路径点时,我们跳过当前路径点并且只选择已经有 `LineGenerator` 组件的路径点。然后计算当前路径点与每个路径点的距离,选择距离最近且小于 1 的路径点,并调用其 `SetEndPosition()` 方法将线段的终点移动到该路径点上。
现在,我们就完成了在 Unity 编辑器中创建一个空物体,该物体上挂载一个脚本,该脚本在设置面板上有一个“生成路径点”的按钮,点击后在场景中该节点下生成一个球,可重复点击,在场景中点击某个球右键后出现一个 linerender,起始点是该球,终点在鼠标位置,当鼠标点击其他球体后 linerender 终点放到此球上的功能。
阅读全文