AR開發(fā)實戰(zhàn)Vuforia項目之太陽系八大行星(實現(xiàn)涂涂樂功能)

一蔫耽、框架視圖

二刻蚯、主要代碼

Shader "Color/Special" (傳說會寫shader是大神)

Shader "Color/Special" {
//Shader的路徑和名稱
    Properties {
    //材質(zhì)屬性面板中所顯示的Shader屬性面板
        _MainTex ("Base (RGB)", 2D) = "white" {}
        //"_MainTex"在Shader中調(diào)用時所使用的名稱
        //"Base (RGB)"在面板中顯示的名稱
        //"2D"2D紋理
        //"white"給這個屬性的默認(rèn)值

        //從C#中獲取截圖時 識別圖四個點(diǎn)世界坐標(biāo)
        _Uvpoint1("point1", Vector) = (0 , 0 , 0 , 0)
        //"_Uvpoint1"在Shader中調(diào)用時所使用的名稱
        //"point1"在面板中所顯示的名稱
        //Vector 四個浮點(diǎn)數(shù)組成的類型 
        //"0 , 0 , 0 , 0"附的初始值
        _Uvpoint2("point2", Vector) = (0 , 0 , 0 , 0)
        _Uvpoint3("point3", Vector) = (0 , 0 , 0 , 0)
        _Uvpoint4("point4", Vector) = (0 , 0 , 0 , 0)

    }

    //“ SubShader”著色器方案 在Shader中至少有一個SubShader 顯卡每次只選擇一個SubShader 如果當(dāng)前硬件不支持這個SubShader 就會選擇一個針對較舊的硬件的SubShader
    SubShader {
        Tags { "Queue"="Transparent" "RenderType"="Transparent" }
        //加入透明渲染處理享言,沒有這一段的話賦值透明貼圖時就會出現(xiàn)問題勘究。
        LOD 200
        //細(xì)致程度   Level of Details 也叫作 Level of Development
        //"200"是一個代號 限制Shader的級別到200為止

        Pass{
            Blend SrcAlpha OneMinusSrcAlpha
            //加入Alpha的混合渲染  不加的話Alpha值無用
            CGPROGRAM
            //CG開始的關(guān)鍵詞
            #pragma vertex vert
            //編譯指令 頂點(diǎn)程序
            #pragma fragment frag
            //編譯指令 片段程序
            #include "UnityCG.cginc"
            //"UnityCG.cginc" 是使用unity中帶的封裝好的cg代碼集合
            //有點(diǎn)類似于C#中命名空間的引用

            //C#中傳遞來的值的引用
            sampler2D _MainTex;
            float4 _MainTex_ST;
            float4 _Uvpoint1;
            float4 _Uvpoint2;
            float4 _Uvpoint3;
            float4 _Uvpoint4;
            float4x4 _VP;
            //C#在截取圖像時 世界坐標(biāo)到攝像機(jī)坐標(biāo)以及相機(jī)坐標(biāo)到屏幕坐標(biāo)的兩個矩陣值相乘

            //結(jié)構(gòu)體 
            struct v2f {
                float4  pos : SV_POSITION;
                float2  uv : TEXCOORD0;
                float4  fixedPos : TEXCOORD2;
            } ;

            //頂點(diǎn)程序和片段程序中用來計算UV的匹配和最護(hù)模型效果的渲染
            v2f vert (appdata_base v)
            {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
                
                float4 top = lerp(_Uvpoint1, _Uvpoint3, o.uv.x);
                float4 bottom = lerp(_Uvpoint2, _Uvpoint4, o.uv.x);
                float4 fixedPos = lerp(bottom, top, o.uv.y);
                o.fixedPos = ComputeScreenPos(mul(UNITY_MATRIX_VP, fixedPos));
                return o;
            }
            float4 frag (v2f i) : COLOR
            {
                
                float4 top = lerp(_Uvpoint1, _Uvpoint3, i.uv.x);
                float4 bottom = lerp(_Uvpoint2, _Uvpoint4, i.uv.x);
                float4 fixedPos = lerp(bottom, top, i.uv.y);
                fixedPos = ComputeScreenPos(mul(_VP, fixedPos));
                return tex2D(_MainTex, fixedPos.xy / fixedPos.w);
                
            }
            ENDCG
            //CG結(jié)束的關(guān)鍵詞
            //釋放內(nèi)存 
        }
    }
    //FallBack "Diffuse"
}

