Version: Unity 6.0 (6000.0)
언어 : 한국어
브러시 선택 오버레이 레퍼런스
브러시 인스펙터 창 레퍼런스

스크립터블 브러시 생성

GridBrushBase에서 상속받는 새 클래스(또는 GridBrush과 같이 GridBrushBase의 유용한 하위 클래스)를 생성합니다. 새 Brush 클래스에 필수적인 메서드를 오버라이드할 수 있습니다. 일반적으로 다음과 같은 메서드를 오버라이드할 수 있습니다.

  • Paint를 사용하여 브러시로 타겟 그리드에 항목을 추가할 수 있습니다.
  • Erase를 사용하여 브러시로 타겟 그리드에서 항목을 제거할 수 있습니다.
  • FloodFill을 사용하여 브러시로 타겟 그리드에서 항목을 채울 수 있습니다.
  • Rotate를 사용하여 브러시에 설정된 항목을 회전할 수 있습니다.
  • Flip을 사용하여 브러시에 설정된 항목을 뒤집을 수 있습니다.

ScriptableObject.CreateInstance<(Your Brush Class>()를 사용하여 새 클래스의 인스턴스를 생성합니다. 이 새 인스턴스를 에디터에서 에셋으로 전환하면 AssetDatabase.CreateAsset()를 호출하여 반복적으로 사용할 수 있습니다.

브러시용 커스텀 에디터도 만들 수 있습니다. 이는 스크립터블 오브젝트를 위한 커스텀 에디터와 동일한 방식으로 작동합니다. 다음은 커스텀 에디터를 생성할 때 오버라이드하는 주요 메서드입니다.

  • OnPaintInspectorGUI를 오버라이드하여 브러시가 선택되었을 때 팔레트에 인스펙터 창을 표시할 수 있고 이를 통해 색칠과 관련한 추가 동작을 제공할 수 있습니다.
  • OnPaintSceneGUI를 오버라이드하여 SceneView에서 색칠할 때 추가 동작을 제공할 수 있습니다.
  • validTargets를 오버라이드하여 브러시가 상호작용할 수 있는 커스텀 타겟 목록을 만들 수도 있습니다. 이 타겟 목록은 팔레트 창에 드롭다운 목록으로 표시됩니다.

생성된 스크립터블 브러시는 팔레트 창의 Brushes 드롭다운 메뉴에 표시됩니다. 스크립터블 브러시 스크립트의 인스턴스는 기본적으로 인스턴스화되고 프로젝트의 Library 폴더에 저장됩니다. 브러시 프로퍼티에 적용한 수정 사항은 해당 인스턴스에 저장됩니다. 프로퍼티가 다르게 설정된 브러시의 복사본이 여럿 필요하다면 프로젝트에서 브러시를 에셋으로 인스턴스화할 수 있습니다. 이러한 브러시 에셋은 브러시 드롭다운 메뉴에 별도로 나열됩니다.

Scriptable Brush 클래스에 CustomGridBrush 속성을 추가할 수 있습니다. 이를 통해 팔레트 창에서 브러시의 동작을 설정할 수 있습니다. CustomGridBrush 속성에는 다음 프로퍼티가 있습니다.

  • HideAssetInstances - true로 설정하면 생성된 브러시 에셋의 모든 복사본을 팔레트 창에서 숨깁니다. 타일 팔레트 창의 브러시 드롭다운 메뉴에 기본 인스턴스만 표시하고 싶을 때 유용합니다.
  • HideDefaultInstances - true로 설정하면 브러시의 기본 인스턴스를 팔레트 창에서 숨깁니다. 타일 팔레트 창의 브러시 드롭다운 메뉴에 생성된 에셋만 표시하고 싶을 때 유용합니다.
  • DefaultBrush - true로 설정하면 브러시의 기본 인스턴스가 프로젝트의 기본 브러시로 설정됩니다. 이렇게 하면 프로젝트가 열릴 때마다 이 브러시가 기본적으로 선택되는 브러시가 됩니다. 참고: 스크립트 가능한 브러시 중 하나만 기본 브러시로 설정하십시오. 기본 브러시를 두 개 이상 설정하면 스크립트 가능한 브러시가 잘못 동작할 수 있습니다.
  • DefaultName - 이름을 설정하면 Brush 드롭다운 메뉴에서 Brush 클래스의 이름이 아닌 설정한 이름이 Brush의 이름으로 사용됩니다.

Scriptable Brush 클래스가 특정 툴만 사용하도록 설정하려면 호환되는 TilemapEditorTools 유형의 목록과 함께 BrushTools 속성을 클래스에 추가할 수 있습니다. 이렇게 하면 스크립터블 브러시가 타일 팔레트 툴바에 있는 해당 툴에 대해서만 활성화됩니다.

스크립트 가능한 브러시 예제

LineBrush를 사용하면 시작점과 끝점을 지정하여 타일맵에 타일의 선을 쉽게 그릴 수 있습니다. LineBrush의 Paint 메서드가 오버라이드되어, 사용자가 Paint 모드에서 첫 번째 마우스 클릭으로 선의 시작점을 지정하고 두 번째 마우스 클릭으로 선을 그릴 수 있습니다. OnPaintSceneGUI 메서드가 오버라이드되어 첫 번째 마우스 클릭과 두 번째 마우스 클릭으로 만들어지는 선의 미리보기가 생성됩니다. 다음은 브러시를 생성할 때 사용하는 스크립트입니다.

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

namespace UnityEditor.Tilemaps
{
    [CustomGridBrush(true, false, false, "Line Brush")]
    public class LineBrush : GridBrush {
        public bool lineStartActive = false;
        public Vector3Int lineStart = Vector3Int.zero;
        public override void Paint(GridLayout grid, GameObject brushTarget, Vector3Int position)
        {
            if (lineStartActive)
            {
                Vector2Int startPos = new Vector2Int(lineStart.x, lineStart.y);
                Vector2Int endPos = new Vector2Int(position.x, position.y);
                if (startPos == endPos)
                    base.Paint(grid, brushTarget, position);    
                else
                {
                    foreach (var point in GetPointsOnLine(startPos, endPos))
                    {
                        Vector3Int paintPos = new Vector3Int(point.x, point.y, position.z);
                        base.Paint(grid, brushTarget, paintPos);
                    }
                }
                lineStartActive = false;
            }
            else
            {
                lineStart = position;
                lineStartActive = true;
            }
        }
        [MenuItem("Assets/Create/Line Brush")]
        public static void CreateBrush()
        {
            string path = EditorUtility.SaveFilePanelInProject("Save Line Brush", "New Line Brush", "Asset", "Save Line Brush", "Assets");
            if (path == "")
                return;
AssetDatabase.CreateAsset(ScriptableObject.CreateInstance<LineBrush>(), path);
        }
        // http://ericw.ca/notes/bresenhams-line-algorithm-in-csharp.html
        public static IEnumerable<Vector2Int> GetPointsOnLine(Vector2Int p1, Vector2Int p2)
        {
            int x0 = p1.x;
            int y0 = p1.y;
            int x1 = p2.x;
            int y1 = p2.y;
            bool steep = Math.Abs(y1 - y0) > Math.Abs(x1 - x0);
            if (steep)
            {
                int t;
                t = x0; // swap x0 and y0
                x0 = y0;
                y0 = t;
                t = x1; // swap x1 and y1
                x1 = y1;
                y1 = t;
            }
            if (x0 > x1)
            {
                int t;
                t = x0; // swap x0 and x1
                x0 = x1;
                x1 = t;
                t = y0; // swap y0 and y1
                y0 = y1;
                y1 = t;
            }
            int dx = x1 - x0;
            int dy = Math.Abs(y1 - y0);
            int error = dx / 2;
            int ystep = (y0 < y1) ? 1 : -1;
            int y = y0;
            for (int x = x0; x <= x1; x++)
            {
                yield return new Vector2Int((steep ? y : x), (steep ? x : y));
                error = error - dy;
                if (error < 0)
                {
                    y += ystep;
                    error += dx;
                }
            }
            yield break;
        }
    }
    [CustomEditor(typeof(LineBrush))]
    public class LineBrushEditor : GridBrushEditor
    {
        private LineBrush lineBrush { get { return target as LineBrush; } }
        public override void OnPaintSceneGUI(GridLayout grid, GameObject brushTarget, BoundsInt position, GridBrushBase.Tool tool, bool executing)
        {
            base.OnPaintSceneGUI(grid, brushTarget, position, tool, executing);
            if (lineBrush.lineStartActive)
            {
                Tilemap tilemap = brushTarget.GetComponent<Tilemap>();
                if (tilemap != null)
                    tilemap.ClearAllEditorPreviewTiles();
                // Draw preview tiles for tilemap
                Vector2Int startPos = new Vector2Int(lineBrush.lineStart.x, lineBrush.lineStart.y);
                Vector2Int endPos = new Vector2Int(position.x, position.y);
                if (startPos == endPos)
                    PaintPreview(grid, brushTarget, position.min);
                else
                {
                    foreach (var point in LineBrush.GetPointsOnLine(startPos, endPos))
                    {
                        Vector3Int paintPos = new Vector3Int(point.x, point.y, position.z);
                        PaintPreview(grid, brushTarget, paintPos);
                    }
                }
                if (Event.current.type == EventType.Repaint)
                {
                    var min = lineBrush.lineStart;
                    var max = lineBrush.lineStart + position.size;
                    // Draws a box on the picked starting position
                    GL.PushMatrix();
                    GL.MultMatrix(GUI.matrix);
                    GL.Begin(GL.LINES);
                    Handles.color = Color.blue;
                    Handles.DrawLine(new Vector3(min.x, min.y, min.z), new Vector3(max.x, min.y, min.z));
                    Handles.DrawLine(new Vector3(max.x, min.y, min.z), new Vector3(max.x, max.y, min.z));
                    Handles.DrawLine(new Vector3(max.x, max.y, min.z), new Vector3(min.x, max.y, min.z));
                    Handles.DrawLine(new Vector3(min.x, max.y, min.z), new Vector3(min.x, min.y, min.z));
                    GL.End();
                    GL.PopMatrix();
                }
            }
        }
    }
}
브러시 선택 오버레이 레퍼런스
브러시 인스펙터 창 레퍼런스
Copyright © 2023 Unity Technologies
优美缔软件(上海)有限公司 版权所有
"Unity"、Unity 徽标及其他 Unity 商标是 Unity Technologies 或其附属机构在美国及其他地区的商标或注册商标。其他名称或品牌是其各自所有者的商标。
公安部备案号:
31010902002961