20210802のUnityに関する記事は6件です。

UnityでビルドしたiOSアプリをTestFlightで配信する

全体の流れ App Store Connectにアプリを登録 Unityでビルド Xcodeでアップロード テストユーザーの招待 App Store Connect にアプリを登録 バンドルIDがない場合はApple Developerで作成する。 https://appstoreconnect.apple.com/ にアクセス & ログイン マイApp→新規Appからアプリケーションを作成 Unityでビルド Build Settings > Player > Identification > BundleIdentifierに先ほど登録したバンドルIDを入力 Build Settings > Player > Icon > Marketing Icons を登録 ビルド Xcodeでアップロード Xcodeでプロジェクトを開く Signing & Capabilities > Team を入力 Build Settings > Signing > Development Team を入力 画面上部のProduct > Archive をクリック Validate App をクリック Distribute App をクリック アップロードに成功するとApp Store Connect上でアプリのTestFlight に表示されます。 Xcode上でUploadに成功しているのにApp Store Connectに表示されない場合はメールにエラーの内容が届きます。 Archive一覧はXcodeの Window > Organizerで開くことができます。 テストユーザーの招待 App Store Connect > ユーザーとアクセス > メールアドレスを入力して招待 App > TestFlight から内部テストを作成 内部テストにユーザーを招待 テストプレイする側 メールアドレスを開発者に伝える ユーザー招待メールのリンクから参加 TestFlightをインストール アプリケーション招待メールからTestFlightでテスト
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[VRChat SDK3] Unityで着せ替えをする時、服のArmatureをどこに移動すればよいか解決したのでメモ

着せ替えArmature部分について記事を探したのですが全く見当たらず、一連の流れをライブコーディング(ライブクロージング?)してる動画でようやくわかったので文字に起こしてメモ (VRC始めて3日とかなので単語とか適当です。正式な呼び名とかあったらぜひ教えてください) アバターはミーシェちゃんで、服はBOOTHにあった無料のミーシェちゃん用のものを使わせていただいております。 1. まず、服のArmatureフォルダをArmatureフォルダごとbodyのArmatureフォルダに入れる。 2. 移動した服のArmatureの中にあるオブジェクトについて、すでにbodyのArmature内にあるオブジェクトのフォルダ?と部分文字列が一致してそう(こことても重要)なのに入れる。 (1.とやってることは本質的には同じ) これを再帰する。 3. 終わり。 最後に 最初、服のArmatureフォルダに中にあるものを階層を維持してそのままbodyのArmature直下に持ってくるのかと勘違いしていて思い通りにいきませんでした。(これによって服のArmatureフォルダやBodyフォルダを「中身が空だしいらんやろ!」と言って削除していたのですがヤバかったですね) しかしオブジェクト名を目grepしてオブジェクトを移動してくってエンジニアリング的にどうなんですかね… そのうち手が空いたら画像とかも入れてみます。VRCもUnityも超初心者なので何か間違ってたりしたらぜひツッコミください。 服がズレない感動がここにはあった。。。 P.S. しかしオブジェクト名を目grepしてオブジェクトを移動してくってエンジニアリング的にどうなんですかね… 山兔さんが作られたAvatar Skin Replaceというモジュールがそれを解決してくることもあるらしい。(すごい)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Project Unity

