float pixelX = (worldPositiopn.x - bounds.min.x) / bounds.size.x * bgSprite.texture.width;
float pixelY = (worldPositiopn.y - bounds.min.y) / bounds.size.y * bgSprite.texture.height;
部分编辑器依赖于OdinInspector,不用可以把红线都删了
实现的效果类似这样,根据边界贴图检测鼠标画线位置是否在范围内
using Sirenix.OdinInspector;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
namespace Yueh0607.ClothOperations
{
public class CutBehaviour : MonoBehaviour
{
[ShowIf("IsRuntime")]
[ReadOnly]
[SerializeField]
Sprite bgSprite, lineStyleSprite, edgeSprite;
[ShowIf("IsRuntime")]
[ReadOnly]
[SerializeField]
SpriteRenderer bgRenderer, lineStyleRenderer;
[SerializeField] Color edgeColor = Color.black;
bool initialized = false;
#if UNITY_EDITOR
bool IsRuntime() => Application.isPlaying;
#endif
///
/// 初始化裁剪行为
///
/// 背景精灵图
/// 裁剪线样式精灵图
/// 边界范围精灵图(RBGA 0-1 使用(0,0,0,1)表示裁剪线范围)
public void Initialize(Sprite bgSprite, Sprite lineStyleSprite, Sprite edgeSprite)
{
this.bgSprite = bgSprite;
this.edgeSprite = edgeSprite;
this.lineStyleSprite = lineStyleSprite;
bool sizeMatch = (lineStyleSprite.texture.width == bgSprite.texture.width && edgeSprite.texture.width == bgSprite.texture.width)
&& (lineStyleSprite.texture.height == bgSprite.texture.height && edgeSprite.texture.height == bgSprite.texture.height);
bool rectMatch = (lineStyleSprite.rect == bgSprite.rect && edgeSprite.rect == bgSprite.rect);
if (!sizeMatch) throw new System.Exception("贴图尺寸不合规");
if (!rectMatch) throw new System.Exception("精灵尺寸不合规");
DynamicInitialize();
initialized = true;
}
///
/// 动态内容的初始化
///
private void DynamicInitialize()
{
GameObject bg = new GameObject("CutBackgroundImage");
bg.transform.SetParent(transform);
bg.transform.position = Vector3.zero;
bgRenderer = bg.AddComponent<SpriteRenderer>();
bgRenderer.sprite = bgSprite;
GameObject lineStyle = new GameObject("LineStyle");
lineStyle.transform.SetParent(transform);
lineStyle.transform.position = Vector3.zero;
lineStyleRenderer = lineStyle.AddComponent<SpriteRenderer>();
lineStyleRenderer.sprite = lineStyleSprite;
}
///
/// 检查裁剪行为初始化
///
///
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
private void ExceptionCheck()
{
if (!initialized) throw new System.Exception("未初始化裁剪行为!");
}
///
/// 将世界坐标转换到像素坐标
///
///
///
///
public bool TransPoint(Vector2 worldPositiopn, out Vector2Int pixelPosition)
{
ExceptionCheck();
Bounds bounds= bgRenderer.bounds;
if (bounds.Contains(worldPositiopn))
{
//get pixelX and pixelY
float pixelX = (worldPositiopn.x - bounds.min.x) / bounds.size.x * bgSprite.texture.width;
float pixelY = (worldPositiopn.y - bounds.min.y) / bounds.size.y * bgSprite.texture.height;
//float pixelX = (worldPositiopn.x - bounds.) / bgSprite.rect.width * bgSprite.texture.width;
//float pixelY = (worldPositiopn.y - bgSprite.rect.y) / bgSprite.rect.height * bgSprite.texture.height;
pixelPosition = new Vector2Int(Mathf.RoundToInt(pixelX), Mathf.RoundToInt(pixelY));
return true;
}
pixelPosition = Vector2Int.zero;
return false;
}
///
/// 判断某个世界坐标是否在裁剪线范围内
///
/// Sprite所在的坐标系坐标
///
public bool IsInEdgeRange(Vector2 worldPosition)
{
ExceptionCheck();
bool result = TransPoint(worldPosition, out Vector2Int pixelPosition);
if (!result) return false;
Color color = edgeSprite.texture.GetPixel(pixelPosition.x, pixelPosition.y);
if (color == edgeColor) return true;
return false;
}
}
}