开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

开发者专栏

关注:1818

当前位置:游戏蛮牛 技术专区 开发者专栏

__________________________________________________________________________________
开发者干货区版块规则:

  1、文章必须是图文形式。(至少2幅图)
      2、文章字数必须保持在1500字节以上。(编辑器右下角有字数检查)
      3、本版块只支持在游戏蛮牛原创首发,不支持转载。
      4、本版块回复不得无意义,如:顶、呵呵、不错......【真的会扣分的哦】
      5、......
__________________________________________________________________________________
查看: 2930|回复: 17

[东方喵] 【Hello Vuforia】(五)涂涂乐之程序篇

[复制链接]  [移动端链接]
排名
1162
昨日变化
1

29

主题

776

帖子

2778

积分

Rank: 9Rank: 9Rank: 9

UID
76248
好友
17
蛮牛币
16191
威望
0
注册时间
2015-2-28
在线时间
719 小时
最后登录
2017-8-23

专栏作家蛮牛译员活力之星七夕浪漫情人

发表于 2016-9-28 17:36:56 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
本帖最后由 东方喵 于 2016-9-28 17:41 编辑

【Hello Vuforia】(五)涂涂乐之程序篇

【Hello Vuforia】(一)入门篇:http://www.manew.com/thread-92723-1-1.html?_dsign=51711fb9
【Hello Vuforia】(二)脱卡篇:http://www.manew.com/thread-92769-1-1.html?_dsign=2644a306
【Hello Vuforia】(三)多卡交互篇:http://www.manew.com/thread-92874-1-1.html?_dsign=019474b9
【Hello Vuforia】(四)涂涂乐之美术篇:http://www.manew.com/thread-93047-1-1.html

首先,很是抱歉,因为为了腾讯GAD的一个小比赛,赶工小游戏,程序篇拖更了这么久...对不起各位观众老爷了...T_T
u=2004884860,39054189&fm=21&gp=0.jpg

e6ae63dd2f2eb93863d9ca49d5628535e4dd6faf.png
        
81eac6e0gbcc5095bcd2c&690.jpeg

接下来,负罪之人怀着万分抱歉的心态补更...OTL

涂涂乐的思路大体是酱紫的:在上篇中,我们把模型的UV和识别图上对应的面匹配好,然后利用rendertexture作为模型的贴图,在rendertexture的shader中,根据Vuforia识别出识别图的空间位置信息,对rendertexture的图像进行矩阵变换,使之时刻与模型的UV对其,从而达到实时的涂涂乐效果。

如下代码是先前我自一位github上不知名的洋人老大哥得来,对我这样鶸(cai ji)而言,不停的学习是很必要的,我为大家稍稍解释一小下:
(纯代码的确无聊,然而,没想到什么更好的展示方案,就这样吧,大家都是成年人,直接点!)

[C#] 纯文本查看 复制代码
//为材质设置矩阵
Shader "Custom/Set_Matrix_To_Material" {

    Properties {

        _MainTex("Texture", 2D) = "white" {}
        _BackTex("Texture", 2D) = "white" {}
                _Alpha ("AlphaFront", Range(0,1)) = 1
                _AlphaBack ("AlphaBack", Range(0,1)) = 0
    }

    SubShader{  
        Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}

                        Pass{
                        CGPROGRAM
                        #pragma vertex vert
                        #pragma fragment frag
                        
                        #include "UnityCG.cginc"

                        struct appdata
                        {
                                float4 vertex : POSITION;
                                float2 uv : TEXCOORD0;
                        };

                        fixed _AlphaBack;

                        struct v2f
                        {
                                float2 uv : TEXCOORD0;
                                float4 vertex : SV_POSITION;
                        };

                        v2f vert (appdata v)
                        {
                                v2f o;
                                o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                                o.uv = v.uv;
                                return o;
                        }
                        
                        sampler2D _BackTex;

                        fixed4 frag (v2f i) : SV_Target
                        {
                                fixed4 col = tex2D(_BackTex, i.uv);
                                col.a = _AlphaBack;
                                return col;
                        }
                        ENDCG
                }


    Pass{

    Cull Back//背面剔除
        ZWrite Off//不将像素的深度写入深度缓存中
        Blend SrcAlpha OneMinusSrcAlpha//混合模式:Alpha混合
        
    CGPROGRAM

    #pragma vertex vert
    #pragma fragment frag
    #include "UnityCG.cginc"

    sampler2D _MainTex;
    float4x4 _MATRIX_MVP;//伟大的mvp矩阵
    
    float _KX;
    float _KY;
    
   int _KR = 1;
   int _KG = 1;
      
        fixed _Alpha;
        
    struct v2f{

        float4  pos : SV_POSITION;
        float2  uv : TEXCOORD0;

    };

    v2f vert(appdata_base v){
       
        v2f o;
        float2 screenSpacePos;
        float4 clipPos;

        //从世界空间到视空间转换位置。(M->V)
        //只有UV坐标应该被固定住,所以使用一个不同的矩阵
        clipPos = mul(_MATRIX_MVP, v.vertex);


                //从剪辑空间到屏幕空间转换位置。(V->P)
        //屏幕空间的范围是-1~+1
        screenSpacePos.x = clipPos.x / clipPos.w;
        screenSpacePos.y = clipPos.y / clipPos.w;

        //屏幕空间的范围(-1~+1)需要匹配UV的范围(0~1)

        o.uv.x = (_KX*screenSpacePos.x) + _KX;
        o.uv.y = (_KY*screenSpacePos.y) + _KY;

        //使用标准的UNITY_MATRIX_MVP(MVP矩阵)来使顶点的位置不被锁定
        o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
        return o;
    }

    half4 frag(v2f i) : COLOR{
        fixed4 col = tex2D(_MainTex, i.uv);     

        if (i.uv.x < 0 || i.uv.x > _KX*2 || i.uv.y < 0 || i.uv.y > _KY*2) {col.rgb = 1; col.a = 0;}
        else col.a = _Alpha;

        col.r *= _KR + 1;
        col.g *= _KG + 1;
        
        return col;
    }

    ENDCG

            }
    }
}


