首页 > 其他分享 >Unity如何从0实现技能CD遮罩

Unity如何从0实现技能CD遮罩

时间:2024-02-22 22:55:05浏览次数:33  
标签:遮罩 Vector2 Add CD Unity new var uvRect rectCorners

需求描述


我们需要实现一个类似英雄联盟中的技能CD遮罩,施放技能后,技能遮罩占满技能图标,随着时间推移,技能遮罩顺时针减少遮挡面积,CD结束时,遮罩应完全消失。

需求分析

由于每个时刻,都会有一条线从中心点射向上面那条边的中点,我们自然可以想到将遮罩面片分为8个三角形。

并且我们只需要按照给定的角度angle,发出射线相交于长方形,获得起点,然后从起点开始顺时针遍历长方形边上的点,直到长方形上面那条边的中点。

代码


  private UIMeshInfo GetMeshInfoFilled_Radial360()
  {
      var uvRect = NGUIMath.ConvertToTexCoords(SpriteData.Rect, atlasTexture.width, atlasTexture.height);

      var rectCorners = RenderTargetLocalCorners;
      var meshInfo = new UIMeshInfo();

      var vertexBeforeCutList = new List<Vector3>
      {
          (rectCorners.TopLeft + rectCorners.TopRight) / 2, //↑
          rectCorners.TopRight, // ↗
          (rectCorners.TopRight + rectCorners.BottomRight) / 2, //→
          rectCorners.BottomRight, //↘
          (rectCorners.BottomLeft + rectCorners.BottomRight) / 2, //↓
          rectCorners.BottomLeft, //↙
          (rectCorners.BottomLeft + rectCorners.TopLeft) / 2, //←
          rectCorners.TopLeft, //↖
      };

      var uvBeforeCutList = new List<Vector2>
      {
          new Vector2(uvRect.center.x, uvRect.yMax),  //↑
          new Vector2(uvRect.xMax, uvRect.yMax), // ↗
          new Vector2(uvRect.xMax, uvRect.center.y), //→
          new Vector2(uvRect.xMax, uvRect.yMin), //↘
          new Vector2(uvRect.center.x, uvRect.yMin), //↓
          new Vector2(uvRect.xMin, uvRect.yMin), //↙
          new Vector2(uvRect.xMin, uvRect.center.y), //←
          new Vector2(uvRect.xMin, uvRect.yMax), //↖

      };


      fillAmount = Mathf.Clamp01(fillAmount);
      var angle = fillAmount * 360;
      var indexFromEnd = Mathf.CeilToInt(angle/45);

      var vertexAfterCutList = new List<Vector3>();
      var uvAfterCutList = new List<Vector2>();
      var colorList = new List<Color>();
      vertexAfterCutList.Add(rectCorners.Center);
      uvAfterCutList.Add(uvRect.center);
      colorList.Add(color);

      var indexList = new List<int>();
      int currentIndex = 0;


      for(int i = vertexBeforeCutList.Count-indexFromEnd; i < vertexBeforeCutList.Count; i++)
      {

          var vertex = vertexBeforeCutList[i];
          var uv = uvBeforeCutList[i];

          //TODO 还需要调整uv
          if (i == vertexBeforeCutList.Count-indexFromEnd)
          {
              vertex = GetPointOnRect(rectCorners.Center, angle, rectCorners.Size / 2);
          }

          vertexAfterCutList.Add(vertex);
          uvAfterCutList.Add(uv);
          colorList.Add(color);
          currentIndex++;
          indexList.Add(0);
          indexList.Add(currentIndex);
          indexList.Add(currentIndex+1);
      }

      vertexAfterCutList.Add(vertexBeforeCutList[0]);
      uvAfterCutList.Add(uvBeforeCutList[0]);
      colorList.Add(color);

      meshInfo.uvList = uvAfterCutList;
      meshInfo.vertexList = vertexAfterCutList;

      for(int i = 0; i < vertexAfterCutList.Count; i++)
      {
          vertexAfterCutList[i] = transform.TransformPoint(vertexAfterCutList[i]);
      }
      meshInfo.colorList = colorList;

      meshInfo.indexList = indexList;


      return meshInfo;
  }

  private Vector2 GetPointOnRect(Vector2 center,float angle, Vector2 halfSize)
  {
      var radian = angle * Mathf.Deg2Rad;


      //https://python.tutorialink.com/finding-points-on-a-rectangle-at-a-given-angle/
      //TODO 这里角度需要通过 长方形的 长和宽 arctan来算的
      if (315 <=angle || angle <= 45)
      {
          return new Vector2(center.x - halfSize.y * Mathf.Tan(radian), center.y + halfSize.y);
      }
      else if(135<=angle && angle<=225)
      {
          return new Vector2(center.x + halfSize.y * Mathf.Tan(radian), center.y - halfSize.y);
      }
      else if(45<=angle && angle <= 135)
      {
          return new Vector2(center.x - halfSize.x, center.y + halfSize.x / Mathf.Tan(radian));
      }
      else if(225<=angle && angle <= 315)
      {
          return new Vector2(center.x + halfSize.x, center.y - halfSize.x / Mathf.Tan(radian));
      }

      return default;

  }