overview Unityを使ったゲーム開発のブログ・メモみたいな感じ 毎日90分を目安に作業するので振り返って「成長したな〜」を実感したい 毎日1つこの記事に追加していく DAY01 210730 Today パックマン的なゲーム開発 所要時間: 240min ボールを操作してブロックを消していくっていうゲーム 初めてのゲーム開発だけど意外に4時間で作って動かせた もっとCLIかと思ったけど、全然GUIだった ローカルで作れたのは良いけど、早くリリースしてみたい ゲーム開発はプログラミングというよりは動画制作に近い ほぼほぼGUIで成立するからUnityの操作方法さえわかればほとんどの処理を実装できそう コードを書くこともあるけど、wordpressみたくunity独自のプロパティを繋げるだけ 後々ユーザー登録機能の実装とかでプログラムの処理が多くなるのかな? Tomorrow 今回こんなに早く作れたのは奇跡かもしれんのでもう1個何かゲームを作ってみる DAY02 210731 Today 所要時間: 180min ピタコラスイッチ的なゲーム開発 英語のドキュメントだけど普通に完遂した 主にオブジェクトの生成がメインだった ナビゲーションの操作がめちゃくちゃ難しくて思い通りに視点を切り替えられない Tomorow youtubeを参考に入門的なゲームを作る DAY03 210801 Today 所要時間: 78min ブロック崩しゲームの開発とリリース youtubeを見ながらブロック崩しのゲームを作って、githubpagesに公開 https://oni-unity.github.io/public/block-breaking/ ゲーム開発 クリア判定もないしいきなり始まって終わりもない、ただ単にブロックを崩すというシンプルなゲーム(もはやゲームじゃない) 主に、pcの操作内容をゲーム側に伝達する仕組みがわかった リリース webGLを使ってGithubpagesにコードを乗せて公開できた buildしたファイルが90%で止まるエラーに遭遇 設定から圧縮を解除したら正常に動作した 相変わらずローカルのブラウザでは動作せずにリモートに公開しないと無理だった pc版だからかスマホからだと全く操作できない Tomorrow クリアの画面を作りたい DAY04 210802 Today ゲームに勝敗判定とUIを実装 所要時間: 300min URL: https://oni-unity.github.io/public/block-breaking02/ やったこと クリアとゲームオーバーの処理 それぞれに対するUIの作成とスイッチング 感想 動画を見ながらだったけど意外に5時間もかかった・・・ 特にblockの読み込みなどC#での変数の処理がよくわからずずっとエラーだった とはいえ、シンプルなif文を3・4個書いたら実装できたのでweb application開発よりは簡単だった印象 Tomorrow これまでの知識でビリヤードを作ってみる
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

「そうだ!インターフェースを作ろう!」と生まれて初めて思った日

