2016-08-25 2 views
0

제 질문은 제목과 같습니다. 나는 다시 학교에 돌아 오기 위해 단합을 가지고 놀고 있는데, 나는 약간 위험한 타입의 게임을 만들기로 결심했다.PolygonCollider2D 주위를 강조 표시하는 방법은 무엇입니까?

기본적으로 나는 내지도를 가지고 있는데, 내 영토 중 하나를 클릭하면 (폴리곤 콜리더가 있고 클릭 메서드가 첨부되어 현재 테스트를 위해 작은 상자 스프라이트를 전환 함) 강조하고 싶습니다. 내가 선택한 영토 주변의 가장자리 (다각형 충돌 자의 마녀 가장자리). 그래서 나는 콜라이더를 중심으로 하이라이트 효과를내는 것이 가능한지 궁금해합니다.

현재 내 계획은 포토샵으로 모든 영토의 가장자리를 스프라이트로 만들고 효과를 만들기 위해 테스트 스프라이트처럼 토글하는 것입니다.하지만 훨씬 간단하고 효과적인 방법으로 효과를 낼 수 있다면 훌륭합니다. ! 도움을

enter image description here

덕분에 더 많은 정보가 필요하면, 당신이 할 수있는 경우에하는 질문! 이 쉐이더가 선택한 색상으로 메쉬를 개설 할 것이다 (이 메시 입자 가속기 않는 한)이이 입자 가속기 개요 실 거예요 동안

+0

이 쉽게 C#을 수행 할 수 있습니다. 포토샵이 필요하지 않습니다. 이 사진이 실제로 보일 것 같은 사진을 업로드하여 내가 찾고있는 사진인지 확인할 수 있습니까? – Programmer

+0

안녕하세요. 다음과 같이 보입니다. https://gyazo.com/53d76b924420d6b9294ba9aa2a3445c7 Photoshop으로 어떻게했는지는 비슷하지만 비슷한 효과가 나타납니다! – harrisoncrazy

답변

1

:이 쉐이더를 작성하지 않은

Shader "Custom/OutlineDiffuseShader" 
{ 
    Properties{ 
     _Color("Main Color", Color) = (.5,.5,.5,1) 
     _OutlineColor("Outline Color", Color) = (0,0,0,1) 
     _Outline("Outline width", Range(.002, 0.03)) = .002 
     _MainTex("Base (RGB)", 2D) = "white" { } 
    } 

     CGINCLUDE 
#include "UnityCG.cginc" 

     struct appdata { 
     float4 vertex : POSITION; 
     float3 normal : NORMAL; 
    }; 

    struct v2f { 
     float4 pos : POSITION; 
     float4 color : COLOR; 
    }; 

    uniform float _Outline; 
    uniform float4 _OutlineColor; 

    v2f vert(appdata v) { 
     // just make a copy of incoming vertex data but scaled according to normal direction 
     v2f o; 
     o.pos = mul(UNITY_MATRIX_MVP, v.vertex); 

     float3 norm = normalize(mul((float3x3)UNITY_MATRIX_IT_MV, v.normal)); 
     float2 offset = TransformViewToProjection(norm.xy); 

     o.pos.xy += offset * o.pos.z * _Outline; 
     o.color = _OutlineColor; 
     return o; 
    } 
    ENDCG 

     SubShader{ 
     //Tags {"Queue" = "Geometry+100" } 
     CGPROGRAM 
#pragma surface surf Lambert 

     sampler2D _MainTex; 
    fixed4 _Color; 

    struct Input { 
     float2 uv_MainTex; 
    }; 

    void surf(Input IN, inout SurfaceOutput o) { 
     fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color; 
     o.Albedo = c.rgb; 
     o.Alpha = c.a; 
    } 
    ENDCG 

     // note that a vertex shader is specified here but its using the one above 
     Pass{ 
     Name "OUTLINE" 
     Tags{ "LightMode" = "Always" } 
     Cull Front 
     ZWrite On 
     ColorMask RGB 
     Blend SrcAlpha OneMinusSrcAlpha 
     //Offset 50,50 

     CGPROGRAM 
#pragma vertex vert 
#pragma fragment frag 
     half4 frag(v2f i) :COLOR{ return i.color; } 
     ENDCG 
    } 
    } 

     SubShader{ 
     CGPROGRAM 
#pragma surface surf Lambert 

     sampler2D _MainTex; 
    fixed4 _Color; 

    struct Input { 
     float2 uv_MainTex; 
    }; 

    void surf(Input IN, inout SurfaceOutput o) { 
     fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color; 
     o.Albedo = c.rgb; 
     o.Alpha = c.a; 
    } 
    ENDCG 

     Pass{ 
     Name "OUTLINE" 
     Tags{ "LightMode" = "Always" } 
     Cull Front 
     ZWrite On 
     ColorMask RGB 
     Blend SrcAlpha OneMinusSrcAlpha 

//  CGPROGRAM 
//#pragma vertex vert 
//#pragma exclude_renderers gles xbox360 ps3 
//  ENDCG 
     SetTexture[_MainTex]{ combine primary } 
    } 
    } 

     Fallback "Diffuse" 
} 

