ゲーム制作勉強中!あこがれだったプログラマーに今からなろう!

昔、あこがれていたプログラマー。今からでも勉強してみようと思い立ち、チャレンジ開始! 勉強メモや、悪戦苦闘な日々の記録です。

サイドビューアクションゲームを作ろう(13):レベルアップ(下書き)

アイテムに引き続き、レベルアップ機能を作成した。
といっても、エフェクトなどはまだ勉強していないので、とりあえず今日のところは下書き状態に留めた。

レベルアップだけならば簡単で、要は経験値が、次のレベルに必要な分量溜まっていたら、経験値を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

使用画像
七三ゆきのアトリエ:https://nanamiyuki.com/