STUDIO yu- blog

STUDIO yu- blog

備忘録メモ。プランニングや技術関連が中心。

Amebaでブログを始めよう!
private string url;
public GameObject obj;

public void urlGET(string tgturl){
    if(Application.internetReachability == NetworkReachability.NotReachable){
        Destroy(gameObject);
    }
    this.url = tgturl;
    StartCoroutine("download");
}

private IEnumerator download(){
    WWW w = new WWW(url);
    yield return w;
    obj.DownloadReturn(w.text);
    w.Dispose();
    Destroy(gameObject);
}

―――――――――――――――――――――――――――――

ま、C#しか書かないんですけどね。

objはEditor上で突っ込んであげてください。
最後のDownloadReturnで、結果を受け取りたいクラスに値を渡しています。
ここではtextですが、そこはよしなに変えちゃってください。
自前のPHPでも叩くようにすると割と簡単にサーバとのやりとりが実装できちゃったりします。

さて、yieldとcoroutineとかいう気持ち悪いシロモノですが、
ポイントは

非同期メソッドはIEnumeratorで作る
・StartCoroutineで呼び出す

の2点です。
IEnumerator云々はよく書いてあるんですが、
StartCoroutineで呼び出すところでハマりがち。っていうかハマった。

なんとなく気持ち悪いのでprivateで書いてますが、気分の問題な気もします。
ちなみに、上記urlGETメソッドの最初で、
ネットワーク接続の有無を確認しています。ご参考までにどうぞ。

WWWクラスはメモリ食うらしいので、こいつをプレハブ化してやって
適宜Instantiate/Destroyしてやってください。
サンプルコードは下記参照で。
http://answers.unity3d.com/questions/318743/how-to-get-gps-lattitude-and-longitude-values-.html

さて、locationからどんな値が取得できるかというと

・latitude/longitude
緯度/経度。
これはイメージしやすいかと思います。

・altitude
標高です。

・horizontalAccuracy/verticalAccuracy
GPSから取得した位置情報の誤差。
値が小さければ小さいほど精度が高いことになります。

horizontalAccuracy
は緯度/経度が取得した値からどれだけズレている可能性があるか。

verticalAccuracyは標高にかかる誤差。
単位はメートル。平気で数百m単位で誤差があるようで。

・timestamp
上記値をいつ取得したか、1970年からカウントした実時間の累計値。
あまり使う場面はないかもしれません。

――

サンプルコードはあれど、取得できる値(特にAccuracyまわり)についての
日本語文献が少なかったのでメモ。
Public Function makeWhiteSilhouette(ByVal tex As Bitmap) As Bitmap
        If tex Is Nothing Then
            Return Nothing
        End If

        Dim _texShadow As New Bitmap(tex.Width, tex.Height)

        Dim f(tex.Width * tex.Height * 4) As Byte
        Dim bmd As Imaging.BitmapData
        bmd = tex.LockBits(New Rectangle(0, 0, tex.Width, tex.Height), Imaging.ImageLockMode.ReadOnly, Imaging.PixelFormat.Format32bppArgb)
        System.Runtime.InteropServices.Marshal.Copy(bmd.Scan0, f, 0, f.Length - 1)
        tex.UnlockBits(bmd)

        For i = 0 To f.Length / 4 - 1
            If f(i * 4 + 3) <> 0 Then
                f(i * 4 + 0) = 255
                f(i * 4 + 1) = 255
                f(i * 4 + 2) = 255
            Else
                f(i * 4 + 0) = 0
                f(i * 4 + 1) = 0
                f(i * 4 + 2) = 0
                f(i * 4 + 3) = 0
            End If
        Next
        Dim bmdShadow As Imaging.BitmapData
        bmdShadow = _texShadow.LockBits(New Rectangle(0, 0, _texShadow.Width, _texShadow.Height), Imaging.ImageLockMode.WriteOnly, Imaging.PixelFormat.Format32bppArgb)
        System.Runtime.InteropServices.Marshal.Copy(f, 0, bmdShadow.Scan0, f.Length - 1)
        _texShadow.UnlockBits(bmdShadow)

Return _texShadow

End Function

--------------------------------------------------------

画像の自由な色変更を行う際、読み込んだ色情報だけでなく、
真っ白なシルエットがほしいときがあります。
BitmapDataを用いて、それなりに高速にホワイトシルエット画像を生成するコードです。

BitmapをLockBitsしてメモリアドレスを(仮想的に)固定して、
そこの(疑似)ポインタを取得してMemCopy的なことをしています。
UnlockBitsを忘れずに。

ちなみに、アルファ成分はそのままにしておきたいので、
RGBA8888の4番目(A部分)の値には手を入れていません。

■処理の流れ
1. 出力用のビットマップを用意
2. バイト配列(32bit * 総ピクセル数)を用意
3. 元画像をメモリにアロケート(固定)
4. Marshal.Copyでバイト配列に画素データを一括コピー
5. バイト配列を画素データとしてごにょごにょしてやる
6. 出力用のビットマップをアロケート
7. バイト配列をMarshal.Copyして画素データに上書き
8. 完成!

バイト配列の*4は、画素データが32bit = 4Byteなので*4しています。
シルエットに限らず、画像処理をそれなりに高速に行う場合には
GetPixel/SetPixelではなく、BitmapDataを経由するのがオススメです。
using UnityEngine;
using System.Collections;

public class VibrateScript {
    public static void vibrate(int msec) {
        AndroidJavaObject unityPlayer = new AndroidJavaClass( "com.unity3d.player.UnityPlayer" );
        AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>( "currentActivity" );
        AndroidJavaObject vibrator = currentActivity.Call<AndroidJavaObject>("getSystemService", "vibrator");

        vibrator.Call("vibrate", msec);

vibrator.Dispose();
        currentActivity.Dispose();
        unityPlayer.Dispose();
    }
}
                                                                                    

はい。別段特別なことはしてないですが。
こちらのスクリプトをPluginsフォルダ以下に配置してやれば準備OKです。
VibrateScript.vibrate(50)など、ms単位で指定して端末をバイブさせることができます。

1コールごとにnewが走るのが気持ち悪い場合は、public staticで
InitializeとDestroyを定義してやってください。

ちなみにAndroidのバイブレーションを使用する場合、パーミッションの設定が必要になります。
manifest.xmlを直接編集しても良いですが、他のアセットから置換される可能性もあるので、
上記スクリプトとは別にHandheld.Vibrate()を呼んでおくと、
Unityが自動でパーミッションを設定してくれるので便利です。