简体   繁体   English

如何使用 linerenderer 绘制一个圆圈并将其作为 object 的子 object 的圆圈应该画出来?

[英]How can I draw a circle using linerenderer and make it the circle as object child of the object is should draw around?

When I attach this script to an object it will draw a circle around it.当我将此脚本附加到 object 时,它将在其周围画一个圆圈。 Now I want to make that the script the linerenderer will be attached to empty gameobject that will be a child of the object that it will draw the circle around.现在我想让 linerenderer 的脚本附加到空的游戏对象上,该对象将是 object 的子对象,它将在周围绘制圆圈。

I want that so I can drag the empty gameobject and change the circle height.我想要这样,所以我可以拖动空的游戏对象并更改圆的高度。 That way I can simple duplicate the empty gameobject and have two circles one on ground on higher.这样我就可以简单地复制空的游戏对象并在更高的地面上有两个圆圈。 and both circle will be the same radius around the parent object the parent object will be the center.并且两个圆在父 object 周围的半径相同,父 object 将是中心。

using UnityEngine;
using System.Collections;
using System;

[ExecuteAlways]
[RequireComponent(typeof(LineRenderer))]
public class DrawRadiusAroundTurret : MonoBehaviour
{
    [Range(1, 50)] public int segments = 50;
    [Range(1, 5)] public float xRadius = 5;
    [Range(1, 5)] public float yRadius = 5;
    [Range(0.1f, 5f)] public float width = 0.1f;
    public bool controlBothXradiusYradius = false;
    public bool draw = true;

    [SerializeField] private LineRenderer line;

    private void Start()
    {
        if (!line) line = GetComponent<LineRenderer>();

        CreatePoints();
    }

    public void CreatePoints()
    {
        line.enabled = true;
        line.widthMultiplier = width;
        line.useWorldSpace = false;
        line.widthMultiplier = width;
        line.positionCount = segments + 1;

        float x;
        float y;

        var angle = 20f;
        var points = new Vector3[segments + 1];
        for (int i = 0; i < segments + 1; i++)
        {
            x = Mathf.Sin(Mathf.Deg2Rad * angle) * xRadius;
            y = Mathf.Cos(Mathf.Deg2Rad * angle) * yRadius;

            points[i] = new Vector3(x, 0f, y);

            angle += (380f / segments);
        }

        // it's way more efficient to do this in one go!
        line.SetPositions(points);
    }

#if UNITY_EDITOR
    private float prevXRadius, prevYRadius;
    private int prevSegments;
    private float prevWidth;

    private void OnValidate()
    {
        // Can't set up our line if the user hasn't connected it yet.
        if (!line) line = GetComponent<LineRenderer>();
        if (!line) return;

        if (!draw)
        {
            // instead simply disable the component
            line.enabled = false;
        }
        else
        {
            // Otherwise re-enable the component
            // This will simply re-use the previously created points
            line.enabled = true;

            if (xRadius != prevXRadius || yRadius != prevYRadius || segments != prevSegments || width != prevWidth)
            {
                CreatePoints();

                // Cache our most recently used values.
                prevXRadius = xRadius;
                prevYRadius = yRadius;
                prevSegments = segments;
                prevWidth = width;
            }

            if (controlBothXradiusYradius)
            {
                yRadius = xRadius;
            }
        }
    }
#endif
}

linerenderer 和脚本都附加到 Missles Turrent 而不是我希望它们位于 Missles Turrent 的空游戏对象子对象上,并且它将继续围绕 Missles Turrent 绘制相同的圆圈,但是当它来自子对象时,我会能够改变圆的高度。

The main goal is to have multiple circles around the Missles Turrent but that I will be able to change the circles height with a simple drag.主要目标是在 Missles Turrent 周围有多个圆圈,但我将能够通过简单的拖动来更改圆圈的高度。

The solution is to create empty gameobject/s as children each child position set to 0,0,0 Then adding to each child a linerenderer component and the script.解决方案是创建空的游戏对象/s 作为每个孩子 position 设置为 0,0,0 然后为每个孩子添加一个 linerenderer 组件和脚本。

The script:剧本:

using UnityEngine;
using System.Collections;
using System;

[ExecuteAlways]
[RequireComponent(typeof(LineRenderer))]
public class DrawRadiusAroundTurret : MonoBehaviour
{
    [Range(1, 50)] public int segments = 50;
    [Range(1, 5)] public float xRadius = 5;
    [Range(1, 5)] public float yRadius = 5;
    [Range(0.1f, 5f)] public float width = 0.1f;
    public bool controlBothXradiusYradius = false;
    public bool draw = true;

    [SerializeField] private LineRenderer line;

    private void Start()
    {
        if (!line) line = GetComponent<LineRenderer>();

        CreatePoints();
    }

    //private void Update()
    //{
    //    
    //}

    public void CreatePoints()
    {
        line.enabled = true;
        line.widthMultiplier = width;
        line.useWorldSpace = false;
        line.widthMultiplier = width;
        line.positionCount = segments + 1;

        float x;
        float y;

        var angle = 20f;
        var points = new Vector3[segments + 1];
        for (int i = 0; i < segments + 1; i++)
        {
            x = Mathf.Sin(Mathf.Deg2Rad * angle) * xRadius;
            y = Mathf.Cos(Mathf.Deg2Rad * angle) * yRadius;

            points[i] = new Vector3(x, 0f, y);

            angle += (380f / segments);
        }

        // it's way more efficient to do this in one go!
        line.SetPositions(points);
    }

#if UNITY_EDITOR
    private float prevXRadius, prevYRadius;
    private int prevSegments;
    private float prevWidth;

    private void OnValidate()
    {
        // Can't set up our line if the user hasn't connected it yet.
        if (!line) line = GetComponent<LineRenderer>();
        if (!line) return;

        if (!draw)
        {
            // instead simply disable the component
            line.enabled = false;
        }
        else
        {
            // Otherwise re-enable the component
            // This will simply re-use the previously created points
            line.enabled = true;

            if (xRadius != prevXRadius || yRadius != prevYRadius || segments != prevSegments || width != prevWidth)
            {
                CreatePoints();

                // Cache our most recently used values.
                prevXRadius = xRadius;
                prevYRadius = yRadius;
                prevSegments = segments;
                prevWidth = width;
            }

            if (controlBothXradiusYradius)
            {
                yRadius = xRadius;
            }
        }
    }
#endif
}

Screenshot:截屏:

界

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM