2017년 8월 15일 화요일

Unity, android 특정 앱의 설치 여부 확인(AndroidJavaClass사용)

안드로이드 환경에서 특정 앱의 설치 여부를 패키지 이름으로 확인합니다.


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

public class AndroidUtil : MonoBehaviour 
{
    #if UNITY_ANDROID && !UNITY_EDITOR 

    public static bool IsAppInstalled(string bundleID)
    {
        AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
        AndroidJavaObject packageManager = currentActivity.Call<AndroidJavaObject>("getPackageManager");

        AndroidJavaObject launchIntent = null;

        //if the app is installed, no errors. Else, doesn't get past next line
        try
        {
            launchIntent = packageManager.Call<AndroidJavaObject>("getLaunchIntentForPackage", bundleID);
        }
        catch (Exception ex)
        {
            Debug.Log("exception" + ex.Message);
        }

        return (launchIntent == null ? false : true);
    }

    #endif
}



아래처럼 확인 가능
bool existApp = AndroidUtil.IsAppInstalled("com.android.otherApp");


2017년 8월 7일 월요일

UniRx Note3- OnTriggerXXXXAsObservable (extension method)

void Test_OnTrigger()
{
    Rigidbody rigidBody = GetComponent<Rigidbody>();

    // OnTrigger
    Debug.Log("---------------------------------------------------------------------------------------------------");
    Debug.Log("OnTrigger Enter/Stay/Exit AsObservable Test");

    bool zoneFlag = false;

    // 플래그가 유효한 동안 위쪽으로 힘을 가하면 
    this.FixedUpdateAsObservable()
        .Where(_ => zoneFlag)
        .Subscribe(_ => rigidBody.AddForce(Vector3.up));

    // Zone에 들어오면 하면 플래그를 활성화
    this.OnTriggerEnterAsObservable()
        .Where(x => x.gameObject.tag == "Zone")
        .Subscribe(_ => { 
            zoneFlag = true;
            Debug.Log("Zone Enter");
        });

    this.OnTriggerStayAsObservable()
        .Where(x => x.gameObject.tag == "Zone")
        .Subscribe(_ => { 
            Debug.Log("Zone Stay");
        });

    // Zone에서 나가면 플래그를 해제 
    this.OnTriggerExitAsObservable()
        .Where(x => x.gameObject.tag == "Zone")
        .Subscribe(_ => { 
            zoneFlag = false;
            Debug.Log("Zone Exit");
        });
}

UniRx Note2 - Observable.FromCoroutine

void TestFromCoroutine()
{
    // 5초 카운트하는 코루틴 스트림을 만듦
    Observable.FromCoroutine<int>(observer => GameTimerCoroutine(observer, 5))
        .Subscribe(t => Debug.Log(t));
}

// 초기 값에서 0까지 카운트하는 코루틴 
private IEnumerator GameTimerCoroutine(IObserver<int> observer, int initialCount)
{
    var current = initialCount;
    while (current > 0)
    {
        observer.OnNext(current--);
        yield return new WaitForSeconds(1);
    }
    observer.OnNext(0);
    observer.OnCompleted();
}

UniRx Note1 - ReactiveProperty, ReactiveCollection , ReactiveDictionary, Observable.Create, Observable.Timer...

// 멤버 변수를 인스펙터 필드에 노출
[SerializeField] 
private IntReactiveProperty rpInt = new IntReactiveProperty(100);

[SerializeField] 
private LongReactiveProperty rpLong = new LongReactiveProperty(100);

[SerializeField]
private ByteReactiveProperty rpByte = new ByteReactiveProperty(100);

[SerializeField]
private FloatReactiveProperty rpFloat = new FloatReactiveProperty(100);

[SerializeField]
private BoolReactiveProperty rpBool = new BoolReactiveProperty(true);

[SerializeField]
private StringReactiveProperty rpString = new StringReactiveProperty("string");

[SerializeField]
private Vector2ReactiveProperty rpVector2 = new Vector2ReactiveProperty(Vector2.zero);

[SerializeField]
private ColorReactiveProperty rpColor = new ColorReactiveProperty(Color.clear);




// ReactiveProperty
ReactiveProperty<int> rp = new ReactiveProperty<int>(10);

rp.Value = 0;
rp.Subscribe(x => Debug.Log(x));
rp.Value = 10;


//ReactiveCollection
//ReactiveCollection<T> ReactiveProperty와 같은 것이며, 상태의 변화를 알리는 기능이 내장  List<T>
ReactiveCollection<int> rc = new ReactiveCollection<int>();

rc.ObserveAdd().Subscribe(x =>
    {
        Debug.Log(string.Format("ReactiveCollection Add [{0}] = {1}", x.Index, x.Value));
    });

rc.ObserveRemove().Subscribe(x =>
    {
        Debug.Log(string.Format("ReactiveCollection Remove [{0}] = {1}", x.Index, x.Value));
    });

rc.Add(10);
rc.Add(20);
rc.Add(30);
rc.Remove(20);



//ReactiveDictionary<T1, T2>
ReactiveDictionary<int, string> rd = new ReactiveDictionary<int, string>();

rd.ObserveAdd().Subscribe(x =>
    {
        Debug.Log(string.Format("ReactiveDictionary Add [{0}] = {1}", x.Key, x.Value));
    });

rd.ObserveRemove().Subscribe(x =>
    {
        Debug.Log(string.Format("ReactiveDictionary Remove [{0}] = {1}", x.Key, x.Value));
    });

rd.Add(1, "red");
rd.Add(2, "green");
rd.Add(3, "blue");
rd.Remove(2);



//Observable.Create의 예
// 0에서 100까지 10 단위로 값을 발행하는 스트림 
Observable.Create<int>(observer =>
    {
        Debug.Log("Start");

        for (var i = 0; i <= 100; i += 20)
        {
            observer.OnNext(i);
        }

        Debug.Log("Finished");
        observer.OnCompleted();
        return Disposable.Create(() =>
            {
                Debug.Log("Dispose");
            });

    }).Subscribe(x => Debug.Log(x));



// Observable.Start의 예
// 주어진 블록을 스레드에서 실행 
Observable.Start(() =>
    {
        //Google웹 페이지 요청
        var req = (HttpWebRequest)WebRequest.Create("https://google.com");
        var res = (HttpWebResponse)req.GetResponse();
        using (var reader = new StreamReader(res.GetResponseStream()))
        {
            return reader.ReadToEnd();
        }
    })
    .ObserveOnMainThread() // Unity 메인 스레드로 전환 
    .Subscribe(x => Debug.Log(x)); // write google web page



// Observable.Timer / TimerFrame의 예
// Observable.Timer : 일정 시간 후에 메시지를 발행 
Debug.Log("Observable.Timer / TimerFrame Test");
Observable.Timer(System.TimeSpan.FromSeconds(2))
    .Subscribe(_ => Debug.Log("2초 경과"))
    .AddTo(this);

// 5초 이후에 1초간격으로 호출
Observable.Timer(System.TimeSpan.FromSeconds(5), System.TimeSpan.FromSeconds(1))
    .Subscribe(x => Debug.Log("주기적으로 수행 : " + x.ToString()))
    .AddTo(this);


// 60frame이후 30frame마다 주기적으로 수행
Observable.TimerFrame(60, 30)
    .Subscribe(x => Debug.Log("frame마다 주기적으로 수행 : " + x.ToString()))
    .AddTo(this);