ナニコレ珍百景⓶ - TejimaTuyoshi/returnread GitHub Wiki
continue;//for文を一回分進める
やり直しを行うことができるが、i++のようにforの条件式内に入れてしまうと一回分進んでしまう恐れがある。
ただし、「除外する」や「重複しないようにする」と基本はコードが長くなりがちなのでどっちもどっちなイメージ。
Listを使用するときは配列なのである程度はList内で修正することが可能。
まぁぶっちゃけ長い。
しかも、配列使用しているうえにfor文なので多重配列に近いことをしているのでループしやすくなっている。これが怖い。
抽選リストを別に作るコストと、List は Remove() の処理が重い。
簡単に言えば「除外」のコストが重い。
重複する可能性が低い場合は、最初のでよい。
基本は周囲の探索は地道にすべてやるしかない。
ラムダ式を使用する際、(x => x < P)とすると、実質的にはx < Pのboolを確認することが可能になる。その際、xはfor文のint iみたいに使用される。
変数(名前)時に型がなくとも「__」のみであった場合、その変数は「破棄」という意味合いになる。
通常だけでなく、関数の時にも「受け取るけど、破棄(消す)」ことと同じ。
xとyそれぞれにかかわらず変数を両方とも変化させると、その変数に合うような形になる(いびつ)
toDictionaryってなにしてんの?=>実際分からん。
スコープの中身=>ブロック
atan = アークタンジェント(逆三角),2点間の距離で角度を返す機能。=> これ自体を使わなくても最近は可能である。
Quaternion => 4元数。回転を行わない。 虚数をつかって回転する。(実質的には回転していない)
4時限目を視認することはあり得ない意。一次元にある際、ほかの物を7死人視認することができない意。
「存在するはずのキャラクターに回転をかける。」などに使用可能」。
- Bridgeパターンの条件の追加の方法
チェックを行い、Trueが帰ってくれば使用可能。=>確認するクラスを用意、if文のようにして作成。
条件は複数あってよい、ただしif文内に"\&&"を使わない方が良い。
- Compositパターンの親子関係の設定
BehaviorTreeがいい例。UnityEventsで設定することができ、基本は「親に子の活動をさせる」ように設定する。
コードの書き方によっては逆になることもあるので注意されたし。
ホルダー(子を持つ場所)を作成、その中に入れた事をさせることが可能。
パラメータによっては細かく調整可能。
親子関係はif文やHierarchyに近い。
- Unirx のObserverの機能
オブザーバー=>通知機能。だがUniRXである理由はReactive Propertyにある。
値の変更時に通知をしてUIに直結させることも可能になる。
Animationの終了時にも使えるが、限定的過ぎてあまりよろしくない。
(そもそも前者のやり方が9割)
UniTask+UniRXはもともと一緒だった。=>UniTaskを使えるひとが多かった。
UniRXで便利にさせることに特化している。(10年前からあるライブラリーのため、別の方法でやることが可能)
return=バグを起こす(抜けてしまう)ケースがあるので、できるだけやらないようにした方が吉。
フィールド=>スコープの射程が全体である(usingは除く)
que=>先入後出(奥に順番に入れた後、一番最初の数字を消していく(出していく))
int.MinValue=>小さい数字を出す。(0や-1以下を出さないようにする。)
スタックのpeek=もはやスタックじゃない。(楽ではある。)
組み合わせ=>ビット全探索 = 結局ほぼ計算してる。(なんだったら増えている。)bynaryTree(樹形図)
Array.convartAll => int.parseを後ろで定義可能。
計算時、もとで考える時と計算後で考えるべきと二種類あるので注意。
「String型」.Replace(" ", "");=>空白を無くすことが可能。
select=>convartAllで大丈夫。
図があるとペンと紙が必要。
頂点数が多い=>一番遠回りをする。
トレイル=>経路の頂点の重複を許すが、辺の重複は許さない。
通った道を取るとき=>数字一つではなく、二つで取る必要がある。
深さ優先探索=>どこが通れるかを「常に」もって置く。
辺の状態を記録する=>その地点は使用不可=>次々やっていく必要がある=再帰呼び出し。
重複データ0{2,5}
配列の位置≠頂点の数。
M1方式(勝ち残り戦)=>情報の上書きがいいので注意しろ。
ちょっくを入れる=>二回行わないようになる。
訪問済み枝リスト=>移動後につける訪問済みかを中身でチェックする。
ダメだった場合、そのまま抜ける。
スタートは抜く。ただし、通過したことに新ければならない。
双方向からダメ=>チェックを付ける。
ゴールしていないなら=>スタート以外は繰り返す。
頂点はしっかり買えばいくても良い。
listで行っている。
通貨済みチェックを確認している辺を確認している=>辺との互換性。
訪問済みの枝を保存したい配列。
ゲームでやるうえでアルゴリズムは大事。=>深さ探索・幅探索を学びなおすのが吉
float・double=>精度と容量が異なる。
ディープコピー=>あまりよろしくない方法。参照すべき場所に配列を作成。その配列を「コピー」して代入する方法。
List<Tuple<int, int>> jobs = new List<Tuple<int, int>>();=>これはTupleの抜け道。昔の方法なので使う人は限られる「かも」。
クラス定義をすれば使用可能。変数のように使うのは不可能。
que自体がそもそも新しいものから出力する(箱でいう上から)ので、カウントで数える際は通常と逆の位置にあるので注意。
foreachはあまり使い勝手は良くない。=ループを勝手に続けることが多いのであまりよろしくない。
再帰呼び出し=できるだけ呼びだしたくない。=>ずっとループし続ける=スタックオーバーフロー(停止)してしまう。
foreachで回す際、その時に変数として作成した(inした先の変数)を変更してはいけない。(エラーが起こる。)
本来、トレイルを(通り方)メモする際にはListではなく多重配列で行う方が良い。
timeを使用している場合様々なバグやズレが発生する。
Scaleを使用し続けると、ゲーム内のズレが顕著になるらしい。
''内に入れたアルファベットまたは数字はif文に入れて不等式にすることが可能。
また、数字とするには最初の文字からの数字として計算可能(a = 1, d = 4)。
データと出力の分別をすることが必要。
最適化するためにはコード内のみでしか不可能。
SceneManager.UnloadSceneAsync=>同時にSceneを使用することができ、削除も可能。上だけ変更するようにすることも可能。
rand => 本当に乱数。randam用に作成されている物ではないのでめっちゃ不規則な上、何回も同じ数字が出ることも。
ramdamは「疑似乱数」は計算によってランダムに「近い」ものを作成しているので、完全にはなっていない。が、基本はこっち。
ガチャはrand系。
conpornent系の関数をnewしてはならない。
Unityの外で「作成」や「削除」は対応が不可能のため、基本は編集以外はUnityで行う。
ただし、「addComponent」では可能になるので「【new】してはならない」とする。
そのためnewをする場合は、「Vector」のような元々ある物のみにする。
ただし例外として、「GameObject」は可能である。現実は非情である。
なお、instanceateとは別なので間違えないようにしよう。
Managect Heap = スクリプトで使用されている容量。
必要な分だけ消すだけで、「すぐに全て消す」わけではない。
ただし、中身を空にした変数だからできただけで「一つでも要素が残っているとアウト」。
メモリリークは「エラー」にならない。=>ガベージコレクションも消せない内容だった場合、フリーズorパンクしてpc終了。
ファイナライザはガベージコレクションが重くなって削除されなくなる可能性があるため、NG✕
FPS落ちによって画質低下や場面飛びが起こる=>ガベージコレクションで削除されていない。
構造体(値参照)の場合はok。しかしアドレス参照の場合はガベージコレクション対象外(メモリ管理不可)なので注意。
では、オブジェクトを破棄したい!(いらなくなった場合)は「IDisposable」を使用することがある。(ただし、UnityではDestroyで行うこと)
通信で切るときや一時停止時に「切断する」場合に、使用することがある。が、基本はあまり見ない。
ファイルを「読み込む」操作(ロック中)の動作「TextReader」はIDisposableを継承している。
ライブラリを使う上で「実装の短縮」は大事。-> 「目的」がある。
ミスを減らしたい -> 他の人がミスしないように作成する。
目的を達成するうえで何が言語基盤や開発基盤に足りないのか(手段がない場合にどうするのか)をよく考える。
Serialize => 実際はもっと欲しい。(自分で作成する。)ので、自分で作って他人に渡す。
ゲーム制作エンジン => 足りないものが多い。 = 改造が必要になる。
AQ -> 逆境指数。 コントロール・責任・影響の範囲・持続時間。の四つを合わせている。
コントロール:どれだけ自分の反応をコントロールできるか。
責任:自分自身の問題として受け止められるか。
影響の範囲:人生などにどれほど影響を与えるか。
持続時間:逆境がどのくらい続くのか。の四つ。
これらをうまく話すことで、面接が受かりやすい。
yield return 文を持つメソッドはコルーチン化されているので、内部の処理は IEnumerable/IEnumerator のオブジェクトの実装に、
コンパイラによって置き換えられている。なので、実体はメソッドではなくてクラスに変換されている。
Inputは移動系であってもUpdateにする。
バグや不具合を理解してから書かないとダメ。「これでいい」や「できてる」だけでやらない。
中身を理解してる状態でないと更なるバグや下手にツッコまれる危険性がある。
やり過ぎた挙動(ゴッドクラス)・直接入れる数字(マジックナンバー)・いらない処理はやめよう。
イベントスパゲッティ= 絡まったイベント。 いろいろなクラスの挙動が絡まりすぎて変になる。
アンチパターンを意識して避ければ多少綺麗にはなる。
Coroutineで動かしている場合、ロボットのように一つづつに集中させることになり通常のUpdateのように一気に使用させることは不可能になる。
startCoroutine ≠ .nextMove
RX => 非同期操作。数字を送ったり、独自で開発されている物。(C#対応)
Task => Unity上では動かせてもそれ以外では動かせない。(C#対応)
C#であっても、使用できない媒体やコードがあることを忘れずに。
IObservable => 監視可能なobject。何かが起きた際に通知する。
IObserver => 監視する人。
IEnumerable <= IEnumetor となるのに対し、
IObservable => IObserver である。なお、イベントなので使用方法は限られる。
イベントなので、キー操作での入力やゲーム内情報の変化を受け取ることが可能。
関数である場合は結果を返すことができるが、I系では型が決まっているので返すことが不可能になる。
「繰り返す動作」を行わせることができるが、その結果を返すことはできない。
送る側=>Action 受け取る側=>Func
if = 条件に沿った場合、一度だけその行為を行う。 while = 条件に沿い続ける限り、ずっとその行為を行う。
corotine内でキャンセルの指示を入れてしまうと条件が増えた際に文が伸びてしまうので危険。
そのため、「外部の場所からキャンセル」の指示を飛ばすことで解消することが可能になる。
基本的に内部でなく、外部から「差し込む」といった形が多い。
corotine = 実際まだやりづらい点はある。(UniRXや外部ライブラリなどで対処)
Unityにおいて、特定の物でない限りはCPUはそこまで落ちることはない。
つまり、C#のScriptにおいてUnityが重くなっているためUnityが危険になってもよっぽどのことがないかぎり大丈夫。
Unityは一つの「スレッド」(処理単位)しか使用できない。そのため、Unityだけが落ちるなんてことも普通にあり得る。
Unityでのスレッドはスクリプト込みで作成されているため、起動後固まるコードを作成した場合に「エディター」ごと固まってしまう。
ゲーム自体が重い場合、特にシュミレーションの場合は複数のスレッドで行っているため重くなっている。
複数のスレッドで動かすものは「スレッドセーフ」がかかっている。
ただし、メインスレッドのみでしか反応しないものが基本のためエラーを起こす可能性は少なくない。
原則、生スレッドをいじることはNG。エラーを起こしたり絡まってしまい、PCを壊しかねないから。
コードでいじることは稀。(ただし、あるにはある。)
対処法=> タスクを使用する。(スレッドにおける実行単位)
using System.Threading.Tasks;が必要。
Taskを使用することで、
コルーチンでできなかった「結果を返す」ことが可能になる。が、
if文に近いので、階層が深くなっていくことが多い。
(はっきり言ってスコープ自体がそうなのでは...?)
そんな時は、「acync演算子」である。
awaitを使用することで複数のタスクを返すことが可能。
ただし、awaitを使用するためにはacyncが必要。
大体のコルーチンはTaskで解決することが可能。
書く上では一つの方法で書いた方が良い。(Taskが一番楽カモ。)
Task.Yield = いったん明け渡す。=>一フレーム待つことが可能(実行時がmainThreadである場合。)
よほどのことがない限り、コルーチンの中で終わらせる。
messageを出し切るのが普通なので、基本的には「最後までを一気に出す」
Cancel-> calceletionTokenの順にならないといけない。
作成時、Canceがあるスクリプトを受け取る側がCancelTokenを持っていなければエラー(あるいはスルー)が起こりどちらにせよ不具合となるだろう。
StartCoroutine -> 始まった後、終了を待たずに次が発生する。
yield -> 一つ目の機能が終わるまで二つ目の機能が発生しない。
params IEnumerator[] -> 受け取るのは「配列」だが、型の宣言がいらない。その型と一致するもののみ取得される。
可変長なので、paramsの宣言をした変数後に別の変数を作成することが不可能になる。やろうと思えば、ナンデモ受け取ることが可能なものもつけれる。コワい。