<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      luoyikun

      導航

      Unity3d+Newbie guide引導:讀CSV表驅(qū)動,屏蔽不可點擊區(qū)域,UI鏤空矩形區(qū)域Shader

      主要功能

      1. 表驅(qū)動,引導到哪步查找ui面板下路徑
      2. 屏蔽不可點擊區(qū)域,點擊屏蔽,UImask鏤空
      3. 具有點擊該按鈕驅(qū)動下一步,或者點擊新手引導的下一步驅(qū)動

      數(shù)據(jù)結(jié)構(gòu)

      //新手引導UI箭頭出現(xiàn)的方向
      public enum EnGuideDir
      {
          up = 0,
          down = 1,
          left = 2,
          right = 3  
      }
      
      //出現(xiàn)引導如何跳轉(zhuǎn)下一步
      public enum EnGuideClick
      {
          NoClickCloseSelf = 0, //點擊空白處關閉當前ui面板
          Click = 1, //點擊要引導的按個按鈕
          NoClickNoClose = 2, //點擊空白處,只關閉引導mask,不關閉UI面板
          ClickNeedNext = 3, // 可以點擊但是要通過點擊 "下一步"按鈕  驅(qū)動 ,針對輸入框
      }
      
      [System.Serializable]
      public class NewGuideItem
      {
          public string panelName; //面板的名字
          public string imgPath; //目標的路徑
          public string text;//提示的字
          public EnGuideClick isCanClick = EnGuideClick.Click; // 目標按鈕可點擊 1:可點  0:不可點,并關閉自己   2:不可點,不關閉自己
          public int isTextShowDir = -1; // 文本顯示按鈕的位置 -1 為下, 1為上   ,  2   
          public int belongCanvas = 0; // 屬于哪個ui canvas下   0:screen  1:top
          public string bgPath; //  背景路徑,新手引導的收縮至此,即這個區(qū)域是可點擊區(qū)域,其他區(qū)域半透明黑色,屏蔽點擊
          public int isAutoNext = 1; // 是否自動開始下步引導   0:不自動  1:自動
          public string param = ""; // 傳入?yún)?shù)
      }
      

      策劃用數(shù)據(jù)表
      在這里插入圖片描述

      設置引導到第幾步,開啟引導遮罩

      /// <summary>
          /// 查找當前界面 是否 是當前的新手引導的第n步,如果找到了,執(zhí)行引導遮罩
          /// </summary>
          /// <param name="delay"></param>
          /// <returns></returns>
          IEnumerator YieldDoNextNewGuide(int delay)
          {
              yield return delay;
              //DoNextNewGuide();
      
              NewGuideItem item = m_listGuide[m_curIdx];
              Transform transCanvas = null;
              if (item.belongCanvas == 0)
              {
                  transCanvas = m_canvasScreen;
                  Debug.Log("transCanvas:" + transCanvas.name);
              }
              else if (item.belongCanvas == 1)
              {
                  transCanvas = m_canvasTop;
                  Debug.Log("transCanvas:" + transCanvas.name);
              }
              Transform trans = null;
      
              while (trans == null)
              {
                  //Debug.Log("接著找");
                  yield return new WaitForSeconds(1);
                  try
                  {
                      Debug.Log("新手引導查找:" + item.panelName + "/" + item.imgPath);
                      trans = transCanvas.Find(item.panelName + "/" + item.imgPath);
                  }
                  catch
                  {
                      Debug.Log("新手引導找不到:" + item.panelName + "/" + item.imgPath);
                  }
              }
      
              UGUIPanel panel = transCanvas.Find(item.panelName).GetComponent<UGUIPanel>();
      
              while (panel.m_isOpen == false)
              {
                  yield return null;
              }
              trans.gameObject.AddComponent<DontDrag>(); //如果引導在滾動層上,加屏蔽滾動
      
              //目標本身可點,擊且點擊后能驅(qū)動到下一步引導,m_curIdx+1,并接著引導
              if (item.isCanClick == EnGuideClick.Click && item.isAutoNext == 1)
              {
                  while (trans.gameObject.GetComponent<ClickListener>() == null)
                  {
                      yield return null;
                  }
                  trans.gameObject.GetComponent<ClickListener>().onNewGuideClick = (obj) =>
                  {
                      StartOneNewGuide(); 
                      trans.gameObject.GetComponent<ClickListener>().onNewGuideClick = null;
                  };
              }
      
              //目標本身可點擊,點擊后不能驅(qū)動下一步,新手引導暫停
              if (item.isCanClick == EnGuideClick.Click && item.isAutoNext == 0)
              {
                  while (trans.gameObject.GetComponent<ClickListener>() == null)
                  {
                      yield return null;
                  }
                  trans.gameObject.GetComponent<ClickListener>().onNewGuideClick = (obj) =>
                  {
                      newguidepanel.Instance.PauseGuide();
                      trans.gameObject.GetComponent<ClickListener>().onNewGuideClick = null;
                  };
              }
      
              m_lastTarget = trans;
              Image img = trans.GetComponent<Image>();
              Transform transBg = transCanvas.Find(item.panelName + "/" + item.bgPath);
              Image imgBg = transBg.GetComponent<Image>();
              newguidepanel.Instance.Open(img,imgBg,item);
              
              ReqUpdateOtherDataMessage req = new ReqUpdateOtherDataMessage();
              req.fieldName = "newStep";
              req.value = m_curIdx.ToString();
              HallSocket.Instance.SendMsgProto(MsgIdDefine.ReqUpdateOtherDataMessage, req);
              m_curIdx++;
      
          }
      
      1. 協(xié)程中一直查找當前步驟要引導的界面,目標(界面上的按鈕或者圖,用UImask 包裹的區(qū)域,能驅(qū)動下一步)
      2. 目標本身可點,擊且點擊后能驅(qū)動到下一步引導,m_curIdx+1,并接著引導
      3. 目標本身可點擊,點擊后不能驅(qū)動下一步,新手引導暫停
      4. 如果引導目標是在滾動層上,需要加上禁止?jié)L動腳本,防止?jié)L沒了目標

      設置遮罩

      遮罩繼承ICanvasRaycastFilter
      該元素可以過濾射線投射。如果頂級元素被命中,它還能進一步“檢查”該位置是否有效。

      1. 傳入shader的參數(shù):目標的中心點
      2. 傳入shader的參數(shù):目標的離中心點最大長度的一半
      3. 傳入shader的參數(shù):目標的離中心點最大高度的一半
      void SetNewTargetImage()
          {
              //獲取畫布
              //Canvas m_canvas = GameObject.Find("Canvas").GetComponent<Canvas>();
              //Canvas m_canvas = GameObject.Find("Canvas").GetComponent<Canvas>();
              //獲取高亮區(qū)域四個頂點的世界坐標
              
              m_bgTarget.rectTransform.GetWorldCorners(_corners);
              //計算高亮顯示區(qū)域咋畫布中的范圍
              _targetOffsetX = Vector2.Distance(WorldToCanvasPos(m_canvas, _corners[0]), WorldToCanvasPos(m_canvas, _corners[3])) / 2f;
              _targetOffsetY = Vector2.Distance(WorldToCanvasPos(m_canvas, _corners[0]), WorldToCanvasPos(m_canvas, _corners[1])) / 2f;
              //計算高亮顯示區(qū)域的中心
              float x = _corners[0].x + ((_corners[3].x - _corners[0].x) / 2f);
              float y = _corners[0].y + ((_corners[1].y - _corners[0].y) / 2f);
              Vector3 centerWorld = new Vector3(x, y, 0);
              Vector2 center = WorldToCanvasPos(m_canvas, centerWorld);
              //設置遮罩材料中中心變量
              Vector4 centerMat = new Vector4(center.x, center.y, 0, 0);
              _material = GetComponent<Image>().material;
              _material.SetVector("_Center", centerMat); //傳入要鏤空矩形的中心點
              //計算當前偏移的初始值
              RectTransform canvasRectTransform = (m_canvas.transform as RectTransform);
              if (canvasRectTransform != null)
              {
                  //獲取畫布區(qū)域的四個頂點
                  canvasRectTransform.GetWorldCorners(_corners);
                  //它從左下開始,到左上, 然后到右上,最后到右下-->左下角開始逆時針旋轉(zhuǎn)
                  //求偏移初始值
                  for (int i = 0; i < _corners.Length; i++)
                  {
                      if (i % 2 == 0)
                          _currentOffsetX = Mathf.Max(Vector3.Distance(WorldToCanvasPos(m_canvas, _corners[i]), center), _currentOffsetX);
                      else
                          _currentOffsetY = Mathf.Max(Vector3.Distance(WorldToCanvasPos(m_canvas, _corners[i]), center), _currentOffsetY);
                  }
              }
              //設置遮罩材質(zhì)中當前偏移的變量
              _material.SetFloat("_SliderX", _currentOffsetX);//設置離中心點最大的x距離
              _material.SetFloat("_SliderY", _currentOffsetY);//設置離中心點最大的y距離
              m_isSetOk = true;
          }
      

      遮罩裁剪shader

      // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
      
      Shader "UI/BeginnerGuidance/Rect"
      {
          Properties
          {
              [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
              _Color ("Tint", Color) = (1,1,1,1)
      
              _StencilComp ("Stencil Comparison", Float) = 8
              _Stencil ("Stencil ID", Float) = 0
              _StencilOp ("Stencil Operation", Float) = 0
              _StencilWriteMask ("Stencil Write Mask", Float) = 255
              _StencilReadMask ("Stencil Read Mask", Float) = 255
      
              _ColorMask ("Color Mask", Float) = 15
      
              [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
              
              _Center("Center",vector) = (0,0,0,0)
              _SliderX("SliderX",Range(0,1500)) = 1500
              _SliderY("SliderY",Range(0,1500)) = 1500
          }
      
          SubShader
          {
              Tags
              {
                  "Queue"="Transparent"
                  "IgnoreProjector"="True"
                  "RenderType"="Transparent"
                  "PreviewType"="Plane"
                  "CanUseSpriteAtlas"="True"
              }
      
              Stencil
              {
                  Ref [_Stencil]
                  Comp [_StencilComp]
                  Pass [_StencilOp]
                  ReadMask [_StencilReadMask]
                  WriteMask [_StencilWriteMask]
              }
      
              Cull Off
              Lighting Off
              ZWrite Off
              ZTest [unity_GUIZTestMode]
              Blend SrcAlpha OneMinusSrcAlpha
              ColorMask [_ColorMask]
      
              Pass
              {
                  Name "Default"
              CGPROGRAM
                  #pragma vertex vert
                  #pragma fragment frag
                  #pragma target 2.0
      
                  #include "UnityCG.cginc"
                  #include "UnityUI.cginc"
      
                  #pragma multi_compile __ UNITY_UI_CLIP_RECT
                  #pragma multi_compile __ UNITY_UI_ALPHACLIP
      
                  struct appdata_t
                  {
                      float4 vertex   : POSITION;
                      float4 color    : COLOR;
                      float2 texcoord : TEXCOORD0;
                      UNITY_VERTEX_INPUT_INSTANCE_ID
                  };
      
                  struct v2f
                  {
                      float4 vertex   : SV_POSITION;
                      fixed4 color    : COLOR;
                      float2 texcoord  : TEXCOORD0;
                      float4 worldPosition : TEXCOORD1;
                      UNITY_VERTEX_OUTPUT_STEREO
                  };
      
                  fixed4 _Color;
                  fixed4 _TextureSampleAdd;
                  float4 _ClipRect;
                  
                  float2 _Center;
                  float _SliderX;
                  float _SliderY;
      
                  v2f vert(appdata_t v)
                  {
                      v2f OUT;
                      UNITY_SETUP_INSTANCE_ID(v);
                      UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
                      OUT.worldPosition = v.vertex;
                      OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
      
                      OUT.texcoord = v.texcoord;
      
                      OUT.color = v.color * _Color;
                      return OUT;
                  }
      
                  sampler2D _MainTex;
      
                  fixed4 frag(v2f IN) : SV_Target
                  {
                      half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
      
                      #ifdef UNITY_UI_CLIP_RECT
                      color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
                      #endif
      
                      #ifdef UNITY_UI_ALPHACLIP
                      clip (color.a - 0.001);
                      #endif
      
                      float2 dis = IN.worldPosition.xy - _Center.xy;
                      color.a *= (abs(dis.x) > _SliderX) || (abs(dis.y) > _SliderY);
                      color.rgb *= color.a;
      
                      return color;
                  }
              ENDCG
              }
          }
      }
      

      float2 dis = IN.worldPosition.xy - _Center.xy;
      color.a *= (abs(dis.x) > _SliderX) || (abs(dis.y) > _SliderY);
      以中心點_Center.xy,最大_SliderX的寬度,和最大_SliderY高度內(nèi),color.a = 0,達到鏤空效果

      源碼

      https://github.com/luoyikun/VirtualCity
      TestNewGuide場景
      NewGuideDemo.m_isNewGuideDemo這個參數(shù)要為true(單獨測試用引動用)

      demo演示

      請?zhí)砑訄D片描述

      posted on 2023-07-21 08:32  luoyikun  閱讀(85)  評論(0)    收藏  舉報  來源

      主站蜘蛛池模板: 性欧美乱熟妇xxxx白浆| 兰溪市| 国产精品国产精品偷麻豆| 激情五月天一区二区三区| 久久人妻无码一区二区三区av| 亚洲色最新高清AV网站| 高清一区二区三区不卡视频| 精品国产AV无码一区二区三区| 亚洲av日韩av一区久久| 日本一区二区三区黄色网| 熟女一区二区中文在线| 激情综合五月| 久热这里有精彩视频免费| 精品久久久噜噜噜久久久| 国产精品亚洲专区无码导航| 激情国产一区二区三区四区小说 | 国产AV巨作丝袜秘书| 午夜毛片精彩毛片| 亚洲国产精品线观看不卡| 91久久性奴调教国产免费| 狠狠躁日日躁夜夜躁欧美老妇| 亚洲欧美日韩国产手机在线| 激情综合网激情五月我去也| av中文字幕国产精品| 少妇精品视频一码二码三| 无码精品国产va在线观看dvd| 中文字幕无码不卡免费视频| 国产欧美一区二区精品久久久| 国产91精品调教在线播放| 亚洲 卡通 欧美 制服 中文| 四虎成人在线观看免费| 亚洲AV乱码毛片在线播放| 大胸美女吃奶爽死视频| 成人午夜免费无码视频在线观看| 色综合视频一区二区三区| 搡老熟女老女人一区二区| 成人国产av精品免费网| 97成人碰碰久久人人超级碰oo| 人妻少妇偷人无码视频| 国产高跟黑色丝袜在线| 国产午夜精品亚洲精品国产|