RubyのModuleで困った。。。

Rubyのmoduleで困ったので
共有します!

困っていた時の例

module Hello1
      def hello()
            puts "hello1"
      end
end

module Hello2
      def hello()
            puts "hello2"
      end
end

include Hello1
include Hello2

Hello1::hello() # hello2
Hello2::hello() # hello2

えっ???

module Hello1
      def hello()
            puts "hello1"
      end
end

module Hello2
      def hello()
            puts "hello2"
      end
end

include Hello1

Hello1::hello() #hello1
Hello2::hello() #hello1

えっ???????????

下記が一番欲しかった動作

module Hello1
      def hello()
            puts "hello1"
      end
       module_function :hello
end

module Hello2
      def hello()
            puts "hello2"
      end
       module_function :hello
end

Hello1::hello() #hello1
Hello2::hello() #hello2

自分のイメージは
名前空間に使うなら module_functionで。
includeはmixinに使うみたいです。。。

UnityでノンストレスARKitライフを送るために。。。

最近UnityでARKitのFaceTrackingの機能をつかっています。

UnityのARKitには Unity ARkit RemoteというUnityEditor上でiPhoneを使って
Debugできる機能がありますがこれが思ったよりも使えないです。
結局毎回XcodeプロジェクトにビルドしてiPhoneに流して実機で確認する。。。

このストレスから逃れるために
少しDebug用のXcodeプロジェクトを作ったので
よければ使ってみてください。

GitHub - LeafChage/ios-facetracker
これはただ、iPhone側で取得した顔情報を
UDPで送信し続けるというだけのアプリです。

このぐらいであればみなさんすぐに作ると思いますが、
それさえめんどくさい人がいればこれを使ってみてください!

Unityで画像のパスからアスペクト比を保ちながら貼り付ける

メモがてら張りますが、
このまま使えるかどうかは試していません。

ヒントにしかならないかも。。。

private void uploadImage() {
               // 画像貼り付け
               Texture2D texture = new Texture2D(Screen.width, Screen.height);
               texture.LoadImage(System.IO.File.ReadAllBytes(path));
               this.background.BackGroundImage.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.zero);

               //aspect比を保つ
               this.background.BackGroundImage.preserveAspect = true;
               this.background.BackGroundImage.SetNativeSize();  //これ不要かも

               // aspect比の調整
               float height = this.background.BackGroundImage.mainTexture.height;
               float width = this.background.BackGroundImage.mainTexture.width;
               this.background.BackGroundImage.rectTransform.anchoredPosition = Vector2.zero;

               float aspect_texture = (float)height / (float)width;
               float aspect_screen = (float)Screen.height / (float)Screen.width;
               if (aspect_screen > aspect_texture)
               {
                   //画像よりスクリーンの方が縦が長い時
                   Vector2 v = this.background.BackGroundImage.rectTransform.sizeDelta;
                   v.x = v.x * Screen.height / v.y;
                   v.y = Screen.height;
                   this.background.BackGroundImage.rectTransform.sizeDelta = v;
               }
               else
               {
                   //画像の方がスクリーンより縦が長い時
                   Vector2 v = this.background.BackGroundImage.rectTransform.sizeDelta;
                   v.y = v.y * Screen.width / v.x;
                   v.x = Screen.width;
                   this.background.BackGroundImage.rectTransform.sizeDelta = v;
               }

     // 画像の真ん中を真ん中にする
               this.background.BackGroundImage.rectTransform.pivot = new Vector2(0.5f, 0.5f);
               this.background.BackGroundImage.rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
               this.background.BackGroundImage.rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
}

UnityでiOSのnative plugin

UnityでiOSのカメラロールを取得したかったので
native pluginを書きました。

これにはまってしまって抜け出せなくなってしまったので、
メモを残します:)

UnityでiOS(Swift 3)とAndroid(Java)のNative連携 - カメラロールから画像を取得し、Unity側で表示する - Qiita
基本的にはこの記事のコードを丸コピで進めていったのですが、
少し改良してこのようにしました。

public class CameraPicker
{
    [DllImport ("__Internal")]
    private static extern float OpenCameraRoll (string path);

    private Action<string> callback = (s) => { Debug.Log(s); };

    public void  CameraPickerAction(Action<string> callback) {
	this.callback = callback;
    }

