본문 바로가기
개발/Unity

(5) 버튼 배치하기 - 파이 메뉴(Pie / Radial Menu) 만들기

by 피로물든딸기 2022. 5. 10.
반응형

Unity 전체 링크

 

파이 메뉴 만들기 (Pie / Radial Menu)

 

(1) 중심 게이지 만들기

(2) 버튼 만들기

(3) Tooltip 만들기

(4) Text 자동 크기 조절

(5) 버튼 배치하기

(6) 버튼에 이벤트 연결하기


이제 버튼을 원형으로 배치해보자.

 

버튼의 크기가 모두 다른 경우 정확하게 원형으로 배치하는 것은 큰 의미가 없다.

어느 정도 기준점을 잡기만 하고 세부적인 것은 수동으로 조절하는 것이 좋다.

 

ButtonSet에 Button을 필요한 만큼 추가한다.

 

ButtonArrangement.cs를 ButtonSet에 추가한다.

자식 오브젝트를 원형으로 배치하기를 참고하여 아래의 코드를 작성한다.

자식 중 TooltipBackground는 배치하지 않으므로, List에 담지 않는다.

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

[ExecuteInEditMode]
public class ButtonArrangement : MonoBehaviour
{
    float radius = 180.0f;
    List<GameObject> buttons = new List<GameObject>();

    void Start()
    {
        int numOfChild = this.transform.childCount;

        for(int i = 0; i < numOfChild; i++)
        {
            GameObject child = transform.GetChild(i).gameObject;

            if (child.name == "TooltipBackground") continue;

            buttons.Add(child);
        }
        
        for (int i = 0; i < buttons.Count; i++)
        {
            float angle = i * (Mathf.PI * 2.0f) / buttons.Count;

            GameObject btn = buttons[i];

            btn.transform.position
                = transform.position + (new Vector3(Mathf.Cos(angle), Mathf.Sin(angle), 0)) * radius;
        }
    }
}

 

아래와 같이 버튼이 정렬된 것을 볼 수 있다.

ExecuteInEditMode에 의해 Play를 종료해도 그대로 남는다.

 

마지막으로 각 Gauge의 코드를 임시 메뉴가 아닌 ButtonSet의 버튼 수 대로 설정되도록 코드를 수정한다.

(Gauge 아래의 자식 오브젝트는 모두 지운다.)

TooltipBackground를 제외해야 하므로 1을 뺀다.

        GameObject buttonSet = this.transform.parent.Find("ButtonSet").gameObject;

        int numOfChild = buttonSet.transform.childCount - 1;

 

버튼의 개수대로 Gauge가 적절히 변하는지 직접 확인해보자.

 

Gauge.cs의 최종 코드는 아래와 같다.

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

public class Gauge : MonoBehaviour
{
    Image gauge;
    Vector2 position;
    float theta;

    void Start()
    {
        position = this.transform.position;
        gauge = this.GetComponent<Image>();

        GameObject buttonSet = this.transform.parent.Find("ButtonSet").gameObject;

        int numOfChild = buttonSet.transform.childCount - 1;

        gauge.fillAmount = 1.0f / numOfChild;
        theta = 360.0f / (numOfChild);
    }

    void Update()
    {
        float angle = Mathf.Atan2(
            Input.mousePosition.y - position.y, Input.mousePosition.x - position.x) 
            * Mathf.Rad2Deg /* radian -> degree */
            + 90.0f + (theta / 2.0f); /* 보정 */
        this.transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
    }
}

 

Unity Plus:

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Unity Pro:

 

Unity Pro

The complete solutions for professionals to create and operate.

unity.com

 

Unity 프리미엄 학습:

 

Unity Learn

Advance your Unity skills with live sessions and over 750 hours of on-demand learning content designed for creators at every skill level.

unity.com

반응형

댓글