2017年12月14日 星期四

很不錯的網站:擴增實境在健康照顧上的應用

(請移到影片播放在2小時41分06秒上) 

原本以為擴增實境是用在行銷包裝上很好的工具,最近在瞭解有那些科技可以用來幫助長輩,特別是在中興新村資策會實習學生在參加DiG+數位新星大賞競賽之後,發現一個很不錯的擴增實境應用健康照顧上的網站。

網址:Welcome to Augmented Reality in Medicine(Healthcare)


2017年12月11日 星期一

有蟲嗎?很怪都沒啟動AR,就出現3D物件。

今天試著想要加上旋轉的程式,但一執行,明明就沒有任可標籤,但就看到所建立的物件-Cube,就已經在旋轉,有點怪,如下圖,感覺這好像是Vuforia和Unity整合上的問題。


把所有的資源全部砍掉重練,結果正常了。

利用transform.Rotate()函式就能製造旋轉的效果,程式碼如下:

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

public class rotation : MonoBehaviour {
    public float turnSpeed = 50f;
    // Use this for initialization
    void Start () {

}

// Update is called once per frame
void Update () {
        transform.Rotate(Vector3.up, -turnSpeed * Time.deltaTime);
    }
}

以上程式範例可以參考:Unity程式設計初體驗(三)-遊戲物件位移和旋轉控制

2017年12月10日 星期日

號外!Unity 2017.2內建Vuforia功能,開發擴增實境應用程式更方便!

官方文章:Getting Started with Vuforia in Unity 2017.2

下載Unity 2017.2版本,在安裝時可以選擇Vuforia AR,開發擴增實境應用程式更方便。


1.建立新專案
2.選擇GameObject中的Vuforia,新增AR Camera以及Image,並刪除Camera。

3. 在Player Setting上選擇Vuforia Augmented Realit。

4.在Vuforia Target Manager工具中新增Database,並以Unity Editor格式滙出。
5. 在Unity下,滙入Vuforia Target Manager工具中滙出的Database。
6. 在Vuforia License Manager工具中新增License。
7. 點選Unity中的AR Camera,開啟open Vuforia configuration,貼上新增的License。
8.在Image Target物件下,新增Cube。

9. 使用Target來測試,測試成功如下圖。








超級棒的物聯網工具及資源

超級棒的文章介紹物聯網工具及資源:67 open source tools and resources for IoT,區分成工業聯盟、協定、作業系統、APIs、平台、中介軟體、節點編輯器、工具箱、搜尋、資料視覺化、硬體等。

第62個的開放源碼機器人基金會(Open Source Robotics Foundation),就提供很好的機器人模擬工具,非常適合研究機器人使用,以下是該軟體有關於機器人及汽車的模擬。






第67個洪水網絡(Flood Network)就是很好的使用物聯網讓居家生活品質更好的範例,可以清楚地看到河流的水位,提供即時數據,顯示河流的水位高度,當有可能洪水氾濫,向居民或社區發送警報。



2017年12月9日 星期六

在PC安裝BlueStacks手機模擬器測式擴增實境APPs

本文將介紹一個好用的工具,在PC上裝BlueStacks手機模擬器,就可以使用Android APPs,目前支援Windows和Mac版本。官方網站:https://www.bluestacks.com/tw/index.html


 

BlueStacks手機模擬器測試AR的文章Vuforia Standalone using Bluestacks – Starting Android App on PC,在該篇文章中介紹兩款APP: Animals of Africa Tales of the World




大家可以利用該篇文章提供的圖片進行測試,記得要先安裝APP。


(Animals of Africa)

(Tales of  the World)




2017年12月8日 星期五

如何得知擴增實境功能有被啟用?


擴增實境是採用Vuforia工具,如何在程式中,如何得知Vuforia AR效果有沒有被啟動呢?這是本篇文章的教學重點。

您點選下圖左方的Field,可以看到內嵌一個PolygonField.cs程式。在PolygonField.cs的程式中,可以看到宣告一個公開的GameObject變數,命名為go_raw,因此在下圖中,可以看到Go_raw屬性,並宣告5個元素,這5個元素分別對應到ImageTarget內的圖片,如下圖。go_raw宣告如下:

public GameObject[] go_raw;


在Update()函式中,我們可以看,用getAllAvailablePoints()取得那些標籤有被偵測出來,換句話說是有AR效果,收集這點資訊,供後續畫線及計算使用。

