質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.32%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

1回答

361閲覧

Unity アップグレードシステムの実装が分からない

kaaak496

総合スコア8

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

1クリップ

投稿2025/02/25 11:27

編集2025/02/26 00:28

こうしたら良いんじゃないかという、短い回答でもいただけると嬉しいです。

実現したいこと

現在Unityでローグライクゲームを作っています。
まず、ゲーム本編の戦闘などが行われるメインシーンと、そのメインシーン外で、プレイヤーの強化アイテムなどを買えるショップシーンがあります。
基本的な処理の流れとして、
①ゲーム起動時に初期ステータスを読み込む
②所有する強化アイテムによって強化されたステータス(以下、ショップステータス)を記録・表示する
③メインシーンでレベルアップなどにより強化されたステータスを記録・適応する
④メインシーンが終了したらショップステータス戻す。
ということをやりたいと思っています。
現状、
①については、入れ子構造のScriptable Object(GameStatus)によって初期ステータスを設定しています。イメージ説明
今のところ、ショップおよびレベルアップでの強化は実装しておらず、仮の実装として、上で挙げたスクリプタブルオブジェクトをアタッチして、メインシーンの処理だけを実装しています。
また、Scriptable Objectはマスターデータとして変化させたくないです。

発生している問題・分からないこと

そこで、始めは
スクリプタブルオブジェクトに含まれるデータを全てクラスにコピーして、そのコピーされたデータを書き換え、そのコピーされたデータを変更するようにしようと思いました。
しかし、それではScriptable Objectを使う必要はないし、何よりデータ管理がものすごく面倒になってしまいそうでした。試したら実際にそうでした。

何か他にいい方法はないものでしょうか。

ちなみに、今は、スクリプタブルオブジェクトをコピーして...というくだりを作成する前の状態に戻してあります。

該当のソースコード

参考として、GameStatus.csとそこに格納されるもののひとつであるBulletData.csを貼り付けました。

GameStatus.cs

csharp

1using System; 2using System.Collections.Generic; 3using UnityEngine; 4 5[CreateAssetMenu] 6public class GameStatus : ScriptableObject 7{ 8 [Header("!! Input Default Status !!")] 9 [Space] 10 11 public List<PlayerData> playerDatas = null; 12 13 public List<EnemyData> enemyDatas = null; 14 15 [Space] 16 public int bulletIndex; 17 public List<BulletData> bulletDatas = null; 18 19 public int NWayCount; 20 [NonSerialized] public int NwayCount; 21 22 public float SpreadAngle; 23 [Space] 24 25 public List<DefenceData> defenceDatas = null; 26 27 public List<ReinforceData> reinforceDatas = null; 28} 29

BulletData.cs

csharp

1using System.Collections; 2using System.Collections.Generic; 3using UnityEditor.Purchasing; 4using UnityEngine; 5 6[CreateAssetMenu] 7public class BulletData : ScriptableObject 8{ 9 public GameObject bulletObject; 10 11 [Header("Common")] 12 public BulletType bulletType; 13 14 public BulletSide bulletSide; 15 16 public float bulletScale; 17 18 public float bulletSpeed = 5; 19 20 public float bulletATK = 1; 21 22 public float fireRate = 5; 23 24 public bool isHoming = false; 25 public float homingPower = 10f; 26 public float homingDuration = 5f; 27 28 public int bulletPenetratCount = 0; 29 30 [Space] 31 [Header("Explosive")] 32 public float explodeATK; 33 public float explodeRange; 34 [Tooltip("この距離まで近づくと爆発")] 35 public float explodeDistance; 36 public float explodeSpeed; 37 38 [Space] 39 [Header("Laser")] 40 public float damageRate; 41} 42 43public enum BulletType 44{ 45 Normal, 46 Explosive, 47 Laser 48} 49 50public enum BulletSide 51{ 52 Friendly, 53 Hostile 54} 55

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

「Unity データ管理 ローグライク」、「unity アイテム強化 -学習」などとググってみましたが、ショップでの強化とメインのゲームでの強化を行っている例はほとんど見つかりませんでした。

chatGPT(o1, o3-mini-high, GPT4)に諸々聞いたのですが、
有効なアドバイスは得られませんでした。

補足

Unity 2022.3.15f1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

teratail

2025/02/26 02:33

kaaak496様 いつもご利用ありがとうございます。teratailサポートチームです。 昨日18時頃より、画像が正しく表示されない不具合が発生しておりました。 先ほど修正が完了し、現在は正常に画像を投稿・閲覧いただけます。 ご迷惑をお掛けし申し訳ございません。 画像を表示するには、質問を「編集」して画像を再度挿入していただく必要がございます。 お手数をおかけしますが修正いただけますと幸いです。 今後ともteratailをよろしくお願いいたします。
JunSuzukiJapan

2025/02/27 12:43

PlayerDataクラスのソースコードはどうなってますか? あと、ショップで購入する(?)アイテムのクラスはどういう感じになってますか? プレイヤーステータスの話なのですから、肝心のPlayerDataクラスを見てみないと回答しようがないです。
guest

回答1

0

(Unityを知らないので スクリプタブルオブジェクト とかいうのが一体何なのかもわかりませんけど)
まず話として

ショップでの強化とメインのゲームでの強化

この両者の違いが何なのかが謎なので,話がイマイチわかりません.

仮に「強化」というのが「何らかのステータス値に変更を加えること」なのだとしたら,「強化」の適用とは

強化後ステータス値 = 強化( 強化前ステータス値 )

というだけの話ではないのだろうか?
複数の「強化」を適用するなら 強化2( 強化1(強化前ステータス値) ) という程度の話かな,と(「適用順序は?」という話があり得るにせよ).

そしたら各タイミング(シーン次第?)でどの強化を 適用する/適用しない のか,というのを変えてやるだけの話なのでは.

「上記のような演算を強化後ステータス値が必要なタイミングで毎回実施していたらパフォーマンスに問題が生じる」みたいなギリギリな世界での話なのだとしても,強化後の値を適当に記憶しておいて使えばよい.で,適用具合を変える必要が生じた時点(本件ではシーンの切り替わりタイミング?)で再計算すればいいだけなのではないかな.


実装的な話をすれば
すごく単純には List< Func<int,int> > みたいなのに,現在適用すべき「強化」を適用順に保持するとかしておけばよい.
(各 Func<int,int> は強化適用前の値を引数に受けて,強化適用後の値を返す)

あるいは,「現在適用すべき~ 保持」というところの管理が面倒であれば

C#

1//シーンの種類 2enum Scene{ Main, Shop } 3 4//各強化処理の引数に「現在のシーン」を取る 5List< Func<int,int,Scene> > ReinforcementSequence;

等でもいいかもしれない.
とにかく,こういうのに毛が生えた程度の話(: 実装や理屈の難易度が低い話 )から考えてみたら良いのでは.

投稿2025/02/26 03:54

編集2025/02/26 04:10
fana

総合スコア12136

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.32%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問