VisualStudioでaws開発しようとしたけど無理だった
lambdaのサンプルコードを実行するとaws-sdkパッケージが見つからないと表示される。
docs.aws.amazon.com このチュートリアルにしたがってaws-sdkパッケージをインストールする
https://www.nuget.org/profiles/awsdotnet
どれを入れればいいか分らんのでとりあえずAWSSDK.Coreというやつをインストールしてみる
dotnet add package AWSSDK.Core --version 3.7.300.25
やってみたら「プロジェクトが見つかりませんでした」とエラーが出る
nugetパッケージマネージャーをアンインストール->再インストールしてみる teratail.com
無理でした(4日くらい格闘した)
結論:aws開発にVisualStudioは使うな(環境構築が本当にだるい)
VisualStudioからAWS関連の開発をするための環境を整えるDay2,3
とりあえずLambda向けのスクリプトの作り方を勉強する必要がある。 公式チュートリアルを見つけたのでやってみる
cドライブ配下にMyLambdaAppディレクトリを作成 その配下にslotassets.zipを解凍する。slotassetsフォルダが作成され、その中にいろいろ入った状態になる。 C:\MyLambdaApp/slotassetsができる その中にAWSの認証情報を用いてjsonファイルを作成する必要がある
docs.aws.amazon.com このチュートリアルに従って認証情報を取得する
でもIAMロールってどこから見るんだっけ... docs.aws.amazon.com まずS3で作る必要があるっぽい
だめだやり方がわからん ちゃんと本とか買ってやるか...マジで環境構築とかの本筋じゃないところをやるのが一番だるい
aws向けの開発環境を整える方法を調べてみた。まずはこれに沿ってやってみよう aws.amazon.com
IAMで新しく開発用にユーザーを作成した。 たぶんここでCSVをダウンロードしておく方が後が楽
こんな感じで今作ったユーザー名、アクセスキー、シークレットアクセスキーを入力してToolKitにアクセスする権限、認証情報を追加する
とりあえずここまででいいのかな?引き続き頑張る所存
Visual StudioでのAWS開発環境構築(C#でやりたかったけどjs使うことにした)
あくまで備忘録
初めはC#で開発しようと思った。他に書ける言語ねえし。 とりあえず公式ドキュメントに書かれているままにdotnetのなんやかんやをインストール docs.aws.amazon.com
でも、Lambdaのテンプレ関数使った結果、ランタイムがnode.jsになってるし(不本意)、node.js向けにJavaScriptでいろいろ作る方がナレッジがいっぱいでてきそうだな... ということでnode.js触ってみることに方向転換。VisualStudioでの開発環境を整える
ちょっと調べたらVisualStudioでAWS向けの開発が快適になる拡張機能が出てきたからとりあえず入れておく。js扱う上では必須ではない。 「これインストールできひんで~」というエラーが出た。最近家で開発とか全くやってなかったからVSのバージョンが古くなってたみたい。更新したらすんなり入った。
役に立つのかはこの時点では知らない。インストールしたら思考停止再起動や
なんだこれは。軽く調べたらAWSのIAMでなんか認証情報を作る?見る?して入力せんといかんらしい。よくわからないからいつかやります
さて、jsの開発環境整えるで ぐぐったらこんなんでてきたので参考にする
とりあえずnode.jsをインストール。VS入れたときについでに入れたような気もするけどまあええやろ... こういうときハイスペ大容量PC買っておいてよかったなと思う。
再起動しろとは書かれていないようだが、して損はないのでまたまた再起動
そしたらvisual studio installerからnode.js開発を構成に追加して...
なんかこう、アフィリエイトかってくらいリンク貼ってるな。
プログラミング独学~とかってさ~~~コードの勉強始める前のこの手の環境設定が一番だるいよな~~~ インストールエラーとかが解決できなかったらその時点で勉強やめるよな~~~めんどくせ~~~~
気を取り直してvisual studio起動。[新しいプロジェクトの作成]からテンプレート選んで...あっ おまえだろ!!!
よし!今日はここまで!
ゲーム制作会社に入ったことだし、VTuberでもみるか
久々すぎる。
過去に作ったしょーもないゲームのおかげもあって(あったか?)無事ゲーム制作会社に入社した。もうすぐ半年が経つ。
新卒で入社した会社の副社長が言っていた通り、「人間が変わるには環境を変えるしかない」という言葉の通り、環境を変えることで否応なしに毎日UnityとC#を使ってコードを書きまくっている。ありがてぇありがてぇ…
さて、最近は通勤時間にVtuberの動画を見るのが日課になっている。あなたの推しは誰ですか?僕は兎田ぺこらと猫又おかゆを推しています。
さて、VTuberを支えているのはUnityらしいということを風のうわさで聞いた。
Live2Dという入力された音声によって自動で2Dのキャラクターが動くやつを使っているらしく、しかもこれはUnityをPCに入れてさえいれば素人でも触ることができるらしい。ちょうどいいのでこれをぽちりながらいろいろやってみようと思い立った。
すでに1週間かかった
と軽い気持ちで手を出してみることにしたが、初期設定?の時点でめちゃくちゃ苦労した。同じ轍を踏む人が減ればいいなというのと、備忘録としてやったことの記録をつけておく。
今は「設定された音声ファイルに合わせてキャラが口パクする」というところまでいった。
ここまで一行もコードを書いていないので、私と同レベルの方も安心してほしい。
ただし、なんか知らんが全然動かんくて一度は匙を投げようとしたので、粘り強さだけは持っておいてほしい。
1. まず、Unityの推奨バージョンをインストールします
いろいろ振り返ると、ここが最重要だった。僕は自分での学習のためにUnity2020.~~とかのバージョンを使っていたが、どうも配布されているSDK(Live2Dを動かすための魔法のプログラム群。無料。なんで???)をインポートするときはUnityの推奨バージョンである2019.4~~くらいのを使ったほうがいいみたい。この辺は多分に憶測を含むが、いいからこれ使っといて。
2.こちらの記事を参考に、モデルデータのインポートまでやる
qiita.com多分なんだけど、この記事が少し前に書かれたこともあっていろいろ現在の仕様ではすんなり模倣できないんじゃないか。
この記事通りに貫いてやってみてもいいんですけど、僕は「プレゼンスを上げる」の「口パクの実装」のところでつまづいた。
具体的に言うと、入力された音声に合わせて口が動かなかった。
パラメータを見ると音声に応じて値を書き換えてはいるのだが、Gameビューでは口がほとんど動かなかった。
どのくらい動いていなかったかというと、カメラで5倍くらいに拡大してようやく「動いてる気がする」というレベルで動いていなかった。
途中からはこちらの公式リファレンスを参考に
docs.live2d.comというわけで、一度Unityをアンインストールして、使用するSDKやモデルデータをすべて再インストールしてゼロからプロジェクトを作り直した。そしてモデルの配置の後はこのページを参考にしていろいろと設定をした。
クッソ雑だがこれでとりあえず音声に応じて口がパクパクするようになった。
Live2Dのいいところは、「公式が日本」というところだと思う。
僕程度の英語力では海外の記事がヒットされても一ミリも理解できねえ。
僕のような無課金勢でも手厚く対応してくれるので積極的に公式を見ていこう。
ということで、もし困っている人がいたら
・とりあえずUnity再インストールして推奨バージョンにしよう
・なんかおかしいと思ったら大人しく使用するいろいろなファイルを再インストールしよう
・無理だったら公式を頼ろう。多分この分野、作る人より使う人の方が多いからネットで見つかる情報は玉石混合だ
以上。
UniRxを勉強しよう8(完結)
めっちゃくちゃ間が空いたが、ようやく電卓アプリがひと段落したのでコードを公開してみる。
Githubにも上げているが、もしGithubからいろんな情報が流出したら怖いのでいったんここで公開する。
こんな感じになりました
入力検知クラス
using System.Collections; using System.Collections.Generic; using UnityEngine; using UniRx; using System; using UnityEngine.UI; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Diagnostics; public class PassPushedButton : MonoBehaviour { [SerializeField] List<Button> NumberKeys; [SerializeField] List<Button> operaterKeys; [SerializeField] List<Text> texts; //このクラスからOnNextで別クラスに処理を渡せるようSubjectを用意 private Subject<string> sendCalcSubject = new Subject<string>(); private Subject<int> sendOperaterSubject = new Subject<int>(); //なんだっけこれ…プロパティ?外部クラスからアクセス(getのみ)できるようにしておく public IObservable<string> NumberKeyClicked { get { return sendCalcSubject; } } public IObservable<int> OperaterKeyClicked { get { return sendOperaterSubject; } } void Awake() { for (int i = 0; i < NumberKeys.Count; i++) { SetMonitoringNumberKeyClicked(i); } for(int i =0; i < operaterKeys.Count; i++) { SetMonitoringOperatorKeyClicked(i); } } void SetMonitoringNumberKeyClicked(int i) { NumberKeys[i].onClick.AsObservable() .Subscribe(count => sendCalcSubject.OnNext(texts[i].text)) .AddTo(gameObject); } void SetMonitoringOperatorKeyClicked(int i) { operaterKeys[i].onClick.AsObservable() .Subscribe(count => sendOperaterSubject.OnNext(i)) .AddTo(gameObject); } }
ディスプレイへの表示クラス
using System.Collections; using System.Collections.Generic; using UnityEngine; using UniRx; using UnityEngine.UI; using System.Diagnostics; public class ShowDisplay : MonoBehaviour { //メッセージのやりとり対象はInspector画面から設定する。 public Text displayPanelText; private int operatorFlg = 0; [SerializeField] private PassPushedButton passPushedButton; [SerializeField] private Caculater calculater; void Awake() { //監視対象スクリプトからOnNextが飛んで来たら下記Subscribe処理を実行 passPushedButton.NumberKeyClicked .Subscribe(KeyCode => ShowToDisPlay(KeyCode)) .AddTo(gameObject); calculater.CalculateResult .Subscribe(result => { displayPanelText.text = result; operatorFlg = 1; }) .AddTo(gameObject); } private void ShowToDisPlay(string value) { //イコールの後に数値が入力されたとき if (operatorFlg == 1) { //小数点が入力されたら if (value == ".") { //小数点が既に存在していたら何もせずに終了 if (displayPanelText.text.Contains(".") && value == ".") return; //表示中の数字に小数点をつける displayPanelText.text += value; } //整数が入力されたら else { //ディスプレイを一度クリアする displayPanelText.text = ""; } operatorFlg = 0; } //小数点が二つ以上なら入力を無視する if (displayPanelText.text.Contains(".") && value == ".") return; //入力値が小数点でなければ先頭の0は消す else if (displayPanelText.text == "0" && value != ".") { displayPanelText.text = value; } else { displayPanelText.text += value; } } }
計算クラス
using System.Collections; using System.Collections.Generic; using UnityEngine; using UniRx; using System; using UnityEngine.UI; public class Caculater : MonoBehaviour { //メッセージのやりとり対象はInspector画面から設定する。 public Text displayPanelText; [SerializeField] private PassPushedButton passPushedButton; private Nullable<double> calculatedValue; private Nullable<int> operationSymbol; private string displayText; private Subject<string> sendCalculateSubject = new Subject<string>(); public IObservable<string> CalculateResult { get { return sendCalculateSubject; } } void Awake() { //演算記号の入力を検知 passPushedButton.OperaterKeyClicked .Subscribe(operateKeyNum => Calculate(operateKeyNum)) .AddTo(gameObject); } private void Calculate(int newOperationSymbol) { displayText = displayPanelText.text; //正負の入れ替えが選択されたとき if (newOperationSymbol == 7) { displayText = (double.Parse(displayText) * -1).ToString(); sendCalculateSubject.OnNext(displayText); } //Clearが入力された場合 else if (newOperationSymbol != 5) { //数値・演算記号が共に入力済みだったとき if (calculatedValue.HasValue && operationSymbol.HasValue) { //+ if (operationSymbol == 0) calculatedValue += double.Parse(displayText); //- if (operationSymbol == 1) calculatedValue -= double.Parse(displayText); //× if (operationSymbol == 2) calculatedValue *= double.Parse(displayText); //÷ if (operationSymbol == 3) if(double.Parse(displayText) == 0 )calculatedValue = 0; else calculatedValue /= double.Parse(displayText); //= if (operationSymbol == 4) calculatedValue = double.Parse(displayText); //今回入力された演算記号を格納 operationSymbol = newOperationSymbol; //AC(演算記号リセットのため、これだけ判定タイミングをずらす) if (operationSymbol == 6) { calculatedValue = 0; operationSymbol = null; } //showdisplayに計算結果を送信する sendCalculateSubject.OnNext(calculatedValue.ToString()); } else { calculatedValue = double.Parse(displayText); operationSymbol = newOperationSymbol; sendCalculateSubject.OnNext(calculatedValue.ToString()); } } //Cが入力されたとき、変数の値は書き換えずにディスプレイのみクリアする else sendCalculateSubject.OnNext("0"); } }
以上!
修正点はいくつかあるが、大きなところとしては
- 「イコール」で結果表示後に小数点を入力するとディスプレイ上の数値がクリアされる点を改善
- 0で除算を行った場合に「Err」と表示される点を改善
という修正を実施した。
自分で動かした範囲ではうまいこと動いている。
さて、今回電卓を作るなかでUniRxで四苦八苦したわけだが、次第に慣れてくるとInspectorをポチポチしなくてもイベント関連の処理を定義していけるのは結構便利だった。
使いこなせているかというとまだ微妙だが、いろいろなサイトを参考にしたおかげで何とか形になった。
今からUniRxを勉強する人はここまでで紹介した記事を参照してみたらやりやすいと思います。
とりあえず、簡単だが今日はここまで!
UniRxを勉強しよう7
は~~~~~~い
今日もやっていくぞ!
完成までの流れ
1. まずは簡単に見た目だけ作る
2. ボタンを押下した際にこれを検知する
3. 押下されたボタンから数値や記号を取得する
4. 引数に渡された数値がディスプレイに表示されるようにする
5. 検知した数値や記号から四則演算を実施できるようにする
6. 見てくれを整える
7. 書き出す
昨日は5を実現するためのフローチャートを作り、機能を考えるところで終わっていた。今日はその実装と微調整だ。
完成したものがこちらになります
まず概要だが、今回作成した電卓は大きく3つのスクリプト(クラス)で動作が決まっている。
1. PassPushedButton
電卓のボタンが押下されたことを検知する
2. ShowDisplayButton
電卓のディスプレイに値を表示する
3. Calcurater
計算の実処理を行う
まず一つ目!PassPushedButtonから
using System.Collections; using System.Collections.Generic; using UnityEngine; using UniRx; using System; using UnityEngine.UI; using System.Security.Cryptography.X509Certificates; using System.Threading; public class PassPushedButton : MonoBehaviour { [SerializeField] List<Button> buttons; [SerializeField] List<Button> operaterKeys; [SerializeField] List<Text> texts; //このクラスからOnNextで別クラスに処理を渡せるようSubjectを用意 private Subject<string> sendCalcSubject = new Subject<string>(); private Subject<int> sendOperaterSubject = new Subject<int>(); //なんだっけこれ…プロパティ?外部クラスからアクセス(getのみ)できるようにしておく public IObservable<string> KeyClicked { get { return sendCalcSubject; } } public IObservable<int> OperaterKeyClicked { get { return sendOperaterSubject; } } // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } void Awake() { for (int i = 0; i < buttons.Count; i++) { ButtonCheck(i); } for(int i =0; i < operaterKeys.Count; i++) { OperatorKeyChecked(i); } } void ButtonCheck(int i) { buttons[i].onClick.AsObservable() .Subscribe(count => { //定義したSubjectからOnNextでメッセージを出す sendCalcSubject.OnNext(texts[i].text); }) .AddTo(gameObject); } void OperatorKeyChecked(int i) { operaterKeys[i].onClick.AsObservable() .Subscribe(count => { sendOperaterSubject.OnNext(i); }) .AddTo(gameObject); } }
次にShowDisplay。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UniRx; using UnityEngine.UI; public class ShowDisplay : MonoBehaviour { //メッセージのやりとり対象はInspector画面から設定する。 public Text displayPanelText; private int operatorFlg = 0; [SerializeField] private PassPushedButton passPushedButton; [SerializeField] private Caculater calculater; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } void Awake() { //監視対象スクリプトからOnNextが飛んで来たら下記Subscribe処理を実行 passPushedButton.KeyClicked .Subscribe(KeyCode => ShowToDisPlay(KeyCode)) .AddTo(gameObject); calculater.CalculateResult .Subscribe(result => { displayPanelText.text = result; operatorFlg = 1; }) .AddTo(gameObject); } private void ShowToDisPlay(string value) { //演算記号が入力されたら一度ディスプレイをクリアする if (operatorFlg == 1) { displayPanelText.text = ""; operatorFlg = 0; } //入力値が少数点でなければ先頭の0は消す //else if (displayPanelText.text=="0" && value !=".") { displayPanelText.text = value; } else { displayPanelText.text += value; } } }
最後にCalcurater
using System.Collections; using System.Collections.Generic; using UnityEngine; using UniRx; using System; using UnityEngine.UI; public class Caculater : MonoBehaviour { //メッセージのやりとり対象はInspector画面から設定する。 public Text displayPanelText; [SerializeField] private PassPushedButton passPushedButton; private Nullable<double> calculatedValue; private Nullable<int> operationSymbol; private string displayText; private Subject<string> sendCalculateSubject = new Subject<string>(); public IObservable<string> CalculateResult { get { return sendCalculateSubject; } } // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } void Awake() { //演算記号の入力を検知 passPushedButton.OperaterKeyClicked .Subscribe(operateKeyNum => Calculate(operateKeyNum)) .AddTo(gameObject); } private void Calculate(int newOperationSymbol) { displayText = displayPanelText.text; if (newOperationSymbol != 5) { //数値・演算記号が共に入力済みだったとき if (calculatedValue.HasValue && operationSymbol.HasValue) { //+ if (operationSymbol == 0) calculatedValue += double.Parse(displayText); //- if (operationSymbol == 1) calculatedValue -= double.Parse(displayText); //× if (operationSymbol == 2) calculatedValue *= double.Parse(displayText); //÷ if (operationSymbol == 3) calculatedValue /= double.Parse(displayText); //= if (operationSymbol == 4) calculatedValue = double.Parse(displayText); //今回入力された演算記号を格納 operationSymbol = newOperationSymbol; //AC(演算記号リセットのため、これだけ判定タイミングをずらす) if (operationSymbol == 6) { calculatedValue = 0; operationSymbol = null; } //showdisplayに計算結果を送信する sendCalculateSubject.OnNext(calculatedValue.ToString()); } else { calculatedValue = double.Parse(displayText); operationSymbol = newOperationSymbol; sendCalculateSubject.OnNext(calculatedValue.ToString()); } } //Cが入力されたとき、変数の値は書き換えずにディスプレイのみクリアする else sendCalculateSubject.OnNext("0"); } }
各コードについての解説をコメントで書いた。
今回はフローチャートを作成してからスクリプトを作成したのだが、これがとても楽しい…
先に色々考えておいて、コードを書いてみてカチッと動きがはまるとたまらん!(まあ適宜ロジック修正したけど)
期限は明日となっているのでコードをきれいに書きなおし、また見た目も整えていきたいと思う。
UniRxを勉強しよう6
はい!前回からコードに手を入れて、以下のようにディスプレイコードを書き換えた。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UniRx; using UnityEngine.UI; public class ShowDisplay : MonoBehaviour { //メッセージのやりとり対象はInspector画面から設定する。 public Text displayPanelText; [SerializeField] private PassPushedButton passPushedButton; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } void Awake() { //監視対象スクリプトからOnNextが飛んで来たら下記Subscribe処理を実行 passPushedButton.KeyClicked //.Scan((pre, current) => pre + current) .Subscribe(KeyCode => ShowToDisPlay(KeyCode)) .AddTo(gameObject); passPushedButton.OperaterKeyClicked .Subscribe(a => { ShowToDisPlay(""); }) .AddTo(gameObject); } private void ShowToDisPlay(string value) { //演算記号が入力されたら一度ディスプレイをクリアする if(value == "") { displayPanelText.text = ""; } //入力値が少数点でなければ先頭の0は消す else if(displayPanelText.text=="0" && value !=".") { displayPanelText.text = value; } else { displayPanelText.text += value; } } }
これ期日が明後日(24日)なので巻いていかないといけないぞ!
今日は四則演算の処理を作っていく。演算はそれ用にクラスを設けたいと思っている。あとからクラスを見たときに「入力検知」「ディスプレイ表示」「演算処理」とはっきり役目を分けておきたいからだ。
電卓は以前作ったことがあるので、あれを思い出しながら作ってみたい。
完成までの流れ
1. まずは簡単に見た目だけ作る
2. ボタンを押下した際にこれを検知する
3. 押下されたボタンから数値や記号を取得する
4. 引数に渡された数値がディスプレイに表示されるようにする
5. 検知した数値や記号から四則演算を実施できるようにする
6. 見てくれを整える
7. 書き出す
演算処理のクラスについて少し考えてみる
演算処理について基本的な作りを考えてみる。…と、これまでフィーリングで作ってきたツケが回ってきたのでディスプレイ表示クラスについても再考してみた
ら、30分かかってもまとまらなかったのでフローチャートで考えてみることにした。
www.lucidchart.com
こちらのツールを使った。
*** 演算処理クラス
基本方針として、計算はすべてこいつの中で完結させたい。
ディスプレイから数値を取る必要はあるが、それ以外は独自にイベントを取得して独立して動けるようにしようと思う。
上記のために必要なものとしては
- 演算記号入力前にディスプレイ表示されていた値を格納する「変数1」
- 演算記号を格納する「変数2」
- ディスプレイから数値を取得する機能
- ディスプレイの数値を書き換える(ためのイベントを発生させる)機能
あれ?意外と少ない?
*** ディスプレイ表示クラス
こいつの仕事はあくまで「表示」なので、ここからメッセージを送ったりはしない。
基本的には受け取ったものを表示するだけ。なのでイベントの受け口だけしっかり用意しておき、自分から外部の情報を参照したりはしないように作る。
とすると結構やることはシンプル。
- ディスプレイ数値書き換えイベントを検知して、ディスプレイの値を変更する
これだけだ。
さて、文章量は少ないが結構時間がかかったので今日はここまで。明日は爆裂に進めるぞ!!