效果展示

标签:遮罩,Vector2,Add,CD,Unity,new,var,uvRect,rectCorners
From: https://www.cnblogs.com/dewxin/p/18028244

相关文章

  • Unity编辑器扩展秘籍-反射解决ParticleSystemEditor的扩展显示错误的问题
    如果使用常规的扩展编辑器方法,为ParticleSystem增加一个自定义按钮[CustomEditor(typeof(ParticleSystem))]publicclassMyParticleSystemEditor:UnityEditor.Editor{privateList<Material>_mats=newList<Material>();publicoverridevoi......
  • Unity引擎2D游戏开发,场景管理和切换
    需要用到的工具资源打包、远程热更新工具Addressables工具基本操作在Window菜单下方,会有AssetManagement,选择Addressables中的Groups会弹出相关菜单,将其拖入底部工具栏会提示没有创建Addressables的相关配置,则点击CreateAddressablesSettings这时候会在Project中,多出......
  • CDN优化
    1.传统上传到应用2.通过应用下载,并发大所有流量都打到引用和出口带宽限制 采用cdn,大概是下面这个图这个流程,我们只需要配置cdn域名指向我们应用地址下载针对防止恶意下载可以使用cdn鉴权大概流程是这样鉴权逻辑说明CDN服务器接到资源访问请求后,判断最终生成鉴权URL请求......
  • 超省电LCD液晶段码驱动芯片VKL144A/B 超薄封装 适用于燃气表,瓦斯表等产品
    由于煤气罐的使用安全隐患较大,现在大部分城市使用管道输送燃气,燃气表的计费大都是通过远程抄表的方式,或者充值的方式,为了让用户更好地了解自家燃气表的使用情况,需要一款液晶屏来显示燃气表的状态和用气量等信息,而燃气表通常选用超低功耗的芯片来进行显示驱动。超低功耗的芯片,由于......
  • Unity引擎2D游戏开发,场景互动的逻辑实现
    创建接口由于所有可互动的物体都会有一个共通的属性,即“互动”的处理。因此,新建一个接口,让所有可互动的物体都实现这个接口内的互动处理方法新建接口创建一个处理互动逻辑的抽象方法publicinterfaceIInteractable{voidTriggerAction();}创建处理宝箱交互逻辑的脚......
  • Unity中关于刚体和碰撞器遇到的告警
    告警信息:Scripterror:OnCollisionEnter2DThismessageparameterhastobeoftype:Collision2DThemessagewillbeignored.  解决:经查验发现,由于该脚本是粘贴的类似功能脚本,而粘贴前使用的触发器,因此方法为 privatevoidOnTriggerStay2D(Collider2Dcollision),而......
  • Unity引擎2D游戏开发,切换场景与人物可互动标识总结
    切换场景可以通过新建一个持久化地场景,将所有常驻元素放置进此场景里面,然后再将进入的场景加载(Loud)在Hierarchy窗口中。如果切换了其他某一个场景,再将离开的场景停用(Unload),进入的场景加载(Loud),即可实现。创建持久化场景,移入Hierarchy将所有永恒不变,常驻的元素移入此创建的持久......
  • Unity中的SerializeReference使用简介
    Unity默认可以序列化值类型,Serializable属性修饰的类型,派生自UnityEngine.Object的类型,通常这些类型已经足以供日常使用了.但是有时我们希望在编辑器面板上序列化一个接口或者抽象类,则需要用到SerializeReference属性.假定我们有一个接口IEatable,并实现了两个类Brea......
  • Unity基于AssetBundle资源管理流程详解
    在Unity游戏开发中,资源管理是一个非常重要的环节。随着游戏的发展,资源会变得越来越庞大,因此需要一种高效的资源管理方式来减少内存占用和加快加载速度。AssetBundle是Unity提供的一种资源打包和加载方式,可以将资源打包成一个独立的文件,然后在运行时进行加载和卸载。本文将详细介绍......
  • Unity MVC开发模式与开发流程详解
    在Unity游戏开发中,采用MVC(Model-View-Controller)模式是一种非常常见的设计模式。MVC模式将应用程序分为三个部分:模型(Model)、视图(View)和控制器(Controller)。这种模式可以有效地分离应用程序的逻辑和用户界面,使得代码更易于维护和扩展。本文将详细介绍Unity中的MVC开发模式及其开发流......