- 投稿日:2019-02-26T23:58:13+09:00
Rx風メソッドチェーンの定義方法
概要
Rx的なメソッドチェーンの定義方法について書きます。
あくまでも自分用の備忘録なので、細かい説明は書きません。後日、気が向いたら書きます。
使い方
test.cs//Class only public class Observe<T> { private T result{ get; } public Observe(T initial) => result = initial; public Observe<TR> Operation<TR>(Func<T, TR> function) => new Observe<TR>(function(result)); public void End(){} } public static class Observe{ public static Observe<T> Start<T>(Func<T> initial) => new Observe<T>(initial()); } //Class included interface public interface IObserve<T> { IObserve<TR> Operation<TR>(Func<T, TR> function); void End(); } public class Inheritance<T> : IObserve<T>{ private T result { get; } public Inheritance(T initial) => result = initial; public IObserve<TR> Operation<TR>(Func<T, TR> function) => new Inheritance<TR>(function(result)); public void End(){} } public static class Inheritance { public static IObserve<T> Start<T>(Func<T> initial) => new Inheritance<T>(initial()); } //How to use public class Hoge { public void Fuga() { Observe.Start(() => 1).Operation(x => x++).End(); Inheritance.Start(() => 1).Operation(x => x++).End(); } }追記:
Rx風とまでは行きませんが、下のコードでもそれっぽいことができます。test.cspublic static class Chain { public static TR MethodChain<T, TR>(this T value, Func<T, TR> function) => function(value); }
- 投稿日:2019-02-26T21:18:59+09:00
C#からPythonスクリプトを呼び出す
はじめに
唐突に画像と動画を加工してみたくなり、VisualStudio2017でPython3/OpenCVを使ってみました。
普段はC#を使っているので、使い慣れたC#からPythonスクリプトを呼び出せないか試してみました。
参考資料
下記のサイトを参考に実装しています。
Inter-process communication between C# and Python実装方法
言語 実装する処理 Python 「第1引数の値」 + 「第2引数の値」 を出力する C# 「第1引数の値」と「第2引数の値」を指定して、Pythonスクリプトを呼び出し、結果を出力する 1. Python側を実装
AdditionSample.pyimport sys if len(sys.argv) == 3: firstArgument = int(sys.argv[1]) secondArgument = int(sys.argv[2]) print(firstArgument + secondArgument) else: print('ArgumentException...')2. C#側を実装
Sample.csclass Program { static void Main(string[] args) { //VisualStudioが利用しているインタープリターのパス var pythonInterpreterPath = @"C:\sample\path\Anaconda3\python.exe"; //「1. Python側を実装」にて保存したスクリプトのパス var pythonScriptPath = @"C:\sample\path\AdditionSample.py"; var arguments = new List<string> { pythonScriptPath , "10", //第1引数 "20" //第2引数 }; var process = new Process() { StartInfo = new ProcessStartInfo(pythonInterpreterPath) { UseShellExecute = false, RedirectStandardOutput = true, Arguments = string.Join(" ", arguments), }, }; process.Start(); //python側でprintした内容を取得 var sr = process.StandardOutput; var result = sr.ReadLine(); process.WaitForExit(); process.Close(); Console.WriteLine("Result is ... " + result); } }実行結果
Result is ... 30
感想
この方法を使えば、C#とPythonを組み合わせた実装ができそうです。
しかし、この方法だとPython側でprintした内容を受け取ることしかできないようです。
また、指定したPythonスクリプトを実行するだけなので、自由にPython側の処理を呼べるというわけでもありません。処理内容にもよると思いますが、Python側をWebAPI化して、処理結果をJSON形式で結果を返すのが一番使いやすそうな気もします。
- 投稿日:2019-02-26T15:56:20+09:00
UnityのいろいろなTips
はじめに
当たり前に設定していることでも忘れてしまうことがよくあるので備忘録もかねて記事にしました。
Unityのバージョンは、2017.4 を基準に作成してあります。画面サイズを変更するとUIが崩れる
Canvas Scalerが"Constant Pixel Size"になっているのが原因。
下の画像のように"UI Scale Mode"を"Scale With Screen Size"にするとよい。
また、"Reference Resolution"にはメインで使用する解像度を指定しておく。
※ただし、アスペクト比を変える場合はここの設定だけでは不十分
スマートフォンの複数バージョン対応や、縦横持ち対応などのアスペクト比を変えた場合のUIの設計は、
Unity公式ドキュメントに 複数解像度のためのUI設計 がありますので、そちらを参照ください。
スクリプト上でUIを生成した時に原点がずれる
例えば、
Image img = new GameObject("img").AddComponent<Image>(); img.rectTransform.position = Vector2.zero;と、しても原点に生成されないときがあります。
UIの複数の解像度にも対応した相対的な位置は、"anchoredPosition"を使用します。Image img = new GameObject("obj").AddComponent<Image>(); img.rectTransform.anchoredPosition = new Vector2(0,0);Publicな変数がInspectorでも変更できてしまう
宣言した変数上に"[System.NonSerialized]"を書けばInspectorに表示されなくなります。
Editorで変更する仕様でない限り、書いておけば他人が見たときに外から読み取りたい旨がわかるようになります。[System.NonSerialized] Public int hoge = 0;Privateな変数をInspectorに表示させたい
表示させたい変数の上に"[SerializeField]"を書く。
Editor上で値を書き換えたいときにPublicだと外から読み(書き)たいのか、Inspectorから指定したいのかわからないので、privateな変数でも大丈夫ならこちらの方法で書くといいでしょう。[SerializeField] private int hoge = 0;フレームレートが落ちる(カクカクする)とキャラクターのスピードが遅くなる
Unity上でスクリプトを作成するとデフォルトでUpdate()が生成されてしまうため、そこに書きがちですが、Updateはフレームレート依存な関数なので、移動などの物理的な挙動に関してはFixedUpdate()に書くか、Update()に書く場合はTime.deltaTimeをかけるといいです。
参考までにvoid Update() { gameObject.transform.position += Vector3.forward * Time.deltaTime; }もしくは、
void FixedUpdate() { gameObject.transform.position += Vector3.forward; }他のScriptから参照したい
UnityというかC#の話なうえ、ケースバイケースでその時によって変わりますが、使い分けてください。
当たり前に使うことですが、なぜか調べてもなかなか出てこない上にGameObject.Find()が目立っている気がしたのでいろいろな方法を載せておきます。ManagerとしてSingletonにする
Enemyとか、Itemなど同じものが複数個生成される場合では使えませんが、GameManager等の一つしか生成されないスクリプトによく使う方法です。
hogeManager.cspublic int hoge = 100; public static Instance; void Awake() { if(Instance == null) Instance = this; } void OnDisable() { Instance = null; }とし、呼び出すほうでは、
void Start() { Debug.Log(hogeManager.Instance.hoge); //100 }とすると簡単に使用できます。Singletonの詳しい使い方や組み方、MonoBehaviourとのより良い共存方法などは調べると沢山出てきます。
そちらのほうが丁寧に分かりやすく解説されていると思いますので、各自で調べてみてください。FindWithTag()等で保持しておく
参照したいScriptがついているGameObjectにTagをつけて、StartやAwakeで保持しておく方法。
GameObject.Find()でも大丈夫ですが、重たい処理な為、特に利用が制限される場合じゃなければFindWithTag()を利用するのが無難だと思います。HogeScript hoge; void Start() { hoge = GameObject.FindWithTag("hoge").GetComponent<HogeScript>(); }Inspectorで直接アタッチする
SerializeField等でInspectorに表示させ、ドラッグアンドドロップでアタッチする方法です。
直感的でわかりやすく手間のかからない方法ですが、プロジェクトファイルを移動した際にアタッチが外れることが多々あります。接触したオブジェクトに送る
上記と違い、極端に限定的ですが、Enemyに当たったらダメージを与えるとか、Itemに触れたらインベントリに入れるなど、
接触した時に接触したもののスクリプトを呼びたい時に使う方法です。void OnTriggerEnter(collider col) { if(col.tag == "enemy") { col.GetComponent<enemy>().Damage(); } }あとがき
もっといろいろ書きたいことがあった気がしますが、思い出せないのでその都度更新していく予定です。
それではよきUnityライフを!参考文献
- 投稿日:2019-02-26T13:15:11+09:00
【Windows Forms】TabControl配下にあるタブ一欄の高さを取得する
最初に
少しニッチな話題ですが、
TabControl
を動的に作る際にTab
の選択欄の高さが欲しいことがありました。
「タブストリップ」と言うらしいです。タブストリップの高さを取得する情報が見つけられなかったのでこの記事を作成しました。
ベストな道かはいまいち判断できませんが、同じことを実装されたいと考えた方々の参考になれば幸いです。用語の意味
タブ・・・
TabControl
の上部に表示されるタブページを表示するためのコントロール(TabPage
のことではない)
タブストリップ・・・タブを選択する一覧のこと(詳細は下記)
タブページ・・・TabControl
の下部に表示される選択したタブと対応付けられたページのこと(TabPage
オブジェクトのこと)
TabControl
・・・タブストリップとタブページを持ち合わせたControl
オブジェクトタブストリップとは?
次の画像に表示されているタブの一覧のことを指します。
赤線が指している高さはTabControl配下のタブページの数とTabControlのWidthなどに依存するので、多ければ行が増えタブストリップの
Height
は高くなり、少なければ行が減りタブストリップのHeight
は低くなるはずです。そもそもTabの選択欄の高さが必要になった背景は?
GroupBox
の配下へ動的にTabControl
を追加した際に、次の2点の実装を行いたかったのです。
-TabControl
の全て(タブストリップ・タブページ含め)が表示されるようサイズを明示的に指定
-GroupBox
は子コントロール(TabControl
)のサイズに合わせて大きくするようにしたかった実装
別に難しいことを考える必要はありませんでした。
「タブの高さ」と「タブストリップの行数」さえ分かれば取得できるでしょう。次のように実装しました。
TabPage tabPage = new TabPage(); TabControl tab = new TabControl(); //「タブの高さ」×「タブストリップの行数」+「タブページの高さ」でtab全体を表示するための高さを取得 tab.Height = tab.ItemSize.height * tab.RowCount + tabPage.Height;
- 投稿日:2019-02-26T13:15:11+09:00
【Windows Forms】TabControl配下にあるタブ欄の高さを取得する
最初に
TabControl
を動的に作る際に「配下にあるタブ欄」の高さが欲しいことがありました。「タブストリップ」と言うらしいです。タブストリップの高さを取得する情報が見つけられなかったのでこの記事を作成しました。
ベストな道かはいまいち判断できませんが、同じことを実装されたいと考えた方々の参考になれば幸いです。用語の意味
タブ・・・
TabControl
の上部に表示されるタブページを表示するためのコントロール(TabPage
のことではない)
タブストリップ・・・タブを選択する一覧のこと(詳細は下記)
タブページ・・・TabControl
の下部に表示される選択したタブと対応付けられたページのこと(TabPage
オブジェクトのこと)
TabControl
・・・タブストリップとタブページを持ち合わせたControl
オブジェクトタブストリップとは?
次の画像に表示されているタブの一覧のことを指します。
赤線が指している高さはTabControl配下のタブページの数とTabControlのWidthなどに依存するので、多ければ行が増えタブストリップの
Height
は高くなり、少なければ行が減りタブストリップのHeight
は低くなるはずです。そもそもタブストリップの高さが必要になった背景は?
TabControl
を親コントロールへ追加する際に、次の2点の実装を行いたかったことがきっかけです。
TabControl
の全て(タブストリップ・タブページ含め)が表示されるようサイズを変更- 親コントロールは子コントロール(
TabControl
)のサイズを元にサイズを調整する1点目の実装で、
TabControl
のサイズを決めるためにはタブストリップの高さが必要になりました。実装
難しいことを考える必要はありませんでした。
「タブの高さ」と「タブストリップの行数」さえ分かれば取得できます。次のように実装しました。
TabPage tabPage = new TabPage(); TabControl tab = new TabControl(); //「タブの高さ」×「タブストリップの行数」+「タブページの高さ」でtab全体を表示するための高さを取得 tab.Height = tab.ItemSize.height * tab.RowCount + tabPage.Height;
- 投稿日:2019-02-26T12:55:44+09:00
ASP.NET CoreをNginxで動かす場合に必要なコード(メモ)
ASP.NET Core 構築で必要なコードのメモ
Nginxなどのプロキシーを通して配信する場合
日本語を含むコードの場合そのほか、現在コーディング中においてのメモ他
日本語対処用コード
日本語と言うよりUTF8による2byte以上の文字の場合にHTMLエンティティされる問題を解決するおまじない
public void ConfigureServices(IServiceCollection services) { // UTF8文字コード設定 services.Configure<Microsoft.Extensions.WebEncoders.WebEncoderOptions>(options => { options.TextEncoderSettings = new System.Text.Encodings.Web.TextEncoderSettings(System.Text.Unicode.UnicodeRanges.All); }); ... 以下略プロキシー設定
プロキシーを通す場合のおまじない
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { ... 以下略 // リバースプロキシー設定用 app.UseForwardedHeaders(new Microsoft.AspNetCore.Builder.ForwardedHeadersOptions { ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedFor | Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedProto }); ... 以下略設定情報
設定情報系の読み込み用のおまじない(まだ意味の把握全容が出来ていない)
using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; ... 以下略 public Microsoft.Extensions.Configuration.IConfigurationRoot Configuration { get; } public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) .AddEnvironmentVariables(); Configuration = builder.Build(); ... 以下略途中です。