2023-04-03 11:04:31 +08:00

206 lines
6.4 KiB
C#

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System;
namespace BF
{
[DisallowMultipleComponent]
public class UIEraserTexture : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, ICancelHandler{
protected Action<int, float, float> luaFunc;
private RawImage image;
public int brushScale = 4;
Texture2D texRender;
RectTransform mRectTransform;
int totalPixels = 0;
int mRectTransformWidth = 0;
int mRectTransformHeight = 0;
Camera camera;
Vector2 end = Vector2.zero;
private bool touching = false;
protected int currentPointerId = 0;
public float eraseScale = 0f;
int pixelCount = 0;
Dictionary<int, bool> erasePosX = new Dictionary<int, bool>();
Dictionary<int, bool> erasePosY = new Dictionary<int, bool>();
#if UNITY_EDITOR
private UITouchEventType touchEvent = UITouchEventType.Unknown;
#endif
public void AddTouchEventListener(Action<int, float, float> func)
{
luaFunc = func;
}
public void RemoveEventListener()
{
luaFunc = null;
}
void Awake(){
mRectTransform = GetComponent<RectTransform>();
image = GetComponent<RawImage>();
GameObject cameraObj = GameObject.Find("ui_camera");
if(cameraObj != null)
{
camera = GameObject.Find("ui_camera").GetComponent<Camera>();
}
}
void Start() {
mRectTransformWidth = (int)mRectTransform.rect.width;
mRectTransformHeight = (int)mRectTransform.rect.height;
totalPixels = mRectTransformWidth * mRectTransformHeight;
texRender = new Texture2D(mRectTransformWidth, mRectTransformHeight,TextureFormat.ARGB32,true);
Reset();
}
public void OnPointerDown(PointerEventData eventData){
if (touching)
{
return;
}
#if UNITY_EDITOR
touchEvent = UITouchEventType.Down;
#endif
touching = true;
currentPointerId = eventData.pointerId;
if (luaFunc != null)
{
luaFunc((int)UITouchEventType.Down, eventData.position.x, eventData.position.y);
}
}
public void OnPointerUp(PointerEventData eventData){
if (currentPointerId != eventData.pointerId)
{
return;
}
touching = false;
OnMouseMove(eventData.position);
#if UNITY_EDITOR
touchEvent = UITouchEventType.UpInside;
#endif
if (luaFunc != null)
{
luaFunc((int)UITouchEventType.UpInside, eventData.position.x, eventData.position.y);
}
}
public void OnCancel(BaseEventData eventData)
{
#if UNITY_EDITOR
touchEvent = UITouchEventType.Cancel;
#endif
if (luaFunc != null)
{
luaFunc((int)UITouchEventType.Cancel, 0.0f, 0.0f);
}
touching = false;
}
public bool ContainsPos(int x, int y)
{
if(erasePosX.ContainsKey(x) && erasePosY.ContainsKey(y))
{
return true;
}
return false;
}
void Update(){
if (touching) {
OnMouseMove(Input.mousePosition);
}
}
Vector2 ConvertSceneToUI(Vector3 posi){
Vector2 postion;
if(camera == null)
{
return Vector2.zero;
}
if(RectTransformUtility.ScreenPointToLocalPointInRectangle(mRectTransform , posi, camera, out postion)){
return postion;
}
return Vector2.zero;
}
void OnMouseMove(Vector2 position)
{
end = ConvertSceneToUI(position);
Rect rect = new Rect(end.x + mRectTransformWidth/2, end.y + mRectTransformHeight/2, brushScale, brushScale);
DrawCircle((int)rect.x, (int)rect.y, brushScale);
}
public void Reset(){
if(texRender == null)
{
return;
}
for (int i = 0; i < mRectTransformWidth; i++) {
for (int j = 0; j < mRectTransformHeight; j++) {
Color color = texRender.GetPixel(i,j);
color.a = 1;
texRender.SetPixel(i, j, color);
}
}
texRender.Apply();
image.material.SetTexture("_RendTex", texRender);
eraseScale = 0f;
pixelCount = 0;
erasePosX.Clear();
erasePosY.Clear();
}
void DrawCircle(int centerX, int centerY, int brushScale){
int startX = centerX - brushScale;
int startY = centerY - brushScale;
int endX = centerX + brushScale;
int endY = centerY + brushScale;
startX = Mathf.Max(0, startX);
startY = Mathf.Max(0, startY);
endX = Mathf.Min(mRectTransformWidth, endX);
endY = Mathf.Min(mRectTransformHeight, endY);
for (int x = startX; x <= endX; x++) {
for (int y = startY; y <= endY; y++) {
float distance = Mathf.Sqrt(Mathf.Pow((centerX - x), 2) + Mathf.Pow((centerY - y), 2));
if(distance < brushScale)
{
Color color = texRender.GetPixel(x,y);
if(color.a > 0)
{
pixelCount = pixelCount + 1;
}
color.a = 0;
texRender.SetPixel(x, y, color);
erasePosX[x] = true;
erasePosY[y] = true;
}
}
}
texRender.Apply();
image.material.SetTexture("_RendTex",texRender);
if(totalPixels <= 0)
{
eraseScale = 0;
}
else
{
eraseScale = (float)(pixelCount) / totalPixels;
}
}
void OnDestroy()
{
luaFunc = null;
if(texRender != null)
{
Destroy(texRender);
}
}
}
}