AudioPlay

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AudioPlay : MonoBehaviour {

    //定義一條射線的類型;
    private Ray ray;

    //定義一個射線碰撞信息的存貯刹衫;
    private RaycastHit hit;//類型: 射線檢測碰撞(信息存貯)

    //播放地球的聲音
    //private AudioSource mAudioSource;
    //public AudioSource earthAudioSource;
    //public AudioSource sunAudioSource;

    //將所有便簽放進(jìn)去
    public AudioSource[] mAudioSource;
    //貯存名稱醋寝;
    //string strName;

    //貯存便簽
    int intTag;

    //貯存太陽系的,太陽系消失带迟,所有配音不播放音羞;
   // public GameObject SolarSystem;
    void Start () {
        
    }
    

    void Update () {
        //執(zhí)行射線的方法;
        CameraSendRay();
        //判斷太陽系隱藏仓犬,所有聲音都停止嗅绰;
        //if (SolarSystem.activeInHierarchy==false)
        //{
        //    sunAudioSource.Stop();
        //    earthAudioSource.Stop();
        //}
    }
    //----------------------------------------------------------------
    /// <summary>
    ///執(zhí)行播放聲音的方法; 
    /// </summary>
    //void CameraSendRay() //第一種方法
    //{
    //    if (Input.GetMouseButtonDown(0)) //點(diǎn)擊屏幕
    //    {
    //        ray = Camera.main.ScreenPointToRay(Input.mousePosition); //射線的位置就是鼠標(biāo)點(diǎn)擊的位置
    //        if (Physics.Raycast(ray, out hit))  //獲取射線碰撞信息
    //        {
    //            strName = hit.transform.name;
    //            Debug.Log(strName);
    //            switch (strName) //分別播放不同聲音的信息
    //            {
    //                case "Earth_A":
    //                    if (sunAudioSource.isPlaying)
    //                    {
    //                        sunAudioSource.Stop();
    //                    }
    //                    earthAudioSource.Play();
    //                    break;
    //                case "Sun_Modle":
    //                    if (earthAudioSource.isPlaying)
    //                    {
    //                        earthAudioSource.Stop();
    //                    }
    //                    sunAudioSource.Play();
    //                    break;
    //                default:
    //                    break;
    //            }
    //        }
    //    }
    //}
    //----------------------------------------------------------------

    /// <summary>
    ///執(zhí)行播放聲音的方法搀继; 
    /// </summary>
    void CameraSendRay() //第二種方法
    {
        if (Input.GetMouseButtonDown(0)) //點(diǎn)擊屏幕
        {
            ray = Camera.main.ScreenPointToRay(Input.mousePosition); //射線的位置就是鼠標(biāo)點(diǎn)擊的位置
            if (Physics.Raycast(ray, out hit))  //獲取射線碰撞信息
            {
               intTag =int.Parse(hit.transform.tag);
                //Debug.Log(intTag);
                //mAudioSource[intTag].Play();
                for (int i = 0; i < mAudioSource.Length; i++)
                {
                    if (mAudioSource[i].isPlaying && i != intTag)
                    {
                        mAudioSource[i].Stop();
                    }
                    else
                    {
                        mAudioSource[intTag].Play();
                    }
                }
            }
        }
    }


    /// <summary>
    /// 停止所有播放音樂的方法 第一種方法
    /// </summary>
    //public void StopAudioPlay() {
    //    sunAudioSource.Stop();
    //    earthAudioSource.Stop();
    //}

    /// <summary>
    /// 停止所有播放音樂的方法 第二種方法
    /// </summary>
    public void StopAudioPlay()
    {
        for (int i = 0; i < mAudioSource.Length; i++)
        {
                mAudioSource[i].Stop();
        }
    }



}

EarthInSunA

using UnityEngine;
using System.Collections;

public class EarthInSunA : MonoBehaviour
{

    public GameObject Earth;
    //保存地球
    public GameObject SolarSystem;
    //保存太陽系

    //地球顯示的標(biāo)志位
    private bool isShow = false; 

    // Use this for initialization
    void Start()
    {
        //賦值給聲效
        //mAudioSource = gameObject.transform.GetComponent<AudioSource>();
    }

    // Update is called once per frame
    void Update()
    {
     
    }

    void OnMouseDown()
    {
        if (isShow)
        {
            //Earth.GetComponent<Renderer>().enabled = true;
            Earth.SetActive(true);
            //激活地球渲染組件
            Earth.GetComponent<ScreenShot>().EarthFrame.SetActive(true);
            //通過截圖腳本中地球儀配件的變量 來激活地球儀配件的顯示
            //Earth.GetComponent<EarthTouchA>().SetState = 0;
            Earth.GetComponent<EarthTouchA>().SetState = 0;
            //將點(diǎn)擊交互的狀態(tài)設(shè)置為0
            GameObject.Find("Sun").SendMessage("StopAudioPlay");
           // Debug.Log("有沒有發(fā)送方法------------------");
            SolarSystem.SetActive(false);
            //取消太陽系的顯示
        }
        isShow = !isShow;
    }

    
}


EarthTouchA

using UnityEngine;
using System.Collections;
using UnityEngine.UI; //引用命名空間

public class EarthTouchA : MonoBehaviour
{

    public GameObject EarthFrame;
    //儲存地球儀配件

    public GameObject SolarSystem;
    //儲存太陽系模塊

    public int SetState = 0;
    //申請Int型變量來儲存點(diǎn)擊的次數(shù)

    //public Image UIArea;
    //掃描框隱藏

    void Start()
    {

    }