    public void WakeUp()
    {
        if (Application.isEditor)
        {
            this.callback("Assets/Resources/test/background_test.jpg");
        }
        else
        {
            switch (Application.platform)
            {
                case RuntimePlatform.IPhonePlayer:
                    OpenCameraRoll( Application.temporaryCachePath + "/tempImage");
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
    }

    public void CallbackAction(string path)
    {
        Debug.Log("callback!!!!!!!!!!!!");
	this.callback(path);
    }
}

このクラスのインスタンスをカメラロールを起動したいタイミングで作成して、
callbackのActionをセットして、WakeUpを実行すれば
起動するはずでしたが、何回やってもうまくいかない。

iPhone/Androidでネイティブプラグインを作るコツ…みたいなもの - テラシュールブログ

void UnitySendMessage(const char* オブジェクト名, const char* メソッド名, const char* 引数);

これをUnityで再現するなら、こんな処理になる。
GameObject.Find(オブジェクト名).SendMessage(メソッド名, 引数) ;```

色々なサイトを眺めていたところこのサイトにたどり着きました。

始めの詰まりは
UnitySendMessageの第一引数をクラス名にしていて呼ばれなかったこと(本当はオブジェクト名)

次の詰まりは
ユニークなオブジェクト名ではなかったことです。(クラス名と同じオブジェクト名でもうまくいかなかったような気がする)

「callbackできないよ!」
みたいなエラーが上がった時には確認してみてください。

Uniyで簡易的なColorPickerを作りました。

先日ラムダ式を使いたくてAction Classを見つけたのですが、
早速使ってみました。

using System;
using UnityEngine;
using UnityEngine.UI;

public class ColorPicker : MonoBehaviour
{
  //スライダーを三つ用意して使う
  [SerializeField] private Slider r;
  [SerializeField] private Slider g;
  [SerializeField] private Slider b;

  private Color rgb = new Color(0, 0, 0, 1);
  private Action<Color> changeRgbAction = (c) => { Debug.Log("no function"); };

  //ここで色が変わった時のコールバックをセットする
  public Action<Color> ChangeRGBAction
  {
      get{ return this.changeRgbAction; }
      set { this.changeRgbAction = value; }
  }

  private void Start()
  {
      this.r.onValueChanged.AddListener((r) =>
      {
          this.rgb.r = r;
          this.changeRgbAction(this.rgb);
      });
      this.g.onValueChanged.AddListener((g) =>
      {
          this.rgb.g = g;
          this.changeRgbAction(this.rgb);
      });
      this.b.onValueChanged.AddListener((b) =>
      {
          this.rgb.b = b;
          this.changeRgbAction(this.rgb);
      });
  }
}
// 使い方
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Test : MonoBehaviour {
	[SerializeField] private Image image;
	[SerializeField] private ColorPicker colorPicker;

    void Start()
    {
       //画像の色を変える
        this.colorPicker.ChangeRGBAction = (Color c) =>
       {
           this.image.color = c;
       };
    }

    void Update()
    {
    }
}

こんな感じになります。
f:id:pascal_tongue:20180309131943p:plain
f:id:pascal_tongue:20180309131951p:plain

Unityでラムダ式

日常にラムダ式を使いたい時ってありますよね?

UnityでHttpアクセスを行って
終わり次第コールバック関数を実行して欲しい時とかありますよね?

そういう時は
Activeクラスが使えます。

using System;
using System.Collections;
using UnityEngine;

public class HttpClient
{
      // シングルトン作り方
      private static HttpClient singleton = new HttpClient();
      public static HttpClient Singleton
      {
            get { return HttpClient.singleton; }
      }
      private HttpClient() {
      }

      // WWWという引数を持つをActiveクラスを渡している。
      public IEnumerator Get(string url, Action<WWW> okAction, Action<WWW> ngAction)
      {
            WWW www = new WWW(url);

            while (!www.isDone) { yield return null; }

            if (!string.IsNullOrEmpty(www.error))
            {
                  ngAction(www);
            }
            else
            {
                  okAction(www);
            }
      }
}

こう使います。

StartCoroutine( HttpClient.Singleton.Get( "https://www.ichikara.co.jp/",
                  (www) => {
                        Debug.Log(www.text);
                  },
                  (www) => {
                        Debug.Log(www.error);
                  }));

ちなみにActiveクラスは返り値なしで、
Funcクラスは返り値ありみたいです:)

C#のラムダ式はAction・Funcと一緒に理解を深めるとヨロシイようで - 銀の弾丸
ラムダ式っぽいのはActive、Funcクラスのシンタックスシュガーみたいですね。
あまいあまい。

Rustの`?`クエスチョンマーク2

最近Rust 勉強中です。

Rustのクエスチョンマーク(?) - c_leaf.blog
去年もRustの?について調べた時のメモがわりの記事を書いていたのですが
うまく理解できていなかったのでもう一度調べて書き直したいと思います。

rustc 1.21.0 (3b72af97e 2017-10-09)です。

下記はtxtファイルから中身を読み込む処理です。

let mut file = File::open("./hello.txt")?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;

?が出てきています。

このままmain関数に書くとエラーが起きます。

fn main() {
    let mut file = File::open("./hello.txt")?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
}
/*
  |
  | let mut file = File::open("./hello.txt")?;
  |             ---------------------------------
  |           |
  |           the `?` operator can only be used in a function that returns `Result` (or another type that implements `std::ops::Try`)
  |           in this macro invocation
  |
*/

? マークはResultを返す関数の中だけで使えるよ!でしょうか?

その通りでこの?マークは
関数の中でResultに対して使います。
Errが上がった場合すぐにErrをreturn、
Okが上がった場合処理を続行します。

こんな感じ

// read_file  read_file2は同じ処理
//?を使わない版
fn read_file() -> Result<String> {
    let mut file = match File::open("./hello.txt") {
        Ok(file) => file,
        Err(e) => return Err(e)
    };

    let mut contents = String::new();

    match file.read_to_string(&mut contents) {
        Ok(_) => {},
        Err(e) => return Err(e)
    }

    Ok(contents)
}

//?版
fn read_file2() -> Result<String> {
    let mut file = File::open("./hello.txt")?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    Ok(contents)
}

//これらを呼び出すときは
fn main() {
    // unwrapしちゃったり
    let str1 = read_file().unwrap();
    let str2 = read_file2().unwrap();

    // errorハンドリングしちゃったり
    match read_file() {
        Ok(src) => println!("{}", src),
        Err(err) => println!("{}", err)
    }
    match read_file2() {
        Ok(src) => println!("{}", src),
        Err(err) => println!("{}", err)
    }
}


参考にしました。
rust - What is this question mark operator about? - Stack Overflow