- 投稿日:2020-01-21T23:48:56+09:00
C#の基礎知識 No.1
今後必要になってくると思うので、Microsoftが出しているチュートリアルの内容を議事録としてまとめました。
文字列の処理
二つの方法がある。
Foobar.csstring friend = "Tom"; Console.WriteLine("Hello" + friend);この方法だとエラーを吐くことなく出力が可能ではあるが、一回一回「+」を入れなければならないので面倒。
そのため、Foobar.csstring friend = "Tom"; Console.WriteLine($"Hello {friend}");でも同じ結果が出力される。
文字列の開始引用符の前に$
を入れることにより、文字列内に変数が入れることが可能。文字列の追加操作
トリミング
無駄な空白がある文字列のトリミングを行うことも可能。
Foobar.cs// 以下のような変数を定義すると string food = " apple "; Console.WriteLine($"[{food}]"); // このように出力される → [ apple ]そのため、Trimメソッドを用いる
Foobar.csstring trimFood = food.Trim(); Console.WriteLine($"[{trimFood}]"); → [apple] // 先頭のみトリミング trimFood = food.TrimStart(); Console.WriteLine($"[{trimFood}]"); → [apple ] // 末尾のみトリミング trimFood = food.TrimEnd(); Console.WriteLine($"[{trimFood}]"); → [ apple]置き換え
文字列を置き換えすることも可能。
Foobar.csstring fav = "Like Movie"; Console.WriteLine(fav); → Like Movie //置き換えを行う時はReplaceメソッドを使用する fav = fav.Replace("Movie", "Running"); Console.WriteLine(fav); → Like Running文字サイズ変更
全てを大文字・小文字に変換することも可能。
Foovar.csConsole.WriteLine(fav.ToUpper()); → LIKE RUNNING Console.WriteLine(fav.ToLower()); → like runnning文字列の検索
文字列内に検索文字列が含まれているかどうかを調べることが可能。
出力はTrue
かFalse
のどちらかによるboolean型
メソッドは3種類あり各々に違いがある。
Containts
: 文字列のどこかに検索文字列があればTrueを返し、なければFalseを返す
StartsWith
: 文字列の先頭に検索文字列があればTrueを返す
EndsWith
: 文字列の末尾に検索文字列があればTrueを返すFoobar.csstring intro = "I have no friends, but live strongly"; // Contains Console.WriteLine(intro.Containts("friends")); Console.WriteLine(intro.Containts("foods")); // StartsWith Console.WriteLine(intro.StartsWith("I")); Console.WriteLine(intro.StartsWith("friends")); // EndsWith Console.WriteLine(intro.EndsWith("stringly")); Console.WriteLine(intro.EndsWith("friends")); → True → False → True → False → True → False
- 投稿日:2020-01-21T22:09:42+09:00
【Unity/C#】コルーチンを自前で動かすためにIEnumeratorについて簡単に調べた
コルーチンを自前で動かしたい
コルーチンは
MonoBehaviour
を継承していればStartCoroutine
で動かすことができます。しかし、MonoBehaviour
を継承していなくても使いたい場面は割と多いです、多分。
MonoBehaviour
なしでコルーチンを動かす方法は調べるとそれなりに出てきますが、そもそもコルーチンで使われているIEnumerator
とはなんぞ?から始めたい所存です。IEnumeratorインターフェース?
MSDNを見てみるとシンプルに書かれています。
非ジェネリック コレクションに対する単純な反復処理をサポートします。
IEnumerator
インターフェースは反復処理を実現するためのインターフェースになります。
コルーチンはUnityが反復処理をいい感じに実行してくれてる仕組みというわけですね。反復処理を作って動かしてみる
とりあえず物は試しということでUnityで適当な反復処理を作ってみます。
わかりやすくデバッグログも出してこんな感じに。SampleCoroutine.cspublic IEnumerator Coroutine() { Debug.Log("Coroutine 1"); yield return 1; Debug.Log("Coroutine 2"); yield return 2; }こいつをこんな感じで動かしてみます
SampleCoroutine.cspublic void Sample() { var iEnumerator = Coroutine(); while (iEnumerator.MoveNext()) { Debug.Log($"Coroutine Return {iEnumerator.Current}"); } }ConsoleCoroutine 1 Coroutine Return 1 Coroutine 2 Coroutine Return 2おもったよりかんたん!
何をやっているの?
まずは反復処理についてです。何気なく使っている
yield
ですが、yield
を含むブロックのことをイテレータブロックと言います。
大雑把に説明すると「1回の処理でここまでやってね」というブロックになります。yield
には値を返すreturn
と処理を抜けるbreak
の2つのキーワードがあります。次に
MoveNext
です。これはイテレータを次に進ませます。イテレータが進んだ場合はtrue
を返すため、while
を使うとイテレータを全て進めることができます。
Current
は反復処理が返した値を保持しているプロパティです。yield return
で返した値がそのまま入ってくる感じですね。
object
型なので色んなものを返せます。SampleCoroutine.cspublic IEnumerator Coroutine() { yield return 1; yield return 9.6; yield return "ほげえ"; }ConsoleCoroutine Return 1 Coroutine Return 9.6 Coroutine Return ほげえまた、
Reset
に関してですが、こちらは自前で実装する必要があります(実装してないとNotSupportedException
がスローされます)。
単純にIEnumerator
インターフェースで実装した反復処理メソッドをやり直したい場合は対象のメソッドを再び取得して動かします。SampleCoroutine.cspublic void Sample() { var iEnumerator = Coroutine(); while (iEnumerator.MoveNext()) { Debug.Log($"Coroutine Return {iEnumerator.Current}"); } // iEnumerator.Reset(); <- NotSupportedExceptionがスローされる iEnumerator = Coroutine(); while (iEnumerator.MoveNext()) { Debug.Log($"Coroutine Return {iEnumerator.Current}"); } }思ったよりシンプル!これなら
StartCoroutine
なしでもなんとかなりそう・・・?WaitFor関係は更に自前で実装しないとダメ
注意点として
WaitForSecounds
等は単純にyield return
しただけではうまくいかないです。
よくあるのがyield return WaitForSeconds
でカウントをするコルーチンですが、単純にMoveNext
をしただけではできません。
MoveNext
は1フレーム毎にイテレータを進めるというイメージが良いと思います。この辺はStartCoroutine
がいい感じに処理してくれてる部分です。反復処理の入れ子をやりたい
反復処理から反復処理を実行するような形にすればできます。実は
IEnumerator
インターフェースを調べ始めたきっかけでもあります。SampleCoroutine.cspublic IEnumerator Coroutine() { Debug.Log("Coroutine Start"); var coroutine2 = Coroutine2(); while (coroutine2.MoveNext()) { yield return coroutine2.Current; } Debug.Log("Coroutine End"); } public IEnumerator Coroutine2() { Debug.Log("Coroutine2 1"); yield return 1; Debug.Log("Coroutine2 2"); yield return 2; } public void Sample() { var iEnumerator = Coroutine(); while (iEnumerator.MoveNext()) { Debug.Log($"Coroutine Return {iEnumerator.Current}"); } }ConsoleCoroutine Start Coroutine2 1 Coroutine Return 1 Coroutine2 2 Coroutine Return 2 Coroutine Endおしまい
何気なく使っていたコルーチンと
IEnumerator
インターフェースですが、思ったよりシンプルでした。
これでもまだ触りの部分だと思いますが、当初の目的を達成しつつある程度は分かった気がしたのでとりあえずOKとしましょう。何かあったらコメントください。
参考
++C++; // 未確認飛行 C イテレーター
WisdomSoft 処理の分割(コルーチン)
Qiita:[C#]IEnumeratorとIEnumerableを調べた
- 投稿日:2020-01-21T20:34:15+09:00
オイラ用、テキストを日本語ボイスに変換してくれるしょぼいWindowsソフトを作ったよ。
下記はBLOG引用になります
VS2017のC#で、テキストを日本語ボイスに変換してくれるしょぼいWindowsソフト( 滑舌が悪いけどYOUTUBERしたい人用)を作ったよ。自分はかなり滑舌悪いくてどもるので、YOUTUBER向かないのですがユーチューバーしてみたい願望があったので、Gさんの「Cloud Text-to-Speech API」で適当に作ってみた。ちなみにまだYOUTUBERするかは決めてない!APIですが月に0~100万文字までは無料枠なので、大量に使わない限り無料枠で収まると思います。これを他の人に提供しようとするとアウトだろうけど・・。
自分だけが使用するのには何とかその範囲内かと思います。尚、ソースコードを提供します可変してお好みで使ってください。大量のテキストをボイス変換した場合、ビジーになるかもしれません。そこら辺の処理は入れてません。またGさんからダウンロードしたJSONファイルを置いている階層に合わしてください。
参考にしたサイトは下記になります。
https://cloud.google.com/text-to-speech/docs/quickstart-client-libraries?hl=ja#client-libraries-install-csharpフォームのオブジェクトの配置は下記になります。画像を参照ください。
using System; using System.IO; using System.Windows.Forms; using Google.Cloud.TextToSpeech.V1; namespace テキストを日本語ボイスする { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { if(richTextBox1.Text.Replace("\r", "").Replace("\n", "") == "") { MessageBox.Show("文字を入力してください"); return; } Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", "C:\\xxxxx\\xxxxx\\xxxxx\\xxxxx.json", EnvironmentVariableTarget.Process); TextToSpeechClient client = TextToSpeechClient.Create(); SynthesisInput input = new SynthesisInput { Text = richTextBox1.Text.Replace("\r", "").Replace("\n", "") }; VoiceSelectionParams voice = new VoiceSelectionParams { LanguageCode = "ja-JP", Name = "ja-JP-Wavenet-A", SsmlGender = SsmlVoiceGender.Neutral, }; AudioConfig config = new AudioConfig { AudioEncoding = AudioEncoding.Mp3, SpeakingRate = f1(trackBar1.Value), Pitch = f2(trackBar2.Value), }; var response = client.SynthesizeSpeech(new SynthesizeSpeechRequest { Input = input, Voice = voice, AudioConfig = config }); DateTime dt = DateTime.Now; string dttimename = dt.ToString("yyyy-MM-dd-HH-mm-ss"); using (Stream output = File.Create("voice-" + dttimename + ".mp3")) { response.AudioContent.WriteTo(output); Console.WriteLine($"Audio content written to file 'voice - " + dttimename + ".mp3'"); MessageBox.Show("生成しました=>>voice - " + dttimename + ".mp3"); System.Diagnostics.Process.Start(Directory.GetCurrentDirectory()); } } private void trackBar1_ValueChanged(object sender, EventArgs e) { label3.Text = string.Format("{0:0.00}", f1(trackBar1.Value)); } private void trackBar2_ValueChanged(object sender, EventArgs e) { label4.Text = string.Format("{0:0.00}", f2(trackBar2.Value)); } private double f1(int a) { return Convert.ToDouble(a) / 100; } private double f2(int a) { return Convert.ToDouble(a) - 20; } } }
- 投稿日:2020-01-21T15:32:21+09:00
メソッド名を日本語(JP)で作ったら分かりやすいんでは
*日本語でコーディングしてもコンパイルが通るみたいな話じゃないよ
言いたいこと
コーディング始めにメソッドを作るとき
パッと見何をやるかわかりにくい ↓
実装.cs#region event private void Form1_MouseMove(object sender, MouseEventArgs e) { IsPaintBox(); } #endregion #region method private void IsPaintBox() { if (csrPos[0] <= BOX_POS_LEFT) return; if (csrPos[0] >= BOX_POS_RIGHT) return; if (csrPos[1] <= BOX_POS_TOP) return; if (csrPos[1] >= BOX_POS_BOTTOM) return; PaintBox(); } private int[] GetMousePosition() { } private void DrawBoxFrame() { } private void PaintBox() { } #endregionので 日本語でみたら
日本語.cs#region イベント マウスが動いたときのイベント() { 四角に色を塗るか判断するメソッド(); } #endregion #region メソッド マウスの位置を補足するメソッド() { } // 画面初期描写時にのみ使用する 四角を描写するメソッド() { } 四角に色を塗るか判断するメソッド() { マウスの位置を補足するメソッド(); if(マウスの位置が四角の中なら) { 四角を塗るさせるメソッド(); } } 四角を塗るメソッド() { } #endregionわかりやすくない? って話
問題提起
最初から英字・ローマ字でコーディングすると、めっちゃ頭がこんがらがる...
→なら日本人に合った言語=日本語でコード組み立ててみたらいいんでは
→分かりやすくなった(手間は増える)メリット(日本語で組むとどうなる)
・わかりやすい≒見やすい → 不足点・変更点が見つけやすい
これが大きい・そのままコメント化できる
英字で作った後にコード読み直しながら概要コメントを作らなくていい・メソッド名を考えやすくなる
マウスが四角の上に来たら四角を塗りつぶすメソッド
→マウスが四角の上に来たら/四角を塗りつぶすメソッド
→Mouse_On_Square / Paint_Square
→Paint_Square_On_Mouse
みたいな・メソッド作る目的の軸がブレない
GetMousePosition より マウス位置取得、の方が
目的が明確に見える ワイは見えるデメリット
・多人数プロジェクトだと 命名の仕方が人によってバラつきが出そう
日本語→英字に変える時、コーディングルールに気をつけよう
既存メソッドがあるならそれに合わせよう(既存プロジェクトなら)・後で結局メソッド名作んなきゃなのでめんどくさい
具体例
作成するプログラムは
「カーソルを四角の中に移動させると、四角の中に色がつく」
とする流れとして
①イベントとメソッドを1つずつ作る
②メソッドを細分化する
③メソッドへ遷移する条件分岐を考える
④足りなそうなメソッドを足す
⑤完成
の順で考える①イベントとメソッドを1つずつ作る.csマウスが動いたときのイベント() { 四角に色を塗るか判断するメソッド(); } 四角に色を塗るか判断するメソッド() { }すごく大まかにつくる ↑
②メソッドを細分化する.cs四角に色を塗るか判断するメソッド() { } //↓ マウスの位置を補足するメソッド() { } 四角を塗るメソッド() { }大まかなメソッドに、何が必要なのかを解体して考える ↑
③メソッドへ遷移する条件分岐を考える.cs四角に色を塗るか判断するメソッド() { マウスの位置を補足するメソッド(); if(マウスの位置が四角の中なら) { 四角を塗るメソッド(); } } マウスの位置を補足するメソッド() { } 四角を塗るメソッド() { }どう遷移するかぼんやり書く↑
④足りなそうなメソッドを足す.cs四角の枠を描写するメソッド() { }上の方で遷移書いてみて、足りないなーと思う機能(動作)が出たら追加する
出なければいい⑤完成.csマウスが動いたときのイベント() { 四角に色を塗るか判断するメソッド(); } 四角に色を塗るか判断するメソッド() { マウスの位置を補足するメソッド(); if(マウスの位置が四角の中なら) { 四角を塗るメソッド(); } } マウスの位置を補足するメソッド() { } 四角を塗るメソッド() { } 四角の枠を描写するメソッド() { }みたいな
最後に
英語がわかりにくいんだ
- 投稿日:2020-01-21T11:15:53+09:00
【Unity】個人用にメソッド拡張してみた(随時更新予定
初めに
プログラミングしていると「なんでこの機能ないんだろ?」とか「この機能が欲しい」ということが度々行ったりするようにいつもなっているのでそろそろ拡張していきたいと思いました。
ダウンロード先
内容説明
基本的にUnityを触っている時に使うことを想定して作っています。
使う場合はusing SKTool.Unityをお忘れなく。目次(クラス、メソッド名)
・ListExtension
・RemoveNull()
・Allocation(T _add,bool _addFlag=false
・GameObjectExtension
・GetClosestObjectList(List _list)
・GetClosestObjectArray(GameObject[] _array)機能説明
ListExtension
RemoveNull()
Allocation(T _add,bool _addFlag=false)
List内にnullがある場合そのnullに割り当てる、nullがない場合なにもしない。_addFlagがtrueであれば要素内にnullがない場合Addします。
GameObjectExtension
GetClosestObjectList(List _list)
渡されたListの中から自身から一番近いオブジェクトを返します。
(自身が青で一番近いオブジェクトが赤になっていますがこれはわかりやすくするために色を変えているだけなのでこの関数を呼んでも色は変わりません)
GetClosestObjectArray(GameObject[] _array)
渡された配列の中から自身から一番近いオブジェクトを返します。
(自身が青で一番近いオブジェクトが赤になっていますがこれはわかりやすくするために色を変えているだけなのでこの関数を呼んでも色は変わりません)
- 投稿日:2020-01-21T00:49:52+09:00
C# implicit explicit
implicit
暗黙のうちに変換。
宣言してもいい。explicit
暗黙のうちに変換はできない。
明示的変換はできる。使い方
public class Hoge { // intをhogeにしたとき public static implicit operator Hoge(int a) => new Hoge(); // Hogeをintにしたとき public static implicit operator int(Hoge h) => 3; } private void Test() { Hoge h = new Hoge(); // キャストする必要がない暗黙のうちに変換される。 しても良い。 int i = h; h = i; i = h; }public class Sample { public class Hoge { // intをhogeにしたとき public static explicit operator Hoge(int a) => new Hoge(); // Hogeをintにしたとき public static explicit operator int(Hoge h) => 3; } private void Test() { Hoge h = new Hoge(); // int i = h; コンパイルエラー int i = (int)h; // OK // h = i コンパイルエラー h = (Hoge)i; // OK // i = h; コンパイルエラー i = (int)h // OK } }
- 投稿日:2020-01-21T00:11:59+09:00