; 주변에 떠 다니는 다양한 변형 중 하나입니다.

당신은 재료의 쉐이더를 설정하여 게임 오브젝트에 적용 할 수 있으므로이 같은 : SelectedShader 공공 필드 (안 속성)이다

gameObject.renderer.material.shader = SelectedShader;

같은 당신이 결합 할 수 있음 검사기를 통해 셰이더를 해당 변수로 윤곽을 그립니다. 선택 취소시 돌아갈 수 있도록 이전 셰이더에 대한 참조를 유지하십시오.

당신은 재료에 설정하여 외곽선의 색상을 선택할 수 있습니다

gameObject.renderer.material.SetColor("_OutlineColor", outlineColor);

희망이 충분히 가까이입니다!

+0

안녕하세요, 고마워요.하지만 조금 복잡합니다. 저는 게임 프로그래밍 2 년차에 들어가기 만하면됩니다. 그래서 그 중 대부분은 저에게 완전 횡설수설합니다. 어디를 꽂을 지 전혀 모르겠습니다. – harrisoncrazy

0

enter image description here

나는 몇 달 전에 아주 비슷한 일을했다. LineRendererPolygonCollider2D으로 수행 할 수 있습니다. 당신은 당신이 알지 못하는 많은 정보를 가지고 있기 때문에 새로운 사용자로서 문서를 읽는 방법을 알아야합니다. 이 작업을 수행하는 방법에 대한

단계 : 코드에서

1 .Create 새로운 LineRenderer.

. 소재를 새 라인 렌더러에 지정하려면 너비와 색상을 설정하십시오.

3

갔지 PolygonCollider2D에있는 점의 배열을 반환 PolygonCollider2D에서 points.

.LineRendererSetVertexCount이 점의 Length에 1을 더한 될 수

5 .SET 점 이상 루프와 TransformPoint 기능을 가진 세계 공간 지역에서 각각의 변환은 .. 우리가 필요 엑스트라 위해 그 우리가 그려 놓고있는 것을 닫는 것.

DRAW의 LINES : 포인트 위에

6 .Finally 루프 및 SetPosition 기능을 갖는 LineRenderer의 위치를 ​​변경하여 선을 그린다. 이 이후

LineRenderer.SetPosition(currentLoop, pointsArray[currentLoop]); 

는 2D, 당신은 개체의 모든 게임 오브젝트의 앞에 표시되어 있는지 확인하기 위해 pointsArray의 Z 축을 수정할 수 있습니다. (pointsArray [0]) 지점에 마지막 (pointsArray.Length) 점 위치에서 새로운 라인을 그려서 라인 .Close

7

.

다음은이 작업을 완전히 수행 할 수있는 기능입니다. 다른 2D Collider도 지원하도록 확장 할 수 있습니다. 스크립트를 작성하고 코드를 작성하십시오. PolygonCollider2D가 첨부 된 Sprite를 myGameObject 슬롯에 드래그 한 다음 재생을 클릭하십시오. 그 스프라이트에 선을 그립니다.

