- 投稿日:2020-09-24T22:09:09+09:00
(C#)次の平日を取得するLINQ
はじめに
C#で、次の平日を取得するコードをきれいに書けないかなと思ってLINQで試してみました。
もっといいコードがあればコメントいただけると嬉しいです。環境
Windows 10
Visual Studio 2019参考
こちらの記載にアイデアをもらいました。
https://tercel-tech.hatenablog.com/entry/2014/02/08/183432コード
DateTimeの拡張メソッドとしています。
NextWeekday.cspublic static DateTime NextWeekday(this DateTime date,List<DateTime> holidayList = null) { // 100日後までの間で最も近い営業日を取得 // 100は適当な大きな数値でOK DateTime next = Enumerable.Range(1, 100).Select(x => date.AddDays(x)).First( x => x.DayOfWeek != DayOfWeek.Saturday && x.DayOfWeek != DayOfWeek.Sunday && !(holidayList?.Contains(x) ?? false) ); return next; }注意点
祝日リストはどこかから持ってくる AND DateTime.Todayなどで時刻部分は0の前提です。
単純に、「土曜日でない & 日曜日でない & 祝日リストに入ってない」日付を順に判定しています。おわりに (今後の展開)
次は祝日リストですが、Google Calendar APIを調べてみたいと思います。
ここを参考にして試してみようと思っています。
https://blog.divakk.co.jp/entry/holidays
- 投稿日:2020-09-24T20:05:04+09:00
【C#】【DxLib】FPSが全然出ない!? そんな時はたった一行のコードを追加するだけで、一気に爆上がりするかも?
概要
今回はたった一行追加することで、FPSが上がる
かも?
というやり方を紹介します。
この記事は、DXライブラリの関数を用いて上の課題を解決していきます。
サンプルコードをコピペしたり、可能ならば必要な関数を覚えながら書き写しましょう。やりたいこと
DxLib既存の関数を利用し、FPSをある程度上昇させたい。
例
whileより前部にある、
DX.SetDrawScreen(DX.DX_SCREEN_BACK);
は削除してしまって構わないです。// メインループ while (DX.ProcessMessage() != -1) { // 描画先を裏画面に設定 SetDrawScreen(DX.DX_SCREEN_BACK); // 画面をクリア DX.ClearDrawScreen(); // //処理(); // // 裏画面の内容を表画面に反映する DX.ScreenFlip(); }説明
while処理内の先頭に
SetDrawScreen(DX.DX_SCREEN_BACK);
こちらの関数を呼び出しました。
ループするところにこんな関数を置いてしまって大丈夫なのか?と心配な方もいらっしゃるとは思いますが、画面・処理には何の支障をきたさないので安心してください。
- 投稿日:2020-09-24T17:55:44+09:00
MVVM Show View パターン2 Commandパラメータ
参考コード
ICommandインターフェイスを実装したコマンドを利用して、表示します。
MVVM_WindowCommands
https://github.com/mike-eason/MVVM_WindowCommands
のコードを見てみましょう。View
コマンドを指定して、そのパラメータにウインドウ名を指定しています。
<Button Content="Open Window" Command="{Binding OpenWindowCommand}" CommandParameter="{x:Type local:TestWindow}"/>ViewModel
OpenWindowCommand
public class MainWindowViewModel { public OpenWindowCommand OpenWindowCommand { get; private set; } public ShowDialogCommand ShowDialogCommand { get; private set; } public MainWindowViewModel() { OpenWindowCommand = new OpenWindowCommand(); ShowDialogCommand = new ShowDialogCommand(PostOpenDialog, PreOpenDialog); }Commandクラス(Modelに該当する部分?)
ここで、Showしています。
ViewとViewModel以外は、すべてModelと考えますから、この部分もModelという認識で良いと思いますが、どうでしょうか。public class OpenWindowCommand : ICommand { protected virtual void OpenWindow(Window wnd) { wnd.Show(); }分からない点
この処理の流れで、TestWindowを確定して表示を行っているのはどこでしょうか?
Viewでしょうか、ViewModelでしょうか、OpenWindowCommandでしょうか?
これは、x:Type local:TestWindow とTestWindowと名前を指定しているViewだと私は考えるのですが、違うのでしょうか?
ViewModelも、OpenWindowCommandも、引数を与えられて処理を行う部分ですから、TestWindowと確定しているわけではありません。
従って、TestWindowというViewを知っているのは、ViewのMainWindowだと私には思えます。そうすると、基本パターン1と、同じですね。基本パターン1はコードビハインドで、Viewから指定したViewを表示していますが、このパターンは、XAMLでコマンドを利用して、Viewから指定したViewを表示します。TestWindowを指定するところを変更する場合
けれども、XAMLで
CommandParameter="{x:Type local:TestWindow}"を指定せず、
- MainWindowViewModelでTestWindowを指定する → VMが他のViewを知っている
- OpenWindowCommandでTestWindowを指定する → Mが他のViewを知っている
ことになると考えますが、この考え方で合っているでしょうか。
記事予定
- パターン1 Viewのコードビハインド
- パターン2 Commandパラメータ(この記事)
- パターン3 Prism の Dialog Service
- パターン4 引数を渡す
- 投稿日:2020-09-24T17:55:44+09:00
MVVM Show View パターン2 Commandパラメータ
参考コード
ICommandインターフェイスを実装したコマンドを利用して、表示します。
MVVM_WindowCommands
https://github.com/mike-eason/MVVM_WindowCommands
のコードを見てみましょう。View
コマンドを指定して、そのパラメータにウインドウ名を指定しています。
<Button Content="Open Window" Command="{Binding OpenWindowCommand}" CommandParameter="{x:Type local:TestWindow}"/>ViewModel
OpenWindowCommand
public class MainWindowViewModel { public OpenWindowCommand OpenWindowCommand { get; private set; } public ShowDialogCommand ShowDialogCommand { get; private set; } public MainWindowViewModel() { OpenWindowCommand = new OpenWindowCommand(); ShowDialogCommand = new ShowDialogCommand(PostOpenDialog, PreOpenDialog); }Commandクラス(Modelに該当する部分?)
ここで、Showしています。
ViewとViewModel以外は、すべてModelと考えますから、この部分もModelという認識で良いと思いますが、どうでしょうか。(VMのコードで、modelに相当するものではなく、単にView・ViewModelではないという意味で)public class OpenWindowCommand : ICommand { protected virtual void OpenWindow(Window wnd) { wnd.Show(); }分からない点
この処理の流れで、TestWindowを確定して表示を行っているのはどこでしょうか?
Viewでしょうか、ViewModelでしょうか、OpenWindowCommandでしょうか?
これは、x:Type local:TestWindow とTestWindowと名前を指定しているViewだと私は考えるのですが、違うのでしょうか?
ViewModelも、OpenWindowCommandも、引数を与えられて処理を行う部分ですから、TestWindowと確定しているわけではありません。
従って、TestWindowというViewを知っているのは、ViewのMainWindowだと私には思えます。そうすると、基本パターン1と、同じですね。基本パターン1はコードビハインドで、Viewから指定したViewを表示していますが、このパターンは、XAMLでコマンドを利用して、Viewから指定したViewを表示します。TestWindowを指定するところを変更する場合
けれども、XAMLで
CommandParameter="{x:Type local:TestWindow}"を指定せず、
- MainWindowViewModelでTestWindowを指定する → VMが他のViewを知っている
- OpenWindowCommandでTestWindowを指定する → Mが他のViewを知っている
ことになると考えますが、この考え方で合っているでしょうか。
記事予定
- パターン1 Viewのコードビハインド
- パターン2 Commandパラメータ(この記事)
- パターン3 Prism の Dialog Service
- パターン4 引数を渡す(予定)
- 投稿日:2020-09-24T17:55:22+09:00
MVVM Show View パターン 1 Viewのコードビハインド
Viewを表示するパターンを考える
MVVMを勉強しはじめた時に、いったいコードをどうかけばいいのかさっぱり分からなかったのことは、Viewを表示するコードをどこに書くのか?
今でもそれらが曖昧なので、明確にしておくためにこの記事を書きます。
ただし、調べると、より分からない点がさらに増えました。
フィードバックを頂けるとありがたいです。Newする順序
V・VM・MをNewする順序も、パターンによって異なります。それにも留意します。
結合・参照?
MVVMでは、ModelはViewModelを知らないし、ViewModelはViewを知らない、ことが前提です。
この知らない、というのは、名前を知っているだけなのは知るうちに入るのか入らないのか。この点がよくわかりません。
例えば、SubView.xamlを新しく表示する場合、SubViewという確定している名前がコードに書かれているだけなら、それで知っていることになるのか?ということです。
これについては、パターン2の、Commandパラメータで考えます。コード
https://github.com/mikihiro-t/MVVMPattern
開発環境
.NET Core 3.1 + ReactiveProperty で構築します。
パターン 1 Viewのコードビハインド
アプリを起動した時の最初のViewは、App.xamlのStartupUriで指定します。
それ以降のViewを、Viewのコードビハインドから表示します。ファイルの構成
Class Model MainManager ViewModel MainViewModel View MainView Newする順序は、
- ViewからViewModelをNew
- NewされたViewModelから、ModelをNewします。
V → VM → M の順序です。
プロジェクトの構成
スタート時のウインドウ
App.xamlの、StartupUriに、MainView.xamlを指定しました。
<Application x:Class="ShowView1.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:ShowView1" StartupUri="View/MainView.xaml">MainViewのコードビハインド
MainViewModelをNewしています。
DataContextに、vmをセットします。ここではなく、XAMLでVMを指定もできます。
ただし、ViewのコードビハインドでVMのメソッドを呼び出すことがあるなら、ここで指定しておくと便利だと思います。public partial class MainView : Window { MainViewModel vm = new MainViewModel(); public MainView() { InitializeComponent(); this.DataContext = vm; }ViewModel
ModelをNewして保持します
class MainViewModel : INotifyPropertyChanged, IDisposable { public MainManager Model { get; } public MainViewModel() { Model = new MainManager();ボタンクリックで新しいViewを表示
ボタンをクリックして、別のViewを表示するには、
private void Button_Click(object sender, RoutedEventArgs e) { var cls = new MainView(); cls.Show(); }Viewのコードビハインドで良いはずです。
ここでは、2つめのMainViewを表示しています。Viewと他のViewとの関係
ここでは、ボタンクリックで、MainViewをさらに表示していますが、他のViewを表示するのも同じです。
SubViewがあるとすれば、
- MainViewのボタンクリック
- SubViewを表示
になります。
これだと、MainViewは、SubViewを知っていることになります。SubViewという名前を知っているし、参照もしています。MVVMとして、それで良いのかどうかが分かりません。View1が、View2を、表示する処理(閉じる処理も?)を、View1で行って良いとすると、また、例えば、View2のDialogResultを、View1で受け取り、ViewModel, ViewModel経由でModelで処理をする程度のこともOKかもしれません。
Viewのコードビハインドの是非
Viewには、できるだけコードを書かないでおこうという考え方もあるのですが、私は次の条件の時は、Viewにコードを書くと良いと考えます。
- Viewに関わる事
- Viewのコードで処理した方が、ViewModelやModelで処理するより容易
XAMLに書くのも、Viewにコードビハインドで書くのも同じViewでの処理です。単に、言語がXAMLなのかC#なのか程度の違いです。
https://stackoverflow.com/a/37294259/9924249XAMLだけで処理をしようとして、複雑なコードになるのは本末転倒な気がします。また、UIのテストが行いやすくなるからXAMLだけで処理をしようとするのも、同様に本末転倒に思います。
同様の例
Handle it in the view
https://stackoverflow.com/a/5829704/9924249private void AddCustomerView_Click(object sender, RoutedEventArgs e) { AddCustomerView view = new AddCustomerView(data); view.Show(); }となっています。ここでは、ViewをNewする時に、引数としてdataを渡していますが、このdataはモデルのデータであるはずです。それを、Viewから渡すことは、MVVMらしいでしょうか? これも分からない点です。
疑問点まとめ
- Viewが他のViewを知っているのはMVVMとしてそれでよいのか?
- ViewからViewを表示する場合、引数(Modelのデータ)をどうやって渡すのか?
単純な処理なようで、疑問も増えました。このパターンを基本として、他のパターンと比べていきましょう。
記事予定
- パターン1 Viewのコードビハインド(この記事)
- パターン2 Commandパラメータ
- パターン3 Prism の Dialog Service(予定)
- パターン4 引数を渡す(予定)
- 投稿日:2020-09-24T17:55:22+09:00
MVVM Show View パターン1 Viewのコードビハインド
Viewを表示するパターンを考える
MVVMを勉強しはじめた時に、いったいコードをどうかけばいいのかさっぱり分からなかったのことは、Viewを表示するコードをどこに書くのか?
今でもそれらが曖昧なので、明確にしておくためにこの記事を書きます。
ただし、調べると、より分からない点がさらに増えました。
フィードバックを頂けるとありがたいです。Newする順序
V・VM・MをNewする順序も、パターンによって異なります。それにも留意します。
結合・参照?
MVVMでは、ModelはViewModelを知らないし、ViewModelはViewを知らない、ことが前提です。
この知らない、というのは、名前を知っているだけなのは知るうちに入るのか入らないのか。この点がよくわかりません。
例えば、SubView.xamlを新しく表示する場合、SubViewという確定している名前がコードに書かれているだけなら、それで知っていることになるのか?ということです。
これについては、パターン2の、Commandパラメータで考えます。コード
https://github.com/mikihiro-t/MVVMPattern
開発環境
.NET Core 3.1 + ReactiveProperty で構築します。
パターン 1 Viewのコードビハインド
アプリを起動した時の最初のViewは、App.xamlのStartupUriで指定します。
それ以降のViewを、Viewのコードビハインドから表示します。ファイルの構成
Class Model MainManager ViewModel MainViewModel View MainView Newする順序は、
- ViewからViewModelをNew
- NewされたViewModelから、ModelをNewします。
V → VM → M の順序です。
プロジェクトの構成
スタート時のウインドウ
App.xamlの、StartupUriに、MainView.xamlを指定しました。
<Application x:Class="ShowView1.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:ShowView1" StartupUri="View/MainView.xaml">MainViewのコードビハインド
MainViewModelをNewしています。
DataContextに、vmをセットします。ここではなく、XAMLでVMを指定もできます。
ただし、ViewのコードビハインドでVMのメソッドを呼び出すことがあるなら、ここで指定しておくと便利だと思います。public partial class MainView : Window { MainViewModel vm = new MainViewModel(); public MainView() { InitializeComponent(); this.DataContext = vm; }ViewModel
ModelをNewして保持します
class MainViewModel : INotifyPropertyChanged, IDisposable { public MainManager Model { get; } public MainViewModel() { Model = new MainManager();ボタンクリックで新しいViewを表示
ボタンをクリックして、別のViewを表示するには、
private void Button_Click(object sender, RoutedEventArgs e) { var cls = new MainView(); cls.Show(); }Viewのコードビハインドで良いはずです。
ここでは、2つめのMainViewを表示しています。Viewと他のViewとの関係
ここでは、ボタンクリックで、MainViewをさらに表示していますが、他のViewを表示するのも同じです。
SubViewがあるとすれば、
- MainViewのボタンクリック
- SubViewを表示
になります。
これだと、MainViewは、SubViewを知っていることになります。SubViewという名前を知っているし、参照もしています。MVVMとして、それで良いのかどうかが分かりません。View1が、View2を、表示する処理(閉じる処理も?)を、View1で行って良いとすると、また、例えば、View2のDialogResultを、View1で受け取り、ViewModel, ViewModel経由でModelで処理をする程度のこともOKかもしれません。
Viewのコードビハインドの是非
Viewには、できるだけコードを書かないでおこうという考え方もあるのですが、私は次の条件の時は、Viewにコードを書くと良いと考えます。
- Viewに関わる事
- Viewのコードで処理した方が、ViewModelやModelで処理するより容易
XAMLに書くのも、Viewにコードビハインドで書くのも同じViewでの処理です。単に、言語がXAMLなのかC#なのか程度の違いです。
https://stackoverflow.com/a/37294259/9924249XAMLだけで処理をしようとして、複雑なコードになるのは本末転倒な気がします。また、UIのテストが行いやすくなるからXAMLだけで処理をしようとするのも、同様に本末転倒に思います。
同様の例
Handle it in the view
https://stackoverflow.com/a/5829704/9924249private void AddCustomerView_Click(object sender, RoutedEventArgs e) { AddCustomerView view = new AddCustomerView(data); view.Show(); }となっています。ここでは、ViewをNewする時に、引数としてdataを渡していますが、このdataはモデルのデータであるはずです。それを、Viewから渡すことは、MVVMらしいでしょうか? これも分からない点です。
疑問点まとめ
- Viewが他のViewを知っているのはMVVMとしてそれでよいのか?
- ViewからViewを表示する場合、引数(Modelのデータ)をどうやって渡すのか?
単純な処理なようで、疑問も増えました。このパターンを基本として、他のパターンと比べていきましょう。
記事予定
- パターン1 Viewのコードビハインド(この記事)
- パターン2 Commandパラメータ
- パターン3 Prism の Dialog Service
- パターン4 引数を渡す(予定)
- 投稿日:2020-09-24T12:54:46+09:00
C# Conditional属性の罠
問題の概要
defineを定義し、Conditionalを使用したのに何故か関数が呼ばれないぞ???
といった事件に出会しました。こんな感じ
#define Debug_AAA public class AAA { public AAA() { new BBB().Method_DebugAAA(); new BBB().Method_DebugBBB(); } }#define Debug_BBB using System.Diagnostics; public class BBB { [Conditional ("Debug_AAA")] public void Method_DebugAAA() { UnityEngine.Debug.Log("AAAから呼び出したなら、ログが出るよ"); } [Conditional ("Debug_BBB")] public void Method_DebugBBB() { UnityEngine.Debug.Log("AAAから呼び出した時は、ログが出ないよ"); } }(Unityで作業してたので、ログ出力がUnity仕様なのは堪忍でござる)
どゆこと?
どうやら、Conditional属性はスクリプト内のdefineではなく、呼び出し元のdefineを参照してるらしい。
(リファレンス読んでない人並みの感想)
そもそも、各々のスクリプトでdefineを設定してるのが良くないのかもしれませんね ^^;最後に
defineを外(例えばUnityの
ScriptingDefineSymbols
等)で定義してて
下記のように使いたい時に困っちゃう...気が...#if Debug_AAA || Debug_BBB #define ORIGINAL_DEBUG #endif [Conditional ("ORIGINAL_DEBUG")] public void OriginalDebugMethod(){}とりあえず私のプロジェクトではdefineを整理することにしてみます。
場合によっては素直に#if
使うとかですかね。
- 投稿日:2020-09-24T10:07:38+09:00
Azure の静的サイトをホストする Azure Static Web Apps が Blazor と C# の Functions サポートしたらしいので試してみた
まだプレビューのサービスですが、期待大の Azure Static Web Apps で Blazor と C# の関数がサポートされました。以下のブログでアナウンスされてます。
Azure Static Web Apps with .NET and Blazor
Microsoft MVP の三宅さんのツイートのトップにも、このサービス関連のスライドがピン止めされてますね!
Front-end web applications with Azure Static Web Apps https://t.co/oAQN1Zj74R #VACD
— k-miyake (@kazuyukimiyake) July 28, 2020Azure Static Web Apps の更新情報を確認してみると Python もサポートされていたりして着々と開発が進んでるみたいです。
Blazor + C# の Functions の試し方
最初に紹介したブログに書いてあるのですが、若干気を付ける点があったので書いておこうと思います。
ブログにある GitHub のリポジトリを自分のアカウントにコピーして始めるのですが、これをクローンして Api プロジェクトと Client プロジェクトをローカルで実行して Client の Fetch data のページを開くと CORS のエラーが出ます。これは、デフォルトでローカル開発用の設定ファイルの
local.settings.json
が.gitignore
に入ってるのでリポジトリに含まれていないためです。なので以下の内容のlocal.settings.json
を Api プロジェクトに追加することでエラー無しでローカルで実行できます。local.settings.json{ "Values": { }, "Host": { "CORS": "*" } }これを追加して実行すると以下のようにローカルで動くようになります。
Client プロジェクトの
Program.cs
を見てみるとbuilder.Configuration["BaseAddress"] ?? builder.HostEnvironment.BaseAddress
という感じで設定にBaseAddress
という設定があったらHttpClient
のBaseAddress
に設定しています。設定にない場合はホストのBaseAddress
を使うようになっています。Program.csusing System; using System.Net.Http; using System.Threading.Tasks; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Microsoft.Extensions.DependencyInjection; namespace BlazorApp.Client { public class Program { public static async Task Main(string[] args) { var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add<App>("app"); var baseAddress = builder.Configuration["BaseAddress"] ?? builder.HostEnvironment.BaseAddress; builder.Services.AddScoped(_ => new HttpClient { BaseAddress = new Uri(baseAddress) }); await builder.Build().RunAsync(); } } }Blazor WebAssembly の開発中のみ有効な設定は
wwwroot/appsettings.Development.json
に書いてあって、ここにBaseAddress
がhttp://localhost:7071/
であると書いてあります。appsettings.Development.json{ "BaseAddress": "http://localhost:7071/" }これでローカルの時だけローカルで実行している Azure Functions の方を見に行くようになっています。Azure Static Web Apps にデプロイしたときは、関数は同じホストにいるので同じホストの
/api/関数名
を見に行くようになっています。なるほどね。デプロイして実行
デプロイから実行するのは本当にトラブルがないです。
routes.json
もリポジトリに入ってるし。フレームワークの中の選択肢に Blazor も入ってるし。既存のプロジェクトがあって、それに合わせるとなるとちょっとカスタム頑張らないとですが、そうじゃなければ Static Web Apps が想定しているものに合わせるのがいいですね。
デプロイが完了すると紐づけた GitHub のリポジトリに自動で GitHub Actions が構成されて動きます。
動き終わるとちゃんと表示されました。
PullRequest の時に確認用の環境をたててくれたりとかは試してませんが、生成された GitHub Actions を見る限り対応してくれてそうでした。
まとめ
ということで、ローカル実行を試してみようと思ったら
local.settings.json
を作っておかないと CORS のエラーになってしまいますが、そこさえ気を付けていれば割と簡単にローカル実行から Static Web Apps へのデプロイまでを体験するのは、そんなに難しくないと感じました。今のところ一番 GA が待ち遠しいサービスなので期待大ですね!
- 投稿日:2020-09-24T07:43:29+09:00
C#のActionは途中でExceptionを起こすと中断される
思てたんとちがう!
C#
のAction
をコールバックのリスナとして利用していたところ「思てたんとちがう!」という挙動があったので、改めて検証しました。
Unity
の.NET 4.x
で実行していますが、C#
ならどのプラットフォームでも同じことが起こると思います。テストコード
テストコード// コールバック用のリスナー public event Action OnSomething; private void Start() { // コールバックをそれぞれ登録 OnSomething += OnSomething1; OnSomething += OnSomething2; OnSomething += OnSomething3; // イベントを実行 OnSomething?.Invoke(); } private void OnSomething1() { Debug.Log("1"); } private void OnSomething2() { throw new NotImplementedException(); } private void OnSomething3() { Debug.Log("3"); }このコードを実行するとこうなります。
ログ1 NotImplementedException: The method or operation is not implemented.本来ならばOnSomething1〜3は独立のため、2で
Exception
が起きても3が実行されてほしいところですが、出力されていません。こんな感じで
try-catch
してあげると3も実行されます。try-catchprivate void OnSomething2() { try { throw new NotImplementedException(); } catch (Exception e) { Debug.LogException(e); } }ログ1 NotImplementedException: The method or operation is not implemented. 3何が怖いか
「コールバック公開しておくから、誰でも好きにイベント登録しといてくれよな!」というのがわりと一般的な使い方と思いますが、この挙動だと「他のところで登録した誰かが
throw
したら自分のところにイベントが来なくなる(しかもそれを知ることすらできない)」というなかなか恐ろしいことになります。
C#
のAction
は他にもラムダ式でイベント登録すると解除できなかったり、いろいろ「コワ〜」な挙動が多いです。それすらもなかった昔よりはマシになっているだろうと言われればそうなのですが……。なにはともあれ、良い子はイベント購読側で、イベントを購読しているという状態をインスタンスとして保持・破棄できる
ReactiveExtension
とかUniRx
使おうね!1 という話でした。おしまい。
とはいえ
Rx
もまだ人類には早すぎる代物感がある。 ↩
- 投稿日:2020-09-24T00:26:21+09:00
inputFieldのTMP版をスクリプトで使う方法。
テキストメッシュプロで日本語が使える設定などは各自で済ませておいてください。
それについては参考になるようなサイトを貼っておきます↓
TextMeshProで日本語フォントを使用する【Unity】では早速始めにCreate→UI→InputField - TextMeshProを選択。
その後空のゲームオブジェクトを作る。次に新しくスクリプトを作る。
スクリプトの名前はなんでもよし。
スクリプトを作成したらusing System.Collections; using System.Collections.Generic; using UnityEngine;のusing〜と書いてあるところに
using TMPro;を追加する。
その後「TMP_InputField」型の変数を宣言。↓のように書く。
ここでは変数の名前を「_inputField」としている。public class Textscript : MonoBehaviour { TMP_InputField _inputField; void Start() {その後Startの中でInputField (TMP)のゲームオブジェクトを探し、そこに「TMP_InputField」をGetComponentする。
void Start() { _inputField = GameObject.Find("InputField (TMP)").GetComponent<TMP_InputField>(); }その後「public」で「InputName」という関数を作ります。
↓関数の中身も含めこんな感じです。public void InputName() { string name = _inputField.text; Debug.Log(name); _inputField.text = ""; }中身の説明としてstring型のnameという変数に、先ほど作った「TMP_InputField」型の「_inputField」という変数の中のtextを入れる。
そしてDebug.Log(name)でコンソールに出力。
という感じ。
ここまでのスクリプトの全体を貼っておきます。using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro; public class Textscript : MonoBehaviour { TMP_InputField _inputField; void Start() { _inputField = GameObject.Find("InputField (TMP)").GetComponent<TMP_InputField>(); } void Update() { } public void InputName() { string name = _inputField.text; Debug.Log(name); } }スクリプトはここまでで、作り終わったら先ほど作った空のゲームオブジェクトにこのスクリプトを貼っつける。
そしたら「InputField (TMP)」のインスペクタービューの「On End Edit(String)」の「+」を押し、「None」の部分にスクリプトがついている空のゲームオブジェクトをドラッグ。
右に色々選択できるところがあるので、そこで先ほど作ったスクリプトの名前を探し、その中に先ほど作った関数「InputName」があるのでそれを選択。
そうするとこうなる↓。以上。
一番上のGIF画像みたいに入力した文字がコンソールに出力されるはず。