[C#] 纯文本查看 复制代码
using System;
using System.Collections;
using UnityEngine;
using Vuforia;


#if UNITY_EDITOR
#pragma warning disable 0414//忽略0414警告
#endif

public class Region_Capture : MonoBehaviour
{
    private Camera Child_AR_Camera;
    private GameObject AR_Camera_Vector;
        private Renderer m_renderer;
    [Space(10)] //为了美观,在检视面板中空点儿格
    public GameObject ARCamera;//AR相机
    public GameObject ImageTarget;// 识别图
    public GameObject BackgroundPlane;//rendertexture
    [Space(20)]
    public bool AutoRegionSize = true;//自动调节区域尺寸
    public bool HideFromARCamera = true;//是否在AR相机中隐藏
    public bool CheckMarkerPosition = false;
    [Space(20)]
    public bool ColorDebugMode = false;

    [HideInInspector]//不在检视面板显示
    public bool MarkerIsOUT, MarkerIsIN;

    private bool Is_Child_ImageTarget, reverse_matrix;
        private float tmp00_init, tmp01_init, tmp02_init, tmp00_updt, tmp01_updt, tmp02_updt;
        private int frame_num;
    public static Texture2D VideoBackgroundTexure;
        public static float CPH,CPW,vuforia_ios_magic;
        private TrackableBehaviour mTrackableBehaviour;

    private void Start()
    {
                mTrackableBehaviour = ImageTarget.GetComponent<Vuforia.TrackableBehaviour>();//Vuforia的识别跟踪

        if (!m_renderer) m_renderer = GetComponent<Renderer>();
        AR_Camera_Vector = GameObject.Find("AR Camera Vector");

        if (AR_Camera_Vector == null)
        {
            AR_Camera_Vector = new GameObject("AR Camera Vector");//生成一个空物体,为了提供伟大的MVP矩阵中的V(视)
        }

        if (GetComponentInParent<ImageTargetBehaviour>()) Is_Child_ImageTarget = true;

        if (ARCamera == null || ImageTarget == null || BackgroundPlane == null)
        {
            Debug.LogWarning("ARCamera, ImageTarget or BackgroundPlane not assigned!");
            enabled = false;
        }
        else
        {
            if (AutoRegionSize)
            {
                var imageTargetBehaviour = ImageTarget.GetComponent<ImageTargetBehaviour>();
                if (Is_Child_ImageTarget)
                {
                    transform.localPosition = Vector3.zero;
                    transform.localEulerAngles = Vector3.zero;


                    if (imageTargetBehaviour.GetSize().x > imageTargetBehaviour.GetSize().y)
                        transform.localScale =
                                                        new Vector3(0.1f, 0.1f,imageTargetBehaviour.GetSize().y/imageTargetBehaviour.GetSize().x*0.1f);
                    else
                        transform.localScale =
                            new Vector3(imageTargetBehaviour.GetSize().x/imageTargetBehaviour.GetSize().y*0.1f, 0.1f, 0.1f);
                }

                else
                {
                    transform.position = ImageTarget.transform.position;
                    transform.localRotation = ImageTarget.transform.localRotation;
                    transform.localScale =
                        new Vector3(imageTargetBehaviour.GetSize().x, 10.0f, imageTargetBehaviour.GetSize().y)/10.0f;
                }
            }

            Child_AR_Camera = ARCamera.GetComponentInChildren<Camera>();
            gameObject.layer = 20;

            if (HideFromARCamera && !ColorDebugMode)
                Child_AR_Camera.cullingMask &= ~(1 << LayerMask.NameToLayer("Region_Capture"));//相机渲染的层

            if (ColorDebugMode)
            {
                m_renderer.material.SetInt("_KR", 0);
                m_renderer.material.SetInt("_KG", 1);
            }

            CPH = Child_AR_Camera.pixelHeight;
            CPW = Child_AR_Camera.pixelWidth;

                        vuforia_ios_magic = 1.0f;

            StartCoroutine(Start_Initialize());
            StartCoroutine(CheckVideoMode());
        }

                ////////////////////////////////////////////////////////////////////////////////////////////
                //                                                                IOS Devices Names
                //
                //   http://www.everyi.com/by-identifier/ipod-iphone-ipad-specs-by-model-identifier.html
                //
                ////////////////////////////////////////////////////////////////////////////////////////////


                if (SystemInfo.deviceModel.Contains ("iPad5,3") || SystemInfo.deviceModel.Contains ("iPad5,4"))
                        reverse_matrix = true;

    }


    private void Initialize()//初始化
    {
        var meshFilter = BackgroundPlane.GetComponent<MeshFilter>();
        if (VuforiaRenderer.Instance.IsVideoBackgroundInfoAvailable())
        {
            var videoTextureInfo = VuforiaRenderer.Instance.GetVideoTextureInfo();

            if (videoTextureInfo.imageSize.x == 0 || videoTextureInfo.imageSize.y == 0) goto End;

            var k_x = videoTextureInfo.imageSize.x/(float) videoTextureInfo.textureSize.x*0.5f;
            var k_y = videoTextureInfo.imageSize.y/(float) videoTextureInfo.textureSize.y*0.5f;

            m_renderer.material.SetFloat("_KX", k_x);
            m_renderer.material.SetFloat("_KY", k_y);

            VideoBackgroundTexure = VuforiaRenderer.Instance.VideoBackgroundTexture;

            if (!VideoBackgroundTexure || !meshFilter) goto End;

            m_renderer.material.SetTexture("_MainTex", VideoBackgroundTexure);

            AR_Camera_Vector.transform.parent = ARCamera.transform;//对上文声明的V进行变换
            AR_Camera_Vector.transform.localPosition = Vector3.zero;
            AR_Camera_Vector.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
            AR_Camera_Vector.transform.localEulerAngles = new Vector3(0.0f, 180.0f, 180.0f);

                        #if !UNITY_EDITOR && !UNITY_STANDALONE

                                var P = VuforiaUnity.GetProjectionGL(0, 0, 0);

                                        tmp00_init = P.m00;
                                        tmp01_init = P.m01;
                                        tmp02_init = P.m02;

                                if (CameraDevice.Instance.GetCameraDirection() == CameraDevice.CameraDirection.CAMERA_FRONT) AR_Camera_Vector.transform.localEulerAngles = new Vector3 (0.0f, 0.0f, 0.0f);

                                if (Screen.orientation == ScreenOrientation.LandscapeRight || Screen.orientation == ScreenOrientation.LandscapeLeft) 
                                        vuforia_ios_magic = -1.0f;

                                if (Screen.orientation == ScreenOrientation.Portrait) {
                                        if (Application.platform == RuntimePlatform.IPhonePlayer && tmp02_init < 0) vuforia_ios_magic = -2.0f;
                                        else vuforia_ios_magic = 1.0f;
                                        if (SystemInfo.deviceModel.Contains ("iPhone5,3") || SystemInfo.deviceModel.Contains ("iPhone5,4")) vuforia_ios_magic = -1.0f;
                                }

                                if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {
                                        if (Application.platform == RuntimePlatform.IPhonePlayer && tmp02_init > 0) vuforia_ios_magic = 2.0f;
                                        else vuforia_ios_magic = -1.0f;
                                        if (SystemInfo.deviceModel.Contains ("iPhone5,3") || SystemInfo.deviceModel.Contains ("iPhone5,4")) vuforia_ios_magic = 1.0f;
                                }

                        #endif


                        #if UNITY_EDITOR || UNITY_STANDALONE
                AR_Camera_Vector.transform.localPosition = new Vector3(0.0f, ImageTarget.GetComponent<ImageTargetBehaviour>().GetSize().x/240.0f, 0.0f);

                        #else
                                float aspect = (float)videoTextureInfo.imageSize.x / (float)videoTextureInfo.imageSize.y;
                                if (Screen.orientation == ScreenOrientation.Portrait || Screen.orientation == ScreenOrientation.PortraitUpsideDown) {
                                AR_Camera_Vector.transform.localScale = new Vector3 (1.0f / aspect, aspect, 1.0f);
                                }
                        #endif

            End:

                        if (videoTextureInfo.imageSize.x == 0 || videoTextureInfo.imageSize.y == 0 || !VideoBackgroundTexure || !meshFilter) {
                                StartCoroutine (Start_Initialize ());
                        }

        }
        else
        {
            StartCoroutine(Start_Initialize());
        }
    }

    private void LateUpdate()
    {
        if (AutoRegionSize && !Is_Child_ImageTarget)
        {
            transform.position = ImageTarget.transform.position;
            transform.localRotation = ImageTarget.transform.localRotation;
        }

        var M = transform.localToWorldMatrix;
        var V = AR_Camera_Vector.transform.worldToLocalMatrix;
        var P = VuforiaUnity.GetProjectionGL(0, 0, 0);

        #if !UNITY_EDITOR && !UNITY_STANDALONE

                tmp00_updt = P.m00;
                tmp01_updt = P.m01;
                tmp02_updt = P.m02;

                if (tmp00_updt != tmp00_init || tmp01_updt != tmp01_init || tmp02_updt != tmp02_init) StartCoroutine(Start_Initialize());

                if (Screen.orientation == ScreenOrientation.LandscapeRight) P.m02 *= vuforia_ios_magic;
                if (Screen.orientation == ScreenOrientation.LandscapeLeft) P.m12 *= vuforia_ios_magic;

                if (Screen.orientation == ScreenOrientation.Portrait || Screen.orientation == ScreenOrientation.PortraitUpsideDown) {

                if (reverse_matrix) {

                        P.m02 = -P.m12;
                        P.m12 = -tmp02_updt;
                        }

                        P.m02 /= vuforia_ios_magic;
                        P.m12 *= vuforia_ios_magic;

                }

        #endif

        m_renderer.material.SetMatrix("_MATRIX_MVP", P*V*M);//这哥仨组成了我们熟悉的MVP矩阵

                if (mTrackableBehaviour != null && (int)mTrackableBehaviour.CurrentStatus > 1) {
                        m_renderer.material.SetFloat ("_Alpha", 1);
                        m_renderer.enabled = true;
                } 

                else {
                        m_renderer.material.SetFloat ("_Alpha", 0);
                        frame_num += 1;

                        if (frame_num > 3) {
                                m_renderer.enabled = false;
                                frame_num = 0;
                        }
                }

        if (CheckMarkerPosition || ColorDebugMode)
        {
            var boundPoint1 = m_renderer.bounds.min;
            var boundPoint2 = m_renderer.bounds.max;
            var boundPoint3 = new Vector3(boundPoint1.x, boundPoint1.y, boundPoint2.z);
            var boundPoint4 = new Vector3(boundPoint2.x, boundPoint1.y, boundPoint1.z);

            var screenPos1 = Child_AR_Camera.WorldToScreenPoint(boundPoint1);
            var screenPos2 = Child_AR_Camera.WorldToScreenPoint(boundPoint2);
            var screenPos3 = Child_AR_Camera.WorldToScreenPoint(boundPoint3);
            var screenPos4 = Child_AR_Camera.WorldToScreenPoint(boundPoint4);

            if (screenPos1.x < 0 || screenPos1.y < 0 || screenPos2.x < 0 || screenPos2.y < 0 || screenPos3.x < 0 ||
                screenPos3.y < 0 || screenPos4.x < 0 || screenPos4.y < 0 || screenPos1.x > CPW || screenPos1.y > CPH ||
                screenPos2.x > CPW || screenPos2.y > CPH || screenPos3.x > CPW || screenPos3.y > CPH ||
                screenPos4.x > CPW || screenPos4.y > CPH)
            {
                if (!MarkerIsOUT)
                {
                    StartCoroutine(Start_MarkerOutOfBounds());

                    MarkerIsOUT = true;
                    MarkerIsIN = false;
                }
            }
            else
            {
                if (!MarkerIsIN)
                {
                    StartCoroutine(Start_MarkerIsReturned());

                    MarkerIsIN = true;
                }
                MarkerIsOUT = false;
            }
        }
    }

    private void MarkerOutOfBounds()
    {
        // Add action here if marker out of bounds

        Debug.Log("Marker out of bounds!");

        if (ColorDebugMode)
        {
            m_renderer.material.SetInt("_KR", 1);
            m_renderer.material.SetInt("_KG", 0);
        }
    }

    private void MarkerIsReturned()
    {
        // Add action here if marker is visible again

        Debug.Log("Marker is returned!");

        if (ColorDebugMode)
        {
            m_renderer.material.SetInt("_KR", 0);
            m_renderer.material.SetInt("_KG", 1);
        }
    }

    private IEnumerator Start_Initialize()
    {
        yield return new WaitForEndOfFrame();
        Initialize();
    }


    private IEnumerator CheckVideoMode()
    {
        var rtc = GetComponent<RenderTextureCamera>();

        while (true)
        {
            yield return new WaitForSeconds(1);
            if (Math.Abs(CPH - Child_AR_Camera.pixelHeight) > Mathf.Epsilon ||
                Math.Abs(CPW - Child_AR_Camera.pixelWidth) > Mathf.Epsilon)
            {
                CPH = Child_AR_Camera.pixelHeight;
                CPW = Child_AR_Camera.pixelWidth;

                StartCoroutine(Start_Initialize());
                if (rtc && rtc.enabled)
                    rtc.RecalculateTextureSize();
            }
            yield return null;
        }
    }


    private IEnumerator Start_MarkerOutOfBounds()
    {
        yield return new WaitForEndOfFrame();
        MarkerOutOfBounds();
    }

    private IEnumerator Start_MarkerIsReturned()
    {
        yield return new WaitForEndOfFrame();
        MarkerIsReturned();
    }

    public void RecalculateRegionSize()
    {
                var imageTargetBehaviour = ImageTarget.GetComponent<ImageTargetBehaviour>();

        transform.position = ImageTarget.transform.position;
        transform.localRotation = ImageTarget.transform.localRotation;
                transform.localScale = new Vector3(imageTargetBehaviour.GetSize().x, 10.0f, imageTargetBehaviour.GetSize().y)/10.0f;
    }

}


[C#] 纯文本查看 复制代码
using UnityEngine;
using System.Collections;

public class MyGetTexture : MonoBehaviour {
        public static MyGetTexture instance;

        private Camera RenderTextureCamera;
        public GameObject Region_Capture;

        [SerializeField] Material myMat;

        public bool motion=true;
        void Awake () {
                MyGetTexture.instance = this;
        }
        void Start () {
                RenderTextureCamera = Region_Capture.GetComponentInChildren<Camera>();
        }

        void Update(){
                if (motion) {
                        if (RenderTextureCamera.targetTexture) {
                                myMat.SetTexture ("_MainTex", RenderTextureCamera.targetTexture);
                        }
                }
        }

        public void GetTexture(){
                if (RenderTextureCamera.targetTexture) {
                        //将RenderTexture转换成为Texture2D,这样,贴图就不再受到camera影响
                        RenderTexture.active = RenderTextureCamera.targetTexture;  
                        Rect rect = new Rect (0, 0, RenderTextureCamera.targetTexture.width, RenderTextureCamera.targetTexture.height);
                        Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24,false); 
                        //这个是从RenderTexture.active中读取像素  
                        screenShot.ReadPixels(rect, 0, 0);
                        screenShot.Apply();  

                        myMat.SetTexture ("_MainTex", RenderTextureCamera.targetTexture);//为材质的shader附主图
                }
                RenderTextureCamera.enabled = false;
        }

}


[C#] 纯文本查看 复制代码
using UnityEngine;
public class DisableSystemUI//为安卓把系统UI隐藏掉
{
        #if UNITY_ANDROID
        static AndroidJavaObject activityInstance;
        static AndroidJavaObject windowInstance;
        static AndroidJavaObject viewInstance;
        
        const int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 2;
        const int SYSTEM_UI_FLAG_LAYOUT_STABLE = 256;
        const int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 512;
        const int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 1024;
        const int SYSTEM_UI_FLAG_IMMERSIVE = 2048;
        const int SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 4096;
        const int SYSTEM_UI_FLAG_FULLSCREEN = 4;
        
        public delegate void RunPtr();
        
        public static void Run()
        {
                if (viewInstance != null) {
                        viewInstance.Call("setSystemUiVisibility",
                                          SYSTEM_UI_FLAG_LAYOUT_STABLE
                                          | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                                          | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                                          | SYSTEM_UI_FLAG_HIDE_NAVIGATION
                                          | SYSTEM_UI_FLAG_FULLSCREEN
                                          | SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
                }
                
        }
        #endif  
        public static void DisableNavUI()
        {
                if (Application.platform != RuntimePlatform.Android)
                        return;
                #if UNITY_ANDROID
                using (AndroidJavaClass unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
                {
                        activityInstance = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");
                        windowInstance = activityInstance.Call<AndroidJavaObject>("getWindow");
                        viewInstance = windowInstance.Call<AndroidJavaObject>("getDecorView");
                        
                        AndroidJavaRunnable RunThis;
                        RunThis = new AndroidJavaRunnable(new RunPtr(Run));
                        activityInstance.Call("runOnUiThread", RunThis);
                }
                #endif
        }
        
}


[C#] 纯文本查看 复制代码
using System;
using UnityEngine;
using System.Collections;

#if UNITY_EDITOR
using UnityEditor;
#endif

public class RC_Extension
{
    [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
    public sealed class ShowAsLayerAttribute : PropertyAttribute
    {
    }

#if UNITY_EDITOR
    [CustomPropertyDrawer(typeof(ShowAsLayerAttribute))]
        public class ShowAsLayerAttributeDrawer : PropertyDrawer//显示为图层属性
    {
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            if (property.propertyType != SerializedPropertyType.Integer)
            {
                EditorGUI.HelpBox(position, "Use ShowAsLayer only with int fields!", MessageType.Error);
                return;
            }

            EditorGUI.BeginProperty(position, label, property);
            {
                EditorGUI.showMixedValue = property.hasMultipleDifferentValues;
                {
                    property.intValue = EditorGUI.LayerField(position, label, property.intValue);
                }
                EditorGUI.showMixedValue = false;
            }
            EditorGUI.EndProperty();
        }
    }
#endif
}


[C#] 纯文本查看 复制代码
using UnityEngine;
using System.Collections;
using Vuforia;

public class RC_Tools : MonoBehaviour {//相机自动对焦

        [Space(20)]
        public bool AutofocusCamera = true;
        public bool HideAndroidToolbar = true;

        void Start () {
        
                #if UNITY_ANDROID
                if (HideAndroidToolbar) {
                        DisableSystemUI.Run();
                        DisableSystemUI.DisableNavUI();
                }
                #endif

                StartCoroutine(Autofocus());

        }
        
        private IEnumerator Autofocus()
        {
                yield return new WaitForSeconds(1.0f);
                if (AutofocusCamera) CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
        }


        void OnApplicationPause() {
                StartCoroutine(Autofocus());
        }
}


[C#] 纯文本查看 复制代码
using UnityEngine;
using System.Collections;
using Vuforia;
using System.Runtime.InteropServices;

#if UNITY_EDITOR
#pragma warning disable 0219
#endif

public class RenderTextureCamera : MonoBehaviour
{
        [RC_Extension.ShowAsLayerAttribute]
    public int CameraLayer = 20;

        [Space(20)]
        public int TextureResolution = 512;
        [Space(10)]
        public Texture SetMarkerBackground;
        public bool MarkerBackgroundAlpha = false;
    private string screensPath;
    private int TextureResolutionX;
        private int TextureResolutionY;
        [Space(20)]
        public bool ShowTexture = false;
        public static Camera ARCamera_Camera;
        private Camera Render_Texture_Camera;
        private GameObject DebugGUITexture;
        private RenderTexture CameraOutputTexture;

    public RenderTexture GetRenderTexture()//没有被调用过
    {
        return CameraOutputTexture;
    }

        void Start() {

                StartCoroutine(StartRenderingToTexture());

        }

                IEnumerator StartRenderingToTexture() {//别分神哈,上课玩手机的都收起来哈~这个脚本的重点函数在这里!
                //为rendertexture的shader初始化各个属性
                if (SetMarkerBackground) GetComponent<Renderer>().material.SetTexture ("_BackTex", SetMarkerBackground);
                if (MarkerBackgroundAlpha) GetComponent<Renderer>().material.SetFloat ("_AlphaBack", 0);
                else GetComponent<Renderer>().material.SetFloat ("_AlphaBack", 1);
                yield return new WaitForSeconds(0.5f);
                //获取ARCamera下挂着的那个相机,调节相机的各属性
                Render_Texture_Camera = GetComponentInChildren<Camera>();
                Render_Texture_Camera.GetComponent<Camera>().orthographicSize = transform.localScale.z * 5;

                if (GetComponentInParent<ImageTargetBehaviour> ())//ImageTargetBehaviour继承自ImageTargetAbstractBehaviour
                        Render_Texture_Camera.GetComponent<Camera> ().orthographicSize *= 20.0f;


                if (transform.localScale.x >= transform.localScale.z) {

                        TextureResolutionX = TextureResolution;
                        TextureResolutionY = (int)(TextureResolution * transform.localScale.z / transform.localScale.x);
                }

                if (transform.localScale.x < transform.localScale.z) {

                        TextureResolutionX =  (int)(TextureResolution * transform.localScale.x / transform.localScale.z);
                        TextureResolutionY = TextureResolution;
                }

                CameraOutputTexture = new RenderTexture(TextureResolutionX, TextureResolutionY, 0);
                CameraOutputTexture.Create();
                Render_Texture_Camera.GetComponent<Camera>().targetTexture = CameraOutputTexture;

                gameObject.layer = CameraLayer;
                Render_Texture_Camera.cullingMask = 1 << CameraLayer;

                StartCoroutine(ShowTextureOnGUI());
        }


    IEnumerator ShowTextureOnGUI() {//这个也没被调用过,在gui上显示图片,估计是这洋人老哥用来测试的函数

                if (ShowTexture) {

                        if (!DebugGUITexture) {
                                DebugGUITexture = new GameObject ("Debug GUI Texture");
                                GUITexture DebugTexture = DebugGUITexture.AddComponent<GUITexture> ();
                                DebugTexture.color = Color.gray;
                                DebugTexture.texture = CameraOutputTexture;

                                ARCamera_Camera = VuforiaManager.Instance.ARCameraTransform.GetComponentInChildren<Camera>();
                                float GuiTextureAspect = TextureResolutionX / (TextureResolutionY * ARCamera_Camera.aspect);

                                DebugGUITexture.transform.localScale = new Vector3 (0.3f * GuiTextureAspect, 0.3f, 0.3f);                                
                                DebugGUITexture.transform.position = new Vector3 ((1.0f - (0.3f * GuiTextureAspect / 2)) - 0.1f * (1 / ARCamera_Camera.aspect), 0.25f, 0.0f);
                        }
                        else {
                                
                                float GuiTextureAspect = TextureResolutionX / (TextureResolutionY * ARCamera_Camera.aspect);

                                DebugGUITexture.transform.localScale = new Vector3 (0.3f * GuiTextureAspect, 0.3f, 0.3f);                                
                                DebugGUITexture.transform.position = new Vector3 ((1.0f - (0.3f * GuiTextureAspect / 2)) - 0.1f * (1 / ARCamera_Camera.aspect), 0.25f, 0.0f);
                        }

                } 

                else {
                        if (DebugGUITexture) Destroy (DebugGUITexture);
                }
                yield return null;
        }


        public void RecalculateTextureSize() {
                StartCoroutine(RecalculateRenderTexture());
        }

        private IEnumerator RecalculateRenderTexture() {

                yield return new WaitForEndOfFrame();

                Render_Texture_Camera.GetComponent<Camera> ().targetTexture = null;
                CameraOutputTexture.Release();
                CameraOutputTexture = null;
                if (DebugGUITexture) Destroy (DebugGUITexture);

                StartCoroutine(StartRenderingToTexture());

        }


        void OnValidate(){
                
                #if UNITY_EDITOR
                if (Application.isPlaying) {
                        if         (GetComponent<RenderTextureCamera>().isActiveAndEnabled) StartCoroutine(ShowTextureOnGUI());
                }
                #endif
                
        }
        

    public void MakeScreen() {//这洋人老哥并未调用这个函数,为尊重原版未做改动,下方函数是要分平台确定路径,保存图片用的

        if (screensPath == null) {

                #if UNITY_ANDROID && !UNITY_EDITOR
                        screensPath = "/sdcard/DCIM/RegionCapture";

                #elif UNITY_IPHONE && !UNITY_EDITOR
                        screensPath = Application.persistentDataPath;

                #else
            screensPath = Application.dataPath + "/Screens";

                #endif
            System.IO.Directory.CreateDirectory(screensPath);
        }

        StartCoroutine(TakeScreen());
    }

    private IEnumerator TakeScreen() {

        yield return new WaitForEndOfFrame();

        Texture2D FrameTexture = new Texture2D(CameraOutputTexture.width, CameraOutputTexture.height, TextureFormat.RGB24, false);
        RenderTexture.active = CameraOutputTexture;
        FrameTexture.ReadPixels(new Rect(0, 0, CameraOutputTexture.width, CameraOutputTexture.height), 0, 0);
        RenderTexture.active = null;

        FrameTexture.Apply();
        saveImgToGallery(FrameTexture.EncodeToPNG());//这里调用了下方的函数,保存图片

    }

        #if UNITY_IPHONE && !UNITY_EDITOR
        //在iphone上时,调用函数ImgToAlbum
        [DllImport ("__Internal")]
        private static extern void ImgToAlbum(string str);
        #endif

    private void saveImgToGallery(byte[] img)//保存图片
    {
            string fileName = saveImg(img);

                #if UNITY_IPHONE && !UNITY_EDITOR 
                ImgToAlbum(fileName);
                #endif
    }

    private string saveImg(byte[] imgPng)
    {
        string fileName = screensPath + "/screen_" + System.DateTime.Now.ToString("dd_MM_HH_mm_ss") + ".png";

        Debug.Log("write to " + fileName);

        System.IO.File.WriteAllBytes(fileName, imgPng);
        return fileName;
    }
}


最后,附上unitypackage:
TuTuLe5.unitypackage.zip (18.63 KB, 下载次数: 205)




评分

参与人数 3蛮牛币 +10 鲜花 +12 收起 理由
MemoryC + 10 + 5 赞一个!
airvant + 5 很给力!
CC_rmvb + 2 赞一个!

查看全部评分


回复

使用道具 举报

7日久生情
2432/5000
排名
338
昨日变化
1

9

主题

195

帖子

2432

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
55220
好友
5
蛮牛币
658
威望
0
注册时间
2014-11-13
在线时间
798 小时
最后登录
2017-8-23

活力之星

QQ
发表于 2016-9-28 18:51:33 | 显示全部楼层
非常感谢~~~~~~~~~~~~~

点评

谢谢观众老爷的支持  发表于 2016-9-29 09:29

回复

使用道具 举报

排名
323
昨日变化
1

41

主题

380

帖子

4778

积分

Rank: 9Rank: 9Rank: 9

UID
26484
好友
17
蛮牛币
12455
威望
0
注册时间
2014-5-24
在线时间
2473 小时
最后登录
2017-8-23

游戏蛮牛QQ群会员VIP

QQ
发表于 2016-9-28 20:26:55 | 显示全部楼层
赞一个,话说我也参加了腾讯Gad的比赛~

点评

哦尼酱,干巴待哟~~~  发表于 2016-9-29 09:28

回复 支持 反对

使用道具 举报

7日久生情
2379/5000
排名
169
昨日变化

2

主题

74

帖子

2379

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
20580
好友
0
蛮牛币
5882
威望
0
注册时间
2014-4-8
在线时间
561 小时
最后登录
2017-8-23
发表于 2016-9-29 09:21:40 | 显示全部楼层
一直期待的AR教程

点评

拖更了一个月,万分抱歉~~~  发表于 2016-9-29 09:28

回复 支持 反对

使用道具 举报

6蛮牛粉丝
1243/1500
排名
1768
昨日变化
6

1

主题

380

帖子

1243

积分

Rank: 6Rank: 6Rank: 6

UID
56496
好友
0
蛮牛币
3497
威望
0
注册时间
2014-11-19
在线时间
280 小时
最后登录
2017-8-23
发表于 2016-9-29 10:24:57 | 显示全部楼层
求点赞,求评论,求拍砖,求推广,谢谢各位大老爷了~~~

点评

谢谢大老爷~~~!  发表于 2016-9-29 10:35

回复 支持 反对

使用道具 举报

3偶尔光临
166/300
排名
24287
昨日变化
25

0

主题

31

帖子

166

积分

Rank: 3Rank: 3Rank: 3

UID
132960
好友
0
蛮牛币
415
威望
0
注册时间
2015-12-29
在线时间
126 小时
最后登录
2017-8-23
发表于 2016-9-29 11:51:41 | 显示全部楼层
不错,赞一个,希望有更多的实际例子

回复 支持 反对

使用道具 举报

排名
37048
昨日变化
79

0

主题

2

帖子

6

积分

Rank: 1

UID
172748
好友
0
蛮牛币
19
威望
0
注册时间
2016-9-28
在线时间
0 小时
最后登录
2016-9-29
发表于 2016-9-29 13:13:28 | 显示全部楼层
屏幕快照 2016-09-29 下午1.10.50.png

请问ios项目嵌入unity,怎么关闭unity 和从新打开unity啊,他俩的混编怎么搞啊



回复 支持 反对

使用道具 举报

排名
1162
昨日变化
1

29

主题

776

帖子

2778

积分

Rank: 9Rank: 9Rank: 9

UID
76248
好友
17
蛮牛币
16191
威望
0
注册时间
2015-2-28
在线时间
719 小时
最后登录
2017-8-23

专栏作家蛮牛译员活力之星七夕浪漫情人

 楼主| 发表于 2016-9-29 15:11:50 | 显示全部楼层
a120816813 发表于 2016-9-29 13:13
请问ios项目嵌入unity,怎么关闭unity 和从新打开unity啊,他俩的混编怎么搞啊

http://www.manew.com/thread-93750-1-1.html
@777777716有一个系列的教程,你可以看看

回复 支持 反对

使用道具 举报

排名
37048
昨日变化
79

0

主题

2

帖子

6

积分

Rank: 1

UID
172748
好友
0
蛮牛币
19
威望
0
注册时间
2016-9-28
在线时间
0 小时
最后登录
2016-9-29
发表于 2016-9-29 17:59:30 | 显示全部楼层
东方喵 发表于 2016-9-29 15:11
http://www.manew.com/thread-93750-1-1.html
@777777716有一个系列的教程,你可以看看

这个我看了,解决不了我的问题啊,我现在可以切换到unity,我想问的是,能不能我再次打开unity的时候,从新加载unity或者加载新的unity,

回复 支持 反对

使用道具 举报

2初来乍到
103/150
排名
11745
昨日变化
9

0

主题

10

帖子

103

积分

Rank: 2Rank: 2

UID
155511
好友
0
蛮牛币
149
威望
0
注册时间
2016-7-6
在线时间
41 小时
最后登录
2017-7-19
发表于 2016-10-31 17:25:37 | 显示全部楼层
支持下,看样子先得学习shader

回复 支持 反对

使用道具 举报

5熟悉之中
744/1000
排名
2582
昨日变化
4

0

主题

86

帖子

744

积分

Rank: 5Rank: 5

UID
60139
好友
0
蛮牛币
1536
威望
0
注册时间
2014-12-8
在线时间
238 小时
最后登录
2017-8-21
发表于 2016-11-3 12:09:47 | 显示全部楼层
用这个试了试,mvp应该是没错的,但是颜色上有点问题,颜色只取了图片左下角的一点,模型出来是纯色的,有人遇到过这个问题吗

回复 支持 反对

使用道具 举报

3偶尔光临
181/300
排名
10278
昨日变化
5

0

主题

44

帖子

181

积分

Rank: 3Rank: 3Rank: 3

UID
43306
好友
1
蛮牛币
169
威望
0
注册时间
2014-9-2
在线时间
70 小时
最后登录
2017-8-22
发表于 2016-11-9 17:17:19 | 显示全部楼层
你好,我看了你这个,用了你分享出来的这个tutule5。但是给模型上贴图得时候有一点问题,应该是跟UV有关,但是我不知道怎么解决!希望版主能不吝赐教,跪谢!另外,这个项目有点急,急等回复。1663470645

回复 支持 反对

使用道具 举报

排名
49710
昨日变化
353

0

主题

5

帖子

14

积分

Rank: 1

UID
212628
好友
0
蛮牛币
36
威望
0
注册时间
2017-3-17
在线时间
8 小时
最后登录
2017-5-19
发表于 2017-5-10 10:10:00 | 显示全部楼层
请问一下,这个是不是不支持一个ArCamera多个涂涂乐模型

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

快速回复 返回顶部 返回列表