Zeichne einen Kreis um das Spielobjekt, um den Radius anzuzeigen

10

Ich habe einen Turm in meinem Turmverteidigungsspiel, den ich mit einem aufrüstbaren Radius mache, und ich möchte, wenn der Benutzer auf den Turm klickt, um den Radius als Kreis um den Turm anzuzeigen

Mein ursprünglicher Gedanke war es, ein Zylinderspielobjekt zu erstellen und es flach unter dem Turm zu platzieren, aber wenn Feinde auf den Turm zukommen, "stolpern" sie und beginnen überall zu spiralisieren (yep hatte einen blonden Moment)

Dann nahm ich den Collider vom Zylinder, aber dies führte dazu, dass einige wirklich seltsame Dinge zwischen dem Boden und dem Zylinder passierten (große grafische Störungen).

Kann ich also trotzdem einen Kreis zeichnen, der nur irgendwie visuell ist?

Der Turm ist stationär und bewegt sich nie und der Radius des Turms kann durch erreicht werden radius

Auch die Kamera ist auch stationär unten ist ein Screenshot der Spielansicht, bitte ignorieren Sie es mit der Aufschrift "Neuer Text", die zur Laufzeit eingestellt werden

Bildschirmfoto

Joséph Flames
quelle

Antworten:

13

Lösung 1

Der Linienrenderer nimmt ein Array von zwei oder mehr Punkten im 3D-Raum und zeichnet zwischen jedem eine gerade Linie. Eine einzelne Linienrenderer-Komponente kann somit verwendet werden, um alles von einer einfachen geraden Linie bis zu einer komplexen Spirale zu zeichnen. Die Linie ist immer durchgehend; Wenn Sie zwei oder mehr vollständig getrennte Linien zeichnen müssen, sollten Sie mehrere GameObjects mit jeweils einem eigenen Linienrenderer verwenden.

https://docs.unity3d.com/Manual/class-LineRenderer.html

Geben Sie hier die Bildbeschreibung ein

Tolles kleines Skript für Unity, das eine LineRenderer-Komponente in einen Kreis oder eine Ellipse verwandelt, wenn man die Anzahl der Liniensegmente zusammen mit dem x- und y-Radius berücksichtigt.

Beispiel 1:

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(LineRenderer))]
public class example : MonoBehaviour {
    [Range(0,50)]
    public int segments = 50;
    [Range(0,5)]
    public float xradius = 5;
    [Range(0,5)]
    public float yradius = 5;
    LineRenderer line;

    void Start ()
    {
        line = gameObject.GetComponent<LineRenderer>();

        line.SetVertexCount (segments + 1);
        line.useWorldSpace = false;
        CreatePoints ();
    }

    void CreatePoints ()
    {
        float x;
        float y;
        float z;

        float angle = 20f;

        for (int i = 0; i < (segments + 1); i++)
        {
            x = Mathf.Sin (Mathf.Deg2Rad * angle) * xradius;
            y = Mathf.Cos (Mathf.Deg2Rad * angle) * yradius;

            line.SetPosition (i,new Vector3(x,y,0) );

            angle += (360f / segments);
        }
    }
}

Beispiel 2:

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(LineRenderer))]
public class example : MonoBehaviour {


        [Range(0.1f, 100f)]
        public float radius = 1.0f;

        [Range(3, 256)]
         public int numSegments = 128;

        void Start ( ) {
            DoRenderer();
        }

        public void DoRenderer ( ) {
            LineRenderer lineRenderer = gameObject.GetComponent<LineRenderer>();
            Color c1 = new Color(0.5f, 0.5f, 0.5f, 1);
        lineRenderer.material = new Material(Shader.Find("Particles/Additive"));
           lineRenderer.SetColors(c1, c1);
            lineRenderer.SetWidth(0.5f, 0.5f);
            lineRenderer.SetVertexCount(numSegments + 1);
            lineRenderer.useWorldSpace = false;

         float deltaTheta = (float) (2.0 * Mathf.PI) / numSegments;
            float theta = 0f;

            for (int i = 0 ; i < numSegments + 1 ; i++) {
                float x = radius * Mathf.Cos(theta);
                float z = radius * Mathf.Sin(theta);
            Vector3 pos = new Vector3(x, 0, z);
                lineRenderer.SetPosition(i, pos);
                theta += deltaTheta;
        }
    }
}

Lösung 2

danke @Savlonmit diesem Kommentar:

Die obige Antwort mag zwar funktionieren, aber ich denke, Ihr Endziel könnte mit ein wenig Mathematik und einem Sprite mit Kreisumrissen und Transparenz viel einfacher erreicht werden. Ein zusätzliches Skript für jedes Objekt, das nur eine visuelle Darstellung eines Radius-IMO benötigt, ist ein wenig übertrieben.

