zoukankan      html  css  js  c++  java
  • 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;
                }
            }
    
        }
    
    }
  • 相关阅读:
    使用Bat自动打包并通过FTP发送到备份服务器
    IIS 注意事项
    Windows 2008 R2 IP安全策略设置
    修改远程桌面端口
    mac osx 下的apt-get,yum的代替工具 ----homebrew
    mac终端命令大全介绍
    windows 服务器设置相关
    Mac OS 下使用EXE文件
    Mybaits的运行原
    No constructor found in com.website.entity.News matching
  • 原文地址:https://www.cnblogs.com/mrblue/p/5405172.html
Copyright © 2011-2022 走看看