갓똥
나는야 프로그래머
갓똥
전체 방문자
오늘
어제
  • 분류 전체보기 (186)
    • 프로그래밍 (146)
      • 자바 (9)
      • 안드로이드 (2)
      • 유니티 (20)
      • C++ (38)
      • C# (56)
      • HTML (2)
      • 파이썬 (3)
      • 자료구조 (2)
      • 알고리즘 (0)
      • 문제풀이 (4)
      • 디자인 패턴 (7)
      • 카카오톡 봇 (1)
      • 엑셀 (1)
      • 기타 (1)
    • 게임 (21)
      • 테일즈위버 (0)
      • 카이로소프트 (1)
      • 순위 (19)
      • 기타 (1)
    • 일상 (13)
      • 카페 (1)
      • 방탈출 (12)
    • 기타 (6)
      • 웃긴자료 (5)

블로그 메뉴

  • 홈
  • 방명록

공지사항

인기 글

태그

  • c# Thread
  • 모바일 게임 순위
  • 유니티 그래프 그리기
  • C++ 소멸자
  • Unity Graph
  • 게임 디자인 패턴
  • C++ 상속
  • pc게임 순위
  • 유니티 그래프
  • 유니티 골드그래프
  • c# collection
  • 2020년 게임 매출
  • c# unboxing
  • 게임 매출 순위
  • 전세계 게임 매출
  • c# coroutine
  • C++
  • 전세계게임매출순위
  • 글로벌게임매출
  • c# 코루틴
  • 자바
  • pc 게임 순위
  • 롤 골드그래프
  • 알고리즘
  • 게임매출순위
  • C++ virtual
  • C# boxing
  • 강남 방탈출
  • C# 예외 처리
  • c# delegate

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
갓똥

나는야 프로그래머

[유니티] 롤 골드그래프를 만들어보자(4) - 최종 코드
프로그래밍/유니티

[유니티] 롤 골드그래프를 만들어보자(4) - 최종 코드

2021. 8. 12. 02:27
728x90
반응형

UI를 이용하여 롤 골드그래프를 만들어보자

using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;

public class GraphMaker : MonoBehaviour
{
    public int SAMPLE_RATE = 10;

    Dictionary<int, int[]> AllTeamTotalGold = new Dictionary<int, int[]> { };

    [Header("GoldGraph")]
    public Transform DotGroup;
    public Transform LineGroup;
    public Transform InnerFilledGroup;
    public GameObject Dot;
    public GameObject Line;
    public GameObject MaskPanel;
    public Color DotGreen;
    public Color DotRed;
    public Material BlueMat;
    public Material PurpleMat;

    public RectTransform GraphArea;

    private float width;
    private float height;
    
    void Start()
    {
        var rand = new System.Random();
        int BlueTeamGold = 0, PurpleTeamGold = 0;
        for(int time=0; time < 100; time++)
        {
            BlueTeamGold = BlueTeamGold + rand.Next(0, 1000);
            PurpleTeamGold = PurpleTeamGold + rand.Next(0, 1000);
            AllTeamTotalGold.Add(time, new[] { BlueTeamGold, PurpleTeamGold });
        }

        width = GraphArea.rect.width;
        height = GraphArea.rect.height;

        DrawGoldGraph();
    }

    private void DrawGoldGraph()
    {
        float startPositionX = -width / 2;
        float maxYPosition = height / 2;
        var comparisonValue = new Dictionary<int, float>();
        var innterFilled = new List<Vector3>();

        foreach (var pair in AllTeamTotalGold)
            comparisonValue.Add(pair.Key, pair.Value[0] - pair.Value[1]);

        float MaxValue = comparisonValue.Max(x => Mathf.Abs(x.Value));
        Vector2 prevDotPos = Vector2.zero;

        for (int i = 0; i < SAMPLE_RATE; i++)
        {
            // Dot
            GameObject dot = Instantiate(Dot, DotGroup, true);
            dot.transform.localScale = Vector3.one;

            RectTransform dotRT = dot.GetComponent<RectTransform>();
            Image dotImage = dot.GetComponent<Image>();
            
            int tick = SAMPLE_RATE - 1 == i ? AllTeamTotalGold.Count-1 : AllTeamTotalGold.Count / (SAMPLE_RATE - 1) * i;

            float yPos = comparisonValue[tick] / MaxValue;

            dotImage.color = yPos >= 0f ? DotGreen : DotRed;

            dotRT.anchoredPosition = new Vector2(startPositionX + (width / (SAMPLE_RATE - 1) * i), maxYPosition * yPos);

            innterFilled.Add(dotRT.anchoredPosition);

            // Line
            if (i == 0)
            {
                prevDotPos = dotRT.anchoredPosition;
                continue;
            }

            GameObject line = Instantiate(Line, LineGroup, true);
            line.transform.localScale = Vector3.one;

            RectTransform lineRT = line.GetComponent<RectTransform>();
            Image lineImage = line.GetComponent<Image>();

            float lineWidth = Vector2.Distance(prevDotPos, dotRT.anchoredPosition);
            float xPos = (prevDotPos.x + dotRT.anchoredPosition.x) / 2;
            yPos = (prevDotPos.y + dotRT.anchoredPosition.y) / 2;

            Vector2 dir = (dotRT.anchoredPosition - prevDotPos).normalized;
            float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
            lineRT.anchoredPosition = new Vector2(xPos, yPos);
            lineRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, lineWidth);
            lineRT.localRotation = Quaternion.Euler(0f, 0f, angle);

            GameObject maskPanel = Instantiate(MaskPanel, Vector3.zero, Quaternion.identity);
            maskPanel.transform.SetParent(LineGroup);
            maskPanel.GetComponent<RectTransform>().anchoredPosition = Vector2.zero;
            maskPanel.transform.SetParent(line.transform);

            prevDotPos = dotRT.anchoredPosition;
        }

