//截图赋值,移走图片,涂色还在,正方形识别图,同时UV也是正方形
//模型使用shander-ScanTex
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
//扫描识别,脚本挂载在Plane上,plane为ImageTarget子物体,大小一样,UV为正方形,识别图也为正方形
public class Scanning_Plane : MonoBehaviour {
public GameObject Img_Scan;
//储存识别框图片
public GameObject Img_Sucess;
//储存识别成功图片
//public GameObject Model1;
//储存地球模型
//public GameObject Model2;
//储存地球框架模型
public GameObject Plane;
//储存面板B
public Material Green_Mate;
//申请材质变量储存绿色的材质
public Material Red_Mate;
//申请材质变量储存红色材质
public Material Tran_Mate;
//申请材质变量储存透明材质
private bool HasRe=false;
//申请布尔变量来确定是否已经识别
private CanvasScaler CanS;
//申请变量储存UI屏幕自适度的缩放组件
private float X_Sc;
//申请浮点型类型的变量储存实际的缩放比例
//记录扫描框的范围
private Vector2 TopLeft_UI;
//记录扫描框左上角的坐标
//“private”申请类型为私有
private Vector2 BottomLeft_UI;
//记录扫描框左下角的坐标
private Vector2 TopRight_UI;
//记录扫描框右上角的坐标
private Vector2 BottomRight_UI;
//记录扫描框右下角的坐标
//记录面片的世界坐标
private Vector3 TopLeft_Pl_W;
//记录面片左上角的世界坐标
private Vector3 BottomLeft_Pl_W;
//记录面片左下角的世界坐标
private Vector3 TopRight_Pl_W;
//记录面片右上角的世界坐标
private Vector3 BottomRight_Pl_W;
//记录面片右下角的世界坐标
//记录面片的屏幕坐标
private Vector2 TopLeft_Pl_Sc;
//记录面片左上角的屏幕坐标
private Vector2 BottomLeft_Pl_Sc;
//记录面片坐下角的屏幕坐标
private Vector2 TopRight_Pl_Sc;
//记录面片右上角的屏幕坐标
private Vector2 BottomRight_Pl_Sc;
//记录面片右下角的屏幕坐标
private Vector2 PlaneWH;
//记录面片的宽高
//面片为ImageTarget的子物体,大小和ImageTarget一样大,面片的纹理和ImageTarget一样。
public float ImageTargetScale;
//父级目标识别ImageTarget缩放系数
public float PlaneScale;
//Plane缩放系数
//脚本刚开始运行的时候调用一次
void Start () {
CanS = GameObject.Find ("Canvas").gameObject.GetComponent ();
//获取控制屏幕自适度的组件
X_Sc = Screen.width / CanS.referenceResolution.x;
//获取实际的缩放比例
}
//每一帧都调用
void Update () {
//计算了扫描框四个点的坐标位置,“*X_Sc"是屏幕自适度的缩放比例,这样才能获取真正运行时UI图片的宽高
TopLeft_UI = new Vector2 (Screen.width-400*X_Sc,Screen.height+300*X_Sc)*0.5f;
//给扫描框左上角的坐标赋值
//"Screen.width-400,Screen.height+300" 屏幕的宽度减去扫描框的宽度,屏幕的高度减去扫描框的高度
BottomLeft_UI=new Vector2(Screen.width-400*X_Sc,Screen.height-300*X_Sc)*0.5f;
//给扫描框左下角的坐标赋值
TopRight_UI=new Vector2(Screen.width+400*X_Sc,Screen.height+300*X_Sc)*0.5f;
//给扫描框右上角的坐标赋值
BottomRight_UI=new Vector2(Screen.width+400*X_Sc,Screen.height-300*X_Sc)*0.5f;
//给扫描框右下角的坐标赋值
//PlaneWH = new Vector2 (gameObject.GetComponent().mesh.bounds.size.x*1*0.1f,gameObject.GetComponent().mesh.bounds.size.z*1*0.064f)*0.5f;
PlaneWH = new Vector2(gameObject.GetComponent().mesh.bounds.size.x * ImageTargetScale * PlaneScale, gameObject.GetComponent().mesh.bounds.size.z * ImageTargetScale * PlaneScale) * 0.5f;
//获取面片的宽高的一半
//"gameObject.GetComponent().mesh.bounds.size.x"获取面片X方向的宽度
//"*5"是因为开始获取到的长宽是模型本身的长宽,而场景中我们有缩放因素,父级物体(ImageTarget)放大了1f倍,自身缩小到了0.1,因此获取实际宽高需要再乘以0.5
//获取面片四个点的世界坐标
TopLeft_Pl_W = gameObject.transform.parent.position + new Vector3 (-PlaneWH.x,0,PlaneWH.y);
//获取面片左上角的世界坐标
//"gameObject.transform.parent.position"物体的父级物体的世界坐标
//"new Vector2 (-PlaneWH.x,PlaneWH.y)"向左上方偏移的量
BottomLeft_Pl_W = gameObject.transform.parent.position + new Vector3 (-PlaneWH.x,0,-PlaneWH.y);
//获取面片左下角的世界坐标
TopRight_Pl_W = gameObject.transform.parent.position + new Vector3 (PlaneWH.x,0,PlaneWH.y);
//获取面片右上角的世界坐标
BottomRight_Pl_W = gameObject.transform.parent.position + new Vector3 (PlaneWH.x,0,-PlaneWH.y);
//获取面片右下角的世界坐标
//获取面片的屏幕坐标
TopLeft_Pl_Sc=Camera.main.WorldToScreenPoint(TopLeft_Pl_W);
//获取面片左上角的屏幕坐标
//Camera.main.WorldToScreenPoint(Vector3()); 将世界坐标转化为屏幕坐标
BottomLeft_Pl_Sc=Camera.main.WorldToScreenPoint(BottomLeft_Pl_W );
//获取面片左下角的屏幕坐标
TopRight_Pl_Sc=Camera.main.WorldToScreenPoint(TopRight_Pl_W);
//获取面片右上角的屏幕坐标
BottomRight_Pl_Sc=Camera.main.WorldToScreenPoint(BottomRight_Pl_W );
//获取面片右下角的屏幕坐标
//判断面片是否在扫描框范围内
if(TopLeft_Pl_Sc.x>TopLeft_UI.x&&TopLeft_Pl_Sc.yBottomLeft_UI.x&&BottomLeft_Pl_Sc.y>BottomLeft_UI.y&&TopRight_Pl_Sc.xBottomRight_UI.y){
//当面片完全处于扫描框范围内时 执行以下代码
if(HasRe==false){
//如果尚未识别
gameObject.GetComponent().material=Green_Mate;
//将脚本所附着的物体(面片)的材质变为绿色材质
StartCoroutine("SuccessUI");
//调用显示识别成功图片的延迟函数
StartCoroutine("ScreenShot");
//调用截图的延迟函数
HasRe=true;
//已经识别
}
}else{
//当面片并非完全处于扫描框范围内时 执行以下代码
gameObject.GetComponent().material=Red_Mate;
//将脚本所附着的物体(面片)的材质变为红色材质
HasRe=false;
//识别状态设置为未识别
}
}
//显示识别成功图片的延迟函数
IEnumerator SuccessUI (){
yield return new WaitForSeconds (0.5f);
//延迟0.5秒
Img_Sucess.SetActive(true);
//激活提示识别成功的图片
gameObject.GetComponent().material=Tran_Mate;
//给面片材质赋值为透明材质,除去截图时的影响
Img_Scan.SetActive(false);
//扫描框取消
}
//截图的延迟函数
IEnumerator ScreenShot(){
yield return new WaitForSeconds (2.0f);
//延迟2秒
if(HasRe==true){
//当处于识别状态的时候才执行截图函数
gameObject.GetComponent().material=Tran_Mate;
//给面片材质赋值为透明材质,除去截图时的影响
////Earth.SetActive(true);
//////地球模型显示出来
////EarthFrame.SetActive(true);
//////地球模型框架显示出来
//Earth.GetComponent().ScreenShot_Button();
//调用地球模型上截图脚本的截图函数
Plane.GetComponent().ScreenShot_Button();
}
}
}
//////////////////////////////////////////////////////////////////////
using UnityEngine;
using System.Collections;
//识别图为正方形时,UV图也为正方形时,可只用一个面板plane,ScreenShot_Plane(扫描),ScreenShot_Plane(截图)都挂载在Plane上
//屏幕截图,脚本挂载在Plane上,Plane,为ImageTarget子物体,为正方形,长与ImageTarget一样,纹理为3D模型(正方形)UV纹理,正方形=长方形+空白
public class ScreenShot_Plane : MonoBehaviour {
public GameObject Model1;
//申请公有变量储存要赋予贴图的模型
//public GameObject Model2;
//储存地球仪配件模型
public GameObject Plane;
//储存面片A,ImageTarget的子物体平面,和ImageTarget一样大小,识别时,显示红色,识别成功后,显示绿色
//储存面片B,ImageTarget的子物体平面,和ImageTarget一样的长,为正方形,和ImageTarget一样的(长方形)纹理贴图,
//屏幕截图,从他身上截图和Image一样的长方形纹理,正方形内(长方形以外部分为空)
private int ScreenWidth;
//申请私有int型变量 记录屏幕的宽
private int ScreenHeight;
//申请私有int型变量 记录屏幕的高
private Texture2D TextureShot;
//申请Texture2D型变量 用来储存屏幕截图
private Vector2 PlaneWH;
//记录面片A的宽高
//记录面片的世界坐标
private Vector3 TopLeft_Pl_W;
//记录面片左上角的世界坐标
private Vector3 BottomLeft_Pl_W;
//记录面片左下角的世界坐标
private Vector3 TopRight_Pl_W;
//记录面片右上角的世界坐标
private Vector3 BottomRight_Pl_W;
//记录面片右下角的世界坐标
public float ImageTargetScale;
//父级目标识别ImageTarget缩放系数
public float PlaneScale;
//Plane缩放系数
void Start () {
ScreenWidth = Screen.width;
//获取屏幕的宽
ScreenHeight=Screen.height;
//获取屏幕的高
TextureShot = new Texture2D (ScreenWidth,ScreenHeight,TextureFormat.RGB24,false);
// 标准格式 : Texture2D(int width,int height,TextureFormat format,bool mipmap);
// “int width,int height,” 纹理的宽高
//"TextureFormat format" 纹理的模式 RGB24 RGBA32等模式
//"bool mipmap"mipmap是一种分级纹理 在屏幕中显示大小不同时候给予不同级别的纹理 这里不使用
Model1.GetComponent().enabled = false;
// Model2.GetComponent().enabled = false;
//隐藏模型
//??透明脚本不管用??
}
//截图函数
public void ScreenShot_Button(){
PlaneWH = new Vector2 (Plane.GetComponent().mesh.bounds.size.x* ImageTargetScale * PlaneScale, Plane.GetComponent().mesh.bounds.size.z* ImageTargetScale * PlaneScale) *0.5f;
//获取面片的宽高的一半;*0.5;
//"gameObject.GetComponent().mesh.bounds.size.x"获取面片X方向的宽度
//"*M*N"是因为开始获取到的长宽是模型本身的长宽,而场景中我们有缩放因素,父级物体(ImageTarget)放大了n倍,自身缩小到了m,因此获取实际宽高需要再乘以m*n
//获取面片四个点的世界坐标
TopLeft_Pl_W = Plane.transform.parent.position + new Vector3 (-PlaneWH.x,0,PlaneWH.y);
//获取面片左上角的世界坐标
//"gameObject.transform.parent.position"物体的父级物体的世界坐标
//"new Vector2 (-PlaneWH.x,PlaneWH.y)"向左上方偏移的量
BottomLeft_Pl_W = Plane.transform.parent.position + new Vector3 (-PlaneWH.x,0,-PlaneWH.y);
//获取面片左下角的世界坐标
TopRight_Pl_W = Plane.transform.parent.position + new Vector3 (PlaneWH.x,0,PlaneWH.y);
//获取面片右上角的世界坐标
BottomRight_Pl_W = Plane.transform.parent.position + new Vector3 (PlaneWH.x,0,-PlaneWH.y);
//获取面片右下角的世界坐标
//将截图时识别图四个角的世界坐标信息传递给Shader
Model1.GetComponent().material.SetVector("_Uvpoint1",new Vector4(TopLeft_Pl_W.x,TopLeft_Pl_W.y,TopLeft_Pl_W.z,1f));
//将左上角的世界坐标传递给Shader ,其中1f是否了凑齐四位浮点数 ,用来进行后续的矩阵变换操作
Model1.GetComponent().material.SetVector("_Uvpoint2",new Vector4(BottomLeft_Pl_W.x,BottomLeft_Pl_W.y,BottomLeft_Pl_W.z,1f));
Model1.GetComponent().material.SetVector("_Uvpoint3",new Vector4(TopRight_Pl_W.x,TopRight_Pl_W.y,TopRight_Pl_W.z,1f));
Model1.GetComponent().material.SetVector("_Uvpoint4",new Vector4(BottomRight_Pl_W.x,BottomRight_Pl_W.y,BottomRight_Pl_W.z,1f));
//将截图时识别图四个角的世界坐标信息传递给Shader
//Model2.GetComponent().material.SetVector("_Uvpoint1",new Vector4(TopLeft_Pl_W.x,TopLeft_Pl_W.y,TopLeft_Pl_W.z,1f));
//将左上角的世界坐标传递给Shader ,其中1f是否了凑齐四位浮点数 ,用来进行后续的矩阵变换操作
//Model2.GetComponent().material.SetVector("_Uvpoint2",new Vector4(BottomLeft_Pl_W.x,BottomLeft_Pl_W.y,BottomLeft_Pl_W.z,1f));
//Model2.GetComponent().material.SetVector("_Uvpoint3",new Vector4(TopRight_Pl_W.x,TopRight_Pl_W.y,TopRight_Pl_W.z,1f));
//Model2.GetComponent().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;
//获取截图时世界坐标到相机的矩阵
Matrix4x4 VP=P*V;
//储存两个矩阵的乘积
Model1.GetComponent().material.SetMatrix("_VP",VP);
//将截图时的矩阵转换信息传递给Shader
//Model2.GetComponent().material.SetMatrix("_VP",VP);
//将截图时的矩阵转换信息传递给Shader
TextureShot.ReadPixels (new Rect(0,0,ScreenWidth,ScreenHeight),0,0);
//获取屏幕的像素信息
//第一个"0,0"获取屏幕像素的起始点
//“ScreenWidth,ScreenHeight”获取屏幕像素的范围
//第二个“0,0” 填充texture2D时填充的坐标
TextureShot.Apply ();
//确认之前对Texture2D进行的修改
Model1.GetComponent().enabled = true;
//Model2.GetComponent().enabled = true;
//显示模型
Model1.GetComponent ().material.mainTexture = TextureShot;
//获取Earth的渲染组件中的材质的主纹理,并将Texture2D赋值给这个主纹理
//Model2.GetComponent ().material.mainTexture = TextureShot;
//获取Earth的渲染组件中的材质的主纹理,并将Texture2D赋值给这个主纹理
Plane.SetActive (false);
//取消面片的激活状
}
}
//////////////////////////////////////////////////////////////////
using UnityEngine;
using System.Collections;
public class ExitUI : MonoBehaviour {
// Use this for initialization
void Start () {
}
public void QuitUI(){
Application.Quit ();
//退出app
}
}
/////////////////////////////////////////////////////////////////////
using UnityEngine;
using System.Collections;
public class SecUI : MonoBehaviour {
private float CancelTime=0;
//申请浮点类型的变量来记录 识别成功提示所存在的时间
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
CancelTime += Time.deltaTime;
//记录识别成功提示所存在的时间
//每一帧运行都加经过一帧所使用的键
if(CancelTime>1.3f){
//当识别成功的提示存在时间大于1.3秒时
CancelTime=0;
//记录存在时间归零
gameObject.SetActive(false);
//取消识别成功提示面板
}
}
}