void Update () {
getAllAvailablePoints ();
draw ();
drawLines ();
calculation ();
}

利用go_raw來對應到AR標籤物件,再使用enabled屬性值來判斷是否有AR效果,下面程式就是利用這個技巧,來取得有AR效果的標籤物件,再決是否把角度和距離的物件啟用,最後把收集到的資料轉成陣列。

private void getAllAvailablePoints(){
// Create new Vector2 and Text Lists
List vertices2DList = new List();
List textAList = new List();
List textDList = new List();
List oList = new List();

// Fill lists if availble
for(int i = 0; i < go_raw.Length; i++){
if (go_raw [i] != null) {
if (go_raw [i].GetComponent ().enabled) {
go_text_angle [i].enabled = true;
go_text_distance [i].enabled = true;

vertices2DList.Add (new Vector2 (go_raw [i].transform.position.x, go_raw [i].transform.position.y));
textAList.Add (go_text_angle [i]);
textDList.Add (go_text_distance [i]);
oList.Add ( go_raw [i] );
} else {
go_text_angle [i].enabled = false;
go_text_distance [i].enabled = false;
}
}
}

// Convert to array
go_points_text_a = textAList.ToArray ();
go_points_text_d = textDList.ToArray ();
go_points = vertices2DList.ToArray ();
go_n = oList.ToArray ();
}


2017年12月7日 星期四

用擴增實境測量距離、周長、面積、還有辨識形狀

本篇文章將介紹當數張具有擴增實境標籤卡片移動時,可以測量出鄰近兩張卡片的中心點距量,當卡片移動時,還能自動地顯示改變後的距離。

原文網址:Augmented Reality Shapes Combined from Trackers
Download: Download Whole Unity3D AR Shapes project (*.rar file)請大家留意影片中左上角,可以計算周長、面積、還有辨識形狀。

 




2017年12月1日 星期五

思考如何試圖抓住目標對象的程式設計




這個腳本(Enemy.cs)在需要敵方物體跟隨玩家或者其他想要瞄準的物體時很有用。 當敵人朝著目標物體(上圖中白色物體)移動時,敵人(Enemy)產生跳躍效應。 看起來好像敵人自己在思考,像是有點具備人工智慧(AI)的感覺,敵人可以思考行動路徑試圖抓住目標對象。

程式解析如下:

1.前面沒有障礙物
if (!isThereAnyThing) {
Vector3 relativePos = target.transform.position - transform.position;
Quaternion rotation = Quaternion.LookRotation (relativePos);
transform.rotation = Quaternion.Slerp (transform.rotation, rotation, Time.deltaTime);
}
2.往前移動
transform.Translate (Vector3.forward * Time.deltaTime * speed);
3.檢查前方有沒有障礙物,並使用Physics.Raycast()進行偵測
Transform leftRay = transform;
Transform rightRay = transform;

                
if (Physics.Raycast (leftRay.position + (transform.right * 7), transform.forward, range)) {
isThereAnyThing = true;
transform.Rotate (Vector3.up * Time.deltaTime * rotationSpeed);
}
                
if (Physics.Raycast (rightRay.position - (transform.right * 7), transform.forward, range)) {
isThereAnyThing = true;
transform.Rotate (Vector3.up * Time.deltaTime * rotationSpeed);
}
4.已經通過障礙物
if (Physics.Raycast (transform.position - (transform.forward * 4), transform.right, 10)) {
// Just making this boolean variable false it means there is nothing in front of object.
isThereAnyThing = false;
}

if (Physics.Raycast (transform.position - (transform.forward * 4), -transform.right, 10)) {
// Just making this boolean variable false it means there is nothing in front of object.
isThereAnyThing = false;
}
5.輸出除錯資訊
Debug.DrawRay (transform.position + (transform.right * 7), transform.forward * 20, Color.red);

Debug.DrawRay (transform.position - (transform.right * 7), transform.forward * 20, Color.red);

Debug.DrawRay (transform.position - (transform.forward * 4), - transform.right * 20, Color.yellow);

Debug.DrawRay (transform.position - (transform.forward * 4), transform.right * 20, Color.yellow);

擴增實境與物聯網結合的應用影片

物聯網可以提供物品對物品通訊的功能,感知器(如溫溼度、PM2.5等)可以將訊息經由控制器傳送到雲端伺服主機,控制器也能從雲端伺服主機中取得資料,經過運算後,就能啟閉致動器(馬達、警報器等)。