Lösung 3

Projektor verwenden:

Geben Sie hier die Bildbeschreibung ein

Shader "Projector/AdditiveTint" {
    Properties {
        _Color ("Tint Color", Color) = (1,1,1,1)
        _Attenuation ("Falloff", Range(0.0, 1.0)) = 1.0
        _ShadowTex ("Cookie", 2D) = "gray" {}
    }
    Subshader {
        Tags {"Queue"="Transparent"}
        Pass {
            ZWrite Off
            ColorMask RGB
            Blend SrcAlpha One // Additive blending
            Offset -1, -1

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct v2f {
                float4 uvShadow : TEXCOORD0;
                float4 pos : SV_POSITION;
            };

            float4x4 _Projector;
            float4x4 _ProjectorClip;

            v2f vert (float4 vertex : POSITION)
            {
                v2f o;
                o.pos = mul (UNITY_MATRIX_MVP, vertex);
                o.uvShadow = mul (_Projector, vertex);
                return o;
            }

            sampler2D _ShadowTex;
            fixed4 _Color;
            float _Attenuation;

            fixed4 frag (v2f i) : SV_Target
            {
                // Apply alpha mask
                fixed4 texCookie = tex2Dproj (_ShadowTex, UNITY_PROJ_COORD(i.uvShadow));
                fixed4 outColor = _Color * texCookie.a;
                // Attenuation
                float depth = i.uvShadow.z; // [-1 (near), 1 (far)]
                return outColor * clamp(1.0 - abs(depth) + _Attenuation, 0.0, 1.0);
            }
            ENDCG
        }
    }
}

Auswahl der RTS-Stileinheit in Einheit

Lösung 4

Verwenden von Shader:

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Shader "Custom/RTSCircle" {
    Properties {
        _CirclePosition ("CirclePosition", Vector) = (0,0,0,0)
        _Length ("Length", Float ) = 2
        _Thickness ("Thickness", Float ) = 2
    }
    SubShader {
        Tags {
            "RenderType"="Opaque"
        }
        LOD 200
        Pass {
            Name "FORWARD"
            Tags {
                "LightMode"="ForwardBase"
            }


            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #define UNITY_PASS_FORWARDBASE
            #include "UnityCG.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma multi_compile_fog
            #pragma only_renderers d3d9 d3d11 glcore gles 
            #pragma target 3.0
            uniform float4 _CirclePosition;
            uniform float _Length;
            uniform float _Thickness;
            struct VertexInput {
                float4 vertex : POSITION;
            };
            struct VertexOutput {
                float4 pos : SV_POSITION;
                float4 posWorld : TEXCOORD0;
                UNITY_FOG_COORDS(1)
            };
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;
                o.posWorld = mul(unity_ObjectToWorld, v.vertex);
                o.pos = UnityObjectToClipPos( v.vertex );
                UNITY_TRANSFER_FOG(o,o.pos);
                return o;
            }
            float4 frag(VertexOutput i) : COLOR {
////// Lighting:
////// Emissive:
                float node_1386 = distance(i.posWorld.rgb,_CirclePosition.rgb);
                float node_8493 = (step((node_1386-_Thickness),_Length)-step(node_1386,_Length));
                float3 emissive = float3(node_8493,node_8493,node_8493);
                float3 finalColor = emissive;
                fixed4 finalRGBA = fixed4(finalColor,1);
                UNITY_APPLY_FOG(i.fogCoord, finalRGBA);
                return finalRGBA;
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
    CustomEditor "ShaderForgeMaterialInspector"
}

Erstellen Sie einen Kreis um Ihr Gelände

Seyed Morteza Kamali
quelle
Das sieht unglaublich komplex aus und jenseits meiner Gehirnebene könnten Sie einen Beispielcode geben, wie dies für mein Problem funktionieren würde?
Joséph Flames
was ist falsch? Mit diesem Code können Sie einen Kreis um Ihr Objekt zeichnen
Seyed Morteza Kamali
@ JoséphFlames Es ist die grundlegende Kreisformel, was ist daran so komplex?
S. Tarık Çetin
Ich habe keine Ahnung, wie ich das in meinem Spiel implementieren soll
Joséph Flames
3
Die obige Antwort mag zwar funktionieren, aber ich denke, Ihr Endziel könnte mit ein wenig Mathematik und einem Sprite mit Kreisumrissen und Transparenz viel einfacher erreicht werden. Ein zusätzliches Skript für jedes Objekt, das nur eine visuelle Darstellung eines Radius-IMO benötigt, ist ein wenig übertrieben.
Savlon