Unity初心者の俺が調べたことをメモするスレ
1 :名前は開発中のものです。 :2023/08/30(水) 21:52:43.22 ID:zQtYmNBI.net ちなスペックは コード作成は生成AI頼り・基礎的なコンポーネントの使い方すら理解してない・C#の経験皆無 こういうレベル
2 :名前は開発中のものです。 :2023/08/30(水) 21:58:13.30 ID:zQtYmNBI.net 基礎的なことすら理解してないから一歩ずつ調べてメモしていきたい 今日調べたこと ・EventSystemとPlayerInputの実行順序について Project SettingのScriptExecutionOrderでは、EventSystemが-1000・PlayerInputが-100の実行順既定値が設定されている これを見るとEventSystemの処理の方がPlayerInputより先に行われるように見えるが、EventSystemによるUI操作はUpdate関数でInput.Actionを購読しに行く形で行われる一方、PlayerInputはPreUpdateのタイミングでInput.Actionを生成しイベントを発火させるので、実はPlayerInputによる関数コールの方がEventSystemのUI操作より先に行われる
3 :名前は開発中のものです。 :2023/08/30(水) 22:04:40.12 ID:zQtYmNBI.net あとで見返すために番号付けとくか なるべく毎日調べたこと書きたいね
4 :名前は開発中のものです。 :2023/08/31(木) 18:16:21.62 ID:SnlLP3DA.net その2 I〇〇Handlerについて Unityでは独自のインターフェースとして、ISubmitHandlerなどのUIイベント発生時にコールバックを受け取る機能が実装されている。 インターフェースという概念自体はあくまでクラス外部向けに内部実装の設計を規律するものにすぎず、I〇〇Handlerを実装してもC#としてコールバックを受け取る機能そのものが実装されるわけではない。 コールバックの発火は@ フォーカス、決定やキャンセルイベントなどEventSystemが発火を決定 → イベントを作成(BaseEventData) → ExecuteEventsに依頼してインターフェースを実装する該当クラスに送信してコールバックを発火するケースと、A マウスイベントなどInputModuleが自分でイベントを作成(PointerEventData) → ExecuteEventsに依頼して〜、という二つの異なるパターンがあるらしい(もっとあるかも)。 疑問としては、InputSystem導入後にInputModuleとInputSystemUIInputModuleの二つを統合するBaseInputModuleクラスが導入されたらしいが、この場合はマウスイベントを発火させるのは何処なのだろうか?
5 :名前は開発中のものです。 :2023/08/31(木) 18:16:23.48 ID:SnlLP3DA.net その2 I〇〇Handlerについて Unityでは独自のインターフェースとして、ISubmitHandlerなどのUIイベント発生時にコールバックを受け取る機能が実装されている。 インターフェースという概念自体はあくまでクラス外部向けに内部実装の設計を規律するものにすぎず、I〇〇Handlerを実装してもC#としてコールバックを受け取る機能そのものが実装されるわけではない。 コールバックの発火は@ フォーカス、決定やキャンセルイベントなどEventSystemが発火を決定 → イベントを作成(BaseEventData) → ExecuteEventsに依頼してインターフェースを実装する該当クラスに送信してコールバックを発火するケースと、A マウスイベントなどInputModuleが自分でイベントを作成(PointerEventData) → ExecuteEventsに依頼して〜、という二つの異なるパターンがあるらしい(もっとあるかも)。 疑問としては、InputSystem導入後にInputModuleとInputSystemUIInputModuleの二つを統合するBaseInputModuleクラスが導入されたらしいが、この場合はマウスイベントを発火させるのは何処なのだろうか?
6 :名前は開発中のものです。 :2023/08/31(木) 18:33:55.46 ID:SnlLP3DA.net なんか多重送信されてるわ 「PlayerInputの方がEventSystemより実行タイミングが早い」っていう昨日の話だけ覚えておけば、どこが発火するかなんて正直割とどうでもいい気はするが念のため調べてみた。 ところでEventSystem(UnityのUI)って基本的にはイベントが発生したことは取得できるけど、「どういうキーが押されてイベントが発生したか」っていう情報を取得するのが難しい(できない?)気がする 例えば、画面上にA・B・Cの三つのUIが横並びで配置されていて、「B」がフォーカスを取得した時に発生させるイベントの内容を、直前のフォーカスが右にあったか左にあったかで条件分岐したい場合、 UIイベントが発生する原因となったキー操作そのものをEventSystemはEventDataに内包してくれる訳ではないっぽいので、工夫をしないとこの分岐は実現できなさそう 一つの案は直前までにフォーカスを取得していたA又はCにIDeselectHandlerを実装(又はSelectableがA・Cの基底クラスにあるならオーバーライド)して、フォーカスを失ってOnDeselectが実行された時に自身の情報をマネージャークラスに渡しておいてBにそれを見て判断させるという方法 この方法は分かりやすいけどUIのゲームオブジェクトが変動する・動的に生成される場合には「隣にいた」認定の処理が面倒になりそう もう一つの案はPlayerInputを利用して、該当するキー入力があった際に入力があったことをマネージャークラスやBに渡す方法 BがAの方から来たなら右キー、Cの方向から来たなら左キーが入力されているはずなので、Bはこの入力情報を見ればどっちから来たかが分かるし、UI要素が変動しても対応しやすい ただしイベント発火が絡む関係でパフォーマンス面では前者の手法に劣りそう
7 :名前は開発中のものです。 :2023/08/31(木) 18:49:55.41 ID:/dI3F1uF.net んなややこしいことせんと 先入れ先出しのスタック1つ作っておけば?
8 :名前は開発中のものです。 :2023/08/31(木) 19:22:23.67 ID:SnlLP3DA.net >>7 独自のデータロード式スクロールビューに利用するんだけどもう後者を採用(PlayerInput)して一応完成させたのよね 上下キーでは要素1個ずつ移動、左右キーでは表示エリア全部をページ送りする機能を実装したかったんだけど A(画面上では不可視) B C D E F G(画面上では不可視) この順に子要素が並んでいて、Aにフォーカスが入った時に上方向にデータロードして子要素を並び替え(上からGABCDEFになる)、Gにフォーカスが入った時下方向にデータロードして並び替え(BCDEFGAになる)をする感じで動く 例えばBにいる状態で下キーをを押しっぱなしにするとCDEFGAB…ってループしながらリストや配列の次のデータを読み込みながらフォーカスを変えていく 各子要素には上下方向は上下に、左方向はAに右方向はGにSelectableのナビゲーションを設定してるんだけど、このデータロードを行う際にB→AやF→Gのフォーカスの移行が「上下キー」で行われたのか「左右キー」で行われたのかを判別する必要があったのよね それでPlayerInput使う方法を思いついた
9 :名前は開発中のものです。 :2023/09/01(金) 15:34:09.80 ID:p9KeXpxb.net 普通に詳しいじゃん
10 :名前は開発中のものです。 :2023/09/01(金) 18:06:12.03 ID:jPfSgGL6.net >>9 その都度調べてはいるけど結構忘れちゃうわ 自分のコードすら翌日見るとよく分からん その3 ゲーム上のアイテムシステムの管理について Unity特定の機能というよりどうやってこういう概念を実装したらいいのかな?って話 アイテムの入手と管理をどうやってゲームシステムとして実装するか @ノベルゲー寄りの小規模なゲーム(アイテムは入手か未入手だけで特定の場面でしか利用しない。同じアイテムの複数個所持もない。) 正直一つずつbool値を設定して管理しても何とかなりそう。とは言っても場面毎に必要なアイテムを設定する際の利便性を考えると、スクリプタブルオブジェクト、Enumや通し番号あたりを割り振る必要性は結局あるかもしれない A一般的なゲーム(それなりのアイテム数で複数個所持もある) Dictionaryで、アイテム種類別管理データ(スクリプタブルオブジェクト、Enumや通し番号あたり)をキーに、値を所持数にして格納すると楽そう。 Bハクスラ要素のあるゲーム(同じアイテムでも性能が違っていたりする。Minecraftのエンチャントようなシステムもこのタイプ) アイテム種類別管理データだけではなく、個別アイテムの管理データも必要になる。雑に調べた限りではこのパターンは意外とネットに情報がない。自分は購入したノーコード系アセットのサンプルゲームを見て、Dictionaryの値を個別アイテムインスタンスにする方法で実装できることを知った。 public class MyItem { private int itemNo; // アイテム種類別管理データに対応する enumでも何でもない private int myAbility;// 個別データとか } こういうクラスを実装して、アイテム入手時にこのクラスのコンストラクターに個別情報を渡してインスタンス化して、そのままDictionaryに入れる。キーを0から始まる通し番号にでもしてキー自体を更に別のコレクションで管理すれば、疑似的なインデックスとして入手順にアイテムの個別インスタンスにアクセスすることも可能。(SortedDictionaryとどっちが早いかは未検証)
11 :名前は開発中のものです。 :2023/09/01(金) 18:09:01.68 ID:jPfSgGL6.net コンストラクタに渡して〜って言ったけどコードにコンストラクタ含めてなかったわ 自分のプロジェクトではもうちゃんと実装しているからセーフ(適当)
12 :名前は開発中のものです。 :2023/09/02(土) 21:04:00.56 ID:zmatsJxn.net その4をまとめられるほど学習が進まなかったわ デザイン方向と機能案に時間を多く割いた結果、有名アセットとしてFinalIKを購入してデモを見て使い方をほんの少し覚えるだけで終わった FinalIKそのものの話ではないけど、FinalIKは昔はアニメーション時にイベントを発生させる方法がSendMessageしか用意されていなかったっぽいのね(古いデモ動画見たらこれしかインスペクターに映ってなかった) 今はUnityEventにも対応しているので基本的にこっちを使うことになりそう そもそもUnityにイベントを発生させる方法って何があるの?って再度調べてみると、現在ではUnityEventとC#Eventの二つが主流っぽい? 他にもSendMessageやBroadCastMessageというイベント発生機能も用意されているが、パフォーマンス面や管理のコストの問題を指摘する記事が多い印象(ゲームオブジェクト全体にイベントを送信してしまうため重い、関数を名前で指定するからゲームシステムを設計変更したりすると変更漏れとかが生じやすい?) ちなみにEventSystemが入力情報を経てコールバックを発火するのに使うExecuteEventsもIEventSystemHandlerを実装するコンポーネントの関数をコールするものらしいので実はイベント発生に利用できるらしい(使う必要性があるかは知らない)
13 :名前は開発中のものです。 :2023/09/03(日) 22:10:58.50 ID:OCQOviyY.net 今日は独自のスクロールビューとスクロールバーをより汎用的に使えるようにコードの調整を始めた 今のコードではスクロール自体のクラスとスクロールにコンテンツを渡すクラスが密接に結びついているので、その繋がりを弱めていきたい そこで方法を調べてみると、抽象クラスやインターフェースを利用する方法があるらしい 実は前にも抽象クラスとインターフェースについて購入したアセット素材を解読するために調べたことがあったが、正直その頃は「実装が持てない」以外のことがよく分からなかった 自分で抽象クラス・インターフェースを使ってみようと調べ直した結果、前よりは理解ができたので、ひとまずコードが少なくて調整が楽そうな独自スクロールバーにこの二つを実装してみて、ビューとバーの繋がりを弱めてみた その4 抽象クラスとインターフェースについて 抽象クラスもインターフェースも、これを継承したクラスに対して自身が要求する関数などメンバーを実装するように強制させる機能を有する。 他の類似点としては、両方ともインスタンスを生成することができない。抽象クラスはMonoBehaviourを継承していてもゲームオブジェクトにアタッチすることができない(エディタ上で警告文が出てアタッチ処理自体が行われない)。 逆にこの二つの違いは、 @抽象クラスは(C#では多重継承が不可能であるため)直接的には1個しか継承できないが、インターフェースは2個以上を継承することができる A抽象クラスはフィールドを持つことができるが、インターフェースは持てない B抽象クラスや実装のある(中身のある)関数等を持つができるため、普通の基底クラスとしても利用できる。インターフェースは持てないっぽい?(実はデフォルト実装という機能があるらしいが、C#の新しい機能だそうでUnityで対応しているかよく調べてない。しかも今のところあまり利用が推奨されないらしい) C抽象クラスの抽象メソッドはアクセス修飾子はpublic又はprotectedでなければならない。protected(自身と派生クラスのみアクセス可能)が許されている点から抽象クラスはクラスの内部向けルールを定める性質が強い。一方でインターフェースのメンバーはpublicに限定される。インターフェースはInter + Faceの語源通りクラスの外部向けルールを定める性質が強い
14 :名前は開発中のものです。 :2023/09/03(日) 22:30:09.73 ID:OCQOviyY.net 今回は、インターフェースの「他のクラスのメンバーにアクセスしたいとき、そのクラスがインターフェースを実装していることさえ分かっていれば、クラス内の細かい実装を知る必要がない」という利点を体感することができた 他のクラスへの参照をインターフェースの型で取得することで、そのクラスがどんなクラスであってもそのインターフェースの実装たるメンバには確実にアクセスすることができるようになるのだ(もちろんメンバで滅茶苦茶な内容が実装されている可能性はある。ここはコードを書く人の良心任せ) 自分のプロジェクトでは独自のスクロールビューとスクロールバーを利用しているが、このうち「スクロールビューからスクロールバーに数値を渡す関数」をインターフェースの実装とすることで、スクロールバーは独自スクロールビューがどんなクラスでも数値を受け取れるようになった(今後用途に応じてスクロールビュークラスを拡張や派生させても、スクロールバークラスをその都度修正する必要がなくなった) ちなみにスクロールビュークラス側には、今後の拡張に備えて抽象クラスを作成してその抽象クラス内でインターフェースを抽象メンバとして実装したのだが、この辺は自分でもどういう利点があるのかまだ理解しきれてないのでまた今度
15 :名前は開発中のものです。 :2023/09/04(月) 22:59:12.23 ID:8vO4bi2+.net 書こうと思ったけどTMP・文字列・GCの復習をしていたら時間がなくなったから今日は終わり!
16 :名前は開発中のものです。 :2023/09/04(月) 23:14:20.64 ID:DD6FCi8L.net てかUnityというより C#の仕様
17 :名前は開発中のものです。 :2023/09/05(火) 22:27:53.86 ID:1xAiAK3x.net いまシステム面とUIを重点的に作ってるからどうしてもC#寄りになるね その5はまとめられてないからUnityのマジックメソッドについて少し StartやUpdateといったUnity独自の関数はランタイムによってゲーム実行時 (?)だったかに呼び出しリストが作成される Unityの内部クラスが呼んでる訳ではないのでこれらのマジックメソッドはprivateでも呼び出しが行われる 逆にこれが原因なのか、通常の関数より呼び出しコストが高い Update100個より1個のUpdateが100個の独自アプデ関数呼ぶ方がコール回数が1回多いはずなのに動作が軽いのは有名な話(らしい) 加えてawake OnEnable startの呼び出し順には多少注意が必要かもしれない 具体的にはStartよりOnEnableの方が早いので、Startで外部参照の設定するコードを書いてると先にOnEnableが呼ばれてヌルリファだったり意図しない挙動が起きがち メニュー画面などのUI要素をGameObject.SetActiveで有効無効を切り替えてその際にOnEnable/OnDisableで初期化や再設定を行う設計を採っている時は扱いに注意(n敗) ちなみにアセットのサンプル見てたら、OnEnableでコルーチン呼んで1f待機することで先に確実にStartを通す設計をしているものが見つかった 無理やりな気もするけどどうなんだろうね
18 :名前は開発中のものです。 :2023/09/05(火) 22:33:42.70 ID:Ts+LtVa/.net UIやってるなら今ならちょうど ユニティ・テクノロジーズ・ジャパンは、日本語の電子書籍『Unityにおけるユーザーインターフェースのデザインと実装』を無料で提供。専用ページから申し込めばダウンロードできるようになりました てことで無料で見られるよ Startを1frame待つのは理にかなってるんじゃないかな Start関数は画面表示前の処理だし、1frameということは表示してからだから 確実だよね
19 :名前は開発中のものです。 :2023/09/05(火) 22:42:05.64 ID:JlRpf2nJ.net >>18 マジか 良いこと聞いた
20 :名前は開発中のものです。 :2023/09/06(水) 22:29:47.35 ID:xeaBYfjk.net >>18 情報サンクス 早速ダウンロードしてみたわ UIToolKitはまだ全く手付かずだからどういうものか早く勉強しないとなあ サンプルシーンで1f待ってるのはStartじゃなくてOnEnableね そのサンプルはアイテム管理システムで、マネージャークラスがOnEnableでコルーチンで1f待機している間に、ゲーム開始後に道具メニューを開いた時に初めて生成されるアイテム表示用プレハブたちがStartで参照情報をマネージャーに渡してくる設計になっていた マネージャーのOnEnableでプレハブの描画更新とイベントへのデリゲートの登録をやってるので、仮に1f待機がないとプレハブが生成される最初の1回目だけ参照情報をまだ受け取っておらずヌルリファが発生するからだと思われる その5 「抽象クラスの個人開発における利点がよく分からない」 まとめというより疑問に近い。 抽象クラスのメリットを調べると、大抵のサイトや記事では「抽象化によって複数人の開発で統一が取れたコードが作成できる」といった内容が挙げられている。では、個人開発における抽象クラスの利点は何なのだろうか。 結論から言うと調べても自分にはあまり理解できなかった。「無い」や「殆ど無い」としている記事も散見される。 というのも、単に複数のクラスで共通したルールを実装したいなら純粋に基底クラスを継承して利用すればだいたい足りる気がする。 たしかに抽象クラスで関数の名称やシグネチャなどを設定して派生クラスにそれに沿った実装を強制するのは、コードの統一性を確保する上では有用ではあるが、個人開発だとコードを弄るのは基本的に自分だけなので、自分で注意すればよくない?という気も まあC#に限らずヒューマンエラーを防げます系機能は究極的には全部「自分で注意すりゃよくない?」になるし、もちろん自分にそんな神みたいなこと無理なんで…(OnEnableとStartで何回もエラー引き起こす程の低い注意力) 自分としては抽象クラスは「インスタンスは絶対これで生成しないけど共通・統一された処理を実装したい」ケースでお守り的に使っていこうかなと思った(適当)
21 :名前は開発中のものです。 :2023/09/07(木) 23:01:59.92 ID:zzCLMbJH.net 眠いから雑なぼやき シングルトンを初めて自分のゲームに導入してみた。理由はどういうものか使ってみたかったから。 戦闘システム管理クラスをシングルトンにした。戦闘キャラクラスからたくさんアクセスする。 これが密結合か? グローバル変数化を目的として作っちゃいけないという話は聞いたことあるけど、これもその一つかもしれない。 この辺のコード作成のパターンの理念について何も知らないからそろそろ勉強するときかなあ
22 :名前は開発中のものです。 :2023/09/08(金) 22:50:45.01 ID:whCfvpks.net GCalloc(ヒープメモリアロケーション)にまとめたいけどまだ理解が足りていない 今日は有料アセットのGCalloc潰しを中心に作業をしたが、フィールドのList<構造体>をSortする箇所でアロケーションが発生する理由がイマイチよく分からなかった 引数としてデリゲートを渡すとアロケーションが発生するのはその都度コンパイラがnewしてしまうからで、「デリゲートの代わりにメンバを参照しないラムダ式を利用する」と初回のみのアロケーションで済むらしい 実際ラムダ式に変えたら毎フレームのGCallocが消えたのだが、「IComparerを実装したクラスのインスタンスを利用する」という方法もあると聞き、こちらも試してみたところGCallocは消えないどころか増えた なんかボックス化というものが絡んでいるような気もするがよく分からないので今日はこれで終わり
23 :名前は開発中のものです。 :2023/09/09(土) 23:03:59.62 ID:DhDPacVH.net GCalloc潰し二日目 昨日IComparerでGCallocが防止出来なかった理由については未だに分かっていない(というか殆ど調べていない) 「ラムダ式でメンバを参照する」コードを複数の有料アセットで見かける GCalloc対策の話題でまず槍玉に上がる点だと思うのだが、あまり気にされていない・自分が気にしすぎなのだろうか?
24 :名前は開発中のものです。 :2023/09/09(土) 23:10:00.18 ID:O6P9FobY.net えーと 研究者なら気にしてもいいかと アプリ開発するなら今のハード考えると気にし過ぎじゃね てか気にする必要ないでしょ
25 :名前は開発中のものです。 :2023/09/09(土) 23:34:12.06 ID:DhDPacVH.net >>24 やっぱり気にし過ぎかなあ 特に今作っているゲームはPC向けだから尚更処理落ちやクラッシュはし辛いだろうし 一応自分でコード書く時はアロケーションは基本的に避けるようにしてるけど、有料アセットまで潰して回る必要はないか
26 :名前は開発中のものです。 :2023/09/09(土) 23:46:32.90 ID:tG9qh3d0.net ガベージコレクションなんかC#の基本なんだから気にしなくていいだろ そんなに嫌ならBurstCompilerでもJobSystemでもECSでも使えば良い
27 :名前は開発中のものです。 :2023/09/10(日) 00:04:42.69 ID:u9L0A1tk.net 結構規模の大きいものを作ってるから可能な限り潰しておきたい感はあるのよね 数時間のプレイに堪えられるような設計にしたい
28 :名前は開発中のものです。 :2023/09/10(日) 00:11:59.35 ID:nCKHuG8g.net >>27 ECS,BurstCompiler使えよ
29 :名前は開発中のものです。 :2023/09/10(日) 09:03:38.32 ID:hFRQptHY.net >>23 かける労力と得られるものが釣り合ってると思えるならそれぞれの判断でいいと思うけどね 今自分の作ってるやつはインクリメンタルGCついてても数分に一回3~7msくらいのGC Collectが発生してて シューティングゲームなんでもう少しGCAlloc潰したほうがいいだろうなと思ってる
30 :名前は開発中のものです。 :2023/09/10(日) 15:42:12.07 ID:j4PqFMUR.net あかん、行こう
31 :名前は開発中のものです。 :2023/09/10(日) 21:59:14.98 ID:u9L0A1tk.net >>28 ECSは全然理解してないし有料アセットとの兼ね合いが悪い(自分で調整できない/作業量多すぎ)だから導入するつもりは現状ないかなあ アセット開発者がDiscordで今からECS対応は難しいって言っているのも見かけたし >>29 どういうコードがGCalloc発生するのか自分で見て覚えていきたいってのもあるし、しばらくは続けようかな シューティングゲームって弾幕GameObjectのinitialize/Destroyやオブジェクトプール行き来のDisable/Enableで最適化が大変そうだなあ 差し支えなければ教えてほしいんだけど重い処理を行っている時ってフレーム毎にどのくらいGCalloc発生してますか? >>30 ? 今日はNPC(アセットのコンポーネント)のUpdate30個をOnUpdateに変えるお試し軽量化をしてみた 0.5msぐらいの改善が見られた 他にも自分のゲームに使用しない無駄な機能がついていたりするから削っていこう アセットに更新があった時に面倒だが、勉強道具にしたり自分で色々と改造したりできるから完全なC#コードが提供されているものは便利(DLLで提供されているものがあるか知らんけど) アセットとC#の話で一つ複雑だなと思うのは、AssemblyDefinitionによってアセンブリが定義・分割されているとアセット側からこちらの自作コードにそのままではアクセスできない点。コード弄り始めた頃は原因が分からなくて四苦八苦した。 自作コードにAssemblyDefinitionsを設定していない場合は自動的にAssembly-Csharpに配置されるが、このAssembly-Csharpと他アセンブリのアクセスは一方通行の関係にある。すなわち、Assembly-Csharpから他アセンブリにはアクセスできるが、他アセンブリからAssembly-Csharpにアクセスすることはできない。 なので自分のコードに弄ったアセット側からアクセスしたい場合は、自分のコードをアセンブリ定義・分割して参照設定を追加するか、自分のコードをアセット側のアセンブリ内に入れる必要がある。 まあむしろアセットでアセンブリ定義・分割されてない方が色々と問題らしいので自分の経験は初心者特有の躓きって感じだな
32 :名前は開発中のものです。 :2023/09/10(日) 22:01:38.99 ID:pyk4erDp.net ところでヌシはタイトルには初心者って書いてるけど 所持がガベージとか気にしないよね? ナニモン?
33 :名前は開発中のものです。 :2023/09/10(日) 22:01:57.78 ID:pyk4erDp.net 所持ちゃう、初心者
34 :29 :2023/09/11(月) 07:46:22.08 ID:2rYAG6dH.net >>31 大量にオブジェクト扱う部分は全部Burst使ってるから重い部分ではGCAllocは発生してないし、まだ開発序盤で一時的にお試しで入れてるコードやシューティングと関係ないアセットなんかでGCAllocが出てるだけなので参考になりそうな数字は持ってないよ、申し訳ない
35 :名前は開発中のものです。 :2023/09/11(月) 21:22:14.79 ID:GchgKIS7.net >>34 なるほどありがとう 自分のゲームはだいぶ時間かかりそうだからその間にECSやバーストコンパイラーの仕様や情報が充実するといいなあ >>32 Unity歴5ヵ月弱の初心者だよ 今日はあまり何もしなかった 自作インベントリの検索機能を少し弄ったけど何となく前の仕様の方が使い勝手が良かった気がして結局コードを元に戻した 検索機能を処理する複数のクラスが絡み合っているので(密結合とはこういう状態?)、今後の保守や改良に備えてコードを見直した方がいいかもしれないと思った 自作スクロールの描画処理については既に一部をインターフェースや抽象クラスにしてあるので、検索機能も(今のところ予定はないけど)インベントリ以外に流用することを考えると同じように改良したい ただこの辺はコーディングや設計の思想について先に学ばないと結局グダりそうだね
36 :名前は開発中のものです。 :2023/09/11(月) 21:58:09.05 ID:dpI1L58C.net 歴5ヶ月でインタフェースや抽象クラスとか Unityは浅いけどC#は長い?
37 :名前は開発中のものです。 :2023/09/11(月) 22:31:07.12 ID:GchgKIS7.net Unity歴とC#歴は同じ プログラミングはキッズの頃にキッズ向け言語とRPGツクールのRGSS(Ruby)を少しやった程度 ただRubyはもう全く覚えてない
38 :名前は開発中のものです。 :2023/09/12(火) 22:16:09.67 ID:Agu+xwh8.net ジェネリックについての勉強を少し始めた 自作のスクロールを拡張する上で複数の型を扱うことになるかもしれないので、スクロールの抽象クラスに一部ジェネリックの抽象プロパティや抽象メソッドを実装して今後のコーディングを統一的にするのが目的 ジェネリックな関数には制約条件というものが付けられるそうなので、これでスクロールに渡すべき型に特定のインターフェースの実装を要求すればコーディングのミスも減りそう 逆に言うとこれも個人開発だとミスの防止という点以外の利点が分からん…もっと勉強が必要そうだ
39 :名前は開発中のものです。 :2023/09/12(火) 22:30:53.89 ID:DqJC+Tye.net すごいなぁ 自分はUnity半年あたりはやっと3DでUnityちゃんが動いて喜んでたわ それで満足してた(笑)
40 :名前は開発中のものです。 :2023/09/13(水) 08:16:34.64 ID:zrU2QrrP.net 俺も歴同じくらいでほぼほぼchatGPTに聞きながらやってるけど>>1 ほど理解せずに進めちゃってる キャラクターをステートマシンで動かしてるんだけど、抽象クラスとジェネリック使う機会あってほー便利だなあって思った気がするな
41 :名前は開発中のものです。 :2023/09/13(水) 22:19:12.03 ID:b/7dbaPf.net >>39 自分は2Dはスキップしてるからその分は早いかもしれないね 2Dの学習が必要かをUnity始める前に少し調べたけど、どちらかというと否定的な見解が多い印象で、UIの制作でどうせその辺やC#を扱う必要も出てくるだろうから最初から3Dで始めた >>40 ChatGPT便利だよなあ 厳密には自分はBingの会話AI(GPT4.0をウェブ検索用にチューニングしたやつ)を使ってるけど(無料だから) 無料版の3.5も試したけどBingと比べて誤情報や変なコードの出現率が高いから断念した ステートマシンって現在の状況をノードで繋いだステートを行き来して色々とするものだっけ?(無知) UnityのAnimator(mecanim)がステートマシンらしいからいずれ覚える必要があるし、自分の作ってるUIも段々と状況設定がゴチャゴチャになってきたからそういうのを勉強して整理しなきゃなあ
42 :名前は開発中のものです。 :2023/09/13(水) 22:19:25.85 ID:b/7dbaPf.net 今日やった作業は主に二つ @ディザ抜きを利用した障害物の透過 シェーダーアセットの基本機能を設定しただけ。キャラクターがワールド上の設置物の影に隠れて見えなくなってしまわないように、カメラ距離でディザリングを行うことで透けて見えるようにした。カスタムシェーダーにも対応してるアセットなので、勉強が進んだらキャラクターを隠しているか等の判定も加えてより高性能なものにしていきたい。 AUIを実装するクラスの整理 一昨日から引き続きUIのコードを整理した。アイテム欄クラスと検索欄クラスでそれぞれ大体同じ処理を実装しているので、既に継承させていた抽象クラス(基底クラス)を拡張して派生クラスで実装していたコードを半分ぐらい移植した。アイテム欄クラスと検索欄クラスでは扱うコレクションの型が違っていたので(アイテム欄クラスはアイテムのインスタンス、検索欄クラスはintを扱っていた)、この二つのクラスにコレクションを渡すインターフェースをジェネリックを使って<T>にすることで抽象クラス(基底クラス)で処理を統一できた。これを実現するためにジェネリックを調べていたようなものなのでひとまず満足。 ただ渡されたコレクションから描画すべき情報を取得する処理はまだ統一できていないので明日以降に挑戦してみる。 ところでUI(でも何でも)作り始める前にはちゃんと設計図を作成しないとダメだね 検索システムに「ミニメニューを開いて利用するから〜」というテキト−な理由でMiniMenuUIってクラス名つけたんだけど、ふとミニメニューにアイテム並び替え機能も欲しくなって「MiniMenuUI = 検索システム」じゃなくなってしまったから、クラス名を付け直しになった 付け直し自体はVisualStudioのフォルダ全体置換機能を使ってすぐに終わったんだけど(異なるクラスでもフィールド名を統一しておいたのが功を奏した)、純粋に面倒だし変更し忘れが残っていたらどんなエラー吐くかも分からんし設計はちゃんとすべきだと思いました
43 :名前は開発中のものです。 :2023/09/13(水) 22:27:45.47 ID:HTnl4o+9.net UIは何を使ってますん? UnityUIやMeshプロは将来無くなるとかで 自分はUIToolkitを勉強してます
44 :名前は開発中のものです。 :2023/09/14(木) 06:44:41.69 ID:A6Ctx0a0.net >>41 4.0も誤情報多いんで自分でも調べながらやってます 全く知らん分野に手を付けるとき基本的なアイデア提供してくれるのはありがたいっすね unityのアニメーターみたいなビジュアルスクリプト?もあるしコードでのステートマシンもあります 移動ステートクラスみたいなのを作って、それを抽象クラスにして敵用移動ステートとプレイヤー移動ステートみたいに作ってましたね でも冷静に考えると確かに抽象クラスじゃなくてまんま内容コピペして新しいクラス作ってもよくね?って思いましたね コードの冗長性はなくて読みやすくはなるかもだけど…
45 :名前は開発中のものです。 :2023/09/14(木) 21:12:02.73 ID:BQP80pEG.net >>43 普通のGUIだね GUIは将来無くなる訳じゃないよレガシー行きはするかもしれないけど UItoolKitにTMPが再整備されるまでまだ時間はかかるだろうしUItoolKitは学習コストに見合った性能や作りやすさはなさそうなんでしばらくはスルーするかな >>44 対話式AIはあとコード丸投げして処理追わせたり注釈つけさせるのも便利だね あと自分がちょっと慣れてきた分野で誤情報を見抜けると感動する() ビジュアルスクリプティングは有料アセットのもの? 今後のメンテも考えると共通事項はなるべく基底クラスにまとめておいた方がよいのかなとは思ってる 抽象クラスは今のところ個人開発だと「うっかりインスタンス化」「派生クラス毎に処理が大きく異なるメンバを実装強制して、うっかり実装し忘れ防止」の2つが主な利点なんだろうなあと考えている 単に共通事項まとめるだけから普通の基底クラスでもいいしね
46 :名前は開発中のものです。 :2023/09/14(木) 21:34:26.80 ID:BQP80pEG.net 今日の作業は相変わらずのUI実装クラスの整理 何かUnity Runtime Fee関係でだいぶキナ臭い動きが出てるから、当面は有料アセット購入はせずにUIとゲームシステム面の実装をするつもり 今後の同行次第で(有名なアセット撤退とか自分が覗いてる5ch外のコミュニティ閉鎖とか)ワンチャン3Dゲーからワールドマップのない2Dゲー(ゲームジャンル名が分からん)に目標変えて比較的短期でリリースして別エンジンに移行するかも ただ仮に言語が変わっても設計を考えておくのは絶対に役立つと思うから、ゲームシステムはUnityで完成させたい 今日の作業で気になった点 ①MonoBehaviourの必要性 UIにしろ何にせよ今のところ自分は大抵のクラスにMonoBehaviourを継承させてゲームオブジェクトにアタッチさせて使っているが、全部アタッチする必要性ってあるの?っていう単純な疑問が生じた というのもMonoBehaviourを利用しないデザインが~みたいな話をしばしば耳にするので… MonoBehaviourはAwakeやUpdateみたいなマジックメソッドを利用できるようになる利点はたしかにありがたいのだが、ゲームオブジェクトやクラスが増えてくると管理が面倒になってくるので、特定のゲームオブジェクトのライフサイクルと一蓮托生ではない・又は便宜的にゲームオブジェクトと一体になっていると分かりやすい(例えばキャラクターと所持アイテムみたいに)クラスのインスタンスはnewで作ったほうがいいんじゃないか?と感じたり 今後ゲームシステムを作っていく上では更にMonoBehaviourの機能を使わないクラスも増えてきそうなので、この機会に少し調べてみた方がいいかなと思った
47 :名前は開発中のものです。 :2023/09/14(木) 21:45:06.99 ID:BQP80pEG.net ②クラスのインスタンスのメモリ使用量 自作のアイテムクラス(のインスタンス)はint型フィールドを複数持っている 最大で1万個はアイテムを所持できる想定なので、メモリ圧迫やセーブデータの軽量化を考えるとまあなるべくインスタンスのサイズも小さくしておきたいとは考えている そこで前にフィールドのint型(4バイト)をShort型(2バイト)に変えてみたのだが、プロファイラで雑に確認した限りではメモリ使用量に変化はなかった 数値の型のメモリは単純に半分になったのに変化しないのは何故だろう?と当時は思っていたが、どうもクラスのフィールドとして数値が入っているので、クラスのインスタンスをヒープメモリに配置する時に取りだしやすいよつにサイズが整理されてその際に単純計算したメモリ使用量と比べてサイズが拡張されるらしい これかもしれない(ちゃんと調べてない)
48 :名前は開発中のものです。 :2023/09/14(木) 21:51:03.03 ID:t6pji0Zs.net レガシー行きって何か怖いのよね(笑) 自分はUIToolkitにしてウェブみたいな作り出来るから画面サイズ気にしなくて楽になりました メモリ関連はよーわからんけど宅さんあるときはdictionaryかなぁ
49 :名前は開発中のものです。 :2023/09/15(金) 21:07:15.26 ID:Fj2wueol.net >>48 Dictionaryは個別の値へのアクセスは早いけど高性能な分メモリ使用量は多いよ 配列やリストはメモリ使用量は少なめでIndexでのアクセスは早いけど、個別の値の検索や削除が要素数に比例して遅くなるから多数のアイテムを管理するシステムには不向きな印象がある 明日は久しぶりにコレクションについてまとめてみるか 今日は抽象クラスの整理はひとまず終わったので次に作るUIの設計を考えた クラス間の結合を弱めるにはインターフェースやZenject(外部ライブラリ)が有効だそうだが、導入には一手間かかりそうだなという印象 インターフェースはUnityの標準機能じゃインスペクターから設定できない(オーディンインスペクターという有料アセットや外部ライブラリを利用すれば一応可能)のが残念 それとインスペクターで参照を設定するのだと結局ゲームオブジェクト(MonoBehaviour)同士の結合は緩められてない気がする 「クラスAに機能を追加・修正・削除したから、クラスBの該当部分も直して~」っていう作業から抜けたいなあ
50 :名前は開発中のものです。 :2023/09/15(金) 21:24:06.03 ID:hZKK5Ca7.net 因みに今のパソコンでそのディクショナリのはやさとかメモリとかどれだけ影響あるのでしょうか? 最後の文章見ると個人開発じゃなくてグループ? このメモは一体、、、
51 :名前は開発中のものです。 :2023/09/15(金) 21:52:15.68 ID:Fj2wueol.net 個人開発だよ 「直して〜」の「〜」は呼びかけじゃなくて以下ループとかそういうニュアンスのつもりだった 大量のデータを扱うコレクション(配列とかリストとかディクショナリ)の場合はどのコレクションを選択するかで処理速度は顕著な差が出るね 前に実験したことあるけど、1万個の所持アイテム用インスタンスを格納した@List<自作クラス>とADictionary<int,自作クラス>で一番最初に入手したアイテム(ListではIndex0、Dictionaryではint型キーを連番になるように制御して格納しているのでこれもキー0になる)を削除する処理を行った場合 @Listだと500msぐらいかかる一方で、ADictionaryだと0.1msで終わる これはListでは内部的には配列に特殊な処理を加えて自由に挿入・削除のできるコレクションに仕立てているから、削除関数であるRemoveAt()を実行すると削除した要素Indexの後ろに並んでいる要素たちを全部1つずつコピーして前に詰める作業が内部的に行われると全体の要素数が増えるにしたがってクッソ重くなる 一方でDictionaryは内部ではハッシュテーブルを利用していて、与えられたキーをハッシュに変換する作業がある代わりに基本的に要求された要素だけを参照しに行くから、全体の要素数が増えても処理速度に対して影響は出ない メモリ使用量についてはモバイル端末想定じゃなきゃまあ誤差だとは思うけど可能な限りは軽くしたいね
52 :名前は開発中のものです。 :2023/09/16(土) 21:40:31.42 ID:OFNct1/O.net コレクションについてまとめようと思ったけど別のことして忘れてた とりあえず今日はメニュー画面の作成を進めた 今日から作成を始めたメインメニューはクラス間のシリアライズによる参照は使わずに、イベントとリスナー登録で情報のやり取りをしようと考えている 一般的にイベントでやり取りをする方法は、クラス間でお互いの内部実装に無関心で済むため(イベントの発火がされなければ待機しているだけで、引数を受け取ってどう使うかも自由)、疎結合に分類されるらしい まあシリアライズの代わりにデリゲートへの関数のキャッシュとリスナーの登録をコードで行う必要があって、更に複数のリスナーが存在する場合は実行順序の制御も別所で必要になるので、インスペクターからシリアライズで参照設定をしてグチャっと処理コードを書いた方が短期的には楽に見えるのはナイショ
53 :名前は開発中のものです。 :2023/09/16(土) 22:33:48.81 ID:GeGtMKJg.net やべぇー なんか、高度すぎて 分からん
54 :名前は開発中のものです。 :2023/09/17(日) 22:58:20.80 ID:SjciO0EV.net 基本的に実装したい処理が思い浮かんだ時に必要そうな処理を基礎からその都度調べているだけよ 地道にUnityやっていけば必ず到達できるレベルでしかないからガンバレ 本日の作業もメニュー作り 静的イベントを利用してクラス間のやり取りをするうちに気になったのが、イベントとゲームオブジェクトのライフサイクルとの関係性 メインメニュー → 「装備」ボタンを押すと静的イベントを発火 → リッスンした装備メニューのマネージャークラスが装備メニューをSetActive といった流れを実装したかったが、テストプレイすると「装備」ボタンを押しても装備メニューが起動しない 原因は、装備メニューのマネージャークラスがアタッチされたゲームオブジェクトが無効化されていたためっぽい 無効化されたゲームオブジェクトの関数を外部からコールすることは可能だが、無効化中にはイベントのリスナーとしてコールバックを行うことはできないようだ 確かにゲームオブジェクトにアタッチされたクラスはUpdateなどのマジックメソッドが呼び出されないが、厳密にはこれらもランタイムから呼び出されている訳で、外部からコールされている状態に近いように思える イベントのリスナーとしてのコールバックもEventHandler?が呼び出しているらしいので、「ゲームオブジェクト」のライフサイクルにはこれらの仕様を変更する(というか、制限された仕様のインスタンスをUnityが提供している?)ようだ まあ面倒な理屈はともかく、イベントでやり取りするクラスは発火前にゲームオブジェクトを有効化しておくか、MonoBehaviourを利用しないクラスとして設計しましょう、というのが今日得た結論となる
55 :名前は開発中のものです。 :2023/09/17(日) 23:04:46.48 ID:aXQbPdAS.net それセットアクティブじゃなくて Enableでは?
56 :名前は開発中のものです。 :2023/09/17(日) 23:08:19.89 ID:SjciO0EV.net いやイベントのリスナーになっているクラス(コンポーネント)がアタッチされているゲームオブジェクトが無効化されているとコールバックが行われないっぽのよね コンポーネントじゃなくてゲームオブジェクトだからSetActiveの話
57 :名前は開発中のものです。 :2023/09/18(月) 12:08:45.30 ID:RKiVL9Tq.net l_i_t_e(邪魔という方は左記をNGお願いします) 更にご家族に教えて加えて¥4000×人数をGETできます! https://i.imgur.com/l61BDyt.jpg
58 :名前は開発中のものです。 :2023/09/18(月) 13:39:48.69 ID:YQ8UtnvT.net >>57 もう現金に換えてアンインストした
59 :名前は開発中のものです。 :2023/09/18(月) 16:11:22.17 ID:ylIv/p+P.net 普通なら削除依頼出しとけよって定型文貼られるようなスレだけど 技術者多い板の性質と真面目な内容が組み合わさって技術メモブログのように存在を許されている
60 :名前は開発中のものです。 :2023/09/18(月) 16:34:27.70 ID:GrWZQeuh.net 絵描き板とかである個スレみたいなもんでしょ 過疎板にはよくある
61 :名前は開発中のものです。 :2023/09/18(月) 22:31:41.35 ID:+Uz7sHbq.net アウトプットも兼ねて覚えたこと書き殴りたくなる機会がたまにあるんだけど、Unityの制作面中心の雑談スレが見当たらなかったからノリで立てちゃったのよねすまん 代わりに毎日何かしらは作業する・調べるように努力してます 今日気になったこと ・ジェネリックの扱い方 ジェネリックと抽象クラスを利用してUI関係の整理を続けていたが、独自セレクタブルたちが引数の型の異なるRefresh関数(描画情報を更新するために管理クラス側からコールされるpublicな関数)をそれぞれ持っており、これをどうやって統一するか悩む 統一すること自体は抽象クラスにRefresh関数自体をジェネリック<T>で抽象メソッドとして宣言すれば簡単にできるのだが、そうすると同時セレクタブルたちの型が抽象クラスとしても異なってしまうため、管理クラス側から独自セレクタブルたちの配列を扱う時にその型(内部実装)を知る必要性が出てきてしまうように思える インターフェースでよくないか?とも思ったのだが、インターフェースはUnityの標準機能ではシリアライズ化できないし、キャストしたりGetComponentで具体的な型を指定しないと多分Transform等にもアクセスができないしどうしたものか 抽象クラスの基底に更に抽象クラスを宣言すれば何とかなるのかな…明日以降検証してみる ちなみにコレクションの復習はまだ出来ていない というかUIのクラスとレイアウト周りの整理が中心で、検索システムとか内部面は一段落したので暫くコード書くときにコレクションに触れてない アイテム合成とか敵からのドロップテーブル等を実装する時にまた考えるかな(10月以降)
62 :名前は開発中のものです。 :2023/09/19(火) 22:19:31.36 ID:CqPMq7Md.net 今日の作業 ・独自の派生セレクタブルの処理を抽象化するためにRefresh関数の引数をint型に統一することに決定する。int型以外を引数とするクラスはコード全体を見直す必要が出てきたので数か月前の設計のガバさのツケが回ってきた形。 ・MonoBehaviourを継承しないクラスに[Serializable]を付けて、このクラスをフィールドとして保有するMonoBehaviour継承クラスのインスペクターから値を弄れるようにしてみた 基本的な使い方だけどスクリプタブルオブジェクト以外で[Serializable]を利用してこなかったのでちょっと感動 ・ノーコード系ゲーム制作アセットの戦闘システムに自作の拡張機能を追加した。攻撃時に攻撃者と被害者をそれぞれ独自戦闘システムインターフェース型でGetComponentしてダメージ計算など色々な処理をスクリプトから行う 有料アセットのテンプレートは便利だけど、個人的にはノーコード系のノードやリスト形式の命令処理は何となく苦手 VisualStudioで素直にC#書いた方が楽だし処理も追いやすい気がしてならない ・「今日の疑問」について調べている時にDictionaryのTryGetValueを使えばキーの存在確認と値のチェックを両方できることを知った というか前に調べて覚えたつもりだったけど忘れていた 嫌な予感がして自分のコード見てみたらContansKeyとDictionary[]を両方使って二重にDictionaryを走査している箇所が案の定見つかった out系の使い方がよく分からなくて昔は見かけてもスルーしていた記憶がある(RayCastとかTryGetComponentでもoutはしばしば出てくる。何なら3D空間上の計算をするゲームでは頻繁に見かけそう) ちゃんとやり方覚えなきゃなあと思いました 今日の疑問 ・GetComponentはしばしば重いと言われるが実際問題どの程度使うとボトルネックになるのだろうか?1フレームに30回程度じゃプロファイラーを見る限りでは全く問題にならない程度の負担しかない まあキャッシュしておけばいいものを毎度取得しに行くコードの存在自体が不適切な印象は否めないが
63 :名前は開発中のものです。 :2023/09/19(火) 22:23:27.79 ID:iPzaBk+A.net ゲットコンポーネントは重くないでしょ それは公式でも書いてると思うけど Updateでやっちやあかんって
64 :名前は開発中のものです。 :2023/09/20(水) 03:37:28.78 ID:ncaLFBeu.net 「Unityでよくある失敗」はコードを書く習慣がある層ならUnity初学者でも回避するよう内容が多いな GetComponentとFindを周期処理のなかに書くなんぞ最たるもんだな
65 :名前は開発中のものです。 :2023/09/20(水) 22:16:05.72 ID:6f4RNUvQ.net >>63-64 必要ならキャッシュしておいた方がいい、との記述はあるものの https://learn.microsoft.com/en-us/windows/mixed-reality/develop/unity/performance-recommendations-for-unity?tabs=openxr 色々な人の検証結果を見る限りはGetComponentを1フレーム内で数万回繰り返しても、処理時間はそれ自体ではぶっちゃけ殆ど差が出ないみたいだね そう考えると実はUpdate内で毎度呼び出しても現実的なボトルネックにはならないんだろうね ある意味「GetComponentは重いぞ神話」が独り歩きしている状況かもしれない 自分は基本的にその場限りで利用する場合以外はキャッシュするけども
66 :名前は開発中のものです。 :2023/09/20(水) 22:21:25.16 ID:6f4RNUvQ.net 代わってGameObject.Find系は本当に看過できないほど重いようだ ゲームオブジェクト全体を走査する系の処理は重いのは感覚的にもよく分かる 同じくゲームオブジェクト全体にメッセージを送信するSendMassageも滅茶苦茶重いらしくてMicrosoftのDocには 「SendMessage() と BroadcastMessage() は、どんな犠牲を払っても排除されるべきです。これらの関数は、直接関数呼び出しよりも約1000倍遅くなる可能性があります。」(google翻訳) って書いてあって草 素直にUnityEventsかC#Eventを使うのが安心だな
67 :名前は開発中のものです。 :2023/09/20(水) 22:22:45.41 ID:9mke4B6g.net おそらくはまだCPUがショボい頃の事が今でも尾を引いてらのかもね
68 :名前は開発中のものです。 :2023/09/20(水) 22:30:35.83 ID:6f4RNUvQ.net >>67 あと可能性があるとしたら、TransformへのアクセスはUnityのバージョンアップで最適化がされたことがあるそうで、GetComponentもそうなのかもしれん(調べてない) ・今日の作業 今日の作業は昨日と変わらず、重い処理関係以外で特に何も調べたりはしなかった 引き続き設計思想の話としては、インスペクターから値・参照を設定・確認できるのは便利である一方で、Unityに慣れるにつれてインスペクターから設定しなくてはならないのはコードとインスペクターの双方を行き来する必要があって面倒だとも感じてきた UnityにはEventTriggerなど便利なコンポーネントが存在しているが、一部は自分でスクリプトを組めば代替できるものもある GameObject.Find系が推奨されないもう一つの理由として「制作途中の仕様変更に弱い」という指摘があるが、これにはコードとインスペクターだけではなくヒエラルキーも動作確認の際にチェック対象になってしまう煩雑さを回避したいという願いが暗に含まれていそうだ
69 :名前は開発中のものです。 :2023/09/21(木) 22:13:15.68 ID:+9E6IOzm.net 今日は自作のインベントリシステムに並び替え機能の実装を始めた List.Sortで自作クラスをソートするにはIComparableインターフェイスを継承してCompareTo関数を実装するか、又はラムダ式で直接ソート順を指定することでも可能となる ラムダ式は匿名関数を作成するもので、内部的には最初に実行される時のみnewされて関数が生成されてそれ以降はコンパイラが自動的にそれを使い回してくれるそうなのでアロケーション面でも優しい Unityでお世話になる時は大体ソート関係な気がする
70 :名前は開発中のものです。 :2023/09/22(金) 02:12:08.27 ID:2ujM814X.net Linp使えるからSQL的なSelect,Whereなんかも使ってもいいね
71 :名前は開発中のものです。 :2023/09/22(金) 02:14:29.74 ID:2ujM814X.net すまんLinqだスマホだから打ち間違えた そしてpもqもパッと見見分けつかんからそのまま送信してしまった
72 :名前は開発中のものです。 :2023/09/22(金) 21:58:51.05 ID:TT/FNhBR.net >>70 LINQは便利そうな機能が一通り揃ってるのね ただ前に使ってみた時に(どの関数かは忘れた)素直にForやForeachでやるのと比べて凄い量のアロケーションが出てたから使うのやめちゃってたわ インベントリ内アイテムの並び替えみたいな、そう頻繁に行われない処理にはLINQの使用を再検討してみようかな 直接並び替え用の式を書くと後で見た時に大抵「何だっけこれ…」ってなるから…(まずコード上の注釈を再読む所から始まる) 今日も並び替え機能の実装を進めた そういえばクラス間の情報のやり取りで静的イベント(public static event Action<>〜)はよく使っているけど、Funcはまだどこにも利用してないと思った がChatGPTによるとFuncはリスナーが複数いる場合に戻り値にどのリスナーからの値を使用すべきが不明瞭になるから使っちゃいけないらしい よく意味が分からなかったので明日以降検証したい そもそもこの疑問が浮かんだのが作業が終了してからなのでVisualStudio上でコード自体が適切にコンパイルできるのかすら試してない
73 :名前は開発中のものです。 :2023/09/22(金) 22:10:05.72 ID:1GHnfQ7l.net 適切にコンパイルされたか否かって何かToolとかあるんです?
74 :名前は開発中のものです。 :2023/09/23(土) 13:04:32.12 ID:pGEksIgm.net >>72 たしかにLinqは便利な分最適化には程遠いかも
75 :名前は開発中のものです。 :2023/09/23(土) 17:27:46.55 ID:bmDBxj8t.net >>73 いや分からない(知らない) コンパイルすら通らないのかコンパイルは通るけど使い方間違えると実行時エラーでるのかが分からないからそう書いただけ >>74 便利だけどゲームだと使い道が難しそうな印象があるなあ 今日の作業で久しぶりにLINQ使ってみたけど、FindAllしたら新しいList<T>インスタンスが戻り値として生成されるみたいで結構な量のアロケーションが発生しちゃった Forで要素0からループで走査して条件一致する度にグローバルな使い回し用リストにAddするとアロケーション無しになる ただインベントリのアイテム内を並び替えるだけの処理で戦闘中とかフレームレートが必要な場面で呼び出されることは想定してないから、まあ実際にプレイに影響は出ないとは思うけどね
76 :名前は開発中のものです。 :2023/09/23(土) 17:50:57.84 ID:bmDBxj8t.net そういえばFuncでリスナー複数いるとどうなるの?問題についてちょっと検証してみたそういえばFuncでリスナー複数いるとどうなるの?問題についてちょっと検証してみた using System; using UnityEngine; public class TestClass : MonoBehaviour { // 静的アクション public static event Func<int,int> testFuncEvents; // シリアライズフィールド [Header("Funcテスト")] public bool startFuncTest; public int FuncTestArg; public int Returnvalue; public int? Result { get => Returnvalue; set { Debug.Log("Resultプロパティが呼ばれました 戻り値は"+value); if(value.HasValue) Returnvalue = value.Value; } }
77 :名前は開発中のものです。 :2023/09/23(土) 17:51:54.28 ID:bmDBxj8t.net 改行と文字数の限界でコード貼るのは無理か 結論としては ? 変数に代入される戻り値は一番最後に登録されたリスナーのものになる ? 最後のリスナーのみがプロパティをコールする。リスナーは3人いるのにプロパティは1回しかコールされなかった(リスナーは3人ともデバックログが出たが、プロパティは1回しか出なかった) ? nullはnullじゃない文字列と連結しようとすると空白になるが、単体又はnullと連結しようとすると文字列はNullになる まあリスナーの管理が面倒だからたしかにChatGPTの言う通りFuncはイベントで扱うべきじゃないのかも?
78 :名前は開発中のものです。 :2023/09/24(日) 22:38:55.38 ID:S8roHB1T.net 今日の作業はクラスの設計を考えた 「カプセル化」をすることでクラスを他の処理にも再利用できるので、静的イベントやインターフェースを駆使して様々な「選択」が必要なUI画面で利用できる独自セレクタブルを作りたい
79 :名前は開発中のものです。 :2023/09/25(月) 21:40:56.58 ID:Lma5XPF1.net 今日はグラフィック関係をやっていてコードにあまり触れてないので調べ物はナシ! enumのSwitch式だかSwitch文だかをもう少し書きやすくする方法ないかなとは思ったり
80 :名前は開発中のものです。 :2023/09/26(火) 21:52:51.98 ID:2Scqx0S0.net 制作が軌道に乗ってくるとメモすることがなくなるんだよな 既に調べた知識で作り続けるだけだから だいぶ先になるけど有料アセットのうちFinalIKとEasySaveは詳しく使い方を覚えたいし覚えたら書くかねえ 特にFinalIKはUnity標準のメカニムとどのくらい共用できるのか知りたい
81 :名前は開発中のものです。 :2023/09/28(木) 22:06:34.28 ID:dc32lg9p.net 製作順調なら製作進捗でもいいんだよ
82 :名前は開発中のものです。 :2023/09/29(金) 19:51:15.97 ID:4YW0vA30.net >>81 それはアリだねただ一応秘密で作ってるんでどこまで内容書くかは悩みどころだが 今やってるのはアイテム合成システムの設計 合成時に素材の特殊能力を引き継ぐのだが、異なる特殊能力同士が合体して新たな特殊能力に変わるシステムをどうやって実装するか考えている 一番手っ取り早そうなのは、 ①素材アイテムの特殊能力をコレクションに格納する→②コガネブログからお借りした組み合わせ列挙拡張メソッドを使って事前に指定した合体組み合わせに該当するか調べる→③合体組み合わせが不存在になるまで繰り返す かなと思っている
83 :名前は開発中のものです。 :2023/09/30(土) 07:12:12.43 ID:HN5eRe95.net 俺もちょうど合成システム作ってるとこでビビった 俺は2つのarrayをソートして、比較する単純なものだけど…
84 :名前は開発中のものです。 :2023/09/30(土) 22:25:15.09 ID:AozLAQh5.net >>83 合成が合成システムを実行したその1回しか行われないならそのやり方の方が楽そう 自分のは合成して特殊能力が合体した際に次レベルの合体条件も満たしていたら順次合体を繰り返していく機能を想定しているから、配列やリストを何回も走査すると重いかもなあという懸念がある ただコガネブログのも合体成立時に何回も呼び出すと重そうなので、素材アイテムの持つ特殊能力の管理番号全てをHashSetに入れて、差集合とAddを使って合体組み合わせを探していくのもアリかも こればっかりは自分の設計に合わせて複数のコードを組んで検証してみるしかないね
85 :名前は開発中のものです。 :2023/10/04(水) 01:17:36.07 ID:1pamoYKo.net おや?停滞? 良スレかと思ってたが、中途半端に投げ出す感じな
86 :名前は開発中のものです。 :2023/10/04(水) 17:41:48.36 ID:DAn/y1Is.net 今は既に調べておいた知識でゆっくり作っている状況だから特に書くことが無いのよね グラフィックス関係の勉強もしてるんでそっちに多く時間を割いてるのもある 一応調べたことの備忘のスレのつもりなんで、何も調べてないのに毎日作業内容を報告するのもなんか違うと思うし あと単純に最近安定して5chが見られなくないか? 基本的にメモは作業用ではないPCのEdgeで書いてレスしてるけど、今もまたスレが開けなくて内容ドライブ経由でコピーしてスマホからレスした 今やってる作業はアイテム合成システムのクラス設計、メニュー画面・装備画面UIの作成あたりかな ゲームシステムについての最近考えている事は ・アイテムの購入・売却の実装 既にエクセルデータをスクリプタブルオブジェクト化して売値・買値等のデータを取り込んである & プレイヤー以外もアイテムを所持できるようにプレイヤー・NPCの共通基底キャラクタークラスに所持品クラスのフィールドと取得用インターフェースを実装済み、装備画面UIの作成時に抽象クラスとインターフェースを利用して割と再利用性を高めてある(つもり)なので、作成自体はそこまで難しくなさそう。 アイテム売る商人の持つアイテムデータは、アイテムインスタンスクラスに[Serializable]を付けてキャラクタークラス→所持品クラス→アイテムインスタンスで開いてインスペクターから直接設定するか、又は何らかのコレクションで値だけインスペクターから設定してStart関数でアイテムクラスのインスタンスをnewしてコンストラクタにその値を渡してやればよさそう ただそもそもゲーム内に商人を実装するかは未定 ・3Dのゲーム性を採用するか 購入済みのノーコード系アセットがパフォーマンスの向上目指して改修されるそうなんでやっぱり使ってみたい感がある(気持ちの問題)。 あとこのアセットがasync/await使ってる所為でアセットの機能にアクセスするとそれなりにGC発生するんだけど、将来的にはUnityにも.NET5のAsyncValueTaskが導入されたら更にパフォーマンス向上するかも(非同期処理のこと全然分かってないので自分でアセットのコアコードをUniTaskに置き換えるのはまだ怖い)
87 :名前は開発中のものです。 :2023/10/04(水) 17:42:01.17 ID:DAn/y1Is.net C#・Unityの勉強としては ・非同期処理 上でも書いたがよく分かってない。今作っている範囲だと用途は少なそうだけど、唯一「アイテムを大量に捨てる場合」に役立ちそうな気がしている。 というのもアイテムを捨てる際には自作のアイテム管理クラスのアイテム破棄の関数をコールするのだが、検索システムに備えて入手時にコレクションへの登録を沢山しているので破棄時には逆にコレクションからの削除を行う必要がある アイテム捨てる処理は入手処理と違って新たなインスタンスはほぼ生成しないのでGCの問題はないが、単純にコレクションへのアクセスが多いのと、プレイヤーが何百・何千個ものアイテムを一気に捨てることができるUIを組んでしまったので大量にアイテム破棄を行うと余裕で60fps割ってしまう。また所持品管理ディクショナリーの参照が切れるのでアイテムインスタンス自体もガベコレの対象になるのでガベコレによるスパイク発生の危険性も高くなる。 そこで非同期処理を用いてフレームを分散してアイテムの破棄を行えば、捨てる処理自体のスパイクは軽減できるかなと思った プレイヤーは1f単位で処理を認識している訳ではないので、内部的には数fに分離しても多分気が付かない(あまりに重い場合は「アイテムを捨てています」等の進捗を画面に表示した方がよさそうだけど) 非同期処理はコルーチン、async/await、UniTaskあたりが有名なのかな?性能でいえばUniTask一択なんだろうけどまずはコルーチンから試してみようと思っている(GCは知らない)
88 :名前は開発中のものです。 :2023/10/07(土) 18:13:33.15 ID:zKcOYlJC.net 自分はインボーク、インボークリピートをもっぱら使うなぁ
89 :名前は開発中のものです。 :2023/10/07(土) 21:08:01.13 ID:AbV00O8h.net >>88 InvokeやInvoke.RepeatingはMonoBehaviourの機能だから個人的にあまり使いたくないなあと思ったり(他のクラスに移植したり仕様変更する際に面倒そうなので…) 引数にstring型使うからアロケーションも心配 ただアタッチ先ゲームオブジェクトだけで完結する処理ならそれが手っ取り早そうだね
90 :名前は開発中のものです。 :2023/10/07(土) 21:19:34.52 ID:iuLYjSS8.net でも引数はメソッドの名称だからアロケーション発生しないんじゃね?
91 :名前は開発中のものです。 :2023/10/07(土) 22:01:39.06 ID:AbV00O8h.net >>90 エディタ上でテストプレイしてみたけど。確かにMonoJIT以外でのアロケーションは発生しないね 原因について雑に調べたけど、もしかしたら文字列リテラルだからコンパイル時に生成・メモリに格納されて一致する限りは使い回しがされるからっぽい
92 :名前は開発中のものです。 :2023/10/07(土) 22:01:43.61 ID:AbV00O8h.net >>90 エディタ上でテストプレイしてみたけど。確かにMonoJIT以外でのアロケーションは発生しないね 原因について雑に調べたけど、もしかしたら文字列リテラルだからコンパイル時に生成・メモリに格納されて一致する限りは使い回しがされるからっぽい
93 :名前は開発中のものです。 :2023/10/07(土) 22:23:13.50 ID:ABeNJcDO.net 潔癖症みたいやねそこまで気にするのって
94 :名前は開発中のものです。 :2023/10/08(日) 09:30:28.99 ID:raa6/Dtd.net 非同期処理はコルーチンしか使ったことないや
95 :名前は開発中のものです。 :2023/10/08(日) 21:22:41.79 ID:9d1oOF7A.net >>93 GCallocは削れば削るだけ良いからね 自分はECSを使うのは現状では無理そうだから削減可能な場所は全て対応するようにしている >>94 MonoBehaviourで非同期処理を扱うならコルーチンが入門な感じがあるね 返し値を扱うのが面倒そうなのが難点だけどそれでもUniTaskよりはとっつきやすそう(偏見)
96 :名前は開発中のものです。 :2023/10/08(日) 21:32:09.46 ID:RWVJHt61.net 今のパソコンというか環境でも やはりけづれる物は削る方がいい? 初心者とかそこまで考える必要はあるのかな?
97 :名前は開発中のものです。 :2023/10/09(月) 14:29:55.33 ID:rvC4W/MI.net >>96 明らかなボトルネックや安定した後の最適化ならともかく、開発中はできるだけ素直でメンテナンスしやすいコードの方が良いよ
98 :名前は開発中のものです。 :2023/10/25(水) 17:52:32.75 ID:lBkP/TA2.net 進捗どうですか?
99 :名前は開発中のものです。 :2023/11/15(水) 23:27:25.96 ID:Qaq3TktU.net エタったか 無駄なスレ建ててまで書くなよ
100 :名前は開発中のものです。 :2023/12/08(金) 13:29:57.09 ID:UU5wTPU9R 国会でいい感じに質問してる優秀な議員を見かけて維新かと思ったら立憲だったわ 立憲は憲法の下の平等も世代による公平もガン無視の児童給付だの税金泥棒主張をやめて藤岡隆雄氏みたいなのだけにしろよ 子を育てられるだけの金もないのに孑を産み落としたら遺棄罪で逮捕懲役.日当5千円て゛塀の中から子に送金させるのが筋だろうに 犯罪者に追い銭とかモラルハザ−ドいい加減にしとけ、風俗で働いて子育てしてる自立した女なんていくらでもいるだろうにそんな女と 陳情寄生蟲女と温室効果ガスに騒音にコロナにとまき散らして他人の権利を強奪して儲けてる空飛ぶ強盗殺人女、クズっぷり比較しろ 国が介入するならひとり産み落とすこ゛とに数千万課税して払える見込みがなければ逮捕懲役にしたり親権廃止するくらいだろ 1か月も男と暮らしてた某JKなんて家出だろうに問答無用で逮捕されたんだろな哀れ、その男が充分な金を持ってて責任を持てるなら 毒親と居るより幸せなのは明らかなんだし親を捨てて余裕ある家に行くことを合法化するのか゛税金泥棒より理に適ってるのは明白 (羽田]Ttps://www.call4.jp/info.php?tyРe=items&id=I0000062 , ttps://haneda-projeCt.jimdofree.com/ 〔成田)TТps://n-souonhigaisosyoudan.amеbaownd.Сom/ [テロ組織)тtps://i.imgur.com/hnli1ga.jpeg
60 KB
新着レスの表示
掲示板に戻る
全部
前100
次100
最新50
read.cgi ver 2014.07.20.01.SC 2014/07/20 D ★
本文 スレッドタイトル 投稿者