- 投稿日:2020-05-19T23:55:03+09:00
UniTask2(RC版)まとめ
UniTask2
UniTask
が大きくアップデートされて、バージョン2系がRCとなりました。
今回はいち早くその変更点をまとめていきます。※
Ver 2.0.7-rc7
準拠で書いています。変更があり次第また直します。破壊的変更
まずは1系からの破壊的変更。導入時に気をつける必要があるところです。
名前空間の変更
名前空間が
UniRx.Async
からCysharp.Threading.Tasks
に変更されました。
もともとUniRx
のライブラリの一部だった名残なのですが、今回のアップデートで完全に名残がなくなりました。UniTaskのawait2度漬け禁止
同じ
UniTask
に対しての2回以上のawait
が明確に禁止となりました。
IValueTaskSource
準拠の挙動なので、これは本家ValueTask
と同じ挙動です。UniTaskの2回以上のawait禁止private async UniTaskVoid DoAsync(CancellationToken token) { try { var uniTask = GetAsync("https://unity.com/ja", token); // 1回目のawaitは問題ない await uniTask; // 同じオブジェクトに対して2回以上のawaitはできない // (InvalidOperationExceptionが発行される) await uniTask; } catch (InvalidOperationException e) { Debug.LogException(e); } } private async UniTask<string> GetAsync(string uri, CancellationToken token) { var uwr = UnityWebRequest.Get(uri); await uwr.SendWebRequest().ConfigureAwait(cancellation: token); return uwr.downloadHandler.text; }Preserve()
もし同じ
UniTask
を2回以上await
する必要があるならば、Preserve()
を利用しましょう。Preserve()private async UniTaskVoid DoAsync(CancellationToken token) { try { var uniTask = GetAsync("https://unity.com/ja", token); // Preserve()で何回でもawait可能なUniTaskに変換 var reusable = uniTask.Preserve(); await reusable; await reusable; } catch (InvalidOperationException e) { Debug.LogException(e); } }
AsyncOperation
をawait
するときのConfigureAwait
廃止
AsyncOperation
をawait
するときに利用できていたConfigureAwait
が廃止となりました。
これからはIProgress<float>
やCancellationToken
を指定したい場合はToUniTask()
またはWithCancellation()
を利用する必要があります。private async UniTask<string> GetAsync(string uri, CancellationToken token) { using (var uwr = UnityWebRequest.Get(uri)) { // CancellationTokenを指定 await uwr.SendWebRequest().WithCancellation(token); return uwr.downloadHandler.text; } }// IProgress<float>を指定したい場合(あとついでにCancellationToken) var urw2 = UnityWebRequest.Get("https://unity.com/ja"); await urw2.SendWebRequest() .ToUniTask( Progress.Create<float>(x => Debug.Log(x)), cancellationToken: token);UniTask.Lazyの戻り値の変更
上記の多重
await
禁止の変更をうけて、UniTask.Lazy
の戻り値がAsyncLazy
に変換されました。public static AsyncLazy Lazy(Func<UniTask> factory) public static AsyncLazy<T> Lazy<T>(Func<UniTask<T>> factory)使い勝手としてはあまり変わってはいません。
UniTask.WhenAnyの戻り値変更
WhenAny
の戻り値も変更されました。旧public static async UniTask<(int winArgumentIndex, (bool hasResult, T0 result0), (bool hasResult, T1 result1), (bool asResult, T2 result2))> WhenAny<T0, T1, T2>()新public static UniTask<(int winArgumentIndex, T1 result1, T2 result2, T3 result3)> WhenAny<T1, T2, T3>()UniTask.DelayFrameの戻り値変更
UniTask.DelayFrame
の戻り値がUniTask<int>
からUniTask
に変更されました。既存機能への追加機能とか
全体的なパフォーマンスの向上
全体的にパフォーマンスが向上しています。
内部でUniTask
とAsyncMethodBuilder
、Runner
の再利用が自動的に行われるようになり、ゼロアロケーションで動作するようになりました。UniTaskCompletionSourceが再利用可能に
UniTaskCompletionSource
にReset()
メソッドが追加されました。
こちらを利用することでUniTaskCompletionSource
を再利用することができるようになりました。AutoResetUniTaskCompletionSource追加
AutoResetUniTaskCompletionSource
も追加されました。
こちらはUniTaskCompletionSource
と挙動は同じですが、破棄したときに内部のインスタンスが自動的に再利用される仕組みになっています。
UniTaskCompletionSource
との使い分けですが、何度も同じインスタンスを再利用するならUniTaskCompletionSource
を使う。
使い捨てで都度新しいものを使うならAutoResetUniTaskCompletionSource
を使う。
という使い分けをするとよいでしょう。ファクトリメソッドが追加
ファクトリメソッドがいくつか追加されました。
- UniTask.Create
- UniTask.Defer
- UniTask.Action
- UniTask.UnityAction
- UniTask.WaitUntilCanceled
PlayerLoopTiming追加
PlayerLoopTiming
が追加され、次の種類となりました。
- Initialization
- LastInitialization
- EarlyUpdate
- LastEarlyUpdate
- FixedUpdate
- LastFixedUpdate
- PreUpdate
- LastPreUpdate
- Update
- LastUpdate
- PreLateUpdate
- LastPreLateUpdate
- PostLateUpdate
- LastPostLateUpdate
とくにLastPostLateUpdateが重要で、こちらはコルーチンにおける
WaitForEndOfFrame
に相当します。
いままでUniTask
ではyield return new WaitForEndOfFrame()
ができなかったのですが、今回のアップデートから可能となりました。JobHandle.WaitAsync
JobSystem
のJobHandle
にWaitAsync
が追加されました。
こちらを利用することで、任意のPlayerLoop
のタイミングに切り替えてから完了待ちができます。// WaitForEndOfFrame相当の待機をしてからComplete() await jobHandle.WaitAsync(PlayerLoopTiming.LastPostLateUpdate);AsyncTriggerメソッドのIUniTaskAsyncEnumerable対応
AsyncTrigger
系のメソッド(this.GetAsyncCollisionEnterTrigger
とか)がIUniTaskAsyncEnumerable
に対応しました。
CancellationToken.WaitUntilCanceled
CancellationToken.WaitUntilCanceled
という拡張メソッドが追加されました。
これを用いると、CancellationToken
からUniTask
に変換することができます。生成された
UniTask
は、生成元になったCancellationToken
がキャンセルされたタイミングで完了状態になります。
「相手がキャンセルされるのを待つ」といった使い方ができます。private void Start() { var token = this.GetCancellationTokenOnDestroy(); WaitForCanceledAsync(token).Forget(); } private async UniTaskVoid WaitForCanceledAsync(CancellationToken token) { await token.WaitUntilCanceled(); Debug.Log("Canceled!"); }DoTweenのawaitに対応
DoTween
のawait
にも対応しました。private void Start() { MoveAsync().Forget(); } private async UniTaskVoid MoveAsync() { // 直列実行 await transform.DOMove(transform.position + Vector3.up, 1.0f); await transform.DOScale(Vector3.one * 2.0f, 1.0f); // UniTask.WhenAllで並行実行して終了待機 await ( transform.DOMove(Vector3.zero, 1.0f).ToUniTask(), transform.DOScale(Vector3.one, 1.0f).ToUniTask() ); }新機能
UniTaskAsyncEnumerable/IUniTaskAsyncEnumerable
UniTaskAsyncEnumerable
はUniTask2
の目玉機能です。
IUniTaskAsyncEnumerable<T>
はC# 8.0
のIAsyncEnumerable<T>
をUniTask
として実装したものです。
なんとこちらはC# 7.x系のUnityでも利用可能になっています。何をするためのものかというと、「非同期処理を複数個まとめて扱う」ことができるようになる機能です。
Observable
(IObservable<T>
)と似ていますが、こちらはPull
型として機能するという違いがあります。Observableとの使い分け
Observable
はPush
型なのに対して、UniTaskAsyncEnumerable
はPull
型です。
そのためUniTaskAsyncEnumerable
では非同期処理の実行タイミングを受信側でコントロールできるというメリットがあります。UniTaskAsyncEnumerableで複数の非同期処理を扱うprivate async void Start() { var token = this.GetCancellationTokenOnDestroy(); var uris = new[] { "https://www.google.com/", "https://unity.com/ja", "https://github.com/" }; // URIのリストに対してアクセスしてデータをとってくる // ただし常に実行される通信は同時に1つであり、 // 前回のものが完了しないと次の通信に進まない await uris.ToUniTaskAsyncEnumerable() // 通信完了を待機してメッセージを発行する .SelectAwait(async x => await FetchAsync(x)) .ForEachAsync(x => Debug.Log(x), token); } private async UniTask<string> FetchAsync(string uri) { using (var uwr = UnityWebRequest.Get(uri)) { await uwr.SendWebRequest(); if (uwr.isNetworkError || uwr.isHttpError) { throw new Exception($"Error>{uwr.error}"); } return uwr.downloadHandler.text; } }対する
Observable
はPush
型のため、多数のObserver
に対してメッセージをブロードキャストするのに向いています。複数個の非同期処理を管理する場合は基本には
UniTaskAsyncEnumerable
を使う。
イベント駆動を制御する場合にはObservable
を使う。という使い方をするとよいでしょう。
ForEachAsync/ForEachAwaitAsync
C# 8.0
であればawait foreach
が使えるのですが、それが使えないUnityバージョンでは代替としてForEachAsync
を利用します。
感覚としては、IObservable<T>
に対するSubscribe()
に似ています。
ですがこちらは「ForEachAsync()
の完了をさらにawait
で待つ」といったことが可能となります。ForEachAsyncprivate async void Start() { var token = this.GetCancellationTokenOnDestroy(); // EveryUpdate()は毎フレームのタイミングで完了するUniTaskを返す await UniTaskAsyncEnumerable.EveryUpdate() .Select((_, x) => x) // 5回まで実行する .Take(5) // ForEachAsyncで待機する .ForEachAsync(async _ => Debug.Log(Time.frameCount), token); Debug.Log("Done!"); }また、
ForEachAsync
の他にForEachAwaitAsync
もあります。
こちらはデリゲートの内部でasync/await
が利用でき、この非同期処理が完了するまで次のメッセージを取りに行きません。ForEachAwaitAsyncawait UniTaskAsyncEnumerable.EveryUpdate() .Select((_, x) => x) // 5回まで実行する .Take(5) // ForEachAwaitAsyncで待機する .ForEachAwaitAsync(async _ => { // 10フレーム待ってから次のメッセージを取りに行く await UniTask.DelayFrame(10, cancellationToken: token); }, token);注意:
ForEachAsync
でasync/await
する
ミスしそうな点として、ForEachAsync
でasync/await
を書いてしまうことです。
こちらの場合、コンパイルエラーとならずに動作してしまうのにForEachAwaitAsyncと動作がまったく異なってしまいます。
UniTask2 RC4
でこちらの挙動はコンパイルエラーとなるようになり、安全になりました。もし
ForEachAsync
を使いつつ、UniTaskVoidなasync/await
を使いたい(非同期処理だけどその結果待ちをせずに次のMoveNextAsync()
を呼んで欲しい)場合はUniTask.Void
を併用しましょう。private async void Start() { var token = this.GetCancellationTokenOnDestroy(); await UniTaskAsyncEnumerable.EveryUpdate() .Select((_, x) => x) .Take(5) // 非同期処理を登録できるがこのasync/awaitの結果を // 待たずにForEachAsyncはすぐ次のメッセージを取りに行く .ForEachAsync(_ => UniTask.Void(async () => { Debug.Log("before await:" + Time.frameCount); // ForEachAwaitAsyncはここのawaitを待つ await UniTask.DelayFrame(10, cancellationToken: token); Debug.Log("after await:" + Time.frameCount); }), token); Debug.Log("Done!"); }UniTaskAsyncEnumerableの作り方
UniTaskAsyncEnumerable
はさまざまな方法で生成することができます。ファクトリメソッド
- Return
- Repeat
- Empty
- Throw
- Never
- Range
- EveryUpdate
- Timer
- TimerFrame
- Interval
- IntervalFrame
- EveryValueChanged
他のデータ構造から変換
IEnumerable<T>
IObservable<T>
Task<T>
UniTaskT>
uGUIコンポーネントから変換
uGUIイベントからの変換public class FromUGui : MonoBehaviour { [SerializeField] private Button _button; private void Start() { var token = this.GetCancellationTokenOnDestroy(); // 連打防止ボタン // 1回ボタンを押したら2秒間無反応になる _button.OnClickAsAsyncEnumerable() .ForEachAwaitWithCancellationAsync(async (_, ct) => { Debug.Log("Clicked!"); await UniTask.Delay(2000, cancellationToken: ct); }, token); } }AsyncTriggerを利用する
this.GetAsyncCollisionEnterTrigger()
など。Channel
Channel
はGo
におけるChannel
と同義です。
挙動としてはObservable
におけるSubject
に相当します。なお、
Channel
は内部でメッセージをキューイングします。Channelの例private void Start() { // Channel作成 var channel = Channel.CreateSingleConsumerUnbounded<int>(); // Channelを読み取るときはReaderを使う var reader = channel.Reader; // メッセージの待受 WaitForChannelAsync(reader, this.GetCancellationTokenOnDestroy()).Forget(); // 書き込むときはWriteを使う var writer = channel.Writer; // IObserver<T>.OnNext() に相当 writer.TryWrite(1); writer.TryWrite(2); writer.TryWrite(3); // IObserver<T>.OnCompleted() に相当 writer.TryComplete(); // TryComplete()に例外を渡すと IObserver<T>.OnError() に相当 // writer.TryComplete(new Exception("")); } private async UniTaskVoid WaitForChannelAsync(ChannelReader<int> reader, CancellationToken token) { try { // 1回だけ読み取るならReadAsync var result1 = await reader.ReadAsync(token); // UniTask<int> Debug.Log(result1); // 完了するまで読み続けるなら ReadAllAsync // IObservable<T>.Subscribe() に相当 await reader.ReadAllAsync() // IUniTaskAsyncEnumerable<int> .ForEachAsync(x => Debug.Log(x), token); Debug.Log("Done"); } catch (Exception e) { Debug.LogException(e); } }AsyncReactiveProperty
AsyncReactiveProperty
はUniRx
のReactiveProperty
のUniTask
版です。
ベースとしてIUniTaskAsyncEnumerable<T>
が利用されています。
(ReactiveProperty
はベースがIObservable<T>
)基本的な使い方は
ReactiveProperty
と変わりません。AsyncReactivePropertyprivate void Start() { var token = this.GetCancellationTokenOnDestroy(); // AsyncReactiveProperty生成 var asyncReactiveProperty = new AsyncReactiveProperty<string>(null); // 待受開始 WaitForAsync(asyncReactiveProperty, token).Forget(); // Valueプロパティに値をセットすると // MoveNextAsync() が次に進む asyncReactiveProperty.Value = "Hello!"; // Dispose()するとこのAsyncReactivePropertyが完了する asyncReactiveProperty.Dispose(); } private async UniTaskVoid WaitForAsync( IReadOnlyAsyncReactiveProperty<string> asyncReadOnlyReactiveProperty, CancellationToken token) { // Valueプロパティで現在値を取得可能 var current = asyncReadOnlyReactiveProperty.Value; Debug.Log(current); // IUniTaskAsyncEnumerable<T>として扱える var result = await asyncReadOnlyReactiveProperty // null以外の値がセットされるのを待つ .FirstOrDefaultAsync(x => x != null, cancellationToken: token); Debug.Log(result); }UniTask.Linq
IUniTaskAsyncEnumerable<T>
にはLINQ
メソッドが用意されています。
使えるメソッドは次です。同期型
- AggregateAsync
- AllAsync
- AnyAsync
- AsUniTaskAsyncEnumerable
- AverageAsync
- Buffer
- Append
- Prepend
- Cast
- Concat
- ContainsAsync
- CountAsync
- DefaultIfEmpty
- Distinct
- DistinctUntilChanged
- Do
- ElementAtAsync
- ElementAtOrDefaultAsync
- Except
- FirstAsync
- FirstOrDefaultAsync
- ForEachAsync
- GroupBy
- GroupJoin
- Intersect
- Join
- LastAsync
- LastOrDefaultAsync
- LongCountAsync
- MaxAsync
- MinAsync
- OfType
- OrderBy
- OrderByDescending
- Reverse
- Select
- SelectMany
- SequenceEqualAsync
- SingleAsync
- SingleOrDefaultAsync
- Skip
- SkipLast
- SkipWhile
- SumAsync
- Take
- TakeLast
- TakeWhile
- ToArrayAsync
- ToDictionaryAsync
- ToHashSetAsync
- ToListAsync
- ToLookupAsync
- ToObservable
- Union
- Where
- Zip
- CombineLatest
- Pairwise
- Queue
- SkipUntilCanceled
- TakeUntilCanceled
- Publish
非同期型
AwaitAsync
がついているものはasync/await
を内部で利用できます。
- AggregateAwaitAsync
- AllAwaitAsync
- AnyAwaitAsync
- AverageAwaitAsync
- CountAwaitAsync
- DistinctAwait
- DistinctUntilChangedAwait
- DoAwait
- FirstAwaitAsync
- FirstOrDefaultAwaitAsync
- ForEachAwaitAsync
- GroupByAwait
- GroupJoinAwait
- JoinAwait
- LastAwaitAsync
- LastOrDefaultAwaitAsync
- LongCountAwaitAsync
- MaxAwaitAsync
- MinAwaitAsync
- OrderByAwait
- OrderByDescendingAwait
- SelectAwait
- SelectManyAwait
- SingleAwaitAsync
- SingleOrDefaultAwaitAsync
- SkipWhileAwait
- SumAwaitAsync
- TakeWhileAwait
- ToDictionaryAwaitAsync
- ToLookupAwaitAsync
- WhereAwait
- ZipAwait
こちらは
CancellationToken
を内部で必要とするときに使います。
- AggregateAwaitWithCancellationAsync
- AnyAwaitWithCancellationAsync
- AverageAwaitWithCancellationAsync
- CountAwaitWithCancellationAsync
- DistinctAwaitWithCancellation
- DistinctUntilChangedAwaitWithCancellation
- DoAwaitWithCancellation
- FirstAwaitWithCancellationAsync
- FirstOrDefaultAwaitWithCancellationAsync
- ForEachAwaitWithCancellationAsync
- GroupByAwaitWithCancellation
- GroupJoinAwaitWithCancellation
- JoinAwaitWithCancellation
- LastAwaitWithCancellationAsync
- LastOrDefaultAwaitWithCancellationAsync
- LongCountAwaitWithCancellationAsync
- MaxAwaitWithCancellationAsync
- MinAwaitWithCancellationAsync
- OrderByAwaitWithCancellation
- OrderByDescendingAwaitWithCancellation
- SelectAwaitWithCancellation
- SelectManyAwaitWithCancellation
- SingleAwaitWithCancellationAsync
- SingleOrDefaultAwaitWithCancellationAsync
- SkipWhileAwaitWithCancellation
- SumAwaitWithCancellationAsync
- TakeWhileAwaitWithCancellation
- ToDictionaryAwaitWithCancellationAsync
- ToLookupAwaitWithCancellationAsync
- WhereAwaitWithCancellation
- ZipAwaitWithCancellation
補足: Pushベースの
UniTaskAsyncEnumerable
の注意点
IUniTaskAsyncEnumerable<T>
はPull
型として動作します。
そのためメッセージの受信準備が整い、内部でイテレータのMoveNextAsync()
が実行されたタイミングで次のメッセージを取りに行きます。ですが、
UniTaskAsyncEnumerable
ではメッセージ発行がPush
なIUniTaskAsyncEnumerable<T>
も存在します(ややこしい)
UniTask.EveryUpdate()
AsyncReactiveProperty
AsyncTrigger
より生成したものuGUI
のイベントなどから変換したものこれらは
Push
されてきたイベントをIUniTaskAsyncEnumerable<T>
として提供します。
そのためMoveNextAsync()
とタイミングが合わなかった場合は、その間に発行されたイベントは取りこぼされるという点に注意が必要です。逆に、このイベントの取りこぼしを利用して処理を組むこともできます。
イベントの取りこぼしを利用した例// uGUIのボタンの連打防止 // 1回ボタンを押したら2秒間無反応になる // ForEachAwaitAsyncが待機中に発行されたメッセージは無視するという // 性質を利用している _button.OnClickAsAsyncEnumerable() .ForEachAwaitWithCancellationAsync(async (_, ct) => { Debug.Log("Clicked!"); await UniTask.Delay(2000, cancellationToken: ct); }, token);取りこぼしが嫌なら Queue() を使おう
Queue
はUniTask.Linq
が提供するLINQ
メソッドの1つです。
IUniTaskAsyncEnumerable<T>
に対して先にMoveNextAsync()
を実行し、その結果をキューに詰めて再度IUniTaskAsyncEnumerable<T>
として提供します。
(Observable
でいうところのPublish()
に相当します)
Queue
を使えばイベントの取りこぼしを防ぐことができるため、必要に応じて利用しましょう。Queueprivate void Start() { var token = this.GetCancellationTokenOnDestroy(); // AsyncReactiveProperty生成 var asyncReactiveProperty = new AsyncReactiveProperty<string>("Initialize!"); // 待受開始 WaitForAsync(asyncReactiveProperty, token).Forget(); // 値を設定 asyncReactiveProperty.Value = "Hello!"; asyncReactiveProperty.Value = "World!"; asyncReactiveProperty.Value = "Thank you!"; asyncReactiveProperty.Dispose(); } private async UniTaskVoid WaitForAsync( IReadOnlyAsyncReactiveProperty<string> asyncReadOnlyReactiveProperty, CancellationToken token) { // AsyncReactiveProperty はキューイングしてくれないので // タイミングによってはメッセージの取りこぼしが置きうる // 取りこぼしが嫌ならQueueを併用する await asyncReadOnlyReactiveProperty .Queue() // Queueを挟む .ForEachAwaitWithCancellationAsync(async (x, ct) => { Debug.Log(x); // 1秒待って次の値を取りに行く await UniTask.Delay(1000, cancellationToken: ct); }, token); }まとめ
C# 8.0
のIAsyncEnumerable
相当の処理をいち早くUnity
でも利用できるため、かなり期待が高いアップデートとなりました。
UniTaskAsyncEnumerable
とAsyncReactiveProperty
が刺さる人にはかなり刺さる機能でしょう(自分はさっそく使いたい)ただ、これの登場によって
IObservable<T>
との使い分けが一層ややこしくなった可能性もあります。
UniRx
で苦戦していた人はおそらくUniTaskAsyncEnumerable
でも苦戦するような予感が…。
- 投稿日:2020-05-19T17:52:55+09:00
正しいプログラミングの学習方法について語る
今回は プログラミング学習について 見ていきます。
特に独学での学習者はこれらの点を気をつけて学習したほうがいいです。
1 完璧主義を目指してはいけない
プログラミングの学習において、完璧主義を目指すのはほんとに自殺行為といえます。
これは学習でもそうですけど、プロダクトを作るときも同じです。
最初は6割や7割ベースで 全然いいと思う。
特に独学でやっている人ほど、完璧主義を目指すのはやめましょう。
2 暗記も必要もない
学校の勉強のような、暗記も必要ないです。
覚えるのは基礎だけでいいわけで あとは
必要なときに 必要な分だけ覚えていくのがいいと思う。
なので メソッドやライブラリなどを全部覚える必要はないです。
3 小さい目標をつけるべし
わたしもプログラミングは全部独学で覚えたんですけど
独学の場合だと、やはりモチベーションが続かないんですよね。
モチベも続かないし、普通に挫折もすると思います。挫折しない人なんているんでしょうかね???
なので 小さいな目標を立てることが重要です。
例えば 1日 10ページすすめるとか
1日 1回はアウトプットするとか
サンプルコードをやるとかね。
因みに習慣の法則というものがありまして
21日間 続けることが出来れば、 そのあとも継続できるようになるので
とりあえず 3週間は続ける事が大事。
4 インプットよりも アウトプットを増やしなさい
インプット学習ってみんな普通にするんですよ。
でも アウトプットしている人はほんとに少ないです。
みんな、 Udemyとかの動画は見ているけど
それで終わっている人が多いからね。なので、アウトプットする習慣を身に付けることが最も大事。
インプットよりも、どうやってアウトプットできるかを
考えるべし。初心者であれば、 パイザのコードクロニクルなどが
おすすめです。5 とりあえず ググり癖はつけるべし
分からなければ すぐに調べる。
調べ方は色々あるけど
目的で検索するか、 コードをコピペしていくのが基本。
で これは 誰かに質問するときも同じで
質問するときも、 ちゃんと調べてから質問すること。あと 何でもかんでも、質問すればいいってわけじゃないからね。
あんまり、質問ばっかりしていると嫌われるよん。
PS
C#プログラミングマスター講座も
発売中でーす。只今70%OFFセールやってます。
C#が分からないと Unityもできるようにならないので
Unityをやるひとにも おすすめです。
- 投稿日:2020-05-19T16:06:03+09:00
自己紹介
こんにちは。初投稿です。
投稿の練習がてら自己紹介をします。私は現在高校で数学の教員をやっています。
数学の授業で使えるようなソフトやページを作っています。私がプログラミングと出会ったのは大学2年生の時に受けた授業でした。そこではRubyを扱い、全く理解できなかった私はプログラミングに興味を持つことはありませんでした。
しかし大学3年生の春、某大手通信制高校の長期インターンを始めたら、そのインターンではプログラミングを扱う機会がとても多く、扱う教材も面白く私はプログラミングへのめり込んでいきました。
インターンでは主に、HTML、CSS、JavaScript、python、Unity(C#)などを扱いました。紹介しているものも、ここら辺中心に作っています。以下にインターン時代に作ったものを載せておきます。
円周率πの近似~モンテカルロ法~(HTML、JavaScript)
教員になってから作ったものは以下のものです。
サイコロを振りまくったら本当に1/6になるのか(Unity)
数学の展開、因数分解をひたすらやるゲーム(Unity)
これはまだ制作途中なので画像だけです。
サイコロと数学のゲームに関しては別記事でもう少し詳しく紹介できたらなと思います。
コメントやアドバイスをいただけると幸いです。