擴增實境技術能將電腦的資訊呈現在現實生活中,因此結合物聯網技術,就能把生活中的感測器的數值用擴增實境技術呈現在我們生活世界中,經由人們和擴增實境提供的人機介互動,有了物聯網的協助就能操控現實世界的設備,如家電產品等。







2017年11月30日 星期四

AR meets IoTs: 當擴增實境遇到物聯網-讀取感知訊息程式解析

AR meets IoTs: 當擴增實境遇到物聯網相關文章,如下:
初接觸
用網頁來控制LED亮滅
發佈感知訊息程式解析

在上圖我們可以清楚地看到在IoT content目錄下,有三個原始程式:
  1. IoT.cs
  2. ReadStream.cs
  3. WebStreamReader.cs

當您點選右上角的codeContainer,只看到兩個腳本程式,分別是IoT.cs和ReadStream.cs,但沒有看到WebStreamReader.cs。其實WebStreamReader是被宣告在ReadStream程式內,如下:


public class ReadStream : MonoBehaviour
{
public string PhotonParticleURL = "https://api.particle.io/v1/devices/events?access_token=649e7d09d0980e4b649e42f6dcff79887d9570e2";
WebStreamReader request = null;

我們以在ReadStream程式中找到WRequest()函式,您就可以看到程式是如何建立物件new WebStreamReader(),如何啟動網站連結Start(PhotonParticleURL),如何取得網站資料request.GetNextBlock(),再解析出溫度的資料Contains ("temperature"),最後再顯示在AR畫面上gameObject.GetComponent ().microTemperatureVal
IEnumerator WRequest()
{
request = new WebStreamReader();
request.Start(PhotonParticleURL); //https://www.ourtechart.com//wp-content/uploads/2016/04/jsonAllData.txt");
string stream = "";
while (true)
{
string block = request.GetNextBlock();
if (!string.IsNullOrEmpty(block))
{
stream += block;
//Debug.Log ("Stream1: " + stream);
string[] data = stream.Split(new string[] { "\n\n" }, System.StringSplitOptions.None);
//Debug.Log ("Data length: " + data.Length);
stream = data[data.Length - 1];

for (int i = 0; i < data.Length - 1; i++)
{
if (!string.IsNullOrEmpty(data[i]))
{
// Debug.Log ("Data: " + data [i]); // print all block of data (event + data)
if (data [i].Contains ("light")) {
lightTrue = true;
string output = data [i].Substring(data [i].IndexOf("{"));
parseDataLight = JsonUtility.FromJson (output);
//Debug.Log ("Data of Photoresistor: " + parseData.data);
//text.text = parseData.data.ToString ();
//gameObject.GetComponent ().microPhotoresistorVal = parseDataLight.data;
}
if (data [i].Contains ("temperature")) {
temperatureTrue = true;
string output = data [i].Substring(data [i].IndexOf("{"));
parseDataTemperature = JsonUtility.FromJson (output);
//Debug.Log ("Data of Temperature sensor: " + parseData.data);
//text.text = parseData.data.ToString ();
//gameObject.GetComponent ().microTemperatureVal = parseDataTemperature.data;
}
if (data [i].Contains ("motion")) {
motionTrue = true;
string output = data [i].Substring(data [i].IndexOf("{"));
parseDataMotion = JsonUtility.FromJson (output);
//Debug.Log ("Data of PIR sensor: " + parseData.data);
//text.text = parseData.data.ToString ();
//gameObject.GetComponent ().motionDetectedBool = Convert.ToBoolean(parseDataMotion.data);
}
if (data [i].Contains ("ultraviolet")) {
ultravioletTrue = true;
string output = data [i].Substring(data [i].IndexOf("{"));
parseDataUltraviolet = JsonUtility.FromJson (output);
//Debug.Log ("Data of PIR ultraviolet: " + parseData.data);
//text.text = parseData.data.ToString ();
//gameObject.GetComponent ().microUltravioletVal = parseDataUltraviolet.data;
}
if (data [i].Contains ("humidity")) {
humidityTrue = true;
string output = data [i].Substring(data [i].IndexOf("{"));
parseDataHumidity = JsonUtility.FromJson (output);
//Debug.Log ("Data of Humidity: " + parseData.data);
//text.text = parseData.data.ToString ();
//gameObject.GetComponent ().microHumidityVal = parseDataHumidity.data;
}
//Debug.Log ("TEst: " + humidityTrue + temperatureTrue + lightTrue + ultravioletTrue);
if (humidityTrue && temperatureTrue && lightTrue && ultravioletTrue) {
//Debug.Log ("PRINT ALLLLLLLLLLLLLL");
gameObject.GetComponent ().microPhotoresistorVal = parseDataLight.data;
gameObject.GetComponent ().microTemperatureVal = parseDataTemperature.data;
gameObject.GetComponent ().motionDetectedBool = Convert.ToBoolean(parseDataMotion.data);
gameObject.GetComponent ().microUltravioletVal = parseDataUltraviolet.data;
gameObject.GetComponent ().microHumidityVal = parseDataHumidity.data;
humidityTrue = false;
motionTrue = false;
temperatureTrue = false;
lightTrue = false;
ultravioletTrue = false;
}
}
}
}
yield return new WaitForSeconds(1);
}

真正要顯示在畫面上是IoT.cs的任務,在Update()中可以找溫度的片斷程式如下:

microTemperatureText.text = microTemperatureVal.ToString ();
checkTemperature ();

依照顏色來改變按鈕的顏色值:
private void checkTemperature() {
index = 0;
if (microTemperatureVal >= minTemp && microTemperatureVal <= maxTemp) // Green Color - temperature is ok
greenButtonColor (index);// (Buttons[0]);
if (microTemperatureVal > maxTemp) // Red Color - temperature is too Hot
orangeButtonColor(index);
if (microTemperatureVal < minTemp) // Blue Color - temperature is too Cold
blueButtonColor (index);
}

2017年11月29日 星期三

AR meets IoTs: 當擴增實境遇到物聯網-發佈感知訊息程式解析

AR meets IoTs: 當擴增實境遇到物聯網相關文章,如下:
初接觸
用網頁來控制LED亮滅

請先下載Arduino的範例程式:

取出發佈相關程式:
    // Humidity measurement
    temperature = dht.getTempCelcius();
    
    // Humidity measurement
    humidity = dht.getHumidity();
    
    // Light level measurement
    float light_measurement = analogRead(light_sensor_pin);
    light = (int)(light_measurement/4096*100);
    
    int uvValue=analogRead(uv);
    ultraviolet = (uvValue*100)/1023;
    // Publish data
    Particle.publish("temperature", String(temperature));// + " °C");
    delay(t);
    Particle.publish("humidity", String(humidity));// + "%");
    delay(t);
    Particle.publish("light", String(light));// + "%");

Particle.publish()可以將資訊送到物聯網伺服器,一般都採用名稱/內容值的表示方式,來進行資料的連結,"temperature" 是名稱, String(temperature)是內容值


    delay(t);

AR meets IoTs: 當擴增實境遇到物聯網-用網頁來控制LED亮滅

初接觸的文章:AR meets IoTs: 當擴增實境遇到物聯網

今天我們來介紹如何把Arduino訊號傳到雲端伺服主機,設計物聯網應用程式,換句話,就是如何使用HTTP來監控軟硬體設備。

在初接觸文章的下方,您可以看到Arduino的原始程式下載,這是一個可以用網頁技術來控制接到Arduino上的LED。

大家可以參考這篇文章
https://docs.particle.io/guide/getting-started/examples/photon/#control-leds-over-the-39-net

在這篇文章的arduino setup()函式的程式碼如下:


arduino程式:

void setup() {
     pinMode(led1, OUTPUT); OUTPUT);
     pinMode(led2, OUTPUT); 
     Particle.function("led",ledToggle);
     digitalWrite(led1, LOW); 
     digitalWrite(led2, LOW);
 }

最特殊應該是Particle.function()函式,這函式主要的功能是用來橋接HTML程式和Arduino的函式,在這個函式中有兩個參數,其一是 "led"使用在網頁程式中,另一個是ledToggle是函式名稱,其程式如下:



int ledToggle(String command) { if (command=="on") { digitalWrite(led1,HIGH); digitalWrite(led2,HIGH); return 1; } else if (command=="off") { digitalWrite(led1,LOW); digitalWrite(led2,LOW); return 0; } else { return -1; } }

從上面程式中,ledToggle()函式,有使用到一個參數command,這個參數的內容會來自網頁表單傳送,其內容有"on"和"off"兩個。注意arduino程式和下面程式中的"on"和"off",您就可以他們間的關係。另外也要注意下面程式led部份,此部份就是Particle.function()函式第一個參數"led"。

HTML程式:




Tell your device what to do!

"on">Turn the LED on.
"off">Turn the LED off.



在上面程式中your-device-ID-goes-here這部份要替換成您使用到的晶片ID,your-access-token-goes-here這部份也要替換成存取碼。








2017年11月28日 星期二

AR meets IoTs: 當擴增實境遇到物聯網-初接觸

軟硬體整合可參考用Unity工具來整合Arduino和Vuforia設計可以用光亮度來控制火焰大小文章。
擴增實境技術可以應用在虛實整合行銷服務應用上,而物聯網則可以用來收集資料,讓物品對物品能相互彼此交換資料,促使感知器和致動器經由物聯網的通訊進行自動控制或收集大量資料儲存在雲端。若能把兩項技術整合在一起,對於數據分析以及應用數據來進行虛實整合應用有很大的幫助。

有心想學習可以參閱:

Internet of Things (IoT) Cloud Based Photon Particle WiFi Microcontroller. Augmented Reality for Internet of Things.






Arduino的範例程式:
Photon Particle Wi-fi microcontroller code (based on Arduino) (*.ino file)

Unity端的範例應用程式:
Download Whole Augmented Reality IoT Tutorial Project Files (the result to test it) (*.rar file)

Arduino程式需要一塊硬體來執行,此範例用的是特定的晶片,在這個晶片上已經內嵌物聯網協定的軟體,可以減輕開發者的負擔,其晶片的資訊可參考下列網站:

2017年11月27日 星期一

多媒體動畫應用系陳百薰主任跨系指導

今天很難得邀請到本校擴增實境專家多媒體動畫應用系陳百薰主任前來指導,陳主任說明這些年來和學生打拼過程,以及介紹擴增實境的應用,收獲良多。


 
















擴增實境的虛擬按鈕(Augmented Reality Virtual Buttons)

什麼也可以用軟體來虛構出按鈕,真是超強的,超省的作法連按鈕的費用都可省掉。仔細看下面的影片,虛構出兩個按鈕,用手指輕按虛擬按鈕,就可以切換3D的角色。



下載原始程式: Download Whole Project files of VirtualButtons (the result to test it) (*.rar file)

打開VirtualButtons專案,在Project視窗下,選擇Assets目錄下,選擇VirtualNuttonResult,如下圖右下角的紅色方塊,在左上角的方塊上有btnLeft和btnRight兩個按鈕物件。在兩個按鈕上方,可以看到model1和model2兩個角色。


在點選btnLeft物件後,在下圖右方可以看到這個物件內嵌一個Virtual Button Behaiour.cs程式,並且在右邊可以看到有Name和Sensitivity Setting兩個屬性,請特別留意Name。


接下來,請點選ImageTarget物件,在右下方您可以看到VirtualButtonEventHandler.cs腳本程式,這是用來處理按鈕事件的程式。


VirtualButtonEventHandler.cs程式列表如下:


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

public class VirtualButtonEventHandler : MonoBehaviour, IVirtualButtonEventHandler {

