• Unity3d 用NGUI制作做新手引导的思路


    一、先看下效果

    Prefab结构

    二、实现思路:

    1、prefab上的Panel层级设置成较高

    2、背景由5个UISprite拼接起来的,4个(L,R,U,D)当作遮罩,1个镂空(Hollow)当作点击触发(全部都有BoxCollider,并且都生效,有人会问这不就把后面的按钮也给拦截住了,后面会说为什么要这样)

    3、4个遮罩的大小由Holow大小决定

    4、Hollow绑定一个点击事件ClickCenter  (后面代码里有)

    三、关键部分:

    这里解释为什么上面要把Hollow也带上BoxCollider,目的是修正点击位置,只要是点Hollow上,就让NGUI只相应点击在Hollow中心点后面的第一个UIWidget,这样就可以避免因为点不准,拖拽的其他问题

    如图,只要我点在篮筐里,就只响应红点下面的第一个控件

    四、代码

    其实就是NGUI的点击响应代码,位置传入的是Hollow的位置

    using System;
    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    
    
    public class NewbieGuide : MonoBehaviour
    {
    
        public Transform Hollow;
    
    
    
        bool IsVisible(Vector3 worldPoint, GameObject go)
        {
            UIPanel panel = NGUITools.FindInParents<UIPanel>(go);
    
            while (panel != null)
            {
                if (!panel.IsVisible(worldPoint)) return false;
                panel = panel.parentPanel;
            }
            return true;
        }
    
        struct DepthEntry
        {
            public int depth;
            public RaycastHit hit;
            public Vector3 point;
            public GameObject go;
        }
    
    #if UNITY_FLASH
        static bool IsVisible (DepthEntry de)
    #else
        static bool IsVisible(ref DepthEntry de)
    #endif
        {
            UIPanel panel = NGUITools.FindInParents<UIPanel>(de.go);
    
            while (panel != null)
            {
                if (!panel.IsVisible(de.point)) return false;
                panel = panel.parentPanel;
            }
            return true;
        }
    
        void Notify(GameObject go, string funcName, object obj)
        {
            if (NGUITools.GetActive(go))
            {
                go.SendMessage(funcName, obj, SendMessageOptions.DontRequireReceiver);
            }
        }
    
        public void ClickCenter()
        {
            DepthEntry mHit = new DepthEntry();
            BetterList<DepthEntry> mHits = new BetterList<DepthEntry>();
    
            UICamera cam = UICamera.current;
    
            UIEventTrigger.current = null;
    
            // Convert to view space
            var currentCamera = cam.cachedCamera;
    
            // Cast a ray into the screen
            var p = Hollow.transform.position;
            p.z = currentCamera.nearClipPlane;
            Ray ray = new Ray(p, Vector3.forward);
    
            // Raycast into the screen
            int mask = currentCamera.cullingMask & (int)cam.eventReceiverMask;
            float dist = (cam.rangeDistance > 0f) ? cam.rangeDistance : currentCamera.farClipPlane - currentCamera.nearClipPlane;
    
            RaycastHit[] hits = Physics.RaycastAll(ray, dist, mask);
    
            if (hits.Length > 1)
            {
                for (int b = 0; b < hits.Length; ++b)
                {
                    GameObject go = hits[b].collider.gameObject;
    
                    if (go == Hollow.gameObject)
                        continue;
    
                    UIWidget w = go.GetComponent<UIWidget>();
    
                    if (w != null)
                    {
                        if (!w.isVisible) continue;
                        if (w.hitCheck != null && !w.hitCheck(hits[b].point)) continue;
                    }
                    else
                    {
                        UIRect rect = NGUITools.FindInParents<UIRect>(go);
                        if (rect != null && rect.finalAlpha < 0.001f) continue;
                    }
    
                    mHit.depth = NGUITools.CalculateRaycastDepth(go);
    
                    if (mHit.depth != int.MaxValue)
                    {
                        mHit.hit = hits[b];
                        mHit.point = hits[b].point;
                        mHit.go = hits[b].collider.gameObject;
                        mHits.Add(mHit);
                    }
                }
    
                mHits.Sort(delegate(DepthEntry r1, DepthEntry r2) { return r2.depth.CompareTo(r1.depth); });
    
                for (int b = 0; b < mHits.size; ++b)
                {
    #if UNITY_FLASH
                            if (IsVisible(mHits.buffer[b]))
    #else
                    if (IsVisible(ref mHits.buffer[b]))
    #endif
                    {
                        Notify(mHits.buffer[b].go, "OnClick", null);
                        return;
                    }
                }
                mHits.Clear();
            }
            else if (hits.Length == 1)
            {
                GameObject go = hits[0].collider.gameObject;
    
                if (go == Hollow.gameObject)
                    return;
    
                UIWidget w = go.GetComponent<UIWidget>();
    
                if (w != null)
                {
                    if (!w.isVisible) return;
                    if (w.hitCheck != null && !w.hitCheck(hits[0].point)) return;
                }
                else
                {
                    UIRect rect = NGUITools.FindInParents<UIRect>(go);
                    if (rect != null && rect.finalAlpha < 0.001f) return;
                }
    
                if (IsVisible(hits[0].point, hits[0].collider.gameObject))
                {
                    Notify(hits[0].collider.gameObject, "OnClick", null);
                    return;
                }
            }
    
        }
    
    }
  • 相关阅读:
    HDU2059(龟兔赛跑)
    pat 1012 The Best Rank
    pat 1010 Radix
    pat 1007 Maximum Subsequence Sum
    pat 1005 Sign In and Sign Out
    pat 1005 Spell It Right
    pat 1004 Counting Leaves
    1003 Emergency
    第7章 输入/输出系统
    第六章 总线
  • 原文地址:https://www.cnblogs.com/mrblue/p/5405172.html
Copyright © 2020-2023  润新知