Author: mo-takusan

メタボールパズルゲームを作る -メタボール編-

 unity1weekお疲れさまでした.今回は私は以下のようなゲームを作成したので遊んだことのない人は是非プレイしてみてください.

unityroomへ移動

 ちなみにツイートのいいね数が150を超えていて地味にうれしいです.

 本記事ではゲームで使用した主要な技術について軽く解説していきます.なお,サンプルプロジェクトも用意しておいたので気になる方は以下のリンクをどうぞ.

サンプルプロジェクトへ移動

2次元のメタボールを描画する

 さて,このゲームで最も特徴的なのはメタボールだと思います.メタボールとは,2次元のグラフィクスにおいては滑らかな曲線を描画するための技術です.ゲームキャラクター(メタボ~ル)はこの技術によってスライムのような滑らかな表現を表すことができるようになっています.

 以降はメタボールの数式的な理解,及びシェーダ上での実装を順に見ていきます.

メタボールを数式で表す

 まずは,数式を交えながらメタボールの表現方法を述べていきます.
メタボールは一言でいうと,あるピクセル上の点\((x,y)\)において,密度関数\(f_i(x,y)(i=0,…,N)\)の重ね合わせが閾値\(t\)を超えた際に色を塗り,そうでない場合は地の色を塗ると言った処理を全ピクセルに渡って行う操作によって有機的な形状を描画するグラフィクス技法のことです..

 具体例を見てみましょう.\(N=2\)とし,密度関数が次のように表されるとします.

$$
\begin{eqnarray}
f_0(x,y) &=& \exp(-(x^2+y^2)),
f_1(x,y) &=& \exp(-((x+2)^2+y^2))
\end{eqnarray}
$$

 \(f_0\)をグラフにすると次のようになります.なお,\(f_1\)に関しては単に\(f_0\)の中心位置を負の方向に2だけ移動したものになります.

 分かりやすいように等高線で表すと以下のようになります.

 例えば最も濃い部分から3つ目のオレンジ色の部分を閾値\(t\)とすれば,この\(f_0\)によって円形の画像が描画されることが分かります.

 そして,これらの密度関数を重ねあわせると次のようになります.

 等高線では以下のように表されます.

 もうメタボールが見えましたね.この場合,オレンジ色の部分は次の式を満たしていると言えます.

$$
f_0(x,y) + f_1(x,y) > t
$$

 『つながるメタボ~ル』ではキャラクターの位置を中心とした\(f_0\)のような関数を定義してやることで滑らかな表現を実現しているのです.

シェーダで実装する

 それでは具体的な実装を行っていきます.今回の実装では次の2ステップに分解ができます.

  1. スプライトの描画
  2. 全体にイメージエフェクトを適応する

 1.のスプライトの描画は前節で言う,密度関数の定義に当たります.スプライトの描画は4点の頂点で正方形を表しその内部に色を載せていきます.すなわち,頂点シェーダで中心位置を移動(実際にはtransformで調整しています)し,フラグメントシェーダで密度関数の本体を書くことになります.
 そして,2.の操作は閾値を超えているかどうか判定をする操作に当たります.

 それでは実際のプログラムを見ていきましょう.

 長々と書いてありますが,注目すべきは2点のみです.
 まずは23行目です.ここでは透明なオブジェクトをどのようにブレンドしていくかを決定します.今回はメタボールの密度値(密度関数からの出力)をα値に格納するため,適切にブレンド方法を決める必要があります.今回の描画では,地の値をそのまま保存しながら描画しなければならないため,One Oneで指定します.

 そしてもう一つの注目点はフラグメントシェーダです.58行目でスプライトの中心位置からの距離を計算し,59行目で計算した密度関数の出力結果をα値に書き込んでいます.なお,使用する密度関数の形式には特に規定がないため,前節のものとは異なる数式を使用しています(2の累乗数は,プロセッサによっては特殊関数が用意されているためですが,アセンブリが最適化されているかは確認していません).最後に60行目では色をうまくブレンドする際に利用に密度値を参照するために残しておきます.α値に直接密度値を書き込んでいるので必要ないように感じますが,α値は後で上書きしてしまうため,色もうまくブレンドするにはこのようにする必要があるのです.

 続いて,イメージエフェクト用のシェーダです.

 こちらはフラグメントシェーダにのみ注目してください.46行目が核となる部分です._Cutが閾値を表しこの値を超えないピクセルについては黒く塗りつぶします.

