• Unity3D 检测鼠标位置的Sprite像素颜色


    思路

    1. 获取鼠标所在屏幕坐标(Vector2)
    2. 通过相机ScreenToWorldPoint(Vector3)转为世界坐标 (注意Vector3的z是距离相机的距离,相机需要正交)
    3. 通过SpriteRenderer访问边界Bounds
    4. 通过Bounds.Contain检测世界坐标是否在SpriteBounds内
    5. 通过比例计算来确定在Sprite内的UV坐标,并根据像素长宽确定像素坐标

    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;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
  • 相关阅读:
    T2T-ViT:更多的局部结构信息,更高效的主干网络 | ICCV 2021
    加强版python连接飞书通知——本地电脑PC端通过网页链接打开本地已安装软件(调用注册表形式,以漏洞扫描工具AppScan为例)
    项目部署java
    路径规划算法之刚体变换
    Python第五次作业
    C#将图片转换为ICON格式(程序运行图标)
    跟羽夏学 Ghidra ——引用
    VC6 WIN32,Dialog为主窗口编程
    Java用户和内核交互图
    asp.net C#免费反编译工具ILSpy
  • 原文地址:https://blog.csdn.net/qq_46273241/article/details/133241499