    void Update()
    {
       // if (SetState==1||SetState==2)
        if (SetState == 1 || SetState == 2)
        {
            //當(dāng)?shù)谝淮吸c(diǎn)擊狀態(tài)或第二次點(diǎn)擊狀態(tài)時
            transform.Rotate(0, 25 * Time.deltaTime, 0, Space.Self);
            //讓地球沿著自身Y軸轉(zhuǎn)動
        }
    }

    //點(diǎn)擊函數(shù)
    void OnMouseDown()
    {
        //if(SetState==0)
        if (SetState == 0)
        {
           // SetState = 1;
            //設(shè)置為狀態(tài)1
            // gameObject.SetActive(true);
           // UIArea.enabled = false;

        }
        else if (SetState == 1)
            //else if(SetState==1)
        {
            //SetState = 2;
            //狀態(tài)設(shè)置為2
           // gameObject.SetActive(true);
            EarthFrame.SetActive(false);
            //取消地球儀配件

        }
        else if (SetState == 2)
            //else if(SetState==2)
        {
           // SetState = 3;
            //狀態(tài)設(shè)置為3
            //gameObject.GetComponent<Renderer>().enabled = false;
            gameObject.SetActive(false);
            //取消地球的顯示窘面,此處僅僅是渲染方式上不渲染,而不取消模型的激活狀態(tài)
            SolarSystem.SetActive(true);
            //顯示太陽系
        }
        //else if (SetState == 13)
        //{
        //    // SetState = 0;
        //    SetState = -1;
        //    //狀態(tài)設(shè)置為0
        //    // gameObject.GetComponent<Renderer>().enabled = true;
        //    gameObject.SetActive(true);
        //    //顯示地球
        //    EarthFrame.SetActive(true);
        //    //顯示地球儀配件
        //    SolarSystem.SetActive(false);
        //    //取消太陽系的顯示
        //}
        SetState++;
    }

    /// <summary>
    /// 通過發(fā)送方法調(diào)用次函數(shù)律歼,不過已經(jīng)禁用了民镜,沒成功
    /// </summary>
    public void ResetAgain() {
        SetState = 0;
        //狀態(tài)設(shè)置為0
        // gameObject.GetComponent<Renderer>().enabled = true;
        gameObject.SetActive(true);
        //顯示地球
        EarthFrame.SetActive(true);
        //顯示地球儀配件
        SolarSystem.SetActive(false);

    }


}


PageNotFound //脫卡

using UnityEngine;
using Vuforia;
public class PageNotFound : MonoBehaviour, ITrackableEventHandler
{
    //引用
    private TrackableBehaviour mTrackableBehaviour;
    public Transform Target;//識別物
    Vector3 imgPos = new Vector3(0, 0, 0);//識別圖上的位置
    Vector3 camPos = new Vector3(0, -3f, 100f);//脫卡后在屏幕中的位置
                                                //這倆值啡专,具體多少得自己調(diào)险毁,模型尺寸、重心不同

    bool isFirstTime = true; //第一查找

    public GameObject sun;
    //控制太陽大小
    void Start()
    {
        mTrackableBehaviour = GetComponent<TrackableBehaviour>();
        if (mTrackableBehaviour)
        {
            //重置
            mTrackableBehaviour.RegisterTrackableEventHandler(this);
        }
        // Target.GetComponent<MeshRenderer>().enabled = false;//起始時不顯示
        Target.gameObject.SetActive(false);

    }


    //接口實現(xiàn) 公開的
    public void OnTrackableStateChanged(
            TrackableBehaviour.Status previousStatus,
            TrackableBehaviour.Status newStatus)
    {
        if (newStatus == TrackableBehaviour.Status.DETECTED ||
                newStatus == TrackableBehaviour.Status.TRACKED ||
                newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
        {
            //視野內(nèi)發(fā)現(xiàn)識別圖時
            //Target.GetComponent<MeshRenderer>().enabled = true;
            Target.gameObject.SetActive(true);
            Target.parent = this.transform;
            Target.localPosition = imgPos;
            Target.localRotation = Quaternion.identity;
            //Target.localRotation = Quaternion.Euler(90, 0, 0);
            isFirstTime = false;
        }
        else
        {
            //視野內(nèi)沒有識別圖時,這里我是把位置和旋轉(zhuǎn)都?xì)w零了畔况,如果不做處理鲸鹦,可以
            if (!isFirstTime)
            {
                // Target.parent = Camera.main.transform;
                Target.parent = GameObject.FindGameObjectWithTag("MainCamera").transform;
                Target.localPosition = camPos;
                //Target.localRotation = Quaternion.identity;
                Target.localRotation = Quaternion.Euler(-30, 0, 0);
                //Debug.Log("3333333333333");

                //控制太陽大小
                sun.GetComponent<ParticleScaler>().particleScale = 1f;
            }
        }
    }
}

Sun_Rotate

using UnityEngine;
using System.Collections;

public class Sun_Rotate : MonoBehaviour {

    public float speed=8.0f;