Unityで実装する上での注意

 以上でメタボールを描画することができるのですが,一つ注意が必要です.それはUnityは基本的に各色を8bitで表し,0~1を256段階に区切った色しか出力できないという点です.もしも1を超えてしまう場合は,1にクリップされて出力されます.今回算出する密度値は重なりが大きいと1を超えかねないため,何も対策をしないと以下のように一部分が白くなり,光ったような表現になってしまうのです.

Image from Gyazo

 これを防ぐためにはおそらくレンダーテクスチャに描画するしかありません(CameraのAllow HDRtrueにするだけで良さそうですがうまいこといきませんでした).レンダーテクスチャでは色のフォーマットを8bitだけではなく,16bitまたは32bitにすることができます.これによって,値がクリップされることをできるだけ防止することができます.したがって,実際に試してみたい方は次のようにレンダーテクスチャを作成し,カメラの描画先をレンダーテクスチャに設定してください.

Image from Gyazo

 レンダーテクスチャを表示するためにはuGUIのRawImageを使用します.

Image from Gyazo

 すると,次のようにきれいなメタボールを描画できるというわけです.

Image from Gyazo

最後に

 以上でUnity上でのメタボールの実装は完了です.『つながるメタボ~ル』の実装には他にも様々な要素がありますが,今回は疲れたのでここで終了にします.
最後まで読んでいただき,ありがとうございました.また,実装についてアドバイスをして頂いたchokopan先輩,ありがとうございました.
 気が向いたらphotonについての記事も書いていこうと思いますのでその時はまたよろしくお願いします.

超絶簡単unityライフハック -スクリプト生成編-

こんにちは。mo-takusanです。

さて、いよいよ始まりましたKCSアドベントカレンダーです。
第一日目ということで今回はあまり難解なことは書かずに、知っていると便利な機能を紹介していこうと思います。

unityのC#テンプレートがやばい

皆さんも毎日のようにunityを使っていると思いますが、この見出しみたいなこと感じたことありませんか?

2018-11-30_12h33_16

この図のようにunityのテンプレートはC#のコーディング規則に沿っておらずきれにするためにはいちいち書き換えなければなりません。このコメントアウトもいりませんし、ちゃんと名前空間も設定したいところです。さらにMonoBehaviourに限らずScriptableObjectなどもテンプレートとして用意されていれば便利そうです。

したがって今回の記事では、

2018-11-23_23h20_17

2018-11-24_18h59_40

こんな感じで「Create」->「MonoBehaviour」でMonoBehaviourが作成され、いい感じのテンプレートで自動的に初期化してくれることを目標にします。ScriptableObjectも作成したいですが、冗長になるだけなので今回は割愛します。

今回の記事はこの記事を参考にしました。

オリジナルのテンプレートを作る

それではまずはオリジナルのテンプレートを作成することから始めましょう。
参考記事によるとwindowsでは

"unityのアプリケーション位置"\Unity\Editor\Data\Resources\ScriptTemplates\

に存在するテキストを編集することで簡単にテンプレートを作成できるようです。
今回は以下のように編集してみました。なおファイル名は81-MonoBehaviour-NewBehaviourScript.cs.txtとしました。これで「Create」->「MonoBehaviour」から「NewBehaviourScript.cs」を作成することができるようになります。

