跳转至

代码示例

下面整理了常用方法与对应的示例代码片段,涵盖多种常见任务。

设置画笔大小

paintManager.Brush.Size = value;

设置画笔硬度

paintManager.Brush.Hardness = value;

设置画笔颜色

var brushColor = paintManager.Brush.Color;
brushColor = new Color(color.r, color.g, color.b, brushColor.a);
paintManager.Brush.SetColor(brushColor);

设置画笔不透明度

var color = paintManager.Brush.Color;
color.a = value;
paintManager.Brush.SetColor(color);

设置画笔角度

paintManager.Brush.RenderAngle = value;

通过代码创建 PaintManager

PaintManager 可以通过代码创建。下面是创建 PaintManager 的示例:

public void AddPaintManager(GameObject objectForPainting, Material material, string shaderTextureName = "_MainTex")
{
    var paintManager = objectForPainting.AddComponent<PaintManager>();
    paintManager.ObjectForPainting = objectForPainting;
    paintManager.Material.SourceMaterial = material;
    paintManager.Material.ShaderTextureName = shaderTextureName;
    paintManager.Init();
}

若要用一行代码重新初始化 PaintManager,可使用:

paintManager.Init();

通过代码更换用于绘制的纹理:

public void ChangeTexture(Texture texture)
{
    var material = paintManager.Material.SourceMaterial;
    material.SetTexture(paintManager.Material.ShaderTextureName, texture);
    paintManager.Material.SourceMaterial = material;
    paintManager.Init();
}

渲染(重绘)绘制对象及其图层

paintManager.Render();

为没有源纹理的对象设置默认纹理尺寸

paintManager.Material.DefaultTextureWidth = ;
paintManager.Material.DefaultTextureHeight = ;

用颜色填充图层纹理

该方法会清空(clear)图层纹理:

paintManager.Tool = PaintTool.Brush;
paintManager.ToolsManager.CurrentTool.FillWithColor(Color.clear);
paintManager.Render();

切换工具

if (PaintController.Instance.UseSharedSettings)
{
    // 如果 PaintController 启用了 UseSharedSettings
    PaintController.Instance.Tool = PaintTool...;
}
else
{
    // 否则:
    paintManager.Tool = PaintTool...;
}

设置 Blur 工具参数

if (paintManager.ToolsManager.CurrentTool is BlurTool blurTool)
{
    blurTool.Settings.Iterations = 3;
    blurTool.Settings.BlurStrength = 2f;
    blurTool.Settings.DownscaleRatio = 1;
}

设置 Gaussian Blur 工具参数

if (paintManager.ToolsManager.CurrentTool is GaussianBlurTool gaussianBlurTool)
{
    gaussianBlurTool.Settings.KernelSize = 3;
    gaussianBlurTool.Settings.Spread = 5f;
}

启用/禁用所有 PaintManager 的输入

InputController.Instance.enabled = value;

启用/禁用某个 PaintManager 实例的输入

paintManager.PaintObject.ProcessInput = value;

获取某个 PaintManager 的平均颜色

public AverageColorCalculator AverageColorCalculator;

AverageColorCalculator.OnGetAverageColor += color => Debug.Log("Average Color: " + color);

将绘制结果保存到文件

private void SaveResultToFile(PaintManager paintManager, string path)
{
    var texture2D = paintManager.GetResultTexture();
    var pngData = texture2D.EncodeToPNG();
    if (pngData != null)
    {
        File.WriteAllBytes(path, pngData);
    }
    Destroy(texture2D);
}

将 Result Texture 保存到 Application.persistentDataPath

private void SaveResultToPersistentDataPath(PaintManager paintManager, string fileName)
{
    var texture2D = paintManager.GetResultTexture();
    var pngData = texture2D.EncodeToPNG();
    if (pngData != null)
    {
        var filePath = System.IO.Path.Combine(Application.persistentDataPath, fileName);
        System.IO.File.WriteAllBytes(filePath, pngData);
    }
    Destroy(texture2D);
}

从纹理加载

public void LoadResultTextureFromFile(PaintManager paintManager, string fileName)
{
    var filePath = System.IO.Path.Combine(Application.persistentDataPath, fileName);
    var textureData = System.IO.File.ReadAllBytes(filePath);
    var texture = new Texture2D(1, 1);
    texture.LoadImage(textureData);
    var shaderTextureName = paintManager.Material.ShaderTextureName;
    var previousTexture = paintManager.Material.SourceMaterial.GetTexture(shaderTextureName);
    paintManager.Material.SourceMaterial.SetTexture(shaderTextureName, texture);

    // 如果使用 SpriteRenderer
    var spriteRenderer = paintManager.ObjectForPainting.GetComponent<SpriteRenderer>();
    if (spriteRenderer != null)
    {
        var sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
        spriteRenderer.sprite = sprite;
    }

    // 如果使用 RawImage
    var rawImage = paintManager.ObjectForPainting.GetComponent<RawImage>();
    if (rawImage != null)
    {
        rawImage.texture = texture;
    }

    // 将纹理复制到新图层:
    paintManager.CopySourceTextureToLayer = true;
    // 将纹理复制到背景图层:
    // paintManager.UseSourceTextureAsBackground = true;
    paintManager.Init();
    paintManager.Material.SourceMaterial.SetTexture(shaderTextureName, previousTexture);
}