オブジェクト指向を完全に理解し、インターフェースを使いこなして日々プロダクトを開発している強エンジニアの方に聞きたいんですけど、生まれて始めて自力で「ここでインターフェースを作ろう!」と思った日のことを覚えてますか? 世の中にはたくさんの優秀なエンジニア・プログラマがたくさんいて、そういう方々は(もちろん技術分野によって異なるでしょうが)さも当然のように「ここでインターフェースを作ろう」と思ってプロダクトの開発を進められるのだと思います。 でも当然そういう人たちも、生まれた時からインターフェースを使えたわけじゃないと思うんですよね。 人によって経緯やその時の状況は異なると思いますが、オブジェクト指向プログラミングやカプセル化、ポリモーフィズムのことを勉強して、その後自分の開発にそれを「初めて活かせたタイミング」というのがあるんじゃないかと思うんです。 僕は開発というものを個人レベルで、また転職して会社の案件として学び始めて約3年が経ったところで、まだまだ修行中の身であります。 そんな僕は、オブジェクト指向であるとかインターフェースといったようなものは、説明を読んでその意味は分かる、既に実装されたコードがあればどういう動きをしているかなんとなくは分かる、同じように実装しなさいと言われればできる、というレベルのものでした。 ところが先日、明らかに理解のレベルが上がったな、と思うことがありました。 それがタイトルに書いた「そうだ!インターフェースを作ろう!」と自発的に思った瞬間です。 インターフェースがなにか、という技術的な説明に関しては、他にテクニカルな記事がいくらでもあると思うのでそちらを参考にされた方が良いでしょう。 今回僕がしたいのは単なる技術の説明ではなく、まだ自分のものになっていなかった技術を、自発的に「使おう!」と思えた瞬間の、状況や自分の中の理解についてのお話です。 ゲーム中「タップで購入できる」を示すアイコンを表示する処理 僕は個人レベルでゲームを開発することを趣味にしています。 個人でも無料で利用できるゲームエンジンUnityを使い、過去にいくつかのゲームをリリースしており、今も新しいものを開発中です。 インターフェースを作ろう!と思い立ったのは、まさにこのゲーム開発の最中でした。 その時僕は、カンタンなタワーディフェンスのようなゲームを製作中でした。 マップ上を可愛いハムスターが歩いてくるので、お菓子を飛ばす装置を通路上に設置し、お菓子を食べさせることによって満腹になって帰ってもらう、という軽い感じのものです。 その装置を設置するためには、マップ上の特定の位置をタップする必要があります。 その位置をタップした時、必要量のコインを所持していたら装置を設置できる、といった具合です。 またすでに設置した装置もさらにコインを払うことにより、性能を強化することができます。 この操作もタップによって行います。 さらにこのゲームには、全てのハムスターを緊急避難的にスタート地点に引き戻せるアイテム「ネコ」があります。 ネコは所持していれば使うことができるのですが、このネコの所持数を増やすのにもコインを使用し、画面をタップして購入する必要があります。 これらの箇所を制作していた際、ふとこう思いました。 購入に必要な量のコインが手に入ったら、「ここをタップしたら購入できるよ」ということを表示できないだろうかと。 このゲームはどちらかというとゲーム初心者をターゲットにしたようなものだったので、どこをタップしたらアクションが起こせるかを表示する機能があった方が良いと思ったのです。 ↑こういう感じです 実装にあたっての問題点 さっそく僕はその機能の実装に手を付け始めました。 やることは「コインがそのアクションを起こすのに必要な数貯まったら、それを示すUIを表示する」ということです。 しかしここで問題があることに気付きました。 装置設置ベースに装置を設置する 装置を強化する ネコを購入する これらは全て、必要なコインの量が違うのです。 また、Unityでゲーム上に設置するオブジェクトの種類も違い、そのため条件が整った時に表示するUIの種類も違うことになります。 もう一つ、現在所持ししているコインの量は、ゲームマネージャというコンポーネントが管理しています。 これはステージのゲーム進行を統括するような役割のコンポーネントになります。 そして装置、装置設置ベース、ネコを購入するボタンに関してはゲームマネージャとは別のオブジェクトになります。 つまりゲームマネージャでコインが増減したことを契機として、各種オブジェクトが「タップしてアクション可能か?不可能か?」を調べる必要があるということです。 状況を整理すると、 以下のコンポーネントが別々に存在している コインの量を管理する「ゲームマネージャ」 ……① 必要コインを持っている時にタップすると装置を設置する「装置設置ベース」……② 必要コインを持っている時にタップすると自身を強化する「装置」……③ 必要コインを持っている時にタップするとネコを購入する「ネコ購入ボタン」……④ ①が管理しているコインに増減があった時、②③④のアクションに必要なコイン量を調べ、タップ可能アイコンを出し入れする必要がある ②③④それぞれ、アクションに必要なコイン量、タップ可能アイコンのUIオブジェクトはすべて別々 こういう要件のコードを書く必要があったということです。 さて、どうする? コインを管理しているのは①なので、コインが増減したタイミングは①が握っています。 なので、②③④それぞれに「アクション可能になったかどうかをチェックし、結果に応じてタップ可能アイコンを出し入れする」という処理を作り、コインが増減したタイミングで①からその処理を呼び出せば、実現できそうです。 問題は、 アクション可能になったかどうか、という判定基準 タップ可能アイコンオブジェクト ②③④の処理を書いているクラス(コンポーネント)そのもの これらが、②③④によって異なる、ということです。 これらが異なるということは、コインが増減したタイミングで①は、 ②のチェック用メソッド ③のチェック用メソッド ④のチェック用メソッド を別々に呼び出す処理を書く必要があります。 ……こうやって3行で書いてしまうと「イケるじゃん」的な感じがしてしまいますね。 ですがこれ、絶対に3つで済むんだったらいいんですが、あとで新たにタップ可能なオブジェクト⑤を増やしたい、という話になった場合に、⑤のチェック用メソッドをチェックさせる処理を追加しなければならず、少々面倒です。 またこれはUnityの技術的な話になってしまいますが、ゲーム中に②や③が存在している数は変動することが想定されています(④は常に1つしかないですが)。 従ってコインの増減時に②、③をゲーム中から検索し、②だったら②用のチェックメソッドを、③だったら③用のチェックメソッドを呼ぶ必要があります。 オブジェクトの配置(Unityではヒエラルキーと言います)を工夫することで多少手間を抑えられはしますが、コード的には探索やオブジェクト種の判定の処理をオブジェクトの種類分だけ書くことになるので、すごく非効率と言うか……二度手間をしているように見えるんですよね。 // たぶんこんな感じ private void AddCoin(int addition) { coin += addition; foreach(Transform child in foodMachinesParentTransform) { if (child が装置設置ベースだったら) { ②のメソッドを呼んでタップ可能かチェックする; } else if (child が装置だったら) { ③のメソッドを呼んでタップ可能かチェックする; } else if (child がネコ購入ボタンだったら) { ④のメソッドを呼んでタップ可能かチェックする; } else { なんもしない; } // ↑めんどい なんかコード汚い } } なんとかして、コインの増減時に書く処理を、②・③・④の種類で書き分けずに、すべて同じ記述で済ますことはできないだろうか……。 そんなことを考えていた時、閃いたのです。 あれ?これインターフェースじゃね? ITappable というインターフェースを用意します。 /// <summary> /// タップ可能になるオブジェクトのインターフェース /// </summary> interface ITappable { // タップ可能をチェックする処理 void CheckTappable(); // タップ不可能をチェックする処理 void CheckUntappable(); } そしてこれを、②・③・④に実装します。 そうすると、②・③・④は共通で CheckTappable() と CheckUntappable() というメソッドを持つことになります。 そして、タップ可能になった際の処理を②・③・④それぞれ実装します。 このメソッドは名前は同一ですが、処理の内容は②・③・④それぞれで実装するので、異なる処理を記述することができます。 つまり、必要コイン量やタップ可能かどうかの判定基準、表示するアイコンのオブジェクトが違っていても問題ない、ということです。 その後、①が持つコイン増減のタイミングで、コインが増えた時に全てのITappableのCheckTappable()を片っ端から呼び出せば良いのです。 コインが減った場合は全てのITappableのCheckUntappable()を呼び出します。 この時、呼び出す対象のオブジェクトが②なのか③なのか④なのかは考えません。 CheckTappable()とCheckUntappable()は②・③・④に共通して実装されているメソッドでありながら、その内容は②・③・④それぞれで異なっているという特徴を持っているため、呼び出す側がオブジェクトの種類を判定する必要はないのです。 // こんな感じになります private void AddCoin(int addition) { coin += addition; foreach(Transform child in foodMachinesParentTransform) { ITappable tappable = child.GetComponent<ITappable>(); // Unityでコンポーネントを取り出す処理 tappable.CheckTappable(); // ↑オブジェクトの種類とか考えずとにかく CheckTappable() を呼んでしまえ } } とてもコードがスッキリしました! インターフェースを使うことによって起こったこと インターフェースを使ったことによって何が起こったかと言うと、 ②、③、④に、同じ名前で処理内容の違うメソッドを作った そのメソッドを、①から内容やコンポーネントの種類の違いを意識せずに呼び出せるようになった ということです。 これがインターフェースを使う利点、ということなんですよね?(>できるエンジニアのみなさん) 初めてインターフェースを使えた感 この手法を自力で思いついた時、なんか感動したんですよねー……。 今までオブジェクト指向なんかの本でインターフェースに関する記述を読んでも、書いてある文章の意味は分かるんですけど、どうしてもそれを自分で使える気がしないというか。 「ふーんなるほどねー」以上の感想を持てずにいたんですよね。 それがこの時、ようやくインターフェースというものが分かった感じがしました。 もちろんこんなのは初歩の初歩なんでしょうけど、とにかく自分にとっては「初めてのインターフェース」な経験で、ちょっとジーンとした感動があったのでどこかに書き記したい気分だったのです。 おわり
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RenderPassBlockの分類と、FowardRendererの各Passはどのタイミングで実行されるか

