본문 바로가기
개발/Unity

유니티 색상 변경 에디터 만들기 (Circle Color Picker)

by 피로물든딸기 2022. 3. 20.
반응형

Unity 전체 링크

 

색상을 선택하면 선택된 Color 값을 읽을 수 있는 색상 변경 에디터, Circle Color Picker를 만들어보자.

 

먼저 원하는 color picker를 다운받는다.

 

다운받은 이미지를 Texture Type : Sprite (2D and UI)로 변경하고 Read/Write Enabled = true로 설정한다.

Read/Write Enabled를 설정하면 런타임에 mesh를 써넣는 것을 가능하고 메모리에 복사본이 생성된다.

 

그리고 선택된 색깔을 알아보기 위해 picker로 쓸 이미지도 sprite로 만들어둔다.

 

 

그리고 EventSystem, Canvas를 추가한다.

Canvas - ColorPicker(Empty) - Palette(Image), Picker(Image)로 추가한다.


script

 

Palette로 사용할 이미지, picker로 사용할 이미지와 선택된 색깔을 보기 위한 Color를 public으로 선언한다.

Palette의 size와 collider는 private로 선언한다.

    public Image circlePalette;
    public Image picker;
    public Color selectedColor;

    private Vector2 sizeOfPalette;
    private CircleCollider2D paletteCollider;

 

Start에서 위의 변수를 초기화한다.

    void Start()
    {
        paletteCollider = circlePalette.GetComponent<CircleCollider2D>();

        sizeOfPalette = new Vector2(
            circlePalette.GetComponent<RectTransform>().rect.width, 
            circlePalette.GetComponent<RectTransform>().rect.height);
    }

 

selectColor는 picker의 위치를 옮기고 해당 위치의 색깔을 getColor로 얻는다.

picker가 Palette 내에서만 선택되도록 ClampMagnitude로 offset의 크기를 collider.radius 미만으로 제한한다.

    private void selectColor()
    {
        Vector3 offset = Input.mousePosition - transform.position;
        Vector3 diff = Vector3.ClampMagnitude(offset, paletteCollider.radius);

        picker.transform.position = transform.position + diff;

        selectedColor = getColor();
    }

 

위의 selectColor는 마우스 클릭/드래그에서 호출되도록 한다.

    public void mousePointerDown()
    {
        selectColor();
    }

    public void mouseDrag()
    {
        selectColor();
    }

 

selectColor부분을 주석 처리하고 현재까지 구현사항을 확인해보자.

먼저 CircleColorPicker를 ColorPicker 오브젝트에 추가한다.

 

Palette에는 처음에 만든 sprite를 추가하고 CircleCollider2D를 설정한다.

Radius는 sprite의 크기에 맞게 적절하게 변경한다.

 

그리고 Event Trigger를 추가하고 Pointer Down, Drag 이벤트를 추가한다.

ColorPicker 오브젝트를 RuntimeOnly 밑의 칸에 추가한다.

각 이벤트에 CircleColorPicker의 mousePointerDown/mouseDrag를 연결한다.

 

마지막으로 Picker에 sprite를 추가한다.

 

palette의 collider 범위 내에서 picker가 움직이는 것을 확인할 수 있다.


마지막으로 선택한 picker의 좌표를 이용하여 Color을 얻어오자.

picker와 circlePalette의 position의 차이를 구한 후, palette 사이즈의 크기 절반을 더한다.

이 좌표를 pallete 사이즈의 비율을 얻어서 GetPixelBilinear의 (x, y)에 넣으면, 

해당 texture의 Color를 얻을 수 있다.

    private Color getColor()
    {
        Vector2 circlePalettePosition = circlePalette.transform.position;
        Vector2 pickerPosition = picker.transform.position;

        Vector2 position = pickerPosition - circlePalettePosition + sizeOfPalette * 0.5f;
        Vector2 normalized = new Vector2(
            (position.x / (circlePalette.GetComponent<RectTransform>().rect.width)),
            (position.y / (circlePalette.GetComponent<RectTransform>().rect.height)));

        Texture2D texture = circlePalette.mainTexture as Texture2D;
        Color circularSelectedColor = texture.GetPixelBilinear(normalized.x, normalized.y);

        return circularSelectedColor;
    }

 

picker로 선택한 색이 반영되는 것을 알 수 있다.

 

최종 코드는 아래와 같다.

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

public class CircleColorPicker : MonoBehaviour
{
    public Image circlePalette;
    public Image picker;
    public Color selectedColor;

    private Vector2 sizeOfPalette;
    private CircleCollider2D paletteCollider;

    void Start()
    {
        paletteCollider = circlePalette.GetComponent<CircleCollider2D>();

        sizeOfPalette = new Vector2(
            circlePalette.GetComponent<RectTransform>().rect.width, 
            circlePalette.GetComponent<RectTransform>().rect.height);
    }

    public void mousePointerDown()
    {
        selectColor();
    }

    public void mouseDrag()
    {
        selectColor();
    }

    private Color getColor()
    {
        Vector2 circlePalettePosition = circlePalette.transform.position;
        Vector2 pickerPosition = picker.transform.position;

        Vector2 position = pickerPosition - circlePalettePosition + sizeOfPalette * 0.5f;
        Vector2 normalized = new Vector2(
            (position.x / (circlePalette.GetComponent<RectTransform>().rect.width)),
            (position.y / (circlePalette.GetComponent<RectTransform>().rect.height)));

        Texture2D texture = circlePalette.mainTexture as Texture2D;
        Color circularSelectedColor = texture.GetPixelBilinear(normalized.x, normalized.y);

        return circularSelectedColor;
    }

    private void selectColor()
    {
        Vector3 offset = Input.mousePosition - transform.position;
        Vector3 diff = Vector3.ClampMagnitude(offset, paletteCollider.radius);

        picker.transform.position = transform.position + diff;

        selectedColor = getColor();
    }
}

 

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

반응형

댓글