8
\$\begingroup\$

I have a tower in my tower defense game im making with an upgradable radius and i would like when the user clicks the tower to show the radius as a circle around the tower

My original thought was to create a cylinder gameobject and place it flat below the tower but when enemies come torwards the tower they "trip" and start spiraling everywhere(yep had a blonde moment)

Then I took the collider off the cylinder but this caused some really wierd things to happen between the ground and the cylinder(major graphical glitches)

So is there anyway for me to draw a circle that is just kinda there as a visual?

The tower is stationary and never moves and the radius of the tower can be accessed through radius

Also the camera is also stationary below is a screenshot of the game view please disregard it saying "new text" those are set at runtime

Screenshot

\$\endgroup\$
9
\$\begingroup\$

Solution 1

The Line Renderer takes an array of two or more points in 3D space and draws a straight line between each one. A single Line Renderer Component can thus be used to draw anything from a simple straight line, to a complex spiral. The line is always continuous; if you need to draw two or more completely separate lines, you should use multiple GameObjects, each with its own Line Renderer.

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

enter image description here

Great little script for Unity that makes a LineRenderer component shape into a circle or ellipse, given the number of line segments along with x and y radius.

Example 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;
            z = Mathf.Cos (Mathf.Deg2Rad * angle) * yradius;

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

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

Example2:

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;
        }
    }
}

Solution 2

thanks @Savlon with this comment:

While the above answer may work, I think your end goal could be achieved much easier with a little math and a circle outline Sprite with transparency. An extra script on every object that needs only a visual representation of a radius IMO is a little overkill.

Solution 3

Using Projector:

enter image description here

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
        }
    }
}

Rts style unit selection in unity

Solution 4

Using Shader:

enter image description here

enter image description here

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"
}

Creating a circle around your terrain

\$\endgroup\$
  • \$\begingroup\$ this looks incredibly complex and beyond my brain level atm any chance you could give some example code as to how this would work for my problem? \$\endgroup\$ – Joséph Flames Jul 31 '16 at 5:11
  • \$\begingroup\$ what's wrong? by this code you can draw a circle around your object \$\endgroup\$ – Seyed Morteza Kamali Jul 31 '16 at 5:21
  • \$\begingroup\$ @JoséphFlames It is the basic circle formula, what is so complex about it? \$\endgroup\$ – S. Tarık Çetin Jul 31 '16 at 5:33
  • \$\begingroup\$ I have no clue how to implement this in my game \$\endgroup\$ – Joséph Flames Jul 31 '16 at 5:48
  • 3
    \$\begingroup\$ While the above answer may work, I think your end goal could be achieved much easier with a little math and a circle outline Sprite with transparency. An extra script on every object that needs only a visual representation of a radius IMO is a little overkill. \$\endgroup\$ – Savlon Jul 31 '16 at 12:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.