    // Use this for initialization
    void Start () {
    
    }
    
    // Update is called once per frame
    void Update () {
        transform.Rotate(0,speed*Time.deltaTime,0,Space.Self );
    }
}

Area

//命名空間
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
//加入UI命名空間

public class Area : MonoBehaviour
{
    //"Area"類名 ,需要和外部腳本名稱保持一致
    public GameObject SuccessPlane_Image;
    //儲存識別成功圖片
    public GameObject Scan_Image;
    //將用于隱藏掃描框
    public GameObject Earth;
    //儲存地球模型
    public Material Green_Mate;
    //申請材質(zhì)變量儲存綠色的材質(zhì)
    public Material Red_Mate;
    //申請材質(zhì)變量儲存紅色材質(zhì)
    public Material Tran_Mate;
    //申請材質(zhì)變量儲存透明材質(zhì)

    private bool HasRe = false;
    //申請布爾變量來確定是否已經(jīng)識別
    private CanvasScaler CanS;
    //申請變臉儲存UI屏幕自適度的縮放組件

    private float X_Sc;
    //申請浮點(diǎn)型類型的變量儲存實際的縮放比例

    //記錄掃描框的范圍
    private Vector2 TopLeft_UI;
    //記錄掃描框左上角的坐標(biāo)
    //“private”申請類型為私有
    private Vector2 BottomLeft_UI;
    //記錄掃描框左下角的坐標(biāo)
    private Vector2 TopRight_UI;
    //記錄掃描框右上角的坐標(biāo)
    private Vector2 BottomRight_UI;
    //記錄掃描框右下角的坐標(biāo)

    //記錄面片的世界坐標(biāo)
    private Vector3 TopLeft_Pl_W;
    //記錄面片左上角的世界坐標(biāo)
    private Vector3 BottomLeft_Pl_W;
    //記錄面片左下角的世界坐標(biāo)
    private Vector3 TopRight_Pl_W;
    //記錄面片右上角的世界坐標(biāo)
    private Vector3 BottomRight_Pl_W;
    //記錄面片右下角的世界坐標(biāo)

    //記錄面片的屏幕坐標(biāo)
    private Vector2 TopLeft_Pl_Sc;
    //記錄面片左上角的屏幕坐標(biāo)
    private Vector2 BottomLeft_Pl_Sc;
    //記錄面片坐下角的屏幕坐標(biāo)
    private Vector2 TopRight_Pl_Sc;
    //記錄面片右上角的屏幕坐標(biāo)
    private Vector2 BottomRight_Pl_Sc;
    //記錄面片右下角的屏幕坐標(biāo)

    private Vector2 PlaneWH;
    //記錄面片的寬高


    //腳本剛開始運(yùn)行的時候調(diào)用一次
    void Start()
    {

        CanS = GameObject.Find("Canvas").gameObject.GetComponent<CanvasScaler>();
        //獲取控制屏幕自適度的組件

        X_Sc = Screen.width / CanS.referenceResolution.x;
        //獲取實際的縮放比例

        //計算了掃描框四個點(diǎn)的坐標(biāo)位置跷跪,“*X_Sc"是屏幕自適度的縮放比例馋嗜,這樣才能獲取真正運(yùn)行時UI圖片的寬高
        TopLeft_UI = new Vector2(Screen.width - 400 * X_Sc, Screen.height + 300 * X_Sc) * 0.5f;
        //給掃描框左上角的坐標(biāo)賦值
        //"Screen.width-400,Screen.height+300" 屏幕的寬度減去掃描框的寬度,屏幕的高度減去掃描框的高度
        BottomLeft_UI = new Vector2(Screen.width - 400 * X_Sc, Screen.height - 300 * X_Sc) * 0.5f;
        //給掃描框左下角的坐標(biāo)賦值
        TopRight_UI = new Vector2(Screen.width + 400 * X_Sc, Screen.height + 300 * X_Sc) * 0.5f;
        //給掃描框右上角的坐標(biāo)賦值
        BottomRight_UI = new Vector2(Screen.width + 400 * X_Sc, Screen.height - 300 * X_Sc) * 0.5f;
        //給掃描框右下角的坐標(biāo)賦值

        PlaneWH = new Vector2(gameObject.GetComponent<MeshFilter>().mesh.bounds.size.x * 50 * 0.1f, gameObject.GetComponent<MeshFilter>().mesh.bounds.size.z * 50 * 0.0646f) * 0.5f;
        //獲取面片的寬高的一半
        //"gameObject.GetComponent<MeshFilter>().mesh.bounds.size.x"獲取面片X方向的寬度
        //"*5"是因為開始獲取到的長寬是模型本身的長寬吵瞻,而場景中我們有縮放因素葛菇,父級物體放大了50倍,自身縮小到了0.1橡羞,因此獲取實際寬高需要再乘以5
    }

