295 lines
8.5 KiB
C#
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; // <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
public Plane drawingPlane; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD>
|
|||
|
|
|
|||
|
|
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();
|
|||
|
|
|
|||
|
|
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
drawingCamera = DrawController.instance.self;
|
|||
|
|
if (drawingCamera == null)
|
|||
|
|
{
|
|||
|
|
Debug.LogError("Drawing camera is not assigned!");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD>棬<EFBFBD><E6A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD>ķ<EFBFBD><C4B7><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ 10 <20><><EFBFBD><EFBFBD>λ
|
|||
|
|
drawingPlane = new Plane(drawingCamera.transform.forward, drawingCamera.transform.position + drawingCamera.transform.forward * 10);
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
// <20>رհ<D8B1>ť<EFBFBD><C5A5><EFBFBD><EFBFBD>
|
|||
|
|
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 = "<22><>ʾ";
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
Content.GetComponent<DOTweenAnimation>().DOPlayBackwards();
|
|||
|
|
HideBtn.transform.Find("Label").GetComponent<TextMeshProUGUI>().text = "<22><><EFBFBD><EFBFBD>";
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
|
|||
|
|
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;
|
|||
|
|
// <20><><EFBFBD><EFBFBD> UI <20>ij<EFBFBD><C4B3><EFBFBD>
|
|||
|
|
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; // ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ
|
|||
|
|
curLineRender.material.renderQueue = 3000; // <20><><EFBFBD>ýϸߵ<CFB8><DFB5><EFBFBD>Ⱦ<EFBFBD><C8BE><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>ȷ<EFBFBD><C8B7><EFBFBD>ö<EFBFBD><C3B6><EFBFBD>ʾ
|
|||
|
|
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();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD>ķ<EFBFBD><C4B7><EFBFBD>
|
|||
|
|
private void SaveDrawing()
|
|||
|
|
{
|
|||
|
|
string filePath = Application.dataPath + "/Drawings/" + System.DateTime.Now.ToString("yyyyMMddHHmmss") + ".png";
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
|
|||
|
|
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()
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|