参考ページに載っているようにテンプレートにはパラメータがいくつか用意されており、スクリプト名などを勝手に置き替えてくれるようです。しかし、5行目のコメントアウトから分かるようにプロジェクト名や作成したディレクトリ名もパラメータとして用意してあれば文句はなかったのですが、さすがにそこまで融通は利かないようです。(ちなみにディレクトリ名を名前空間として設定するってC#でもやるんですかね?)

そこで、次節ではこれらのパラメータも認識するように工夫していきます。

自作パラメータを置き換えさせる

ところが、先ほどのように単に一筋縄ではいきません。ちゃんとエディタ拡張をする必要があるようです。
unityではアセットを作成した際に対応したEndNameEditAction抽象クラスのActionメソッドが呼ばれるそうです。つまり、前節のようにしてテンプレートを作成すると、unity側が命名規則に従って自動的にデフォルトのActionメソッドを呼び出してくれると考えることができます。パラメータを自作する場合はこのActionメソッド内にパラメータを置き換えるコードを書くことになります。

それでは早速プロジェクトを作成します。
まず、プロジェクト内に「Editor」フォルダを作成し、ここに先ほど作成したテンプレートを入れてしまいます。この時、先ほどのコメントアウトは消しておきます。以降で作成するパラメータは他のプロジェクトでは機能しないのでこのようにして隔離しておく必要があります。

それではEditorファイル内にスクリプトを生成します。

23~27行目のようにしてパラメータに対応する文字列を入れ替えていきます。それ以降にも何やらごちゃごちゃと書いていますが、エディタ拡張職人になるわけではないので「このような手順を踏んでアセットが作成されるんだ」くらいの認識で良いと思います。

ところが、これだけではうまく動きません。先ほど述べたようにActionメソッドは対応したアセットに対してのみ実行されるため、作成したC#スクリプトに結び付けてやる必要があるのです。そこで、メニューアイテムも自作し、EndNameEditActionを紐づけます。メニューアイテムを自作するにはstaticメソッドにMenuItem属性を付与する必要があります。ただし、このようにしてメニューアイテムを自作する場合、既存のC#スクリプトと競合させてしまうと色々と面倒だったため、別のメニューとして作成します。また、この際の紐づけには次のメソッドを利用します。

このように事細かく指定する必要があるのは、自作したメニューアイテムからではデフォルトのActionメソッドだけでなく、アイコンを指定するメソッドや、アセット名を自動的に付けてくれる処理も呼ばれないためです。
完成したスクリプトは以下のようになります。

これで見事今回の目標は達成となりました。

全てのプロジェクトで使いたい

しかし、このままでは今回作成したプロジェクト内でしか利用することができません。そこで、以降に作成するプロジェクト全てに自動的に反映されるように工夫しましょう。と言っても非常に簡単です。windowsでは

"unityのアプリケーション位置"\Unity\Editor\Data\Resources\PackageManager\ProjectTemplates\

にデフォルトのプロジェクトが用意されているので、ここに作成したファイルを入れてやるだけです。
今回はcom.unity.template.3d\Assetsに入れてみます。

それでは試にプロジェクトを作成してみましょう。

2018-11-26_20h49_05

プロジェクトに先ほど作成したファイルが存在していることが確認できると思います。

おわりに

日々利用するアプリケーションだからこそ開発環境を自分好みにカスタマイズすることが大切ですね。unityのエディタ拡張は専用のメソッドが多く、わかりにくいように感じられますが、「全てを理解する必要はない」と割り切ってしまえばそう難しくもないと思います。実際エディタ拡張ばかりではいつになってもゲームは完成しませんしね。

それでは明日以降も部員たちによる個性的な記事が投稿されることを期待して本記事を締めさせて頂きます。

アドベントカレンダー、やります!

こんにちは。mo-takusanです。

だんだんと寒くなってきましたがいかがお過ごしでしょうか。
今回は題名にもあるようにアドベントカレンダーをやるよっていうお知らせです。本当は結構前からSlackの方で呼びかけていたのですが、「記事にもしなくては!」と思い立ったので今回の投稿をしていきます。

経緯

見出しを付けるほど大した動機ではないのですが、最近のKCSの投稿記事を見ると、、

2018-11-23_18h29_11

 

同じ人ばかりの投稿なのです!
しかも、私以外は2人とも4年生なので最悪の場合、このままでは来年の投稿は私だけになってしまうかもしれないのです。これは由々しき事態だ…

ということで時期的にもいい感じだったのでアドベントカレンダーを通して投稿するハードルを下げられればなぁと思った次第です。

アドベントカレンダーとは

 

インターネット上などで、アドベントカレンダーに見立てて12月に一人、または複数人で毎日記事を投稿していくという企画がある。 特にプログラミングに関連するアドベントカレンダーの企画が近年多数行われている。(Wikipediaより)

12月1日から12月25日までの間、KCSのみんなで記事を投稿していこうと思います。投稿する記事の内容については、技術記事からネタ記事、作品紹介でも何でも構いません!

KCS皆様の参加をお待ちしております

今回はADVENTERさんの方で、カレンダーを作成しましたので登録お願いします。

登録はこちらからお願いします!!(それにしてももう一週間くらいしかないのに集まりきってないって大丈夫か…?)

投稿の仕方などはカレンダーが埋まったときにSlackでお知らせしますね。

ジオメトリシェーダでファーシェーダを実装した話

こんにちは、mo-takusanです。
今回は題名の通りファーシェーダを実装しました。

https://kcs1959.jp/archives/1928/research/unity%E3%81%A7fur-shader

こちらの先輩の記事を見て私も実装してみようと思い、今回取り組んでみました。
またググってみると、unityでファーシェーダを実装している記事は多くあるのですが、ジオメトリシェーダを利用しているものが見当たらなかったため、今回はこれを利用したものにすることを目標としました。

完成図は図のようになります。左側が今回実装したファーシェーダになります。左右どちらの球も同じテクスチャを貼っているのですが、違いは一目瞭然ですね。

2018-09-16_11h12_28

なお、実装においてはこちらの記事を大いに参考にしました。
https://qiita.com/edo_m18/items/75db04f117355adcadbb

また、実装において利用したテクスチャは次のサイトから使わせて頂きました。
http://photoshopvip.net/25382

ファーシェーダとは

ファーシェーダとは、その名の通り毛並みのふわふわ感を表現するシェーダを指します。
ファーシェーダは主にシェル法やフィン法などの実装方法がありますが、今回はシェル法を用いていきます。

シェル法

シェル法においては毛並みを一本一本描画していくわけではなく、層状に毛の断面を描画していくことで、全体として毛並みのように表現する手法です。
具体的には、次のように行います。

  1. 各頂点に対してそれぞれの法線方向に一定距離だけ移動した頂点を生成し、元のメッシュより一回り大きいメッシュを生成する。
  2. メインテクスチャとは別に毛束の断面のようなテクスチャを用意し、そのテクスチャのRGB値が一定を超えたテクセルに対してのみメインテクスチャの色を乗せ、それ以外の部分は描画を行わないようにする。
  3. メインテクスチャを貼る閾値を少し大きくしていきながら、1.及び2.の操作をくり返す。

1.の操作をジオメトリシェーダで、2.の操作をフラグメントシェーダによって実装していきます。

先述のようにシェル法では毛を一本一本描画するわけではないため、層の数が十分でない時は毛束に見えません。以下の図に示すように層が目立ってしまうことが分かると思います。

2018-09-16_11h19_14

実装

それでは実装を示していきます。
先述のように、1.をジオメトリシェーダで、2.をフラグメントシェーダで実装します。

まずは1.です。

[maxvertexcount(81)] //これ以上多くの頂点を生成することはできない
void geom(triangle appdata input[3], inout TriangleStream outStream)
{
    const float spacing = 0.35;
    const int start = _Iterator * START;
    const int end = start + _Iterator;

    [unroll(27)]
    for(int x = start; x < end; x++)
    {       
        float shellPos = _ShellInterval * x;

        [unroll]
        for(int y = 0; y < 3; y++)
        {
            g2f o;

            appdata v = input[y];

            float3 forceDir = 0;
            float4 pos = v.vertex;

            //ここの値はなんでも良さそうなのでそのまま流用させて頂いた
            forceDir.x = sin(_Time.y + pos.x * 0.05) * 0.2;
            forceDir.y = cos(_Time.y * 0.7 + pos.y * 0.04) * 0.2;
            forceDir.z = sin(_Time.y * 0.7 + pos.y * 0.04) * 0.2;
            forceDir += _Gravity - _Inertia;

            float factor = pow(shellPos, 3.0);
                        
            float3 norm = v.normal;
            norm += forceDir * factor;
            norm = normalize(norm) * shellPos * spacing;

            pos.xyz += norm;
            pos.w = 1.0; 

            o.position = UnityObjectToClipPos(pos);

            o.uv = v.texcoord;

            TANGENT_SPACE_ROTATION;
            o.lightDir = normalize(mul(rotation, ObjSpaceLightDir(pos)));

            TRANSFER_VERTEX_TO_FRAGMENT(o);

            o.iter = x;

            outStream.Append(o);
        }
        outStream.RestartStrip();
    }
}

今回ジオメトリシェーダでは三角メッシュを受け取って三角メッシュを出力します。それぞれのメッシュは依存関係がないため、PointStreamの入出力でもよさそうですが、仕様上PointStreamで出力してしまうと、面を貼ってくれなくなってしまうため、このように記述するしかありません。
ちなみに、maxvertexcountが81になっていますが、これより大きい3の倍数でVaridation Errorになってしまうためです(maxvertexcountのリファレンスを読んだのですがこれに関する記述は見当たりませんでした)。この値はフラグメントシェーダに値を渡す構造体の大きさにも依存していたので、渡せるデータサイズの上限値があるのでしょう。

残りは先ほど提示したページの実装とほとんど同じものです。
異なる部分はライティングのためのものになりますが、今回の内容と直接の関係はないので割愛します。触りだけ説明すると、ライトの方向を計算し、ライト情報を適切にフラグメントシェーダに渡しています。
詳しくはこちらの記事をご覧ください。
https://qiita.com/edo_m18/items/21d3b37596da3fd4b32b#%E9%96%A2%E9%80%A3%E3%83%AA%E3%83%B3%E3%82%AF

2.についてもライティング以外は同様の処理です。違いといえばノーマルマップによるライティングを行っている程度です。

さて3.についてですが、先ほどmaxvertexcountの値が81だと述べましたが、これでは層の数が最大でも27層までとなってしまい、元々表現したかったフサフサ感が損なわれてしまいます。これでは本末転倒なので、今回の実装でも参考ページと同様に同じパスを何度も記述して層の量増しを行いました。
といっても一回のパスで27層描画できるので3つだけ同じパスを用意しました。

ジオメトリシェーダによる実装のメリット

ジオメトリシェーダを利用して実装を行うと、プラットフォームによっては動かない可能性があるため、望ましくないことも多々あります。しかしながら、ジオメトリシェーダによってファーシェーダを実装した場合、次のようなメリットが考えられます。

  • 全く同じパスを数十個書く必要がないためスマート
  • バッチ数を抑えられる
  • 層の数を可変にすることができる

特に、層を可変にできることでお好みのフサフサ具合を表現でき、非常に便利でしょう。バッチ数を抑えることで
パフォーマンスは改善されるのでしょうか?ジオメトリシェーダがどれほど重いか計測が面倒だったので言及しないことにします。

まとめ

ジオメトリシェーダを利用することで、比較的スマートにファーシェーダを実装することができました。シェーダはすぐにビジュアルに表れるので実装していてとても楽しいですね!

第三回技術交流会

こんにちは。mo-takusanです。

今年の夏は非常に暑いですが皆さんはいかがお過ごしでしょうか?

KCSでは先日技術交流会を開催いたしました!
KCSの他に参加いただいた団体は以下の通りです。

  • ロボット技術研究会
  • 慶應義塾志木高等学校電子工学研究会
  • 慶應義塾高等学校電子工学研究会
  • 慶應女子高校Keio Computer Girls(KCG)

忙しい中参加いただきありがとうございました!

開催概要

日時:

2018年8月22日(水)14:00~18:00

場所:

矢上キャンパス 34棟 407

参加者:

約30名

プログラム:

14:00-挨拶
14:10-各団体紹介
14:40-研究発表(前半)
15:00-休憩
15:10-研究発表(後半)
15:00-休憩
16:10-ワークショップ
18:00解散

研究発表の様子

今回も各団体から発表者を募ってもらい、各自の研究成果をプレゼン形式で発表してもらいました。
今年はプログラミングの話題に偏らず、DTMやデザイン、ロボティクス等多様なお話を聞くことができました。

以下は発表の様子です。

2018_08_23_12 2018_08_23_5 2018_08_23_7 2018_08_23_8

 
今年はTwitterのハッシュタグを設けて実況なんかもしました!
#慶應技術交流会2018

頂けた資料はココに載せますので気になった方は是非どうぞ!(追加で頂けたら随時更新します)

 

ワークショップ

今回はせっかく集まったのでしっかり交流すべく研究発表の他にワークショップを開催しました。内容は以下のスライドの通りです。

このワークショップは今年の3月にDeNAさんがいらしたときに教えていただいたもので、学びながらも超盛り上がるので持ちネタにしてしまいたくなるほどです笑
簡単に工程をまとめるとこんな感じです。

  1. 4人程度でグループを作る
  2. 各グループにイベントを記すための付箋を配布する
  3. 基本ルールを基にして、イベントマスを作成してもらい、実際に遊んでもらう

  4. 基本ルール
    (1)スタート地点からさいころを振り、出た目の数だけ進む
    (2)一周してスタート地点を通過するたびに1点獲得
    (3)3点獲得した人が勝利

  5. みんなに、どのマスがよかったか、悪かったかを考えてもらう
  6. バランスブレイカーについての解説を行う
  7. それをもとにもう一度マスを作成して遊ぶ

それぞれの班でユニークなマスがいくつもできました!
今回のワークショップで簡単なパーティゲームにおいては、マイナスマスはあまり面白くならないこと、適切な運要素とバランスブレイカーが必要であることが分かっていただけたと思います。

2018_08_23_1
すごろくの様子です。

おわりに

ロボット技術研究会さん、慶應義塾志木高等学校電子工学研究会さん、慶應義塾高等学校電子工学研究会さん、慶應女子高校Keio Computer Girls(KCG)さん、そして当日参加された皆さんのおかげで大変素晴らしい交流会となりました。
こうしたサークルの枠を超えた交流はこれからも是非行いたいと考えていますので、今後ともよろしくお願いします。

unityで外部テキストをC#コードとして読み込む

こんにちは。mo-takusanです。

今まではほとんど記事を書いてこなかったのですが、さすがにそろそろ投稿していこうと思います。

unityで外部コードを読み込むには…

最近とある事情でコンパイル後に外部ソースコードを読み込みたい、という場面がありました。

「あああ、Python書くかぁ」

となっていたのですが、念のため調べると、C#はコンパイル言語ですが、ランタイムでコンパイルができるようです。C#神!!やっぱり.NET最強!!!

ただし、untiyとの相性が悪いものが多く、四苦八苦してしたので、紆余曲折の様子を記事にしていきます。

なお、本記事で使用したunityのバージョンは2017.1.1f1です。

まずはできた方法を、、

まあ、とにかく知りたいのは実際にうまくいったやり方でしょう(需要があれば)から、その方法から話していきます。

なんだかんだとググっていくうちに以下のGitHubにたどり着きました。

https://github.com/aeroson/mcs-ICodeCompiler

このサイトを見たとき、ついに来た!最終コミットもそれなりに新しいしこれはいけるやろ!と思ったのですが、ここからが長かった…(unityのバージョンを合わせればよかったとかそういうツッコミはなしでお願いします、、、)

2018-02-07_23h38_41

早速クローンしてサンプルプロジェクトを開いてみると…

2018-02-07_23h42_07

地獄絵図…。unityはICodeCompilerやCompilerResultsが存在していないと主張してくるのですが、

https://msdn.microsoft.com/ja-jp/library/system.codedom.compiler.icodecompiler(v=vs.110).aspx

https://msdn.microsoft.com/ja-jp/library/system.codedom.compiler.compilerresults(v=vs.110).aspx

のように、System.CodeDom.Compiler名前空間には確かに存在しています。実際コードの方でもusingされており問題はなさそうです。やけくそで丁寧に書き直してみても全然ダメ…

2018-02-07_23h45_47

うーーーん。

これについては解決方法が全く分かりませんでした。ので、ダメもとで一緒にクローンしてきた「non Unity3D usage」のコードを新規プロジェクトに入れてみました。dllはPluginsに入れることを忘れずに…

2018-02-08_00h03_29

おや?エラーが出ない!
やった…やったよ、、おれ、ついにやってのけたよ…
そうするとデモが動かなかった理由がいよいよ謎ですね。

それはともかくとして、あとは適切にファイルを読み込むコードを書いて、、、

 private static Assembly Compile(IEnumerable&lt;FileInfo&gt; files)<br />
 {<br />
     var domain = AppDomain.CurrentDomain;<br />
     var references = domain.GetAssemblies().Select(a =&gt; a.Location).ToArray();<br />
     var options = new CompilerParameters<br />
     {<br />
         GenerateExecutable = false,<br />
         GenerateInMemory = true,<br />
     };<br />
     options.ReferencedAssemblies.AddRange(references);<br />
     var compiler = new CodeCompiler();<br />
     var result = compiler.CompileAssemblyFromFileBatch(options, files.Select(f =&gt; f.FullName).ToArray());<br />
     return result.Errors.Count &gt; 0 ? null : result.CompiledAssembly;<br />
 }

完成しました!!!
なお、こちらのプロジェクトは諸事情で公開していないのであしからず。

ここからはできなかったことを書くぞ!

と言いましたが、疲れたので失敗の様子はダイジェストでどうぞ

System.CodeDom.Compilerを素で使う

なぜかコンパイルすると動かない(unityではよくある泣)

AssetStoreからダウンロード

https://assetstore.unity.com/packages/tools/cs-script-for-unity-23510

このページにいい感じのアセットがあったのでダウンロード。が、だめ。(古かった)

Roslynを使う

unityが.NET4.6に対応したことを利用して、次のサイトを参考にして組んでみよう!

https://www.gaprot.jp/pickup/tips/roslyn

unityが反応してくれない!おい!!nugetからdll落としてPluginsに入れてもダメでした。(むしろそれ以外を知りませんが)

2017年Unity講習会総括

こんにちは。はじめまして。
mo-takusanです。

KCSは今年度、4月から6月にかけて主に新入生に向けて様々な講習会を開きました。
本記事ではその中でもUnity講習会について、反省などをつらつらと書いていきます。

まあ大抵の人は興味ないかと思われますが、こういうの書かないと何も活動していないように見えますしね…

さて今年度のUnity講習では、以下のような簡単なアスレチックゲームを作成することを目標に取り組みました。

2017-08-01_12h03_34

ぶっちゃけ公式チュートリアルの「玉転がし」の延長です。非常に単調なゲームでしたが、それだけにUnityの基礎はだいたい抑えられたと思います(Instantiateとか抜けているのは本当に痛手でしたが…)。

前置きはこのくらいにして順番に反省していきたいと思います。

テキストについて

今回は技術書展2への出展も兼ねていたのでできるだけ 丁寧、読みやすい、網羅的 になるように心がけました。
また、要所要所に課題を付け、今まで習ったことを復習できる機会も作ることを意識しました。これは、テキストをできるだけ細かくに書いた分、「読めばわかる」という感じにはなった(と思う)のですが、逆に、考えて取り組まなくなる恐れがあったためです。実際新入生は苦労していた様子でしたが、上級生が手伝いながらこなしていました。

もちろん反省点もありました。まず一つは誤字が多かったことです。もちろん仕方のないことではあるのですが、スクリプト部分での誤字は致命的でした。もう一つはコード上の欠陥によって、正しく作成しても動かなかったことです。これはもう悪夢。急いで作成し直しました。
あれもこれも結局はデバッグ不足が原因でした。実は「これで動くだろ」という安直な考えで一度も試すことなく書いた部分がいくつかあり、そこが見事にバグったのです。これデバッグ以前の問題では…

講習会について

初めから最後まで10人満たない程度の人数で活動しました。人数があまり減らなかったのは良かったのですが、もっと集まると思っていたので(昨年は30人であったため)、宣伝が足りなかったのかもしれません…。

さて講義の進め方ですが、本講習会は自学自習形式を取りました。講義の流れはこんな感じでした。

 

軽い挨拶

今日のポイント

自習(適宜質問)

今日のまとめ

 

一年生にとってどうだったかは後程アンケートを作成しようと思いますが、個人的には良かったです。というのもこの講習会というのはサークルとして必須なのですが、その性質上、上級生は恩恵を受けづらいのです。そのため、毎度講義形式をとるとリソース不足に加えて、モチベーションの低下が著しくなってしまいます。もちろんいくら用意が少なくて済むからと言って「今日のポイント」や「今日のまとめ」をその場で作成するのはやめましょうね。さらに自習形式にして、必要な時に質問をしてもらったため、新入生も多分自ら学ぶ姿勢になりました。あと質問によって新入生と一対一で会話できたので楽しかったです(小並感)。

さらに、5月の中ごろからはまとめの内容をSNSで共有することを始めました。内容はこんな感じ

本日は4章をやりました
☆コルーチン
Updateメソッドによる更新から外れた処理をしたいときに使用するもの
IEnumrator メソッド名(引数){
処理
yield return ~
処理
}
のように記述する。
~の部分には以下のような記述が可能
null…次のフレームに処理を行う
new WaitForSeconds(t)…t秒後に処理を行う
☆レイ
あるオブジェクトから見えない光線を飛ばし衝突したオブジェクトの情報を得るもの
今回は以下のような記述をしてメインカメラからレイを飛ばしてクリックしたオブジェクトの情報を得るようにした
①Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
->MainCameraというタグのついたカメラからレイを作成する
②RaycastHit hit;
->光線が衝突したオブジェクトの情報を入れる変数の定義
③if(Physics.Raycast(ray, out hit)){処理}
->Raycast->衝突した場合trueを返すメソッドで衝突したオブジェクトの情報をhitに入れる

これは、毎回フルメンバーで講習会を行うことができないので、来れなかった人たちが復習しやすいようにするためです。
ただこれも毎回はできていませんでしたね…。モチベーション維持って難しい。

 

その他

そんな中でも一番悔やまれるのが講習会後の食事会でした。初めて企画した際には思いのほか集まってうれしかったのですが、何も考えずに店に直行したら人数多すぎて見事にはじき返されました。人数が決まったらその時点で店に予約を入れるだけでも全然違うと思います。

まとめ

とにかく来年度に向けて気を付けてほしいことを最後にまとめておきます。

  • デバッグはしっかりする
  • その日の講習会でやる内容はあらかじめ決めておく
  •  食事会は計画的に

うーん、割と考えればわかりそうですが、当事者になってみるとうまくいかないものです。できればワンマンで行うのではなく、みんなで一つの講習会ができるといいですね。

 

最後に

本講習会で使用したテキストはここにあります。気になる人は見てみてください。