アイテムに引き続き、レベルアップ機能を作成した。
といっても、エフェクトなどはまだ勉強していないので、とりあえず今日のところは下書き状態に留めた。
レベルアップだけならば簡単で、要は経験値が、次のレベルに必要な分量溜まっていたら、経験値を0化して、各ステータスを上昇。次のレベルに必要な経験値を更新してやれば良い。
Item ManagerでアイテムやEnemyの経験値加算処理するように組んでいるが、
これだと、Item Managerで経験値管理までしなくてはならない。
なので、レベルアップの処理は、EXPバーのPlayerEXP_BarとGame Managerに任せる事にした。
EXPバーに任せたのは、EXPバーを徐々に変化させるように組んでいるので、実際の経験値ではなく、EXPバーが満タンになったらレベルアップ処理を実行する様にしたいから。
こうすれば、EXPバーの途中でいきなりレベルアップしてしまうことはないだろう。
PlayerEXP_Barのスクリプトはこんな感じ。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerEXP_Bar : MonoBehaviour { private Transform playerExpbar; private Animator anim; [SerializeField]PlayerManager player; public float playerEXPnow; //実際の今の経験値➗次のレベルまでに必要な経験値 public float playerEXPdisplay;//経験値の今の表示状態 private void Awake() { playerExpbar=transform.Find("bar"); anim=GetComponent<Animator>(); player.OnUpdateEXP +=SetPlayerEXPBar; playerExpbar.localScale=new Vector3(0,1,1); playerEXPdisplay=0.0f; } public void SetPlayerEXPBar(int _exp) { //ここで現在の経験値を受け取り、更新している。 playerEXPnow=(float)_exp/(float)GameManager.Instance.nextLevel; // } private void FixedUpdate() { //絶対値で表示状態との差を出している。 float remainder=Mathf.Abs(playerEXPdisplay-playerEXPnow); if(remainder<0.009){remainder=0;}//差が近似値なら差はないと判断 if(remainder!=0) { //差と+-の判定で表示状態を増減 playerEXPdisplay -= 0.01f*Mathf.Sign(playerEXPdisplay-playerEXPnow); } //表示を更新する。 playerExpbar.localScale=new Vector3(playerEXPdisplay,1,1); if(playerEXPdisplay>0.99)//表示状態が満タンになっていたら、 { GameManager.Instance.LevelManager();//レベルアップ処理を行う。 playerEXPdisplay=0; //表示状態は0化。 playerEXPnow=(float)GameManager.Instance.playerEXP/(float)GameManager.Instance.nextLevel; } } }
Game Managerのレベルアップ処理はこんな感じ。
シンプルイズベスト😁
public void LevelManager() { Debug.Log("LVUP!"); playerManager.playerLevel.Value+=1; playerEXP-=nextLevel; //ここで経験値からレベルアップに消費した分を減算 nextLevel+=200; playerManager.playerAttack.Value+=5; playerManager.PlayerDef.Value+=5; playerManager.PlayerMaxHP+=20; return; }
今回はUIも下書きに留めた😆
でも、ちょっとUniRXの実験を兼ねて、レベル・攻撃力・防御力の表示をUniRXで表示更新する様にしている。
具体的には、Player ManagerでReactivePropertyとして登録し、UI側でSubscribeして購読させる方法で組んでみた。
Player Manager(関係ないところは省略)
using UniRx; public class PlayerManager : MonoBehaviour { [Header("プレイヤーレベル")] public ReactiveProperty<int> playerLevel = new ReactiveProperty<int>(1) ; [Header("プレイヤーの攻撃力")] public ReactiveProperty<int> playerAttack = new ReactiveProperty<int>(10); [Header("プレイヤーの防御力")] public ReactiveProperty<int> PlayerDef = new ReactiveProperty<int>(0);
Status(UI側)
using System.Collections; using System.Collections.Generic; using UnityEngine; using UniRx; using UnityEngine.UI; public class Status : MonoBehaviour { [SerializeField]PlayerManager playerManager; [SerializeField]Text level_text; [SerializeField]Text attack_text; [SerializeField]Text def_text; void Start() { playerManager.playerLevel.Subscribe(playerLevel => UpdateLevel(playerLevel)); playerManager.playerAttack.Subscribe(playerAttack=> UpdateAttack(playerAttack)); playerManager.PlayerDef.Subscribe(PlayerDef=> UpdateDef(PlayerDef)); } public void UpdateLevel(int level) { level_text.text=level.ToString(); } public void UpdateAttack(int attack) { attack_text.text="Attack:"+attack.ToString(); } public void UpdateDef(int def) { def_text.text="Def:"+def.ToString(); } }
結果はこんな感じ。UIやエフェクトはちゃんと勉強して、いつか差し替えよう🤣
youtu.be
使用アセット
Pixel Fantasy Caves
Hero Knight - Pixel Art
Slime Character
Pixel Potions (with Animation)
Animated 2D Coins
Bandits - Pixel Art