    // Private fields to store the models
    private GameObject model_1;
    private GameObject model_2;
private GameObject btn_1;
private GameObject btn_2;
    /// Called when the scene is loaded
    void Start() {

        // Search for all Children from this ImageTarget with type VirtualButtonBehaviour
        VirtualButtonBehaviour[] vbs = GetComponentsInChildren(); //取得所有虛擬按鈕的物件
        for (int i = 0; i < vbs.Length; ++i) {
            // Register with the virtual buttons TrackableBehaviour
            vbs[i].RegisterEventHandler(this);//註冊事件處理程序
        }

        // Find the models based on the names in the Hierarchy
model_1 = transform.Find("model1").gameObject;//取得3D模型物件
model_2 = transform.Find("model2").gameObject;

btn_1 = transform.Find("hs1").gameObject; //取得按鈕上的特效物件,用特效物件來表示按鈕可以被按下
btn_2 = transform.Find("hs2").gameObject;
        // We don't want to show Jin during the startup
model_1.SetActive(false);
model_2.SetActive(false);
btn_1.SetActive(true);
btn_2.SetActive(true);
    }

    ///



    /// Called when the virtual button has just been pressed:
    ///
    public void OnButtonPressed(VirtualButtonAbstractBehaviour vb) {
//Debug.Log(vb.VirtualButtonName);
Debug.Log("Button pressed!");
     
switch(vb.VirtualButtonName) { //判斷按下那一個按鈕
case "btnLeft":
btn_1.SetActive(false);
btn_2.SetActive(true);
model_1.SetActive(false);
model_2.SetActive(true);
                    break;
case "btnRight":
btn_1.SetActive(true);
btn_2.SetActive(false);
model_1.SetActive(true);
model_2.SetActive(false);
           break;
         //   default:
         //       throw new UnityException("Button not supported: " + vb.VirtualButtonName);
         //           break;
        }
     
    }

