- 本文固定链接: http://www.xuanyusong.com/archives/4408
- 转载自: 雨松MOMO 2017年06月08日 于 雨松MOMO程序研究院
新手引导最好和业务逻辑拆开,也就是做新手引导的程序员不能去影响到下面做系统的人。
1.开发一个新手引导编辑器,让策划配出每个引导的点击区域。
2.在Shader中扣一个洞。(圆形或者矩形)用来做显示的点击区域。
3.新手引导的进度需要与服务器进行同步,为了不影响到下面的业务逻辑,在最顶层将UI事件拦截后,渗透点击事件并且与服务器同步进度。渗透事件可以参考我之前的文章,Unity3D研究院之将UI的点击事件渗透下去(九十)
http://www.xuanyusong.com/archives/4241Drag摇杆的事件,需要把Begin Draging End都要渗透下去。按钮、列表中的Cell元素的点击事件需要特殊注意一下,因为要点击在Cell上,而不是最前面的UI上。
4.新手引导的出现条件,大部分都是打开某个UI并且拥有控制焦点,可能还有 等级/接任务/交任务/进场景 。可以将这些关键点作为事件抛出,在新手引导模块中处理即可。
5.强制引导需要注意,很有可能把玩家卡死。比如引导玩家进副本,请求进副本的消息,和请求新手引导进度的消息是两个不同的,那么就有一定概率出现一个发送成功,另一个发送不成功,如果此时又触发掉线,重进游戏估计就肯定就卡死了。 所以保险起见强制引导最好也可以让玩家跳过。(比如点击空白区域超过5次)
6.最后在分享一个UI的效果,周围是灰色蒙版,然后四周向点击区域聚合的动画。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576using System . Collections ;using System . Collections . Generic ;using UnityEngine ;using UnityEngine . UI ;/// <summary>/// 新手引导动画/// </summary>public class Guide : MonoBehaviour {public Image target ;private Vector4 center ;private Material material ;private float diameter ; // 直径private float current = 0f ;Vector3 [ ] corners = new Vector3 [ 4 ] ;void Awake ( ){Canvas canvas = GameObject . Find ( "Canvas" ) . GetComponent < Canvas > ( ) ;target . rectTransform . GetWorldCorners ( corners ) ;diameter = Vector2 . Distance ( WordToCanvasPos ( canvas , corners [ 0 ] ) , WordToCanvasPos ( canvas , corners [ 2 ] ) ) / 2f ;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 center = new Vector3 ( x , y , 0f ) ;Vector2 position = Vector2 . zero ;RectTransformUtility . ScreenPointToLocalPointInRectangle ( canvas . transform as RectTransform , center , canvas . GetComponent < Camera > ( ) , out position ) ;center = new Vector4 ( position . x , position . y , 0f , 0f ) ;material = GetComponent < Image > ( ) . material ;material . SetVector ( "_Center" , center ) ;( canvas . transform as RectTransform ) . GetWorldCorners ( corners ) ;for ( int i = 0 ; i < corners . Length ; i ++ ) {current = Mathf . Max ( Vector3 . Distance ( WordToCanvasPos ( canvas , corners [ i ] ) , center ) , current ) ;}material . SetFloat ( "_Silder" , current ) ;}float yVelocity = 0f ;void Update ( ) {float value = Mathf . SmoothDamp ( current , diameter , ref yVelocity , 0.3f ) ;if ( ! Mathf . Approximately ( value , current ) ) {current = value ;material . SetFloat ( "_Silder" , current ) ;}}void OnGUI ( ) {if ( GUILayout . Button ( "Test" ) ) {Awake ( ) ;}}Vector2 WordToCanvasPos ( Canvas canvas , Vector3 world ) {Vector2 position = Vector2 . zero ;RectTransformUtility . ScreenPointToLocalPointInRectangle ( canvas . transform as RectTransform , world , canvas . GetComponent < Camera > ( ) , out position ) ;return position ;}}shader是在UI-Default的基础上改了,原理就是扣一个洞,修改每个点的颜色。 –add–是修改的代码。如果unity版本升级shader变化,把–add–中的代码加上即可。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126Shader "UI/Default_Mask"{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//-------------------add----------------------_Center ( "Center" , vector ) = ( 0 , 0 , 0 , 0 )_Silder ( "_Silder" , Range ( 0 , 1000 ) ) = 1000 // sliders//-------------------add----------------------}SubShader{Tags{"Queue" = "Transparent""IgnoreProjector" = "True""RenderType" = "Transparent""PreviewType" = "Plane""CanUseSpriteAtlas" = "True"}Stencil{Ref [ _Stencil ]Comp [ _StencilComp ]Pass [ _StencilOp ]ReadMask [ _StencilReadMask ]WriteMask [ _StencilWriteMask ]}Cull OffLighting OffZWrite OffZTest [ unity_GUIZTestMode ]Blend SrcAlpha OneMinusSrcAlphaColorMask [ _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_ALPHACLIPstruct 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 ;//-------------------add----------------------float _Silder ;float2 _Center ;//-------------------add----------------------v2f vert ( appdata_t IN ){v2f OUT ;UNITY_SETUP_INSTANCE_ID ( IN ) ;UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO ( OUT ) ;OUT . worldPosition = IN . vertex ;OUT . vertex = UnityObjectToClipPos ( OUT . worldPosition ) ;OUT . texcoord = IN . texcoord ;OUT . color = IN . color * _Color ;return OUT ;}sampler2D _MainTex ;fixed4 frag ( v2f IN ) : SV_Target{half4 color = ( tex2D ( _MainTex , IN . texcoord ) + _TextureSampleAdd ) * IN . color ;color . a * = UnityGet2DClipping ( IN . worldPosition . xy , _ClipRect ) ;#ifdef UNITY_UI_ALPHACLIPclip ( color . a - 0.001 ) ;#endif//-------------------add----------------------color . a* = ( distance ( IN . worldPosition . xy , _Center . xy ) > _Silder ) ;color . rgb* = color . a ;//-------------------add----------------------return color ;}ENDCG}}}如下图所示,脚本挂在bg上,target就是点击区域的Image。
Play游戏就能看到动画效果。如下图所示,我们项目是有UI摄像机的,所以canvas和camera需要注意一下,有UI摄像机和没UI摄像机算区域是不同的。
OK ,这个方法我已经在项目中使用, 如果有什么想法或者建议欢迎在下面给我留言。
测试版本unity5.5.2
UGUI研究院之新手引导事件上下分离(转)
猜你喜欢
转载自blog.csdn.net/u014732824/article/details/79628569
今日推荐
周排行