        CreateFilledGraphShape(innterFilled.ToArray()); 
    }

    private void CreateFilledGraphShape(Vector3[] linePoints)
    {
        List<Vector3> filledGraphPointList = new List<Vector3>();
        Vector3 tmp;
        float x;

        for (int i = 0; i < linePoints.Length; ++i)
        {
            filledGraphPointList.Add(new Vector3(linePoints[i].x, 0, 0));
            filledGraphPointList.Add(new Vector3(linePoints[i].x, linePoints[i].y, 0));

            if (i + 1 < linePoints.Length)
            {
                if (linePoints[i].y < 0 && linePoints[i + 1].y >= 0)
                {
                    x = Mathf.Lerp(linePoints[i].x, linePoints[i + 1].x, Mathf.Abs(linePoints[i].y) / (Mathf.Abs(linePoints[i].y) + Mathf.Abs(linePoints[i + 1].y)));
                    tmp = new Vector3(x, 0f, 0f);

                    filledGraphPointList.Add(tmp);

                    MakeRenderer(filledGraphPointList.ToArray(), filledGraphPointList.Count, PurpleMat);

                    filledGraphPointList.Clear();
                    filledGraphPointList.Add(tmp);
                }
                else if (linePoints[i].y > 0 && linePoints[i + 1].y <= 0)
                {
                    x = Mathf.Lerp(linePoints[i].x, linePoints[i + 1].x, Mathf.Abs(linePoints[i].y) / (Mathf.Abs(linePoints[i].y) + Mathf.Abs(linePoints[i + 1].y)));
                    tmp = new Vector3(x, 0f, 0f);

                    filledGraphPointList.Add(tmp);

                    MakeRenderer(filledGraphPointList.ToArray(), filledGraphPointList.Count, BlueMat);

                    filledGraphPointList.Clear();
                    filledGraphPointList.Add(tmp);
                }
            }
        }

        if (filledGraphPointList[filledGraphPointList.Count - 1].y >= 0)
        {
            MakeRenderer(filledGraphPointList.ToArray(), filledGraphPointList.Count, BlueMat);
        }
        else
        {
            MakeRenderer(filledGraphPointList.ToArray(), filledGraphPointList.Count, PurpleMat);
        }
    }

    private void MakeRenderer(Vector3[] graphPoints, int count, Material innerFill)
    {
        int trinangleCount = count - 2;
        int[] triangles = new int[trinangleCount * 3];

        int idx = 0;
        int ex = trinangleCount / 2;
        for (int i = 0; i < ex; i++)
        {
            triangles[idx++] = 2 * i;
            triangles[idx++] = 2 * i + 1;
            triangles[idx++] = 2 * i + 2;

            triangles[idx++] = 2 * i + 1;
            triangles[idx++] = 2 * i + 2;
            triangles[idx++] = 2 * i + 3;
        }

        if (count % 2 == 1)
        {
            triangles[idx++] = 2 * ex;
            triangles[idx++] = 2 * ex + 1;
            triangles[idx++] = 2 * ex + 2;
        }

        Mesh filledGraphMesh = new Mesh();
        filledGraphMesh.vertices = graphPoints;
        filledGraphMesh.triangles = triangles;

        GameObject filledGraph = new GameObject("Filled graph");
        CanvasRenderer renderer = filledGraph.AddComponent<CanvasRenderer>();
        renderer.SetMesh(filledGraphMesh);
        renderer.SetMaterial(innerFill, null);
        filledGraph.transform.SetParent(InnerFilledGroup);
        filledGraph.AddComponent<RectTransform>().anchoredPosition = Vector2.zero;
    }
}

중간중간 글쓰면서 코드를 살짝 바꾼 부분이 있어 아주약간 다를 수 있습니다..

 

시작은 0부터, 격차가 0일때는 블루 퍼플말고 다른색으로 등등은 귀찮아서 제외했습니다.

 

틀린 부분이나 개선 사항 지적은 언제나 환영입니다.

 

퍼플팀이 이겼겠지

끄읏

728x90
반응형

'프로그래밍 > 유니티' 카테고리의 다른 글

[유니티] Hierarchy의 오브젝트 Path복사  (0) 2022.03.09
[유니티] MonoSingleton  (0) 2022.01.14
[유니티] 롤 골드그래프를 만들어보자(3) - 그래프 내부 채우기  (2) 2021.08.12
[유니티] 롤 골드그래프를 만들어보자(2) - 선 찍기  (0) 2021.08.10
[유니티] 롤 골드그래프를 만들어보자(1) - 점 찍기  (26) 2021.08.09
    '프로그래밍/유니티' 카테고리의 다른 글
    • [유니티] Hierarchy의 오브젝트 Path복사
    • [유니티] MonoSingleton
    • [유니티] 롤 골드그래프를 만들어보자(3) - 그래프 내부 채우기
    • [유니티] 롤 골드그래프를 만들어보자(2) - 선 찍기
    갓똥
    갓똥
    공부하며 알아가는 내용을 정리해 봅니다.

    티스토리툴바