    /// Called when the virtual button has just been released:
    public void OnButtonReleased(VirtualButtonAbstractBehaviour vb) {
Debug.Log("Button released!");
}
}



2017年11月26日 星期日

擴增實境名片(Augmented Reality Business Card)程式解析


擴增實境技術是很棒的智慧行銷工具,一個業務出門,往往需要帶一大堆型錄和自己的名片,假如可以用自己的名片來代替型錄,而這個型錄又是3D而且有動畫功能,這應讓是很棒的工具,今天要跟大介紹就是擴增實境名片(Augmented Reality Business Card)。

教學部落格:Augmented Reality Business Card

教學影片:


下載原始程式:Download AR Business Card Tutorial Project Files (the result to test it) (*.rar file)

解開壓縮檔後,在Unity打開,在Project/AppContent/Script目錄下,可以找兩個程式為ModelRotation.cs和SwipeImage.cs。

SwipeImage.cs的原始程式列表:
using UnityEngine;
using System.Collections;

[RequireComponent (typeof (BoxCollider))] //or other collider
public class ModelRotation : MonoBehaviour {

public float rotationSpeed;
public bool rightSide = false;
private bool onOff = false;

// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {
if(onOff && !rightSide)
transform.Rotate(Vector3.up, rotationSpeed * Time.deltaTime, Space.World);
else if(onOff && rightSide)
transform.Rotate(Vector3.up, -rotationSpeed * Time.deltaTime, Space.World);
}

void OnMouseDown() {
if(onOff)
onOff = false;
else
onOff = true;
}
}