highlightAroundCollider(pColider, Color.yellow, Color.red, 0.1f); 함수는 sizecolor과 같이 호출 할 때 옵션을 제공합니다.

using UnityEngine; 
using System.Collections; 

public class LineDrawerTest : MonoBehaviour 
{ 
    public GameObject myGameObject; 
    private PolygonCollider2D pColider; 

    protected void Start() 
    { 
     pColider = myGameObject.GetComponent<PolygonCollider2D>(); 
     highlightAroundCollider(pColider, Color.yellow, Color.red, 0.1f); 
    } 


    void highlightAroundCollider(Component cpType, Color beginColor, Color endColor, float hightlightSize = 0.3f) 
    { 
     //1. Create new Line Renderer 
     LineRenderer lineRenderer = gameObject.GetComponent<LineRenderer>(); 
     if (lineRenderer == null) 
     { 
      lineRenderer = cpType.gameObject.AddComponent<LineRenderer>(); 

     } 

     //2. Assign Material to the new Line Renderer 
     lineRenderer.material = new Material(Shader.Find("Particles/Additive")); 

     float zPos = 10f;//Since this is 2D. Make sure it is in the front 

     if (cpType is PolygonCollider2D) 
     { 
      //3. Get the points from the PolygonCollider2D 
      Vector2[] pColiderPos = (cpType as PolygonCollider2D).points; 

      //Set color and width 
      lineRenderer.SetColors(beginColor, endColor); 
      lineRenderer.SetWidth(hightlightSize, hightlightSize); 

      //4. Convert local to world points 
      for (int i = 0; i < pColiderPos.Length; i++) 
      { 
       pColiderPos[i] = cpType.transform.TransformPoint(pColiderPos[i]); 
      } 

      //5. Set the SetVertexCount of the LineRenderer to the Length of the points 
      lineRenderer.SetVertexCount(pColiderPos.Length + 1); 
      for (int i = 0; i < pColiderPos.Length; i++) 
      { 
       //6. Draw the line 
       Vector3 finalLine = pColiderPos[i]; 
       finalLine.z = zPos; 
       lineRenderer.SetPosition(i, finalLine); 

       //7. Check if this is the last loop. Now Close the Line drawn 
       if (i == (pColiderPos.Length - 1)) 
       { 
        finalLine = pColiderPos[0]; 
        finalLine.z = zPos; 
        lineRenderer.SetPosition(pColiderPos.Length, finalLine); 
       } 
      } 
     } 

     //Not Implemented. You can do this yourself 
     else if (cpType is BoxCollider2D) 
     { 

     } 
    } 

    void Update() 
    { 

    } 
} 
+0

안녕하세요! 이걸 많이 고마워! 놀랄 만한! 저를 위해 단계적으로 설명해 주셔서 감사합니다. 정말 저의 이해를 도왔습니다. 나는 내 콜라이더의 윤곽을 잡았고, 내가 원했던 정확한 효과는 아니지만, 그 가까이 다가왔다! 그래서 내 주위를 망칠 프로젝트에 대한 pefectly :). 나는 시간이있을 때 계속 놀거야! 나를 다시 입력 해 주셔서 감사합니다! – harrisoncrazy

+0

@harrisoncrazy 환영합니다! 더 많이 향상시키고 크기를 늘릴 수 있습니다. 문제가 해결되면 답을 수락하는 것을 잊지 마십시오. – Programmer

0

다음은 내가 사용하는 해결책입니다. Line Renderer를 사용하면 마녀가 마침내 Unity 5.5에서 beatifull이됩니다.

버튼으로 사용하는 객체가 있습니다. 그것은 LineRenderer와이 스크립트 인 PoligonCollider2D를 가지고 있습니다. 또한 라인 렌더러는 해상도가 변경된 후에 자체를 다시 그려야합니다. 그래서 특정 해상도로 내 Poligon 콜리더를 구성합니다.이 해상도는 게임 창에서 구성 할 수 있습니다. 내 스크립트에서는 689 * 500, 즉 16/9 해상도를 사용합니다. 캔버스는 화면 공간 - 카메라이며 가로 세로 비가 1.7777778입니다.

