2025-02-21 11:49:10 +08:00

295 lines
8.5 KiB
C#

using UnityEngine;
using UnityEngine.UI;
using QFramework;
using System.IO;
using UnityEngine.Rendering.Universal;
using static UnityEngine.GraphicsBuffer;
using TMPro;
using UnityEngine.EventSystems;
using DG.Tweening;
using static UnityEngine.Rendering.DebugUI;
namespace QFramework.Example
{
public class UIDrawData : UIPanelData
{
}
public partial class UIDraw : UIPanel
{
public int brushSize = 5;
public LineRenderer curLineRender;
private bool isDrawing = false;
public Camera drawingCamera; // 用于指定绘制使用的相机
public Plane drawingPlane; // 定义绘制平面
Color eraserColor = new Color(1, 1, 1, 0);
enum Tools
{
Pen,
Eraser,
}
Tools curTool = Tools.Pen;
int orderLayer = 0;
protected override void OnInit(IUIData uiData = null)
{
mData = uiData as UIDrawData ?? new UIDrawData();
// 获取绘制相机
drawingCamera = DrawController.instance.self;
if (drawingCamera == null)
{
Debug.LogError("Drawing camera is not assigned!");
return;
}
// 定义绘制平面,这里假设平面的法线为相机的正前方,距离相机为 10 个单位
drawingPlane = new Plane(drawingCamera.transform.forward, drawingCamera.transform.position + drawingCamera.transform.forward * 10);
// 关闭按钮监听
CloseBtn.onClick.AddListener(() =>
{
StringEventSystem.Global.Send($"On{UIDraw.Name}Close");
Hide();
});
PenSizeSlider.onValueChanged.AddListener(value =>
{
RefreshPenSize();
});
AlphaSlider.onValueChanged.AddListener(value =>
{
RefreshAlphaSet();
});
PenHandle.OnPointerEnterEvent(data =>
{
Penvalue.gameObject.SetActive(true);
});
AlphaHandle.OnPointerEnterEvent(data =>
{
AlphaValue.gameObject.SetActive(true);
});
HideBtn.onValueChanged.AddListener(isOn =>
{
if (isOn)
{
Content.GetComponent<DOTweenAnimation>().DORestart();
HideBtn.transform.Find("Label").GetComponent<TextMeshProUGUI>().text = "显示";
}
else
{
Content.GetComponent<DOTweenAnimation>().DOPlayBackwards();
HideBtn.transform.Find("Label").GetComponent<TextMeshProUGUI>().text = "隐藏";
}
});
foreach (var toggle in Colors.GetComponentsInChildren<Toggle>())
{
toggle.onValueChanged.AddListener(isOn =>
{
if (isOn)
{
ChangeColor(toggle.transform.Find("Color").GetComponent<Image>().color);
}
});
}
BackBtn.onClick.AddListener(() =>
{
orderLayer--;
DrawController.instance.Remove();
});
ClearBtn.onClick.AddListener(() =>
{
orderLayer = 0;
DrawController.instance.Clear();
});
Pen.onValueChanged.AddListener(isOn =>
{
curTool = Tools.Pen;
});
Eraser.onValueChanged.AddListener(isOn =>
{
curTool = Tools.Eraser;
});
RefreshAlphaSet();
RefreshPenSize();
}
public void ChangeColor(Color color)
{
Icon.color = new Color(color.r, color.g, color.b, Icon.color.a);
}
public void RefreshPenSize()
{
var value = PenSizeSlider.value;
float mappedValue = (100f * (value)) / 32f;
// 设置 UI 的长宽
Icon.rectTransform.sizeDelta = new Vector2(mappedValue, mappedValue);
Penvalue.text = value.ToString();
}
public void RefreshAlphaSet()
{
var color = Icon.color;
color.a = AlphaSlider.value / 100f;
Icon.color = color;
AlphaValue.text = AlphaSlider.value.ToString();
}
public void SetupCameraStack(Camera subCamera, Camera baseCamera)
{
UniversalAdditionalCameraData additionalCameraData = baseCamera.GetUniversalAdditionalCameraData();
if (!additionalCameraData.cameraStack.Contains(subCamera))
{
additionalCameraData.cameraStack.Add(subCamera);
}
}
private void SetupLineRenderer()
{
orderLayer++;
switch (curTool)
{
case Tools.Pen:
curLineRender.startColor = Icon.color;
curLineRender.endColor = Icon.color;
break;
case Tools.Eraser:
curLineRender.startColor = eraserColor;
curLineRender.endColor = eraserColor;
break;
}
curLineRender.startWidth = brushSize / 50f;
curLineRender.endWidth = brushSize / 50f;
curLineRender.positionCount = 0;
curLineRender.useWorldSpace = true; // 使用世界坐标系
curLineRender.material.renderQueue = 3000; // 设置较高的渲染队列值,确保置顶显示
curLineRender.sortingOrder = orderLayer;
}
void Update()
{
if (Input.GetMouseButtonUp(0))
{
Penvalue.gameObject.SetActive(false);
AlphaValue.gameObject.SetActive(false);
}
if (EventSystem.current.IsPointerOverGameObject() == false)
{
HandleDrawingInput();
HandleSaveClearColorInput();
}
}
private void HandleDrawingInput()
{
if (Input.GetMouseButtonDown(0))
{
isDrawing = true;
curLineRender = DrawController.instance.LineRendererFactory();
SetupLineRenderer();
curLineRender.positionCount = 0;
}
if (Input.GetMouseButtonUp(0))
{
isDrawing = false;
curLineRender = null;
}
if (isDrawing)
{
Ray ray = drawingCamera.ScreenPointToRay(Input.mousePosition);
float enter;
if (drawingPlane.Raycast(ray, out enter))
{
Vector3 drawPoint = ray.GetPoint(enter);
if (ShouldAddNewPoint(drawPoint))
{
AddPointToLineRenderer(drawPoint);
}
Debug.DrawRay(ray.origin, ray.direction * enter, Color.red);
}
}
}
private bool ShouldAddNewPoint(Vector3 drawPoint)
{
return curLineRender.positionCount == 0 ||
Vector3.Distance(drawPoint, curLineRender.GetPosition(curLineRender.positionCount - 1)) > 0.1f;
}
private void AddPointToLineRenderer(Vector3 drawPoint)
{
curLineRender.positionCount++;
curLineRender.SetPosition(curLineRender.positionCount - 1, drawPoint);
}
private void HandleSaveClearColorInput()
{
if (Input.GetKeyDown(KeyCode.S))
{
SaveDrawing();
}
}
// 保存绘制结果的方法
private void SaveDrawing()
{
string filePath = Application.dataPath + "/Drawings/" + System.DateTime.Now.ToString("yyyyMMddHHmmss") + ".png";
// 创建保存文件夹
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
ScreenCapture.CaptureScreenshot(filePath);
Debug.Log("Drawing saved to: " + filePath);
}
protected override void OnOpen(IUIData uiData = null)
{
Show3DCamera.instance.lockMove = true;
DrawController.instance.gameObject.SetActive(true);
}
protected override void OnShow()
{
}
protected override void OnHide()
{
Show3DCamera.instance.lockMove = false;
DrawController.instance.gameObject.SetActive(false);
}
protected override void OnClose()
{
}
}
}