※本記事は Unity2021.1.16f1 を元に記載しています 一つ前の記事 で、 ScriptableRenderPass.Configure() は ScriptableRenderer.InternalStartRendering() と ScriptableRenderer.InternalFinishRendering() の間で、RenderPassBlock分連なっている と書いたのですが、では「RenderPassBlockとは何ぞや?」という事も書いておきます RenderPassBlockは4つ 連なると書きはしましたが、RenderPassBlockは実は4つしかなく static class RenderPassBlock { // Executes render passes that are inputs to the main rendering // but don't depend on camera state. They all render in monoscopic mode. f.ex, shadow maps. public static readonly int BeforeRendering = 0; // Main bulk of render pass execution. They required camera state to be properly set // and when enabled they will render in stereo. public static readonly int MainRenderingOpaque = 1; public static readonly int MainRenderingTransparent = 2; // Execute after Post-processing. public static readonly int AfterRendering = 3; } 描画前 不透明描画 半透明描画 描画後 の4つだけです。シンプル。 RenderPassをAddする際に指定したRenderPassEventを、この4つの大カテゴリに応じて振り分けて、ブロック毎にExecute()しているわけです。 RenderPassEventの大別 各RenderPassEventが何処に所属しているかはRenderPassBlockのコードを見ると確認出来ます。 RenderBlocks.RenderBlocks()の一部を抜粋 m_BlockEventLimits[RenderPassBlock.BeforeRendering] = RenderPassEvent.BeforeRenderingPrePasses; m_BlockEventLimits[RenderPassBlock.MainRenderingOpaque] = RenderPassEvent.AfterRenderingOpaques; m_BlockEventLimits[RenderPassBlock.MainRenderingTransparent] = RenderPassEvent.AfterRenderingPostProcessing; m_BlockEventLimits[RenderPassBlock.AfterRendering] = (RenderPassEvent)Int32.MaxValue; 振り分けの条件式を見るに RenderBlocks.FillBlockRanges()の一部 while (currRenderPass < activeRenderPassQueue.Count && activeRenderPassQueue[currRenderPass].renderPassEvent < m_BlockEventLimits[i]) currRenderPass++; 「 < m_BlockEventLimits[i]」含まずなので RenderPassBlock.BeforeRendering RenderPassEvent.BeforeRendering RenderPassEvent.BeforeRenderingShadows RenderPassEvent.AfterRenderingShadows RenderPassBlock.MainRenderingOpaque RenderPassEvent.BeforeRenderingPrePasses RenderPassEvent.AfterRenderingPrePasses RenderPassEvent.BeforeRenderingOpaques RenderPassBlock.MainRenderingTransparent RenderPassEvent.AfterRenderingOpaques RenderPassEvent.BeforeRenderingSkybox RenderPassEvent.AfterRenderingSkybox RenderPassEvent.BeforeRenderingTransparents RenderPassEvent.AfterRenderingTransparents RenderPassEvent.BeforeRenderingPostProcessing RenderPassBlock.AfterRendering RenderPassEvent.AfterRenderingPostProcessing RenderPassEvent.AfterRendering それ以降 となります。 ForwardRendererではどうなる? よって、普通にForwardRendererで描画した場合は、下記のような大別でPassが振り分けられています RenderPassBlock.BeforeRendering MainLightShadowCasterPass ← RenderPassEvent.BeforeRenderingShadows RenderPassBlock.MainRenderingOpaque ColorGradingLutPass ← RenderPassEvent.BeforeRenderingPrePasses DepthOnlyPass ← RenderPassEvent.BeforeRenderingPrePasses DrawObjectsPass ← m_RenderOpaqueForwardPassについてはRenderPassEvent.BeforeRenderingOpaques RenderPassBlock.MainRenderingTransparent CopyDepthPass ← RenderPassEvent.AfterRenderingSkybox CopyColorPass ← RenderPassEvent.AfterRenderingSkybox DrawObjectsPass ← m_RenderTransparentForwardPassについてはRenderPassEvent.BeforeRenderingTransparents InvokeOnRenderObjectCallbackPass ← RenderPassEvent.BeforeRenderingPostProcessing PostProcessPass ← RenderPassEvent.BeforeRenderingPostProcessing (FinalPostProcessPassはAfterRendering。詳しくはPostProcessingPassesを参照) RenderPassBlock.AfterRendering FinalBlitPass ← RenderPassEvent.AfterRendering + 1 SceneViewCopyDepthPass ← RenderPassEvent.AfterRendering + 9 FrameDebuggerで見た時のお馴染みの順番ですね。 注意点としては↑はあくまでRenderPassEventを元にリストアップしただけなので、 必ず描画の度に↑のPassが全て実行されるわけではありません。 PostProcessの有効無効やCameraStackの有無、そしてCameraStackのどの位置のカメラを描画しているか、Depthはクリアするかしないかなどで各Passの有無は変わります。 ※FinalBlitPassはCameraStackの最後のカメラのAfterRenderingでしか実行されない、など。 ご自身のカスタムPassを、どのタイミングで呼び出したいかの指標になれば幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity】MRTKって3Dモデルの動的ロード とか、XR以外にも使えるよねという話

はじめに MRTKとは、もともとMicrosoft社のMR(AR)ゴーグル、HoloLens用の開発キットです 現在はOculus等VRゴーグルやリープモーションなどにも対応し、 手でのモデル操作や、空間配置するボタン等のUXが充実しています。 XR関係の人しかさわったことがないと思うのですが、 中にはXRに関係なく使えそうな機能がいくつかありますので、 サンプルを見てみるところくらいまで紹介しようと思います。 目次 ・環境、導入方法 ・3Dモデルの動的(ランタイム)ロード ・全部入りの便利なシェーダー(ビルドイン、対処すればURPにも) ・音声入力コマンド ●環境、導入方法 環境、導入方法 現在のUnity2020+MRTKv2.7では、PackageManagerの機能を使いインポートすることが出来ます。 さらに、Mixed Reality Feature Toolという外部ツールが登録をアシストしてくれます。 こちらのツールを使い、「Mixed Reality Toolkit Foundation」「Mixed Reality Toolkit Examples」をインポートします。 https://docs.microsoft.com/ja-jp/windows/mixed-reality/develop/unity/welcome-to-mr-feature-tool 設定後プロジェクトを開くと、XRの設定を自動でしてくれる画面が出ますがスキップします。 すでに基本の機能はインポートされた状態で、PackageManagerにパッケージが登録されています。 「Mixed Reality Toolkit Examples」のSamplesから必要なサンプルをダウンロードできます。 ダウンロードしたサンプルは↓の場所に入ります ●3Dモデルの動的(ランタイム)ロード サンプル名:Demos - Gltf サンプルシーン:Demos - Gltf\Scenes\Glb-Loading-Demo この記事を書いた動機です。 ネット上で「Unity モデル ランタイムロード」などで検索しても有料アセットしか出てこず、買うしかないかなと思っている人多いのでは。 対応しているのはgltfという、主にWEB上でモデル表示をするのに使われている(?)形式。 自分は聞きなじみがなかったですが、世間的には一般的なフォーマットらしく、blender等でも書き出し可能です。 とりあえずの使い方 サンプルシーンを再生すると、インターネット上のラジカセのモデルが表示されます。 他のシーンで使うには、空のオブジェクトにTestGlbLoadingを追加します。 URLを指定して再生すると、インターネット上のgltfモデルを表示してくれます。 ローカルのモデルにも対応しているので、デスクトップなどのファイルを指定することもできます。 ↓はTestGlbLoadingの内容ですが、作成したオブジェクトは gltfObjectに格納されます。 gltfObject.GameObjectReferenceでGameObject型になります。 ●全部入りの便利なシェーダー サンプル名:Demos - StandardShader サンプルシーン:Demos - StandardShader\Scenes URP、shadergraphの普及で難易度が下がってきてはいますが、初心者には難しいシェーダー作成。 MRTKで使われているシェーダーは、書き込み深度の変更、ディソルブや断面表示、リムライトなど、少しニッチだけれども使いたい人は確実にいる機能が1シェーダーの機能切替で使えます。 URPで使用するには↓のコマンドを実行。 ●音声入力コマンド サンプル名:Demos - Input サンプルシーン:Demos - Input\Scenes\Speech あらかじめ登録したワードを使ってイベントを実行できます。 日本語入力も難なくやってくれます。 (日本語なら表音文字だから登録はひらがなで登録すればいいけど、英語はどういう理屈なのかわからん…自分の下手な英語では認識してくれなかった) とりあえずの使い方 MRTKは、どのインプットを受け付けるか、MRTKプロファイルというものを使って設定します。 ”Demos - Input\Scenes\Speech”を開き、独自のコマンドを追加してみます。 次に、音声入力で実行されるイベントを作成します。 サンプルではオブジェクトにアタッチされているので、編集します。 これで、「じっこう」と言うとオブジェクトの色が変わると思います。 ●終わり 各機能、Untiyで公式採用してほしいくらいです。無料とは有り難いですね。 以上紹介でした。参考になれば幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む