using System.Collections; 
using System.Collections.Generic; 
using UnityEngine; 

public class PolygonButton : MonoBehaviour { 

    public string param; 

    public System.Action onClick; 

    float animSpeed = 1.5f; 
    IEnumerator anim; 
    bool animating; 
    Rect res; 
    Camera mainCam; 
    float theWidth = 689; 

    void Start() 
    { 
     mainCam = GameObject.FindObjectOfType<Camera>(); 
     res = mainCam.pixelRect; 
     anim = buttonAnimation(); 
     animating = false; 
     GetComponent<LineRenderer>().material.SetColor("_Color", new Color32(255, 255, 0, 0)); 

     LineRenderer lr = GetComponent<LineRenderer>(); 
     PolygonCollider2D polColliedr = GetComponent<PolygonCollider2D>(); 
     int i = 0; 
     lr.numPositions = polColliedr.points.Length + 1; 
     foreach (Vector2 point in polColliedr.points) 
     { 
      lr.SetPosition(i, point); 
      i++; 
     } 
     lr.SetPosition(i, lr.GetPosition(0)); 

     //change scale for different aspect ratio 

     float currWidth = GetComponentInParent<Canvas>().GetComponent<RectTransform>().sizeDelta.x; 

     GetComponent<RectTransform>().localScale = new Vector3(currWidth/theWidth, currWidth/theWidth, currWidth/theWidth); 
    } 

    void Update() 
    { 
     //If resolution changes - we must change button scale 
     if(mainCam.pixelRect.height != res.height || mainCam.pixelRect.width != res.width) 
     { 
      res = mainCam.pixelRect; 

      float currWidth = GetComponentInParent<Canvas>().GetComponent<RectTransform>().sizeDelta.x; 
      GetComponent<RectTransform>().localScale = new Vector3(currWidth/theWidth, currWidth/theWidth, currWidth/theWidth); 
     } 
    } 

    void OnMouseEnter() 
    { 
     CoroutineExecutor.instance.Execute(anim); 
    } 

    void OnMouseExit() 
    { 
     ResetAnim(); 
    } 

    void OnMouseUpAsButton() 
    { 
     ResetAnim(); 
     if(onClick != null) 
      onClick(); 
    } 

    void OnDestroy() 
    { 
     CoroutineExecutor.instance.StopExecution(anim); 
    } 

    void ResetAnim() 
    { 
     CoroutineExecutor.instance.StopExecution(anim); 
     anim = null; 
     anim = buttonAnimation(); 
     GetComponent<LineRenderer>().material.SetColor("_Color", new Color32(255, 255, 0, 0)); 
     animating = false; 
    } 

    IEnumerator buttonAnimation() 
    { 
     //Debug.Log("Start animation!"); 
     if (animating) 
      yield break; 
     GetComponent<LineRenderer>().material.SetColor("_Color", new Color32(255, 255, 0, 0)); 

     animating = true; 
     LineRenderer lr = GetComponent<LineRenderer>(); 
     while (true) 
     { 
      float t = 0; 
      while(t < 1) 
      { 
       t += Time.deltaTime * animSpeed; 
       lr.material.SetColor("_Color", Color.Lerp(new Color32(255, 255, 0, 0), new Color32(255, 255, 0, 255), t)); 
       yield return new WaitForEndOfFrame(); 
      } 
      t = 0; 

      while (t < 1) 
      { 
       t += Time.deltaTime * animSpeed; 
       lr.material.SetColor("_Color", Color.Lerp(new Color32(255, 255, 0, 255), new Color32(255, 255, 0, 0), t)); 
       yield return new WaitForEndOfFrame(); 
      } 
      yield return new WaitForEndOfFrame(); 
     } 
    } 
} 

그게 전부는 다음과 같습니다

Example

관련 문제