プロジェクトテンプレートを選択して作成します。ここで<port>ランダムに選択されたポート番号です。見るSwaggerページだと思います。試しに実行することもできます。サンプルデータ用のサービスを作成するまず次のようなTodoItemクラスを作成します。}}つぎにそれを扱うITodoItemContainerを作ります。実装は少し長くなったので下の方に書いておきます。単純にList<TodoItem>を用意してそれに足したり抜いたりしているだけです。使うためにはDIコンテナに登録する必要があります。builder.Build();が呼び出されている箇所より上でbuilder.Services.AddSingletonを呼び出せば登録することができます。今回は次のコードをを追加しました。コントローラーはControllerBaseを継承して作ります。これを継承することで応答に便利な関数を利用できます。ControllerBaseApiCotroller属性をつけると以下のようなAPIの動作を有効化できます。コントローラーにメソッドを定義することでアクションを設定できます。DELETEが含まれていると自動的にHTTPメソッドとして登録されますが、Swaggerが認識できないのでHttpGet属性をつけるほうが良いです。}ルーティングルーティングはRoute属性を用いてコントローラーまたはアクションに設定できます。ルーティングは大文字小文字の区別がありません。api/todoでもApi/Todoでも同じものとして扱われます。コントローラにRoute属性を使うとそのコントローラーでのデフォルトのルートが設定されます。部分を取り除いた文字列が入れられます。アクション、つまりメソッドにRoute属性を使うとそのメソッドだけにルーティングを設定できます。このとき、/または~/で始めるとコントローラーのルートテンプレートと結合されません。動詞テンプレートでもルーティングは設定できます。動詞テンプレートを使うこと方が良いです。動詞テンプレートは以下の6つです。}}メソッドの引数メソッドの引数はURLパスから受け取ったりリクエスト本文から受け取ったりできます。URLパスから情報を受け取るRoute属性やHttpGet属性などで{id}のように書くことで、引数idにその値を受け取ることができます。{id?}とすることで省略することができます。省略された場合引数にはデフォルトの値が入ります。リクエストヘッダーFromBodyはSystem.Text.Jsonを使って自動的にパースしてくれます。}}メソッドの返り値メソッドの返り値にはActionResult<T>を指定しておけば暗黙的なT=>ActionResult<T>のキャストが実装されているのでとりあえずは困らにと思います。型が指定できないとき、例えば匿名型を使用するときなどはActionResultを使えばよいです。そのまま値を返しても問題ありませんが、ControllerBaseに実装されているメソッドを利用することで一緒にStatusCodeを指定することもできます。使われそうなものをいかに列挙しておきます。返すオブジェクトを生成する。引数にはアクションの返り値にしたいオブジェクトを指定する。返すオブジェクトを生成する。第2引数にはアクションの返り値にしたいオブジェクトを指定する。返すオブジェクトを生成する。第1引数には作成されたコンテンツを返すアクションの名前を、第2引数にはそのアクションのURLの生成に使用するルートデータ。第3引数にはアクションの返り値にしたいオブジェクトを指定する。返すオブジェクトを生成する。クラスのドキュメントを参照してください。DELETEメソッドを追加して最終的に次のようになりました。どれを使えばいいのか全然わからなかったです。クラスのドキュメントを参照してください。APIを作ってみるにコメント3Dモデルの調整をしながらVRChat用モデルからVRMへ効率良く変換するBlenderで制作して完成したと思っても、実際に動かしてみたりするとウェイトペイントが上手くいってなくて服が突き抜けたり、テキスチャがおかしかったりと、様々な問題が発生してBlenderでの修正を再三に迫られる場面は多いです。そのためにBlender側で修正したものを出力してUnityに読み込ませます。そのUnityへ読み込ませる際にちょっとした工夫をすると作業量を緩和できます。この記事は多分OUCCアドベントカレンダーの最終日の記事になります。去年のハッカソンでは、何かと不満を言われるE-Learningと和解しようという企画にて、自然言語で会話できるBotを制作しました。その過程で会話相手として、E-Learningの化身、angEL-reinちゃん(名前はE-Learningのアナグラムから)が生まれました。私が生みました(生産者表示)この名前微塵も流行らず、代わりにいーちゃんと呼ばれているのですが、このいーちゃんを音声で入出力して会話できるようにして学祭に出そうという話になりました。そこで私はRustサーバーを作って非常に遅い言語生成処理の高速化を行ったりしたわけですが、そんな話は今回どうでも良く、それよりやはり音声での会話をするならば、会話する相手が見えた方がいいですよね?古来より偶像崇拝があるように概念を相手にするよりかは、視覚的に見えるものを相手にした方が良いに違いない。いうわけで、れいんちゃんの3D化計画を極秘裏に進めました。以前の記事で既にLive2D化した話はしましたが、我慢できずに3D化に踏み切ってしまいました。3Dモデル完成(仮)までまずVROIDで素体を生成し、Blenderで服などを制作しました。私は3Dモデルを作るのはこれで2回目なので初めてというわけでは無いですが、やはりそれなりに苦戦はしました。前回と同様ウェイトペイントでは常に苦戦させられ、今回も最後まで難敵となりました。あってFBXモデルが完成しました。VRChatに出したかったのでまずVRChat用の改変をしつつシェーダの調節をしていきました。その結果完成したのがこちらちなみに私は目にこだわる人なので、目は虹彩を奥に配置し、反射光を前面に出すなど立体的にしていますhttps://video.twimg.com/ext_tw_video/1584827761960837122/pu/vid/866x610/CO7Tx-DZP0uWzJJR.mp4その後単眼カメラによる姿勢推定アプリを制作する、又はキャラクタを後世の人に使ってもらうためにVRMモデルへの変換を行いました。本題Blenderで制作して完成したと思っても、実際に動かしてみたりするとウェイトペイントが上手くいってなくて服が突き抜けたり、頂点にウェイトが割り当てられてなかったり、テキスチャがおかしかったりと、様々な問題が発生してBlenderでの修正を再三に迫られる場面は多いです。Toolなどを使って個々の頂点についてウェイトを塗りなおしたりして修正したものを出力してUnityに読み込ませます。そのUnityへ読み込ませる際にちょっとした工夫をすると作業量を緩和できます。fbxファイルのBlender→Unityfbxファイルをunityに読み込むと、モデルをScene上に配置できるようになります。VRChatを想定した場合、その配置したモデルにPhysboneなどのコンポーネントを設定していくことになります。この方式では、後で修正をかけたモデルで上書きして読み込む際にfbxファイルと共にScene上のオブジェクトもリセットされてしまい、またコンポーネントの設置などをしなければならなくなります。これでは非常に非効率なので、fbxファイルを上書きで読み込んだ際にScene上のオブジェクトのコンポーネントがはがれないようにしたいです。Variantで生成できます。この生成したものをドラッグアンドドロップでSceneに配置してコンポーネントを張り付けてみてください。することでfbxファイルを上書き更新しても、Scene上のモデルだけが更新され、コンポーネントは剥がれなくなります。VRChatを使用しますのでこれを既にUnityへインポートしている前提で記述します。avatarで適当に入力してAssetディレクトリ内に用意したフォルダ(フォルダ1)にexportします。この際もしかしたら未使用シェイプキーにチェックを入れてexportした方がいいかもしれません。これでフォルダ1内にVRMファイルとそのprefabが生成されます。エラーが出ても、何も変えずにもう一度実行すると何故かうまくいったりします。VRM0でフォルダ1に出力すると、フォルダ1のVRMを上書き修正することができます。2回目以降のexportモデルを変更した場合、またVRChatモデルからVRMへの変換をする必要があります。avatarで出力する場所はフォルダ1とは異なるフォルダ2へ出力した方が良いです。フォルダ1に出力してしまうとせっかく以前に設定した表情や物理などのコンポーネントが上書きされてしまうからです。この時、フォルダ1には旧、フォルダ2に新モデルが入っていることになります。生成された新モデルのPrefabファイルをSceneにドラッグアンドドロップで配置。Wizardで以前のデータからSpringBoneや表情などの情報を新モデルへコピーします。この時に、Sorceにはフォルダ1の旧Prefabアセット(Projectビュー上)を選択し、Destinationには新モデルオブジェクト(Sceneビュー上)を選択しないとエラーが出ます。ここまででコピーできていないのはマテリアルのみです。マテリアル情報を新モデルにコピーしていくのですが、使用マテリアルが多ければ多いほどこの作業が非常に面倒です。よってそれをやってくれるツールを自作しました。.csファイルを入手して、readmeに書かれている通りに導入してください。Windowとします。sizeにコピーするSkinnedMeshRendererの数を入力し、Sorceにコピー元の、Destinationにコピー先のSkinnedMeshRendererを指定してCopy!ボタンを押すとマテリアル情報がコピーされます。マテリアル自身は複製されません。VRM0でフォルダ1へ出力、上書きします。これでVRMファイルが新しくなって置き換わります。完成3Dモデルはこちらからぐりぐり見れます。https://hub.vroid.com/characters/7942564502413041514/models/2799418893141239533文化祭での様子もっといい方法があるかもしれないですが、私はこの方法でやりました。よければお使いください。アドベントカレンダー3Dモデルの調整をしながらVRChat用モデルからVRMへ効率良く変換するにコメント初学者のためのC#C#とはC#はC++からJavaになる際に追加されたガーベージコレクション(GC)や中間言語を介して共通の実行環境で実行することなどを参考にMicrosoftが開発した言語です。Framework上で実行されます。Studioを使うことで簡単にWindowsアプリケーションが開発・公開ができます。OUCCで主に使用しているUnityというゲーム作成に使われるフレームワークで使用する言語にも採用されています。名前空間はこうやって宣言する。こんな感じで複数行にわたって書くことも可能。}}StructとClass大きく分けてStructとClassの2種類があり、したのようにいろいろ違いはあります。StructはClassよりも動作が早いのですが参照型でないためにおこる様々な問題があるためオブジェクトを自分で定義する際は何か重要な問題がない限りClassで作ることをお勧めします。nullを入れられるstructの問題点スタックに保存されるのでメモリを多く占有する大きなオブジェクトを入れると逆に遅くなる。参照型でないので関数やプロパティでとってきたものを変更してももとのオブジェクトを変更できない。(classでは可能)継承ができない引数なしのコンストラクタを作れないnullを入れられない他の問題を見たい方はC#に潜むstructの罠などを参考にしてみてください。使う型この中ではstringのみがclassでそのほかはstructです。string配列C#で配列はclassであり、大きさは定義時に決定されます。書き方は以下の通りです。//このように書いて初期化することも可能です。//このように書くことで配列の要素にアクセスできます。int[,,]のように書くことで多次元配列を作れます。int[3,4]とすると3×4多次元配列になります。ジャグ配列int[][]のように書くことでジャグ配列(ギザギザ配列)を作れます。これは配列の配列となっているので内側の配列の要素の数はそれぞれ違っても構いません。%(余り)はありますが、pythonにはある累乗の**はありません。静的型付け言語なので以下のような整数同士の割り算は小数点以下が切り捨てられます。どちらかをdoubleにキャストしましょう。