    //每一幀都調(diào)用
    void Update()
    {      
        //獲取面片四個點(diǎn)的世界坐標(biāo)
        TopLeft_Pl_W = gameObject.transform.parent.position + new Vector3(-PlaneWH.x, 0, PlaneWH.y);
        //獲取面片左上角的世界坐標(biāo)
        //"gameObject.transform.parent.position"物體的父級物體的世界坐標(biāo)
        //"new Vector2 (-PlaneWH.x,PlaneWH.y)"向左上方偏移的量
        BottomLeft_Pl_W = gameObject.transform.parent.position + new Vector3(-PlaneWH.x, 0, -PlaneWH.y);
        //獲取面片左下角的世界坐標(biāo)
        TopRight_Pl_W = gameObject.transform.parent.position + new Vector3(PlaneWH.x, 0, PlaneWH.y);
        //獲取面片右上角的世界坐標(biāo)
        BottomRight_Pl_W = gameObject.transform.parent.position + new Vector3(PlaneWH.x, 0, -PlaneWH.y);
        //獲取面片右下角的世界坐標(biāo)


        //獲取面片的屏幕坐標(biāo)
        TopLeft_Pl_Sc = Camera.main.WorldToScreenPoint(TopLeft_Pl_W);
        //獲取面片左上角的屏幕坐標(biāo)
        //Camera.main.WorldToScreenPoint(Vector3()); 將世界坐標(biāo)轉(zhuǎn)化為屏幕坐標(biāo)
        BottomLeft_Pl_Sc = Camera.main.WorldToScreenPoint(BottomLeft_Pl_W);
        //獲取面片左下角的屏幕坐標(biāo)
        TopRight_Pl_Sc = Camera.main.WorldToScreenPoint(TopRight_Pl_W);
        //獲取面片右上角的屏幕坐標(biāo)
        BottomRight_Pl_Sc = Camera.main.WorldToScreenPoint(BottomRight_Pl_W);
        //獲取面片右下角的屏幕坐標(biāo)

        //判斷面片是否在掃描框范圍內(nèi)
        if (TopLeft_Pl_Sc.x > TopLeft_UI.x && TopLeft_Pl_Sc.y < TopLeft_UI.y && BottomLeft_Pl_Sc.x > BottomLeft_UI.x && BottomLeft_Pl_Sc.y > BottomLeft_UI.y && TopRight_Pl_Sc.x < TopRight_UI.x && TopRight_Pl_Sc.y < TopLeft_UI.y && BottomRight_Pl_Sc.x < BottomRight_UI.x && BottomRight_Pl_Sc.y > BottomRight_UI.y)
        {
            //當(dāng)面片完全處于掃描框范圍內(nèi)時 執(zhí)行以下代碼
            if (HasRe == false)
            {
                //如果尚未識別
                gameObject.GetComponent<Renderer>().material = Green_Mate;
                //將腳本所附著的物體(面片)的材質(zhì)變?yōu)榫G色材質(zhì)
                StartCoroutine("SuccessUI");
                //調(diào)用顯示識別成功圖片的延遲函數(shù)
                StartCoroutine("ScreenShot");
                //調(diào)用截圖的延遲函數(shù)
                HasRe = true;
                //已經(jīng)識別
            }

        }
        else
        {
            //當(dāng)面片并非完全處于掃描框范圍內(nèi)時  執(zhí)行以下代碼
            gameObject.GetComponent<Renderer>().material = Red_Mate;
            //將腳本所附著的物體(面片)的材質(zhì)變?yōu)榧t色材質(zhì)
            HasRe = false;
            //識別狀態(tài)設(shè)置為未識別
        }



    }

    //顯示識別成功圖片的延遲函數(shù)
    IEnumerator SuccessUI()
    {
        yield return new WaitForSeconds(0.5f);
        //延遲0.5秒
        SuccessPlane_Image.SetActive(true);
        //激活提示識別成功的圖片
        gameObject.GetComponent<Renderer>().material = Tran_Mate;
        //給面片材質(zhì)賦值為透明材質(zhì)眯停,出去截圖時的影響
        Scan_Image.SetActive(false);
        //識別成功后隱藏掃描框;
    }

    //截圖的延遲函數(shù)
    IEnumerator ScreenShot()
    {
        yield return new WaitForSeconds(2.0f);
        //延遲2秒
        if (HasRe == true)
        {
            //當(dāng)處于識別狀態(tài)的時候才執(zhí)行截圖函數(shù)
            gameObject.GetComponent<Renderer>().material = Tran_Mate;
            //給面片材質(zhì)賦值為透明材質(zhì)卿泽,出去截圖時的影響
            Earth.GetComponent<ScreenShot>().ScreenShot_Button();
            //調(diào)用地球模型上截圖腳本的截圖函數(shù)
        }
    }
}

ResetExitUI

using UnityEngine;
using System.Collections;

public class ResetExitUI : MonoBehaviour {

    // Use this for initialization
    void Start () {
    
    }
    
    // Update is called once per frame
    void Update () {
    
    }

    /// <summary>
    /// 退出游戲的方法
    /// </summary>
    public void QuitUI(){
        //點(diǎn)擊退出按鈕 退出頁面
        Application.Quit ();
        //退出app
    }

