源战役客户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

232 lines
6.1 KiB

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
[RequireComponent(typeof(RawImage))]
public class EraseHandler : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
//擦除完成调用事件
public Action eraseFinishEvent;
//笔刷半径
int brushRadius = 50;
//擦除比例,擦除比例高于该值,是为擦除完成,自动擦除剩余部分
float finishPercent = 0.8f;
//擦除点偏移量,距离上个擦除点>=该值时开始新的擦除点
float drawOffset = 10f;
//是否以擦除完成
bool isFinish;
//是否需要重置颜色透明度
bool needInitColorAlp = false;
//要擦除的图片
RawImage eraseImage;
Texture2D eraseTexture;
//图片长宽
int textureWidth;
int textureHeight;
//图片大小
float textureLength;
//擦除部分图片大小
float eraseLength;
public Camera mainCamera = null;
void Awake()
{
eraseImage = GetComponent<RawImage>();
}
void Init()
{
isFinish = false;
eraseLength = 0;
eraseImage.enabled = true;
//原擦除图片
//Texture2D originalTexture = (Texture2D)eraseImage.mainTexture;
if (needInitColorAlp)
{
InitColor();
return;
}
Texture2D originalTexture = (Texture2D)eraseImage.texture;
//被擦除的图片,展示擦除过程
eraseTexture = new Texture2D(originalTexture.width, originalTexture.height, TextureFormat.ARGB32, false);
textureWidth = eraseTexture.width;
textureHeight = eraseTexture.height;
eraseTexture.SetPixels(originalTexture.GetPixels());
eraseTexture.Apply();
Debug.Log(textureWidth + " - " + textureHeight);
eraseImage.texture = eraseTexture;
textureLength = eraseTexture.GetPixels().Length;
needInitColorAlp = true;
}
#region Pointer Event
public void OnPointerDown(PointerEventData eventData)
{
if (isFinish)
return;
tempLastPoint = eventData.position;
ErasePoint(eventData.position);
}
Vector2 tempEventPoint;
Vector2 tempLastPoint;
public void OnDrag(PointerEventData eventData)
{
if (isFinish)
return;
tempEventPoint = eventData.position;
//距离上个擦除点 >= 该值时开始新的擦除点
if ((tempEventPoint - tempLastPoint).sqrMagnitude < drawOffset * drawOffset)
return;
//擦除点
ErasePoint(tempEventPoint);
//记录点
tempLastPoint = tempEventPoint;
}
public void OnPointerUp(PointerEventData eventData)
{
if (isFinish)
return;
ErasePoint(eventData.position);
}
#endregion
Vector3 tempWorldPoint;
Vector3 tempLocalPoint;
Vector2Int pixelPos;
void ErasePoint(Vector2 screenPos)
{
if (!mainCamera) return;
//点击位置坐标转换,正交相机无效,试着改成平行相机试一下
tempWorldPoint = mainCamera.ScreenToWorldPoint(screenPos);
tempLocalPoint = transform.InverseTransformPoint(tempWorldPoint);
//相对图片像素点坐标
pixelPos.x = (int)tempLocalPoint.x + textureWidth / 2;
pixelPos.y = (int)tempLocalPoint.y + textureHeight / 2;
//点击位置是否在图片范围内
if (pixelPos.x < 0 || pixelPos.x >= textureWidth || pixelPos.y < 0 || pixelPos.y >= textureHeight)
return;
// Debug.Log("OnPointerUp" + " - " + 222);
//遍历笔刷长宽范围内像素点
for (int i = -brushRadius; i <= brushRadius; i++)
{
//超左/右边界
if (pixelPos.x + i < 0 || pixelPos.x + i >= textureWidth)
continue;
for (int j = -brushRadius; j <= brushRadius; j++)
{
//超上/下边界
if (pixelPos.y + j < 0 || pixelPos.y + j >= textureHeight)
continue;
//是否在圆形范围内
if (Mathf.Pow(i, 2) + Mathf.Pow(j, 2) > Mathf.Pow(brushRadius, 2))
continue;
//像素点色值
Color color = eraseTexture.GetPixel(pixelPos.x + i, pixelPos.y + j);
//判断透明度,是否已擦除
if (Mathf.Approximately(color.a, 0))
continue;
//Debug.Log("OnPointerUp" + " - " + 111);
//修改像素点透明度
color.a = 0;
eraseTexture.SetPixel(pixelPos.x + i, pixelPos.y + j, color);
//擦除数量统计
eraseLength++;
}
}
eraseTexture.Apply();
//判断擦除进度
RefreshErasePercent();
}
float tempPercent;
void RefreshErasePercent()
{
if (isFinish)
return;
tempPercent = eraseLength / textureLength;
tempPercent = (float)Math.Round(tempPercent, 2);
if (tempPercent >= finishPercent)
{
isFinish = true;
eraseImage.enabled = false;
//触发结束事件
if (eraseFinishEvent != null)
eraseFinishEvent.Invoke();
}
}
public void SetFinishPercent(float percent)
{
finishPercent = percent;
}
public void SetCamera(Camera cam)
{
mainCamera = cam;
}
public void SetFinishCallBack(Action call_back)
{
eraseFinishEvent = call_back;
}
public void Reset()
{
Init();
}
public void SetEraseArgs(int radius, float draw_offset)
{
brushRadius = radius;
drawOffset = draw_offset;
}
void InitColor()
{
for (int i = 1; i <= textureWidth; i++)
{
for (int j = 1; j <= textureHeight; j++)
{
Color color = eraseTexture.GetPixel(i, j);
color.a = 1;
eraseTexture.SetPixel(i, j, color);
}
}
eraseTexture.Apply();
}
}