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 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 erasePosX = new Dictionary(); Dictionary erasePosY = new Dictionary(); #if UNITY_EDITOR private UITouchEventType touchEvent = UITouchEventType.Unknown; #endif public void AddTouchEventListener(Action func) { luaFunc = func; } public void RemoveEventListener() { luaFunc = null; } void Awake(){ mRectTransform = GetComponent(); image = GetComponent(); GameObject cameraObj = GameObject.Find("ui_camera"); if(cameraObj != null) { camera = GameObject.Find("ui_camera").GetComponent(); } } 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); } } } }