    /// <summary>
    /// 重置游戲方法
    /// </summary>
    public void ResetUI() {
        GameObject.Find("Earth_A").SendMessage("OnMouseDown");
    }
}

ScreenShot

using UnityEngine;
using System.Collections;

public class ScreenShot : MonoBehaviour
{
    public GameObject Earth;
    //申請公有變量儲存要賦予貼圖的模型
    public GameObject EarthFrame;
    //儲存地球儀配件模型
    public GameObject EarthA;
    //儲存太陽系中的地球
    //地球公開的引用
    public GameObject PlaneA;
    public GameObject PlaneB;
    //儲存面片B

    private int ScreenWidth;
    //申請私有int型變量 記錄屏幕的寬
    private int ScreenHeight;
    //申請私有int型變量 記錄屏幕的高
    private Texture2D TextureShot;
    //申請Texture2D型變量 用來儲存屏幕截圖

    private Vector2 PlaneWH;
    //記錄面片的寬高

    //記錄面片的世界坐標(biāo)
    private Vector3 TopLeft_Pl_W;
    //記錄面片左上角的世界坐標(biāo)
    private Vector3 BottomLeft_Pl_W;
    //記錄面片左下角的世界坐標(biāo)
    private Vector3 TopRight_Pl_W;
    //記錄面片右上角的世界坐標(biāo)
    private Vector3 BottomRight_Pl_W;
    //記錄面片右下角的世界坐標(biāo)

    // Use this for initialization
    void Start()
    {
        ScreenWidth = Screen.width;
        //獲取屏幕的寬
        ScreenHeight = Screen.height;
        //獲取屏幕的高

        TextureShot = new Texture2D(ScreenWidth, ScreenHeight, TextureFormat.RGB24, false);
        // 標(biāo)準(zhǔn)格式 : Texture2D(int width,int height,TextureFormat format,bool mipmap);
        // “int width,int height,” 紋理的寬高
        //"TextureFormat format" 紋理的模式 RGB24 RGBA32等模式 
        //"bool mipmap"mipmap是一種分級紋理  在屏幕中顯示大小不同時候給予不同級別的紋理 這里不使用

    }

    // Update is called once per frame
    void Update()
    {

    }