使用存储管理 LayersContainer

// 将 LayersContainer 保存到存储:
var filename = "someFileName";
if (paintManager.SaveToLayersContainer(fileName))
{
    Debug.Log("LayersContainer was successfully saved!");
}

// 从存储加载 LayersContainer:
if (paintManager.LoadFromLayersContainer(fileName))
{
    Debug.Log("LayersContainer was successfully loaded!");
}

// 从存储删除 LayersContainer:
var filename = "someFileName";
if (paintManager.DeleteLayersContainer(fileName))
{
    Debug.Log("LayersContainer was successfully deleted!");
}

// 检查 LayersContainer 是否存在:
var filename = "someFileName";
if (paintManager.IsLayersContainerExists(fileName))
{
    Debug.Log("LayersContainer exist!");
}

添加新图层

var layerName = "SomeLayerName";
paintManager.LayersController.AddNewLayer(layerName);

从现有纹理创建图层:

var layerName = "SomeLayerName";
var layerTexture = ... // 引用 Texture2D,注意纹理尺寸必须与源纹理一致
paintManager.LayersController.AddNewLayer(layerName, layerTexture);

移除图层

var layerIndex = 0;
paintManager.LayersController.RemoveLayer(layerIndex);

通过代码绘制

在纹理空间中绘制可使用以下方法:

// 绘制一个点;参数为纹理上的位置
paintManager.PaintObject.DrawPoint(new Vector3(512, 512));
// 点绘制结束后调用 FinishPainting()。FinishPainting() 也会将结果保存到撤销/重做系统
paintManager.PaintObject.FinishPainting();


// 绘制一条线;参数为起点与终点(纹理坐标)
paintManager.PaintObject.DrawLine(new Vector2(400, 612), new Vector2(100, 100));
// 线绘制结束后调用 FinishPainting()。FinishPainting() 也会将结果保存到撤销/重做系统
paintManager.PaintObject.FinishPainting();

在 UV 或 World 空间中绘制:

InputData prevInputData = default;
var screenPosition = new Vector3(...); // 绘制的屏幕坐标
var ray = PaintManager.GetRay(screenPosition); // 用于射线检测的 Ray
var inputData = new InputData(ray, screenPosition, 1f, InputSource.Screen, 1);
RaycastController.Instance.RequestRaycast(PaintManager, inputData, prevInputData, container =>
{
    var raycastData = RaycastController.Instance.TryGetRaycast(container, inputData.FingerId, inputData.Ray.origin);
    // 检查射线是否命中对象
    if (!raycastData.Equals(null))
    {
        // 然后使用绘制相关方法:
        // PaintManager.PaintObject.OnMouseDown(inputData, raycastData);
        PaintManager.PaintObject.OnMouseButton(inputData, raycastData);
        // PaintManager.Render();
        // PaintManager.PaintObject.OnMouseUp(inputData);
        // PaintManager.PaintObject.FinishPainting();
    }
});
prevInputData = inputData;

检查是否可以撤销/重做

paintManager.StatesController.CanUndo();
paintManager.StatesController.CanRedo();

订阅状态变化事件

paintManager.StatesController.OnUndoStatusChanged += OnUndoStatusChanged;
paintManager.StatesController.OnRedoStatusChanged += OnRedoStatusChanged;

private void OnUndoStatusChanged(bool canUndo)
{
    Debug.Log("Can undo: " + canUndo);
}

private void OnRedoStatusChanged(bool canRedo)
{
    Debug.Log("Can redo: " + canRedo);
}

执行撤销/重做

paintManager.StatesController.Undo();
paintManager.StatesController.Redo();

清空撤销/重做记录

paintManager.StatesController.ResetStates();

将 ColorPickerManager 连接到画笔

[SerializeField] private ColorPickerManager colorPickerManager;

colorPickerManager.OnColorChanged.AddListener(color =>
{
    paintManager.Brush.SetColor(color);
});

切换 ColorPickerManager 模式

colorPickerManager.SetMode(ColorPickerMode.CircleFull);

// 为 Texture 模式设置自定义纹理
colorPickerManager.SetPaletteTexture(myTexture);
colorPickerManager.SetMode(ColorPickerMode.Texture);

运行时创建 ColorPalette

var palette = ScriptableObject.CreateInstance<ColorPalette>();
palette.SetBaseColors(Color.blue);
palette.SetPaletteType(PaletteType.Complementary);
palette.GeneratePalette();

// 通过模式协调器访问调色板设置
var paletteSettings = colorPickerManager.GetPaletteModeSettings();
if (paletteSettings != null)
{
    paletteSettings.ColorPalette = palette;
    colorPickerManager.SetMode(ColorPickerMode.Palette);
}

确保光标对比度

colorPickerManager.SetCursorContrastMode(CursorContrastMode.InvertLightness);

// 或在 Inspector 中直接设置:
// ColorPickerManager → Cursor Contrast Mode → InvertLightness