- 投稿日:2019-03-05T23:54:32+09:00
Excelからコピペしてcsvにする簡易ツール
要点
Excelのセルをコピーしたテキストはtsvなので、これをReplaceで置換してcsvに保存するチャレンジ。
経緯
作業効率化のために、Excelからcsvを吐き出したいものの、
昨今はセキュリティの都合上現場は外のネットワークに繋がらず、VBAのソースもコピペできないことも多いです。
さて困ったけど、どうやってcsvファイルを作ろうかと考えたとき、Excelからセルをコピーしたときの特徴を利用すればよいと分かりました。Excelからコピーしたセルは、テキスト上ではtsvで持っているので、区切り文字を
\t
から,
に置換すればよいのです。完成品の外観
適当にテキストボックスを配置し
(※AcceptsEnter, AcceptsTabをオン(true)にしてください)
通常版とワンライナー版
通常版
CopyTsvToCsv_Normal.csstring[] sepArr = new string[] { "\r\n" }; // Split用 string toCsv = content.Replace("\t", ","); // tsv→csvへ string[] lines = toCsv.Split(sepArr, StringSplitOptions.RemoveEmptyEntries); // 行を分割 File.WriteAllLines(fi.FullName, lines); // 上の行を削除してFile.WriteAllText(fi.FullName, toCsv)でもOKワンライナー
CopyTsvToCsv_One-Liner.csFile.WriteAllLines(fi.FullName, content.Replace("\t", ",").Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries));応用プラン
- ファイルパス、ディレクトリパスから変換できるようにしてもOK
- 後日書きます
ソース
以下、上記のまとめです。
CopyTsvToCsv.csprivate void TxbInputTsv_TextChanged(object sender, TextChangedEventArgs e) { DateTime dtNow = DateTime.Now; string fileName = string.Format("out_{0}.csv", dtNow.ToString("yyyyMMddHHmmss")); FileInfo fi = new FileInfo(Path.Combine(di.FullName, fileName)); if (fi.Exists) return; OutPutCsv(fi, ((TextBox)sender).Text); } private void OutPutCsv(FileInfo fi, string content) { if (string.IsNullOrEmpty(content.Trim())) return; try { // ワンライナー版 // File.WriteAllLines(fi.FullName, content.Replace("\t", ",").Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)); string[] sepArr = new string[] { "\r\n" }; string toCsv = content.Replace("\t", ","); string[] lines = toCsv.Split(sepArr, StringSplitOptions.RemoveEmptyEntries); File.WriteAllLines(fi.FullName, lines); TxbInputTsv.Text = string.Format("Save: {0}", fi.FullName); Thread.Sleep(5000); TxbInputTsv.Text = ""; } catch(Exception ex) { TxbInputTsv.Text = ex.ToString(); } }
- 投稿日:2019-03-05T19:46:46+09:00
(個人的に)よく使うLinq拡張
概要
よく使うLinq拡張をまとめました
https://github.com/kuroshio-ice/Linq.Expansion
コード
Index付きforeach
var hoge = new List<int>() { 1, 3, 5 }; foreach (var (index, value) in hoge.WithIndex()) { Console.WriteLine($"index: {index}, value: {value}"); }結果index: 0, value: 1 index: 1, value: 3 index: 2, value: 5項目の文字列結合
var hoge = new List<int>() { 1, 3, 5 }; var str1 = hoge.JoinString(":"); Console.WriteLine($"str1: {str1}") var str2 = hoge.JoinComma(); Console.WriteLine($"str2: {str2}")結果str1: 1:3:5 str2: 1,3,5要素分割foreach
var hoge = new List<int>() { 1, 3, 5 }; foreach (var h in hoge.Chunk(2)) { Console.WriteLine($"hoge: {h.JoinComma()}"); }結果hoge: 1,3 hoge: 5要素のランダム取得
var hoge = new List<int>() { 1, 3, 5 }; var rand = new Random(); var h = hoge.Sample(rand); Console.WriteLine($"h: {h}");結果例h: 5
- 投稿日:2019-03-05T18:59:46+09:00
【Unity】スワイプ、フリックで分岐するSafari風スクロール【C#】
【Unity】スワイプ、フリックで分岐するSafari風スクロール【C#】
はじめに
スワイプした分スクロールできて、かつフリックすると速度をもってスクロールできる、iOS標準ブラウザのSafari風のUXのスクロール方法を実装したい!
ついでに2本指での拡大と縮小も実装しました。(なぜ?)
応用時はクランプなど用いてスクロール範囲を制御してください。荒い実装ではありますが、そこそこ良い動きになったので備忘録かつ共有。
開発環境
OS: MacOS Mojave
開発環境: Unity 2018.2.14f1 personal
開発言語: C#ソースコードとその説明
SwipeManager.csusing System.Collections; using System.Collections.Generic; using UnityEngine; public class SwipeManager : MonoBehaviour { //フリック時のスピード private float x_speed = 0; private float y_speed = 0; //カメラ拡大縮小時のスピード(実装環境によって要調整) private float cameraSpeed = 0.4f; //初期位置 private Vector2 startPos; //最初のタップからの経過時間 private float duration = 0; //オブジェクトの移動比率を操作する変数(実装環境によって要調整) private float moveRatio = 0.5f; //スワイプするオブジェクト(この場合スクロールビューのコンテンツ)の外部参照 public GameObject obj; //拡大縮小用カメラの外部参照 public Camera cam; void Update() { //経過時間の計算 duration += Time.deltaTime; //一本指での操作(スワイプ、フリック) if(Input.touchCount == 1){ //タップ情報の取得 Touch touch = Input.GetTouch(0); //タップ状態の分岐 switch(touch.phase){ //タップ開始 case TouchPhase.Began: //タッチ開始座標、時間取得 this.startPos = Input.mousePosition; duration = 0; break; //タップ中、指が動いている case TouchPhase.Moved: //オブジェクト移動(スワイプ) Vector3 nowPosi = obj.transform.localPosition; nowPosi.x = nowPosi.x - touch.deltaPosition.x*moveRatio; nowPosi.y = nowPosi.y - touch.deltaPosition.y*moveRatio; obj.transform.localPosition = nowPosi; break; //タップ終了 case TouchPhase.Ended: //タップ終了位置取得 Vector2 endPos = Input.mousePosition; //触れていた秒数でフリックとスワイプ分岐 if(duration <= 0.5){ float x_flickLength = endPos.x - this.startPos.x; float y_flickLength = endPos.y - this.startPos.y; // フリックの長さを速度に変換する this.x_speed = x_flickLength / 500.0f; this.y_speed = y_flickLength / 500.0f; }else{ //フリック判定じゃない場合はcameraのTranslate速度を0にする this.x_speed = 0; this.y_speed = 0; } break; } } //オブジェクト移動(フリック) obj.transform.Translate(this.x_speed, this.y_speed, 0); //毎フレーム減速させる this.x_speed *= 0.8f; this.y_speed *= 0.8f; //2本指での操作(ピンチイン、アウト) if (Input.touchCount == 2){ // 両方のタップ情報を取得 Touch touchZero = Input.GetTouch(0); Touch touchOne = Input.GetTouch(1); // 前フレームでのタップ位置 Vector2 touchZeroPrePos = touchZero.position - touchZero.deltaPosition; Vector2 touchOnePrePos = touchOne.position - touchOne.deltaPosition; // 各フレームのタッチ間の距離 float preTouchDeltaMag = (touchZeroPrePos - touchOnePrePos).magnitude; float touchDeltaMag = (touchZero.position - touchOne.position).magnitude; //各フレーム間の距離の差 float deltaMagnitudeDif = preTouchDeltaMag - touchDeltaMag; //タッチ間の距離の変化からカメラの平行投影サイズを変更 cam.orthographicSize += deltaMagnitudeDif * cameraSpeed; // 平行投影サイズは0以上になるようにする(クランプの範囲は要調整) cam.orthographicSize = Mathf.Clamp(cam.orthographicSize, 0f , 2.0f); } } }終わりに
TouchScriptなどの便利なアセットを使用するとおそらく早かったのですが、スクリプトで実装してもそこまで時間がかからないのと、自分でスクリプトを書いた方が拡張性に富むと思ったのでこのような実装をしました。どなたかの助けになれば幸いです。
参考文献
「フリックとスワイプの違い」
https://enjoy.sso.biglobe.ne.jp/archives/swipe_flick/
「Unity C#で時間の取得」
http://webbeginner.hatenablog.com/entry/2015/09/04/053623
「ピンチによる拡大」
https://unity3d.com/jp/learn/tutorials/topics/mobile-touch/pinch-zoom
「【Unity2D】スワイプでオブジェクトを上下左右自由自在に動かす方法」
https://miyagame.net/swipe/
- 投稿日:2019-03-05T18:37:10+09:00
C#でむりやりOpenCVを使った話。
C#でOpenCVを頑張って使います。
結論から言うと、PythonでOpenCVを動かし、その結果をTCP通信を介してC#に送るというかなりクソ面白い設計になってしまったので参考になるかはわかりません。前書き
こんにちは。
この記事は高専カンファレンス×学生LT in 東京で話した内容に少し加えた内容です。
初めてのQiita記事&初めてのMarkdownなので間違い等ありましたらご連絡ください。C#でOpenCVが使えないのだが...
長々と話してもしょうがないのでさっさと本題に移りましょう。
私の場合、NuGetパッケージからOpenCVのライブラリをダウンロードしてきて使用するという方法をとったとき、謎のエラーが連発しNuGetからOpenCVを使う気が失せてしまったので仕方なく別の方法をとる必要がありました。
そこでできるやつ(Python)に任せてC#はその結果だけを受け取るという方法を取り、そして実際に試したことを書いていきます。Pythonを使ってOpenCVを使おう
1.IronPythonを使う
IronPythonとは何か。
IronPythonとは、.NET FrameworkおよびMono上で動作するPythonの実装である。(引用:Wikipedia)
らしいです(適当)。もっとかみ砕くとC#とかで簡単に動かせることのできるPythonだよ。ってことです。
しかしこのIronPythonでOpenCVを動かそうとしたときOpenCVのライブラリがうまく読み込ませませんでした。詳しい原因は不明ですが、おそらくPythonとIronPythonが本質的に別のものだからだと思います(誰か詳しい人教えてください)。2.Pythonファイルの外部ファイルとしてC#から起動する
Proceess.Start(@"FileName.py");こうするだけでファイルの起動はでき、返り値も簡単に取得できます(詳しくは別の記事を参照してください)。
が、これにも問題があります。それは遅延の問題です。OpenCVをPythonで使用するときの初期化処理には1秒ほど時間がかかり、いちいち起動し直していては実用性がありません。3.TCP通信を使用する
結論としてこの方法をとりました。なんでこんな仕様にしたんだというお叱りあると思いますが設計したのが朝の三時なので仕方ないですね()。
さて、実装ですがC#側でもPython側でも大したことはしていませんので参考にしたリンクだけ貼っておきます。TCPクライアント・サーバープログラムを作成する
少しだけ付け足すと、クライアントからはデータを受け取る必要がないので送信する部分は全部カットでき、何回もデータを受け取る必要があるのですべてをwhile(true)でくくってください。
一応使用したコードを這っておきます(変数の宣言やusingディレクディブについては書いていないので適当に補完しながら見てください)while (true) { listener.Start(); //開始 TcpClient client = null; try { client = await listener.AcceptTcpClientAsync(); } //受け取り catch (Exception) { return; } if (client == null) return; NetworkStream ns = client.GetStream(); //クライアントからストリーム情報を取得 ns.ReadTimeout = 10000; ns.WriteTimeout = 10000; MemoryStream ms = new MemoryStream(); byte[] resBytes = new byte[256]; int resSize = 0; do { //データの一部を受信する resSize = ns.Read(resBytes, 0, resBytes.Length); //Readが0を返した時はクライアントが切断したと判断 if (resSize == 0) break; //受信したデータを蓄積する ms.Write(resBytes, 0, resSize); //まだ読み取れるデータがあるか、データの最後が\nでない時は受信を続ける } while (ns.DataAvailable || resBytes[resSize - 1] != '\n'); //受信したデータを文字列に変換 string resMsg = Encoding.UTF8.GetString(ms.GetBuffer(), 0, (int)ms.Length); ms.Close(); //末尾の\nを削除 resMsg = resMsg.TrimEnd('\n'); //Console.WriteLine(resMsg); CheckMessage(resMsg); //Pythonから送られてくる座標データを解析して適切に処理するすごーい関数。 }次にPython部分の実装です。といってもsocketの機能が強いのであまりコードは書いていません。
def Send(msg): client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) host = "127.0.0.1" port = 51018 client.connect((host,port)) client.send(str(msg).encode()) Send("this is Message")これだけです。そして、実際に動かし遅延を調べた結果がこちら。
左側がC#、右側がPythonになっていて、数字は時間を表しています。御覧の通りそれぞれで時間の差があまりないことがわかると思います。
そして、OpenCVのマーカー検出ライブラリArUcoを使用して得た情報をformに送って表示した結果がこちら
赤いのがカメラからの情報を座標変換してもう一度表示したものです。あまり誤差がないのがわかると思います。
まとめ
本当はC#だけでOpenCVを使えるまで頑張ったほうがいいのですが、Pythonの練習とネットワークの勉強も兼ねてTCP通信を使用してみました。
余談ですが、PythonからC#に送る情報は文字列なので、座標の情報や、idを送る際にすこし工夫が必要だと思います。私の場合は特定の文字列で区切り、正規表現を活用して情報を取り出しました。以上です。ありがとうございました。
参考
IronPython https://ja.wikipedia.org/wiki/IronPython
サーバのコード https://dobon.net/vb/dotnet/internet/tcpclientserver.html
- 投稿日:2019-03-05T15:52:50+09:00
世界にひとつの、宝探しゲームをつくろう!(Unity入門)
これからUnityをつかって、ゲームを作っていきます♪
まずはUnityってナニ?というおはなしからスタートです!Unityとは
カンタンに言うと、ゲームを作るキットです。
スマホ版のどうぶつの森や、スーパーマリオラン、白猫プロジェクトもUnityで作られています。
しかし、Unityはゲーム以外のものも作ることができます。
最近では、手術のシミュレーションにも使われたりしているみたいですよ。そんなUnityを使って、今回は宝探しゲームを作っていきます!
下のQRコードまたはURLから、今回作るゲームのサンプル動画を見ることができるよ。Unityにさわってみよう
まずはUnityにさわってみるところから、はじめていきましょう!
画面の見かた
どこになにがあるのかをカンタンにせつめいするよ。
Scene(シーン)
ゲームに出てくる物体(オブジェクト)は全部ここにあるよ。
ここでオブジェクトの場所を自由に変えることができるよ。Game(ゲーム)
いわゆる「プレイ画面」のこと。
ゲームをプレイする人は、この画面を見てプレイするよ。Hierarchy(ヒエラルキー)
Sceneにあるモノ(オブジェクト)の一覧だよ。
いまは、カメラ(MainCamera)とライト(Directional Light)があるよ。Project(プロジェクト)
Inspector(インスペクター)
オブジェクトなどをクリックすると、そのオブジェクトの情報(じょうほう)が出てくるよ。カメラの情報をチェック!
ためしにカメラ(MainCamera)の情報を見てみよう!
まず、Hierarchyの「MainCamera(メインカメラ)」をクリックしてみよう。
InspectorにMainCameraの情報が出てきたかな?
オブジェクトの大きさや場所などを、きっちり変えたいときはここで数字を変えるとうまくいくよ。Console(コンソール)
エラーや、メッセージが出てくるところだよ。
赤いビックリマークが出てきていないときは、気にしなくて大丈夫だよ。Cube(キューブ)であそぼう
下の画像(がぞう)とおなじ画面になっているかな?
ちがっていたら、まわりのお兄さんお姉さんに聞いてみよう♪
Cubeを出そう
Cubeの作りかた
①「Create」をクリック
②「3D Object」をクリック
③「Cube」をクリック
(「Create」から、色んなものを作ることができるよ!)いろんな場所、むきから見てみよう
いま出したCubeをいろんな場所、むきから見てみよう!
①いろんな場所から見る
まずはいろんな場所から見てみよう。
ハンドツール✋をえらんでね。
Sceneの上でクリックしながらマウスを動かしてみよう!
Cubeをいろんな場所から見ることができるようになったかな?②いろんなむきから見る
Sceneの上で 「右クリック」 しながらマウスを動かしてみよう!
いろんなむきから見ることができたかな?
Cubeを動かそう
次に、さっき作ったCubeを動かすよ。
移動ツールをクリックしてね。
動かしたいモノ(Cube)をクリックしよう!
やじるしが出てきたかな?
まずは上に動かしてみよう!
上に向いている黄緑色のやじるしを、クリックしながらマウスを上に動かそう。
Cubeが上に動いたかな?
動かなかったら、まわりのお兄さん・お姉さんに聞いてみよう!「Game」が、プレイ画面だったね。
あれ?GameにCubeがいないね。
<ミッション>
Gameから見てCubeが見やすい場所になるように、
3つのやじるし(青・赤・黄緑)を使ってCubeを動かしてみよう!
分からないことがあったら、まわりのお兄さん・お姉さんに聞いてね。
ミッションクリアしたら、ゲームを保存(ほぞん)しよう!
⌘Commandキーをおしながら、Sキーをおすとセーブできるよ!宝探しゲームを作ろう!
それでは宝探しゲームを作っていきます!
わからないことがあったら、まわりのお兄さん・お姉さんに聞いてみましょう♪Sceneをひらこう
宝探しゲーム用のSceneをひらくよ。
まずはProjectの、Sceneというフォルダの右にある三角▶をクリック。
「Tutorial」と「Main」のふたつが出てきたね。
Mainが、宝探しゲームのSceneだよ。
Mainを ダブルクリック して、ひらこう!
プレイヤーを動かそう
さっそく、プレイヤー(主人公)を動かしていくよ。
コードをつくろう
動かすためには「コード」がひつようだよ!
「Scripts」フォルダの、「CharacterControllerScript」をダブルクリックしてひらこう!
すこしまつと、こんな画面が出てくるよ。
この画面にならなかったらら、まわりのお兄さん・お姉さんに声をかけてね。
変数を作ろう
プレイヤーを動かすのに使う変数を作っていくよ。
まずは「characterController」という名前の変数を作るよ。
赤いしかくの中のコードを、自分で書いてみよう!
この調子で、あと4つ変数を作ろう!
赤いしかくの中のコードを書いてね。
また、下のコードも書こう。
これは、さっき作った変数「characterController」を使うための初期設定だよ。
①前に動くようにする
上やじるしキーをおしたら、プレイヤーが前にすすむようにしよう。
「○○キーがおされたら、△△歩動かす」は、Scratchだと「ずっと」の中に入れるよね。
Unityでは、「ずっと」のブロックのかわりに「void Update()」を使うよ。
上やじるしキーで前にすすむは、
Scratchであらわすと、こんなコードになるね。
Unityだと赤いしかくの中のようなコードになるよ。
画像を見ながら書いてみよう!
コードが書けたら保存(ほぞん)しよう!
⌘Commandをおしながら、Sキーをおすとセーブできるよ!プレイヤーが動くか確認してみよう♪
Unityにもどって、実行ボタン▶をおしてね。
上やじるしキーで、前にすすむようになったかな?②うしろに動くようにする
次は、下やじるしキーをおしたら、うしろに動くようにしよう!
Scratchだと、こんなコードになるね。
Unityだと、こんなコードになるよ。
画像を見ながら書いてみよう!
コードが書けたら保存(ほぞん)しよう!
⌘Commandをおしながら、Sキーをおすとセーブできるよ!プレイヤーが動くか確認してみよう♪
Unityにもどって、実行ボタン▶をおしてね。
下やじるしキーで、うしろにすすむようになったかな?③右に動くようにする
右やじるしキーをおしたら、右に向くようにしよう!
Scratchだとこんなコードだよ。
これをUnityで書くと、こんなコードになるよ!
画像を見ながら書いてみよう♪
コードが書けたら保存(ほぞん)しよう!
⌘Commandをおしながら、Sキーをおすとセーブできるよ!プレイヤーが動くか確認してみよう♪
Unityにもどって、実行ボタン▶をおしてね。
右やじるしキーで、右をむくようになったかな?④左に動くようにする
左やじるしキーをおしたら、左に向くようにしよう!
Scratchだとこんなコードだよ。
これをUnityで書くと、こんなコードになるよ!
画像を見ながら書いてみよう♪
コードが書けたら保存(ほぞん)しよう!
⌘Commandをおしながら、Sキーをおすとセーブできるよ!プレイヤーが動くか確認してみよう♪
Unityにもどって、実行ボタン▶をおしてね。
左やじるしキーで、左をむくようになったかな?⑤ジャンプできるようにする
スペースキーをおしたら、ジャンプできるようにしよう!
Scratchのブロックだと、こんな組み合わせになるコードをUnityで書いていくよ。
ちなみにUnityでは、こんなコードになるよ。
画像を見ながら書いてみよう!
コードが書けたら保存(ほぞん)しよう!
⌘Commandをおしながら、Sキーをおすとセーブできるよ!プレイヤーが動くかカクニン!
さいごにUnityにもどって、実行ボタン▶をおしてね。
プレイヤーが行きたい方向に動けるようになったかな?
また、ジャンプできるようになったかな?
カクニンしてみよう!宝箱をゲットできるようにしよう
タグを作ろう
Unityさんは、宝箱が宝だと分かっていないから、
Unityさんに「これは宝だよ!」と教えてあげよう。そのために「タグ」という機能を使うよ。
まず宝のタグを作ろう!Hierarchyの、宝箱(Treasure1)をクリック。
いまはタグ(Tag)が「Untagged」になっているね。
(Untaggedは、タグなしという意味だよ)
Untaggedをクリックして、Add Tag...をクリックしよう。
Add Tag...は、タグをふやすという意味だよ。
名前は「Treasure」がおすすめだよ。
(Treasureは、英語で宝という意味だよ)
※日本語は使えないよ!
タグができたら、またHierarchyから宝箱(Treasure1)をクリックしてね。
宝をゲットできるようになったかカクニンするよ。
実行ボタン▶をクリックして、プレイヤーを動かし宝箱に体当たりしてみよう!宝箱が消えたらOKだよ!
ゲームを保存(ほぞん)しよう!
⌘Commandをおしながら、Sキーをおすとセーブできるよ!宝箱をふやそう
宝箱のかずを5こにふやすよ!
Hierarchyの宝箱(Tresure1)を右クリックして、
「Duplicate」をクリック!
Duplicateは、「複製(ふくせい)」という意味だよ。
5こにふやせたら、実行ボタンをおしてゲームで遊んでみよう!
ぜんぶゲットできるかな?ゲームを保存(ほぞん)しよう!
⌘Commandをおしながら、Sキーをおすとセーブできるよ!ゲームをパワーアップさせよう
ステージをかえよう
作りかたはこちら
BGMをつけよう
好きな音楽をながして、もっとカッコいいゲームにしよう♪
作りかたはこちらゲームが完成したら…
自分のゲームで遊んでみよう!
また、まわりのお兄さん・お姉さんやお友だちにも遊んでもらってね♪さいごにゲームを保存(ほぞん)してね。
⌘Commandをおしながら、Sキーをおすとセーブできるよ!
- 投稿日:2019-03-05T15:52:50+09:00
【はじめてのUnity】宝探しゲームをつくろう!(Unity入門)
この記事は古い記事です
最新バージョンの記事はこちら
Unityとは
カンタンに言うと、 ゲームを作るキットです
スマホ版のどうぶつの森や、 スーパーマリオラン、 白猫プロジェクトもUnityで作られています
しかし、 Unityはゲーム以外のものも作ることができます
最近では、 手術のシミュレーションにも使われたりしているみたいですよUnityにさわってみよう
まずはUnityにさわってみるところから、 はじめていきましょう
画面の見かた
Scene(シーン)
ゲームに出てくる物体 (オブジェクト) は全部ここにあるよ
ここでオブジェクトの場所を、自由に変えることができるよGame(ゲーム)
いわゆる「プレイ画面」のこと
ゲームをプレイする人は、この画面を見てプレイするよHierarchy(ヒエラルキー)
Sceneにあるモノ(オブジェクト)の一覧だよ
いまは、カメラ(MainCamera)とライト(Directional Light)があるよProject(プロジェクト)
Inspector(インスペクター)
オブジェクトなどをクリックすると、そのオブジェクトの情報(じょうほう)が出てくるよカメラの情報をチェック
ためしにカメラ(MainCamera)の情報を見てみよう
まず、Hierarchyの「MainCamera(メインカメラ)」をクリックしてみよう
InspectorにMainCameraの情報が出てきたかな?
オブジェクトの大きさや場所などを、きっちり変えたいときはここで数字を変えるとうまくいくよConsole(コンソール)
エラーや、メッセージが出てくるところだよ
赤いビックリマークが出てきていないときは、気にしなくて大丈夫だよCube(キューブ)であそぼう
下の画像(がぞう)とおなじ画面になっているかな?
Cubeを出そう
Cubeの作りかた
①「Create」をクリック
②「3D Object」をクリック
③「Cube」をクリック
(「Create」から、色んなものを作ることができるよ)いろんな場所、むきから見てみよう
いま出したCubeをいろんな場所、むきから見てみよう
①いろんな場所から見る
まずはいろんな場所から見てみよう
ハンドツール✋をえらんでね
Sceneの上でクリックしながらマウスを動かしてみよう
Cubeをいろんな場所から見ることができるようになったかな?②いろんなむきから見る
Sceneの上で 「右クリック」 しながらマウスを動かしてみよう
いろんなむきから見ることができたかな?
Cubeを動かそう
次に、さっき作ったCubeを動かすよ
移動ツールをクリックしてね
動かしたいモノ(Cube)をクリックしよう
やじるしが出てきたかな?
まずは上に動かしてみよう
上に向いている黄緑色のやじるしを、クリックしながらマウスを上に動かそう
Cubeが上に動いたかな?「Game」が、プレイ画面だったね
あれ?GameにCubeがいないね
<ミッション>
Gameから見てCubeが見やすい場所になるように
3つのやじるし(青・赤・黄緑)を使ってCubeを動かしてみよう
ミッションクリアしたら、ゲームを保存(ほぞん)しよう
⌘Commandキーをおしながら、Sキーをおすとセーブできるよ宝探しゲームを作ろう
それでは宝探しゲームを作っていきます
Sceneをひらこう
宝探しゲーム用のSceneをひらくよ
まずはProjectの、Sceneというフォルダの右にある三角▶をクリック
「Tutorial」と「Main」のふたつが出てきたね
Mainが、宝探しゲームのSceneだよ
Mainを ダブルクリック して、ひらこう
プレイヤーを動かそう
さっそく、プレイヤー(主人公)を動かしていくよ
コードをつくろう
動かすためには「コード」がひつようだよ!
「Scripts」フォルダの、「CharacterControllerScript」をダブルクリックしてひらこう
すこしまつと、こんな画面が出てくるよ
変数を作ろう
プレイヤーを動かすのに使う変数を作っていくよ
まずは「characterController」という名前の変数を作るよ
赤いしかくの中のコードを、自分で書いてみよう
この調子で、あと4つ変数を作ろう
赤いしかくの中のコードを書いてね
また、下のコードも書こう
これは、さっき作った変数「characterController」を使うための初期設定だよ
①前に動くようにする
上やじるしキーをおしたら、プレイヤーが前にすすむようにしよう
「○○キーがおされたら、△△歩動かす」は、Scratchだと「ずっと」の中に入れるよね
Unityでは、「ずっと」のブロックのかわりに「void Update()」を使うよ
上やじるしキーで前にすすむは
Scratchであらわすと、こんなコードになるね
Unityだと赤いしかくの中のようなコードになるよ
画像を見ながら書いてみよう
コードが書けたら保存(ほぞん)しよう
⌘Commandをおしながら、Sキーをおすとセーブできるよプレイヤーが動くか確認してみよう
Unityにもどって、実行ボタン▶をおしてね
上やじるしキーで、前にすすむようになったかな?②うしろに動くようにする
次は、下やじるしキーをおしたら、うしろに動くようにしよう
Scratchだと、こんなコードになるね
Unityだと、こんなコードになるよ
画像を見ながら書いてみよう
コードが書けたら保存(ほぞん)しよう
⌘Commandをおしながら、Sキーをおすとセーブできるよプレイヤーが動くか確認してみよう
Unityにもどって、実行ボタン▶をおしてね
下やじるしキーで、うしろにすすむようになったかな?③右に動くようにする
右やじるしキーをおしたら、右に向くようにしよう
Scratchだとこんなコードだよ
これをUnityで書くと、こんなコードになるよ
画像を見ながら書いてみよう
コードが書けたら保存(ほぞん)しよう
⌘Commandをおしながら、Sキーをおすとセーブできるよプレイヤーが動くか確認してみよう
Unityにもどって、実行ボタン▶をおしてね
右やじるしキーで、右をむくようになったかな?④左に動くようにする
左やじるしキーをおしたら、左に向くようにしよう
Scratchだとこんなコードだよ
これをUnityで書くと、こんなコードになるよ
画像を見ながら書いてみよう
コードが書けたら保存(ほぞん)しよう
⌘Commandをおしながら、Sキーをおすとセーブできるよプレイヤーが動くか確認してみよう
Unityにもどって、実行ボタン▶をおしてね
左やじるしキーで、左をむくようになったかな?⑤ジャンプできるようにする
スペースキーをおしたら、ジャンプできるようにしよう
Scratchのブロックだと、こんな組み合わせになるコードをUnityで書いていくよ
ちなみにUnityでは、こんなコードになるよ
画像を見ながら書いてみよう
コードが書けたら保存(ほぞん)しよう
⌘Commandをおしながら、Sキーをおすとセーブできるよプレイヤーが動くかカクニン
さいごにUnityにもどって、実行ボタン▶をおしてね
プレイヤーが行きたい方向に動けるようになったかな?
また、ジャンプできるようになったかな?
カクニンしてみよう宝箱をゲットできるようにしよう
タグを作ろう
Unityさんは、宝箱が宝だと分かっていないから
Unityさんに「これは宝だよ!」と教えてあげようそのために「タグ」という機能を使うよ
まず宝のタグを作ろういまはタグ(Tag)が「Untagged」になっているね
(Untaggedは、タグなしという意味だよ)
Untaggedをクリックして、Add Tag...をクリックしよう
Add Tag...は、タグをふやすという意味だよ
名前は「Treasure」がおすすめだよ
(Treasureは、英語で宝という意味だよ)
※日本語は使えないよ
タグができたら、またHierarchyから宝箱(Treasure1)をクリックしてね
宝をゲットできるようになったかカクニンするよ
実行ボタン▶をクリックして、プレイヤーを動かし宝箱に体当たりしてみよう宝箱が消えたらOKだよ
ゲームを保存(ほぞん)しよう
⌘Commandをおしながら、Sキーをおすとセーブできるよ宝箱をふやそう
宝箱のかずを5こにふやすよ
Hierarchyの宝箱(Tresure1)を右クリックして
「Duplicate」をクリック
Duplicateは、「複製(ふくせい)」という意味だよ
5こにふやせたら、実行ボタンをおしてゲームで遊んでみよう
ぜんぶゲットできるかな?ゲームを保存(ほぞん)しよう
⌘Commandをおしながら、Sキーをおすとセーブできるよゲームをパワーアップさせよう
ステージをかえよう
作りかたはこちら
BGMをつけよう
好きな音楽をながして、もっとカッコいいゲームにしよう
作りかたはこちらゲームが完成したら…
自分のゲームで遊んでみよう
さいごにゲームを保存(ほぞん)してね
⌘Commandをおしながら、Sキーをおすとセーブできるよ
- 投稿日:2019-03-05T14:36:57+09:00
C#のNullable型で三項演算子を使うときの注意
はじめに
C#のNullable型で三項演算子を使おうと思ったらコンパイルエラーになったので、備忘録としてメモを残しておく。
ちなみに三項演算子を使いたかった理由は、三項演算子の方が可読性が高まるケースがあっためです。
(本記事は三項演算子の良し悪しについて議論したいわけではありません)エラー内容
以下のコードはコンパイルエラーになります。
int? num = true ? 1 : null;
error CS0173: Type of conditional expression cannot be determined because there is no implicit conversion between 'int' and '<null>'
エラーメッセージを意訳すると、
三項演算子の第二オペランドの型と第三オペランドの型が異なるうえに、nullはintに暗黙的な型変換ができないよ
とのこと。
そもそも三項演算子は第二オペランドと第三オペランドを同じ型にする必要があります。
そのうえで、さらにnullはintに暗黙的な型変換ができないので、上記のように怒られているようですね。解決策1
nullからNullable<int>へ明示的に型変換すれば、Nullable<int>からintへは暗黙的に型変換してくれるので実行可能になります。
int? num = true ? 1 : (int?)null;解決策2
そもそも三項演算子にこだわらずifで書けば、もちろん問題ないですね。
int? num = null; if (true) { num = 1; }参考リンク
- 投稿日:2019-03-05T12:43:34+09:00
.NET FrameworkアプリでID/Password認証ありのproxyを突破する
やりたかったコト
- BoxのSDKを使って、Box APIに接続しているが、そのコネクションを、認証ありのプロキシ経由にしたかった
- BoxのSDKは、.NET Core で使用していた
できなかったコト
.Net Framework application
では、設定ファイル(App.config)を使用してプロキシの設定ができる- しかし、
.Net Core console application
ではこれ(App.configでプロキシ設定)が実装されていない- ただ、設定ファイルではできないが、機能(Class)としては実装されている
- .NET側としては、HttpClientHandler使ってproxy設定してね!ってことだが・・
- BoxのSDKでは、HttpClientHandler使ってるけど、Proxyの設定は実装されていない・・
- Boxの実装:https://github.com/box/box-windows-sdk-v2/blob/master/Box.V2/Request/HttpRequestHandler.cs
- なぜなら、app.config使えばいいと思ってるから!(.Net Coreでは使えないのに!)
やったコト
- .NET Coreじゃなきゃダメ、ってことがなかったので、.NET Frameworkで動くようにし、App.configでproxyの設定ができるようにした
App.configでのproxy設定方法
proxy設定なしの場合
defaultProxy項目自体なくてもよい
<system.net> <defaultProxy enabled="false" useDefaultCredentials="false"> </defaultProxy> </system.net>proxy設定あり(認証なし)の場合
<system.net> <defaultProxy enabled="true" useDefaultCredentials="true"> <proxy usesystemdefault="true"/> </defaultProxy> </system.net>(本命)proxy設定あり(認証あり)の場合
<appSettings> <add key="http_proxy_url" value="http://[IP]:[Port]"/> <add key="proxy_user" value="hoge"/> <add key="proxy_pass" value="fuga"/> </appSettings> <system.net> <defaultProxy enabled="true" useDefaultCredentials="false"> <module type="Sample.MyProxyModule, Sample"/> </defaultProxy> </system.net>moduleの実装(Sample.MyProxyModule)
- Sample/MyProxyModule.cs
- 後述のApp.configから設定値を取得しています
using System; using System.Net; using System.Configuration; namespace Sample { public class MyProxyModule : IWebProxy { /// <summary> /// 認証情報 /// </summary> public ICredentials Credentials { get; set; } /// <summary> /// ProxyServer名を返却 /// </summary> /// <param name="destination"></param> /// <returns></returns> public Uri GetProxy(Uri destination) { return new Uri(ConfigurationManager.AppSettings["http_proxy_url"]); } /// <summary> /// コンストラクタ /// </summary> public AuthProxyModule() { try { Credentials = new NetworkCredential(ConfigurationManager.AppSettings["proxy_user"], ConfigurationManager.AppSettings["proxy_pass"]); } catch (Exception ex) { // 適宜 throw; } } /// <summary> /// host でプロキシサーバーを使用しない場合は true。それ以外の場合は false。 /// </summary> public bool IsBypassed(Uri host) { return false; } } }
- Sample/App.config
- 認証情報をとりあえず、ここで設定。これは色々と方法あると思うので適宜。
<appSettings> <add key="http_proxy_url" value="http://[IP]:[Port]"/> <add key="proxy_user" value="hoge"/> <add key="proxy_pass" value="fuga"/> </appSettings>
参考にさせていただきました。ありがとうございます
nap3/relayCredentials: 認証のプロキシの情報を中継するモジュール
c# - Is it possible to specify proxy credentials in your web.config? - Stack Overflow
- 投稿日:2019-03-05T10:04:00+09:00
C#でIMEの入力を受けるユーザーコントロールの作成
時々作りたくなるのですが、毎回忘れて調べるのに苦労する、C#でIMEの入力を受けるコントロールの作り方メモです。
class SpTextEditorComponent : System.Windows.Forms.UserControl { #region IME関係 private const int WM_IME_COMPOSITION = 0x010F; private const int GCS_RESULTREADSTR = 0x0200; private const int WM_IME_STARTCOMPOSITION = 0x10D; // IME変換開始 private const int WM_IME_ENDCOMPOSITION = 0x10E; // IME変換終了 private const int WM_IME_NOTIFY = 0x0282; private const int WM_IME_SETCONTEXT = 0x0281; public enum ImmAssociateContextExFlags : uint { IACE_CHILDREN = 0x0001, IACE_DEFAULT = 0x0010, IACE_IGNORENOCONTEXT = 0x0020 } [StructLayout(LayoutKind.Sequential)] public struct C_RECT { public int _Left; public int _Top; public int _Right; public int _Bottom; } [StructLayout(LayoutKind.Sequential)] public struct C_POINT { public int x; public int y; } const uint CFS_POINT = 0x0002; public struct COMPOSITIONFORM { public uint dwStyle; public C_POINT ptCurrentPos; public C_RECT rcArea; } [DllImport("Imm32.dll")] private static extern IntPtr ImmGetContext(IntPtr hWnd); [DllImport("Imm32.dll")] private static extern int ImmGetCompositionString(IntPtr hIMC, int dwIndex, StringBuilder lpBuf, int dwBufLen); [DllImport("Imm32.dll")] private static extern bool ImmReleaseContext(IntPtr hWnd, IntPtr hIMC); [DllImport("imm32.dll")] private static extern IntPtr ImmCreateContext(); [DllImport("imm32.dll")] private static extern bool ImmAssociateContextEx(IntPtr hWnd, IntPtr hIMC, ImmAssociateContextExFlags dwFlags); [DllImport("imm32.dll")] public static extern int ImmSetCompositionWindow(IntPtr hIMC, ref COMPOSITIONFORM lpCompositionForm); IntPtr himc = IntPtr.Zero; private void InitializeComponent() { this.SuspendLayout(); } protected override void Dispose(bool disposing) { if (himc != IntPtr.Zero) { ImmReleaseContext(this.Handle, himc); himc = IntPtr.Zero; } base.Dispose(disposing); } ~SpTextEditorComponent() { if (himc != IntPtr.Zero) { ImmReleaseContext(this.Handle, himc); himc = IntPtr.Zero; } } protected override void WndProc(ref Message m) { switch (m.Msg) { case WM_IME_SETCONTEXT: { //Imeを関連付ける IntPtr himc = ImmCreateContext(); ImmAssociateContextEx(this.Handle, himc, ImmAssociateContextExFlags.IACE_DEFAULT); base.WndProc(ref m); break; } case WM_IME_STARTCOMPOSITION: { //入力コンテキストにアクセスするためのお約束 IntPtr hImc = ImmGetContext(this.Handle); //コンポジションウィンドウの位置を設定 COMPOSITIONFORM info = new COMPOSITIONFORM(); info.dwStyle = CFS_POINT; info.ptCurrentPos.x = 10; info.ptCurrentPos.y = 10; ImmSetCompositionWindow(hImc, ref info); //コンポジションウィンドウのフォントを設定 //ImmSetCompositionFont(hImc, m_Focus->GetFont()->GetInfoLog()); //入力コンテキストへのアクセスが終了したらロックを解除する ImmReleaseContext(Handle, hImc); base.WndProc(ref m); break; } default: //IME以外のメッセージは元のプロシージャで処理 base.WndProc(ref m); break; } } #endregion public SpTextEditorComponent() { InitializeComponent(); } }一部余分なコードや余分なインポートがありますが、ご勘弁を。
以下のことをしておけば最低限動くようです。
- WndProcをオーバーライド
- WM_IME_SETCONTEXT メッセージで
- ImmCreateContext を呼んでコンテキストを作り、ImmAssociateContextEx でハンドルと結びつける
- WM_IME_STARTCOMPOSITION メッセージで
- ImmSetCompositionWindow を使い候補ウィンドウの位置を設定する
- 解放のタイミング(Dispose?)で
- ImmReleaseContext を呼んで解放
入力文字は、KeyPressイベントで一文字ずつ入ってきます。