    public void ScreenShot_Button()
    {

        PlaneWH = new Vector2(PlaneB.GetComponent<MeshFilter>().mesh.bounds.size.x, PlaneB.GetComponent<MeshFilter>().mesh.bounds.size.z) * 5 * 0.5f;
        //獲取面片的寬高的一半
        //"gameObject.GetComponent<MeshFilter>().mesh.bounds.size.x"獲取面片X方向的寬度
        //"*5"是因為開始獲取到的長寬是模型本身的長寬莺债,而場景中我們有縮放因素,父級物體放大了50倍签夭,自身縮小到了0.1齐邦,因此獲取實際寬高需要再乘以5

        //獲取面片四個點(diǎn)的世界坐標(biāo)
        TopLeft_Pl_W = PlaneB.transform.parent.position + new Vector3(-PlaneWH.x, 0, PlaneWH.y);
        //獲取面片左上角的世界坐標(biāo)
        //"gameObject.transform.parent.position"物體的父級物體的世界坐標(biāo)
        //"new Vector2 (-PlaneWH.x,PlaneWH.y)"向左上方偏移的量
        BottomLeft_Pl_W = PlaneB.transform.parent.position + new Vector3(-PlaneWH.x, 0, -PlaneWH.y);
        //獲取面片左下角的世界坐標(biāo)
        TopRight_Pl_W = PlaneB.transform.parent.position + new Vector3(PlaneWH.x, 0, PlaneWH.y);
        //獲取面片右上角的世界坐標(biāo)
        BottomRight_Pl_W = PlaneB.transform.parent.position + new Vector3(PlaneWH.x, 0, -PlaneWH.y);
        //獲取面片右下角的世界坐標(biāo)

        //將截圖時識別圖四個角的世界坐標(biāo)信息傳遞給Shader
        Earth.GetComponent<Renderer>().material.SetVector("_Uvpoint1", new Vector4(TopLeft_Pl_W.x, TopLeft_Pl_W.y, TopLeft_Pl_W.z, 1f));
        //將左上角的世界坐標(biāo)傳遞給Shader ,其中1f是否了湊齊四位浮點(diǎn)數(shù) 第租,用來進(jìn)行后續(xù)的矩陣變換操作
        Earth.GetComponent<Renderer>().material.SetVector("_Uvpoint2", new Vector4(BottomLeft_Pl_W.x, BottomLeft_Pl_W.y, BottomLeft_Pl_W.z, 1f));
        Earth.GetComponent<Renderer>().material.SetVector("_Uvpoint3", new Vector4(TopRight_Pl_W.x, TopRight_Pl_W.y, TopRight_Pl_W.z, 1f));
        Earth.GetComponent<Renderer>().material.SetVector("_Uvpoint4", new Vector4(BottomRight_Pl_W.x, BottomRight_Pl_W.y, BottomRight_Pl_W.z, 1f));

        //將截圖時識別圖四個角的世界坐標(biāo)信息傳遞給Shader
        EarthFrame.GetComponent<Renderer>().material.SetVector("_Uvpoint1", new Vector4(TopLeft_Pl_W.x, TopLeft_Pl_W.y, TopLeft_Pl_W.z, 1f));
        //將左上角的世界坐標(biāo)傳遞給Shader 措拇,其中1f是否了湊齊四位浮點(diǎn)數(shù) ,用來進(jìn)行后續(xù)的矩陣變換操作
        EarthFrame.GetComponent<Renderer>().material.SetVector("_Uvpoint2", new Vector4(BottomLeft_Pl_W.x, BottomLeft_Pl_W.y, BottomLeft_Pl_W.z, 1f));
        EarthFrame.GetComponent<Renderer>().material.SetVector("_Uvpoint3", new Vector4(TopRight_Pl_W.x, TopRight_Pl_W.y, TopRight_Pl_W.z, 1f));
        EarthFrame.GetComponent<Renderer>().material.SetVector("_Uvpoint4", new Vector4(BottomRight_Pl_W.x, BottomRight_Pl_W.y, BottomRight_Pl_W.z, 1f));

        //將截圖時識別圖四個角的世界坐標(biāo)信息傳遞給Shader
        EarthA.GetComponent<Renderer>().material.SetVector("_Uvpoint1",new Vector4(TopLeft_Pl_W.x,TopLeft_Pl_W.y,TopLeft_Pl_W.z,1f));
        //將左上角的世界坐標(biāo)傳遞給Shader 慎宾,其中1f是否了湊齊四位浮點(diǎn)數(shù) 儡羔,用來進(jìn)行后續(xù)的矩陣變換操作
        EarthA.GetComponent<Renderer>().material.SetVector("_Uvpoint2",new Vector4(BottomLeft_Pl_W.x,BottomLeft_Pl_W.y,BottomLeft_Pl_W.z,1f));
        EarthA.GetComponent<Renderer>().material.SetVector("_Uvpoint3",new Vector4(TopRight_Pl_W.x,TopRight_Pl_W.y,TopRight_Pl_W.z,1f));
        EarthA.GetComponent<Renderer>().material.SetVector("_Uvpoint4",new Vector4(BottomRight_Pl_W.x,BottomRight_Pl_W.y,BottomRight_Pl_W.z,1f));


        Matrix4x4 P = GL.GetGPUProjectionMatrix(Camera.main.projectionMatrix, false);
        //獲取截圖時GPU的投影矩陣
        Matrix4x4 V = Camera.main.worldToCameraMatrix;
        //獲取截圖時世界坐標(biāo)到相機(jī)的矩陣
        Matrix4x4 VP = P * V;
        //儲存兩個矩陣的乘積
        Earth.GetComponent<Renderer>().material.SetMatrix("_VP", VP);
        //將截圖時的矩陣轉(zhuǎn)換信息傳遞給Shader
        EarthFrame.GetComponent<Renderer>().material.SetMatrix("_VP", VP);
        //將截圖時的矩陣轉(zhuǎn)換信息傳遞給Shader
        EarthA.GetComponent<Renderer>().material.SetMatrix("_VP",VP);
        //將截圖時的矩陣轉(zhuǎn)換信息傳遞給Shader

       // Debug.Log("----------錯誤前");
        TextureShot.ReadPixels(new Rect(0, 0, ScreenWidth, ScreenHeight), 0, 0);
      //  Debug.Log("錯誤后--------------");
        //獲取屏幕的像素信息 
        //第一個"0,0"獲取屏幕像素的起始點(diǎn)
        //“ScreenWidth,ScreenHeight”獲取屏幕像素的范圍
        //第二個“0,0” 填充texture2D時填充的坐標(biāo)

        TextureShot.Apply();
        //確認(rèn)之前對Texture2D進(jìn)行的修改

        Earth.GetComponent<Renderer>().material.mainTexture = TextureShot;
        //獲取Earth的渲染組件中的材質(zhì)的主紋理,并將Texture2D賦值給這個主紋理
        EarthFrame.GetComponent<Renderer>().material.mainTexture = TextureShot;
        //獲取Earth的渲染組件中的材質(zhì)的主紋理璧诵,并將Texture2D賦值給這個主紋理
        EarthA.GetComponent<Renderer> ().material.mainTexture = TextureShot;
        //獲取Earth的渲染組件中的材質(zhì)的主紋理汰蜘,并將Texture2D賦值給這個主紋理

        //狀態(tài)隱藏
        PlaneA.SetActive(false);
        PlaneB.SetActive(false);
        //取消面片的激活狀態(tài)
    }


}


SecUI

using UnityEngine;
using System.Collections;

public class SecUI : MonoBehaviour {

