首页 > 其他分享 >【Unity】自制PolygonCollider2D

【Unity】自制PolygonCollider2D

时间:2024-07-14 22:10:53浏览次数:17  
标签:Count 自制 public Unity points PolygonCollider2D guiEvent polygonCollider

防止和UnityEngine的PolygonCollider2D重名,所有类包裹在了我自己定义的名称空间JimDevPack中,名称空间的声明部分在文章代码中略去了。

定义PolygonCollider2D和基类

基类

public class Collider2D : MonoBehaviour {}

PolygonCollider2D

public class PolygonCollider2D : Collider2D
{
    public List<Vector2> points;
    
    // 绘制多边形的边
    private void OnDrawGizmos()
    {
        Gizmos.color = Color.green;
        if (points.Count > 1)
        {
            for (int i = 0; i < points.Count - 1; i++)
            {
                Gizmos.DrawLine(points[i], points[i + 1]);
            }
            Gizmos.DrawLine(points[points.Count - 1], points[0]);
        }
    }
}

Editor扩展

[CustomEditor(typeof(PolygonCollider2D))]
public class PolygonCollider2DEditor : Editor
{
    private PolygonCollider2D polygonCollider;

    private void OnEnable()
    {
        polygonCollider = (PolygonCollider2D)target;
        if (polygonCollider.points == null)
        {
            polygonCollider.points = new List<Vector2>();
        }
    }

    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

        if (GUILayout.Button("Add Point"))
        {
            polygonCollider.points.Add(new Vector2());
        }
    }

    private void OnSceneGUI()
    {
        Event guiEvent = Event.current;

        // 如果按住ctrl并且点击了左键,会删除点击位置最近的点
        if (guiEvent.type == EventType.MouseDown && guiEvent.button == 0 && guiEvent.control)
        {
            float closestDistance = float.MaxValue;
            int closestIndex = -1;

            // 寻找最近的点
            for (int i = 0; i < polygonCollider.points.Count; i++)
            {
                float distance = Vector2.Distance(polygonCollider.points[i], HandleUtility.GUIPointToWorldRay(guiEvent.mousePosition).origin);
                if (distance < closestDistance)
                {
                    closestDistance = distance;
                    closestIndex = i;
                }
            }

            if (closestIndex != -1)
            {
                Undo.RecordObject(polygonCollider, "Remove Point");
                polygonCollider.points.RemoveAt(closestIndex);
                guiEvent.Use();
            }
        }

        for (int i = 0; i < polygonCollider.points.Count; i++)
        {
            Handles.color = new Color(0, 0, 1, 1f);
            EditorGUI.BeginChangeCheck();
            // 绘制一个可自由移动的Handle
            Vector2 newTargetPosition = Handles.FreeMoveHandle(polygonCollider.points[i], Quaternion.identity, 0.03f, new Vector2(0.5f, 0.5f), Handles.DotHandleCap);
            if (EditorGUI.EndChangeCheck())
            {
                // 记录信息,为了响应撤销
                Undo.RecordObject(polygonCollider, "Move Point");
                // 赋值新位置
                polygonCollider.points[i] = newTargetPosition;
            }
        }
    }
}

效果

标签:Count,自制,public,Unity,points,PolygonCollider2D,guiEvent,polygonCollider
From: https://www.cnblogs.com/JimmyZou/p/18302082

相关文章

  • [Unity] Dreamteck Splines实现沿路径移动功能
    DreamteckSplines实现沿路径移动功能最近有一个“让物体沿固定路径移动”的需求,因此接触到了DreamteckSplines插件。DreamteckSplines可以很方便地绘制各种插值曲线,但在实现物体移动的时候却遇到了很多坑,因此在这里记录一下。1.绘制路径线首先,让我们在场景上创建一个空物......
  • unity is running as administrator 管理员权限问题
    每次打开工程弹出unityisrunningasadministrator的窗口unity版本2022.3.34f1,电脑系统是win11系统解决方法一:解决方法二:unity版本2022.3.34f1,电脑系统是win11系统每次打开工程都会出现unityisrunningasadministrator的窗口,真的很烦人。本人使用第二种方法......
  • 【Unity】碰撞检测算法及框架实现
    背景硕士期间研究课题是海洋生物数字孪生,基于各类Boids改进的算法里会有大量的海洋鱼类在三维空间中运动,鱼类之间会有互相感知的过程,同一帧里需要对许多行为进行决策判定,例如同伴鱼、食物、捕食者、栖息地等等。因此打算研究下有什么空间加速算法能够避免暴力迭代,减少开销。既然......
  • 【unity开发】怎么下载国际版的unity编辑器版本
    有一天从公司那接手了一个项目,然后发现那个项目的版本我没有,我就去unity官网下载。下载完了发现还是版本不对。仔细一看发现,他们用的版本号末尾少了个"c1"。c1的意思是中国特供版,好像是说有微信api的支持。那么我应该怎么做呢?下面随便一个版本为例子1.点击按钮下载。2.......
  • 如何使用 Unity 的 ScriptableObjects 和 Resources 系统来创建一个简易的数据库系统,
    1.引言问题:如何在Unity中存储数据?解决方案:使用ScriptableObjects和Resources系统创建一个易于使用和管理的数据库。优势:自动读写数据自动处理资源实例化和更改无需额外插件使用用户定义键进行访问可扩展性强2.实现2.1项目结构四个主要的脚本:Item......
  • unity 用gps获取经纬度,然后将经纬度通过逆地理编码转换成中文地址(百度API)
    1.通过GPS获取经纬度直接上代码了usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;usingUnityEngine.UI;publicclassGetGPS:MonoBehaviour{stringGetGps="";//publicButtonupdateBtn;Vector2jingWei=newVe......
  • Unity中用于处理 UI 的射线检测和事件处理的两种脚本
    GraphicRaycaster组件GraphicRaycaster是Unity中用于UI系统的射线检测组件。它主要用于检测屏幕上的图形界面元素(如按钮、图片、文本等)的点击事件,并将这些事件传递给相应的UI元素。主要功能射线检测:用于检测屏幕空间中的射线,确定用户点击了哪个UI元素。UI交互:处理......
  • 在unity中被攻击时无敌的设置
    publicclassInvincible:MonoBehaviour {publicSpriteRendererrender; publicColornormalColor; publicColorflashColor; publicintduration; publicboolisInvincible;publicIEnumeratorSetInvincibility(){  isInvincible=true;  for......
  • Unity入门之重要组件和API(4) : Input
    前言Input类主要处理用户输入设备相关操作;输入设备包括鼠标、键盘、触屏、手柄、陀螺仪(重力感应)。1.鼠标1.1鼠标在屏幕的位置print(Input.mousePosition);1.2检测鼠标输入0-左键1-右键2-中键if(Input.GetMouseButtonDown(0)){ print("鼠标按下");}if(Input......
  • Unity实现安卓App预览图片、Pdf文件和视频的一种解决方案
    一、问题背景最近在开发app项目,其中有个需求就是需要在app软件内显示图片、pdf和视频,一开始想的解决方案是分开实现,也就是用Image组件显示图片,找一个加载pdf的插件和播放视频的插件,转念一想觉得太麻烦了,于是就想着看能不能想电脑浏览器打开图片、pdf和视频一样直接加载显示......