SwipeImage.cs是內嵌在動畫角色上,因此可以點選HatsuneRumba角色就可以查看程式內全域變數,可以看下圖右下角看到rotationSpeed和rightSide,就能改變其速度和旋轉方向。


ModelRotation.cs的全數變數在下圖右下方,有Page、Image、Sliding Speed、Model分別表示型錄頁數和型錄平面圖、滑動速度、以及3D模型。

詳細程式如下:
// based on: http://forum.unity3d.com/threads/swipe-in-all-directions-touch-and-mouse.165416/
// add video: https://developer.vuforia.com/forum/faq/unity-how-do-i-create-simple-videoplayback-app
// and: https://developer.vuforia.com/forum/faq/unity-how-do-i-play-video-url
using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class SwipeImage : MonoBehaviour
{
public GameObject[] page;

Vector2 firstPressPos;
Vector2 secondPressPos;
Vector2 currentSwipe;

Vector2 deltaPosition;
Vector2 currentPosition;

int amount = 0;
int i = 0;
float accumulatePosition = 0.0f;
public Image[] image;
public float SlidingSpeed = 2.0f;

public GameObject[] model;

//Vector3 originalPosition = new Vector3 (-200,0,-6);


// Use this for initialization
void Start ()
{
amount = GameObject.FindGameObjectsWithTag("page").Length; // amount of models
page = new GameObject[amount];
foreach(GameObject gameObj in GameObject.FindGameObjectsWithTag("page"))  // iterate through model names
{
Debug.Log(gameObj);
page[i] = gameObj;
// page[i].GetComponent().localPosition = new Vector3 (originalPosition.x,originalPosition.y,originalPosition.z); // set to original position
page[i].SetActive(false);
model[i].SetActive (false);
i++;
}
i = 0;
page [0].SetActive (true);
model[0].SetActive (true);
Debug.Log(amount);
for(int j = 0; j < amount; j++ ) {
Debug.Log (j + ": " + page[j]);
}
}

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

//inside class


public void Swipe ()
{
if (Input.GetMouseButtonDown (0)) {
//save began touch 2d point
firstPressPos = new Vector2 (Input.mousePosition.x, Input.mousePosition.y);
}
if (Input.GetMouseButton(0)) {
//Vector2 touchDeltaPosition = Input.mousePosition;
//lastMousePosition +=touchDeltaPosition.x;
currentPosition = new Vector2 (Input.mousePosition.x, Input.mousePosition.y);
//create vector from the two points
//deltaPosition = new Vector2 (currentPosition.x - lastPosition.x, currentPosition.y - lastPosition.y);
deltaPosition = new Vector2 (currentPosition.x - firstPressPos.x, currentPosition.y - firstPressPos.y);
//if (deltaPosition.x<0 nbsp="" p=""> accumulatePosition += deltaPosition.x;

//if (deltaPosition.x>0)
// accumulatePosition -= deltaPosition.x;
//Debug.Log ("accumulateDelta: " + accumulatePosition + " deltaPosition: " + deltaPosition.x);
float val = System.Math.Abs(deltaPosition.x);
float remap = val.Remap(0, 200, 1, 0);
Debug.Log ("ABS" + val + " REMAP: " + remap);
image[i].color =  new Color(1.0f,1.0f,1.0f,remap);

if(deltaPosition.x < 0.0f){
page[i].GetComponent().localPosition = new Vector3(deltaPosition.x * SlidingSpeed, 0, -6); // page[i].GetComponent().localPosition.x + 
//page[i].transform.Translate(Vector3.left  * 500 * Time.deltaTime);
} else if (deltaPosition.x > 0.0f) {
page[i].GetComponent().localPosition = new Vector3(deltaPosition.x * SlidingSpeed, 0, -6); // page[i].GetComponent().localPosition.x +
//page[i].transform.Translate(Vector3.right * 500 * Time.deltaTime);
}
}

if (Input.GetMouseButtonUp (0)) {
accumulatePosition = 0;
//save ended touch 2d point
secondPressPos = new Vector2 (Input.mousePosition.x, Input.mousePosition.y);

//create vector from the two points
currentSwipe = new Vector2 (secondPressPos.x - firstPressPos.x, secondPressPos.y - firstPressPos.y);
//Debug.Log ("delta" + (secondPressPos.x - firstPressPos.x));
//normalize the 2d vector
currentSwipe.Normalize ();

//swipe upwards
if (currentSwipe.y > 0 && currentSwipe.x >-0.5f && currentSwipe.x < 0.5f) {
Debug.Log ("up swipe");
}
//swipe down
if (currentSwipe.y < 0 && currentSwipe.x > -0.5f && currentSwipe.x < 0.5f) {
Debug.Log ("down swipe");
}
//swipe left
if (currentSwipe.x > 0 && currentSwipe.y > -0.5f && currentSwipe.y < 0.5f) {
Debug.Log ("left swipe");

page[i].GetComponent().localPosition = new Vector3 (0,0,-6); // set to original position
page[i].SetActive (false);
model[i].SetActive (false);
image[i].color =  new Color(1.0f,1.0f,1.0f,1.0f);
i--;

if (i < 0)
i = amount-1;

model[i].SetActive (true);
page[i].SetActive (true);
}
//swipe right
if (currentSwipe.x > 0 && currentSwipe.y > -0.5f && currentSwipe.y < 0.5f) {
Debug.Log ("right swipe");
page[i].GetComponent().localPosition = new Vector3 (0,0,-6); // set to original position
page[i].SetActive (false);
model[i].SetActive (false);
image[i].color =  new Color(1.0f,1.0f,1.0f,1.0f);
i++;

if (i > (amount-1))
i=0;

page[i].SetActive (true);
model[i].SetActive (true);
}
if ( (currentSwipe.y > 0 && currentSwipe.x >-0.5f && currentSwipe.x < 0.5f) == false && (currentSwipe.y < 0 && currentSwipe.x >-0.5f && currentSwipe.x <0 -0.5f="" .5f="" 0.5f="" 0="" amp="" currentswipe.x="" currentswipe.y="" false="" gt="" lt="" nbsp="" p=""> Debug.Log("Click");
//if (i==0)
// Application.OpenURL("https://www.youtube.com/EdgarasArt");
//if (i==1)
// Application.OpenURL("https://www.ourtechart.com");
//if(i==2)
// Application.OpenURL("https://www.youtube.com/EdgarasArt");
}
}
}



}

public static class ExtensionMethods {

public static float Remap (this float value, float from1, float to1, float from2, float to2) {
return (value - from1) / (to1 - from1) * (to2 - from2) + from2;
}

}