    private float CancelTime=0;
    //申請浮點(diǎn)類型的變量來記錄 識別成功提示所存在的時間

    // Use this for initialization
    void Start () {
    
    }
    
    // Update is called once per frame
    void Update () {
        CancelTime += Time.deltaTime;
        //記錄識別成功提示所存在的時間
        //每一幀運(yùn)行都加經(jīng)過一幀所使用的鍵

        if(CancelTime>1.3f){  
        //當(dāng)識別成功的提示存在時間大于1.3秒時
            CancelTime=0;
            //記錄存在時間歸零
            gameObject.SetActive(false);
            //取消識別成功提示面板
        }
    }
}

Duijiao

using UnityEngine;
using System.Collections;
using Vuforia;

/// <summary>
/// 相機(jī)對焦
/// </summary>
public class Duijiao : MonoBehaviour
{


    // Use this for initialization
    //void Start()
    //{
    //   //通過Find尋找Ar攝像機(jī)
    //    GameObject ARCamera = GameObject.Find("ARCamera");

    //    //實例化攝像機(jī)時候自動對焦
    //    Vuforia.CameraDevice.Instance.SetFocusMode(Vuforia.CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
    //}

    //// Update is called once per frame
    //void Update()
    //{
    //    //運(yùn)行過程中實行對焦功能
    //    Vuforia.CameraDevice.Instance.SetFocusMode(Vuforia.CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
    //}



    //-----------------------------------------------------
    //第二種對焦方法
    void Start()
    {
        //一開始自動對焦
        //Vuforia.CameraDevice.Instance.SetFocusMode(Vuforia.CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
        VuforiaARController.Instance.RegisterVuforiaStartedCallback(OnVuforiaStarted);
        VuforiaARController.Instance.RegisterOnPauseCallback(OnPaused);
    }


    private void OnVuforiaStarted()
    {
        CameraDevice.Instance.SetFocusMode(
        CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
    }

    private void OnPaused(bool paused)
    {
        if (!paused)
        { // resumed
            // Set again autofocus mode when app is resumed
            CameraDevice.Instance.SetFocusMode(
            CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
        }
    }

}



三、效果展示

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末之宿,一起剝皮案震驚了整個濱河市族操,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌比被,老刑警劉巖色难,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異等缀,居然都是意外死亡枷莉,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門尺迂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來笤妙,“玉大人冒掌,你說我怎么就攤上這事《着蹋” “怎么了股毫?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長召衔。 經(jīng)常有香客問我铃诬,道長,這世上最難降的妖魔是什么苍凛? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任趣席,我火速辦了婚禮,結(jié)果婚禮上醇蝴,老公的妹妹穿的比我還像新娘吩坝。我一直安慰自己,他們只是感情好哑蔫,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布钉寝。 她就那樣靜靜地躺著,像睡著了一般闸迷。 火紅的嫁衣襯著肌膚如雪嵌纲。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天腥沽,我揣著相機(jī)與錄音逮走,去河邊找鬼。 笑死今阳,一個胖子當(dāng)著我的面吹牛师溅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播盾舌,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼墓臭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了妖谴?” 一聲冷哼從身側(cè)響起窿锉,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎膝舅,沒想到半個月后嗡载,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仍稀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年洼滚,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片技潘。...
    茶點(diǎn)故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡遥巴,死狀恐怖千康,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情挪哄,我是刑警寧澤吧秕,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布琉闪,位于F島的核電站迹炼,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏颠毙。R本人自食惡果不足惜斯入,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蛀蜜。 院中可真熱鬧刻两,春花似錦、人聲如沸滴某。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽霎奢。三九已至户誓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間幕侠,已是汗流浹背帝美。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留晤硕,地道東北人悼潭。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像舞箍,于是被迫代替她去往敵國和親舰褪。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 用兩張圖告訴你疏橄,為什么你的 App 會卡頓? - Android - 掘金 Cover 有什么料抵知? 從這篇文章中你...
    hw1212閱讀 12,745評論 2 59
  • 太陽系有八大行星,分別是:水星软族、金星刷喜、地球、火星立砸,木星掖疮、土星、天王星颗祝、海王星浊闪,其中我覺得最漂亮的是我們美麗的地球...
    鞍山王靜怡閱讀 765評論 0 3
  • 今天我要介紹的恼布,就是木星,木星也是看著外表像木頭搁宾,所以才叫夢醒的我不認(rèn)識為牟星折汞,你沒是有很多木頭呢,原來是我想錯...
    鞍山王靜怡閱讀 408評論 0 6
  • 今天我要介紹的就是天王星盖腿,天王星一片藍(lán)爽待,幾乎看不到別的顏色,我覺得天王星和海王星很相似翩腐,都是藍(lán)色的鸟款,它們兩個行星...
    鞍山王靜怡閱讀 197評論 0 2
  • 水星-- Mercury 墨丘利 ---希臘神話中的赫爾墨斯 離太陽最近何什,運(yùn)行最快 金星-- Venus 維...
    gbmaotai閱讀 2,349評論 0 2