Unity C#でHaskellのmapっぽいものを実装したお話
かずまです。
最近、すごいHaskell楽しく学ぼう! を読み始めました。
おもしろおかしく書かれているところもあるので読み行ってしまいます。
なので、寝る前に少し読む、みたいなスタイルで。
C#でのFunctional的に書く方法
- Lambda式を使う
C#でもLambda式が使えるのでそれを利用します。
無名関数とも言いますね!
公式ドキュメントはこちら。
Lambda Expressions (C# Programming Guide)
- 引数でデリゲートを使う
Lambda式を受けるデリゲートは
Func(T, TResult) Delegate (System)
ココらへんを使えば良さそうです。
** Func
これは一つ目のTは引数の型、TResultは返り値の型をGenericで指定するようです。
なんと、この2つを使えばできるはずですね!!
クラスとメソッドの作成
とりあえず、Funcというクラスを作って、staticでList
このような感じで書いてみました。
メソッドをGenericにするのはうーん、どうなのかな。
ClassをGenericにするのもいい気がするけど今はこっちでかきました。
使い方
先程のクラスとは別にFunctorTestクラスを用意します。
以下のように記述してみました。
public class FunctorTest : MonoBehaviour { private List<int> list = new List<int>(){ 1, 2, 3, 4, 5 }; private void Start () { System.Func<int, int> f = (int arg) => { return arg * 2; }; list = Functor.map (f, list); print (list); } }
追記 2/7
Lambda式をまとめるのもありです。
public class FunctorTest : MonoBehaviour { private List<int> list = new List<int>(){ 1, 2, 3, 4, 5 }; private void Start () { list = Functor.map ((int arg) => {return arg * 2;}, list); print (list); } }
このコードではHaskellと同じように2倍するLambda式を書いて、それをmapの第一引数として渡すだけ!
簡単ですね!ただHaskellと違ってタイプする数は多いのでスマートじゃない...
これぐらいなら許容範囲!
mapはGenericだけど型を指定しなくても良さそう
mapはGenericな型を要求するので実際は
list = Functor.map<int> (f, list);
と指定するのがいいのか、と想定していました。
ところがTestクラスを書いた時にmapの後ろに型の指定を忘れていたのです。
でもコンパイルエラーも出なく、きちんと出力されていたので
自動的に型を認識するのかと感動してしまいました。
きちんとint型だと認識していますね。
公式のドキュメントにもきちんとかいてありました。
Generic Methods (C# Programming Guide)
便利だしHaskellに一歩近づいた?笑
出力結果
素晴らしい、ちゃんと出てますね!
Stringでも試してみよう!
Listのintが出来たのでstringでも同様に使えるはずです。
private List<string> slist = new List<string>() { "Hello", "World" }; private void Start () { System.Func<string, string> fs = (string arg) => { return arg + "(ΦωΦ)"; }; slist = Functor.map (fs, slist); print (slist); }
この様にHelloとWorldの後ろに(ΦωΦ)を付け足すスクリプトです。
結果
にゃーと猫がでてきましたね。
まとめ
Haskellはまだまだ初心者ですので間違ってる解説などありましたらご指摘ください。
あとこう書いたほうがいいよ〜みたいなのもぜひ!
Global Game Jam 2017に参加しました。
かずまです。
21 ~ 22日で行われた(他の会場では20日もあった)Global Game Jamに参加してきました。
参加だけでなく僕達IGDA琉球大学、琉ゲ部では沖縄会場の運営も行っておりました。
Global Game Jam(GGJ)とは
Game Jamは、ゲーム開発を行うハッカソンです。
その中でも、Global Game Jam (以下、GGJ) は、ギネス記録を持つ世界最大のGame Jamです。全世界にハッカソン会場が設けられており、全世界で同じ日に同じテーマでゲームを開発します。GGJは、2009年の初開催以降年々規模を大きくしており、2016年1月のGGJでは、世界93の国と地域で、36,000人以上が参加し、約6,800の作品が制作されました(世界の会場一覧はここから見られます)。
引用URL
Global Game Jam JAPAN | Innovation, Collaboration, Experimentation! Jan. 20~22, 2017
制作物
今回運営チームとして
彼と2人で作成しました。
もちろんゲームエンジンはUnityです。
担当はHookを飛ばす、引き寄せる部分を彼に担当してもらい、その他(剣のモデルを含める)は僕が担当しました。
タイトル
「Hook VR」
コンセプト
VRで試したことない体験したい、ということで敵にHookを引っ掛けて、近くに引き寄せて剣で切る、というもの。
プレイ動画
Hook VR #ggj17jp #ggjokinawa
— かずま (@kazumalab) 2017年1月22日
島が破壊される前に縄で敵を引っ張り剣で斬る。 pic.twitter.com/d9eHeIxrlD
第2回 技術的ログ Twitterから
前回の記事はこちら。
blog.kazumalab.com
Twitterでの技術エントリー(?)をまとめただけになります。
技術本の大賞
ITエンジニアが投票した「ITエンジニア本大賞2017」ベスト10が発表。機械学習理論入門/SQLアンチパターン/達人プログラマー/ルビィのぼうけん、などランクイン - Publickey https://t.co/Oep2385661
— E. Nakai (@enakai00) 2017年1月18日
学生が作ったUE4の作品
おお遂に完成したか!僕が教えてるバンタン大阪1年の学生でUE4を使ったゲームです。彼らはプログラムは勿論、自分たちでモデルも作り、モーションも作り、エフェクトも作るとんでもないやつらです。今後も期待してる!#UE4 https://t.co/RH4NBkgS8k
— alwei (@aizen76) 2017年1月17日
【刹那を味わう"回避アクション"】
— KELu/しょーご@GFF参加 (@kerunaito) 2017年1月17日
《The Artificer》が完成しました!こちらはPVです!#UE4 pic.twitter.com/nIRCsyFSLL
めっちゃレベル高い。
ゲームの気持ちいい部分を抜き出しててすごくやりたい。
ねこが可愛い...
■アプリ開発:1月中リリース目標
— KTK_kumamoto (@KTK_kumamoto) 2017年1月15日
タイトル:ねこバスケ
ゴール回数のセーブ機能、UIとの連動を実装
明日は、LvUPエフェクトとLVアップのセーブ機能、UIとの連動を実装する。 pic.twitter.com/4CxoE8pYFi
たまには癒やしも必要ですよん。
RapidAPIを使えばすべて同一のコーディングで利用できるらしい。
有名WebサービスのAPIをすべて同じ書き方でプログラミング可能な「RapidAPI」は、検索・テストもブラウザ上で実行可能! https://t.co/kMesbKzDuv @appgigaさんから
— ochotech (@ochotech_jp) 2017年1月12日
Oculus TouchでもSteamVR Pluginが使えるらしい @Unity
唐突なSteamVR Pluginサンプル追加でUnityを使って誰でもVive・Oculus Touchで弓を撃てるようになった https://t.co/GhJGfAbdHq
— 野生の男 (@yasei_no_otoko) 2017年1月12日
The Labのやつができるみたい。
Steam強い。
写真から木を作成SpeedTree
自分で撮った素材からSpeedTreeでシダ作った
— はのば (@hannover_bloss) 2017年1月11日
これくらいは数分で終わっちゃうからほんとにスピード感ある
LODも風で揺らすのもボタン一発
そんでUE4に持ってくとまぁ綺麗なんだ・・・ #Speedtree pic.twitter.com/ZqVW3yBs6h
UE4でも動くのすごくいい。
コードの書く際に見直すべきサイト
RT コードを書く際の指針として見返すサイトまとめhttps://t.co/MAYkWJfQMG
— Shinji Kono (@shinji_kono) 2017年1月8日
Gitからコーディングスタイル、ガイドラインまで、幅広い。
UnityのResourcesからLoadする際のキャストの件
かずまです。
UnityでResourcesからLoadするときになにもキャストしない場合Object型で返ってきます。
ただそれではGameObjectとして使えないのでキャストする必要があります。
今回はas演算子もキャストとして扱っています。
どの方法が一番はやく処理ができるのか、気になったので今回はそれを計測してメモしておきたいと思います。
キャスト方法
現在僕が知っている限りResourcesからのGameObjectへの型の変換方法は3つです。
asを使う
GameObject obj = Resources.Load ("Prefabs/Box/Wood") as GameObject;
予想ではasは早いと聞いたのでこれが早いかと!
(GameObject) 対象物
GameObject obj = (GameObject) Resources.Load ("Prefabs/Box/Wood");
これだとInvalidCastExceptionが投げられる場合があるので2つめの引数として型を指定します。
(GameObject)対象物 + typeof(GameObject)
GameObject obj = (GameObject) Resources.Load ("Prefabs/Box/Wood", typeof(GameObject));
二段階で念入りではありますが、これ実は2回も型変換しているので遅いのでは?と思っています。
Genericで指定
GameObject obj = Resources.Load<GameObject> ("Prefabs/Box/Wood");
Genericはコードを書く文にはキャストし忘れ、ということは減るはずなのでいいのですが、はたしてas演算子とどう変わるかといったところですね。
速度計測方法
今回は上記コードを1万回Loadし、そのたびに速度(時間)を計測します。
それを100回試行し、平均を取ります。
計測に使うのは
C#のStopwatchです。
Stopwatch クラス (System.Diagnostics)
プログラムのサンプルはこちら。
// asでの型変換の計測 for(int count = 0; count < times; count++) { Stopwatch st = new Stopwatch (); st.Start (); for (int i = 0; i < 10000; i++) { GameObject obj = Resources.Load ("Prefabs/Box/Wood") as GameObject; } st.Stop (); total_as += st.Elapsed.TotalMilliseconds; }
計測結果
以下の結果になりました。
表に早い順番に並べるとこのような感じ。
方法 | 実行時間(100回平均) |
---|---|
as演算子 | 9.47781ms |
(GameObject)対象物 + typeof | 9.74216ms |
(GameObject)対象物 | 9.99564ms |
Generic | 10.02538ms |
予想ではas演算子が早いということでしたが、ほんとに早かったです。
as演算子を使う場合は少し制約があるのでそこも考えないと行けないです。
予想より早い(GameObject)対象物 + typeof(GameObject)
今回は早い結果となりましたが、何回か再生をポチポチした時にtypeofがない方が早いという結果になることも。
一概には早かったとはいえないけど、そこまで遅くないので使うのは良さそうですね。
Genericでは他に比べると遅いのかな、という印象でした。
高速に使うならas演算子、確実にキャストするなら(GameObject)対象物 + typeof(GameObject)を使うのが良さそうですね。
もし、もっとこうしたほうが良い、ホントはこうだと思うことがあればどんどんコメントでください。
絶賛C#マスター中ですのでご指摘、議論は嬉しいです。
よろしくお願いします。
初の学会発表に臨んだ件。
かずまです。
1/6 ~ 1/8まで静岡県伊東市にある、
ラフォーレ伊東にてプログラミングシンポジウムに参加、発表してきました。
これが人生初の学会というものです。
毎年この時期恒例だそうです。
発表のもろもろ
専門はデータベースを主としています。
今回の発表もデータベースについての内容でした。
結果としては
図が絶対パスになっていて表示されなかった
内容の良さがあまり伝わってなかった
質問の受け答えが微妙
でした。
発表の際に原稿を一応書いて練習してたはずですが、テンパったあまり真っ白に。
あちゃーです。
反省点
プロジェクターの端子を事前に確認しておく
これは発表前に「HDMIの端子がなくDVIしかない!」となってしまいました。
つまり、新しいMacを画面出力するのに変換ケーブルを持っていたのですがHDMIしか出力できず、あっけなく断念。
先輩のPCを使うことになり、Pathが違うので画像が表示されないという問題に。
相対パスにするべきだ...と反省、卒論は気をつけよう。
用語の意図をきちんと伝える
今回問題になったのはインピーダンスミスマッチ。
インピーダンスミスマッチに関してはここあたりの論文を参考にするのが良いかと。
ci.nii.ac.jp
次回こそはいい発表したいところですが今年3月で学生が終わるので
リベンジは社会人になってからですね。
ところで、こんなツイートが。
研究会とか学会とかの発表,ガチガチに緊張してまともにしゃべれないのが本当に悔しいし悲しい.ボスに発表へたくそみたいな人って印象を持たれたまま卒業しちゃうから,本当に卒研発表は失敗したくないなあーーーー
— かぴばら (@marin72_com) 2017年1月7日
いやー確かにこの通りめっちゃ緊張して、ガチガチでした!悔しい!