ポケモン風RPGの作り方 #6 ScriptableObjectを使った技の実装【Unity教材】

2021年9月28日

この記事で得られること

今回は、モンスターの実装を紹介するぞ!

色々なモンスターを技を実装する必要があるので、ScriptableObjectを活用するぞ!

(基本的には動画の流れを書いてるので、詳しいところは動画を見た方がいいです)

解説動画

技のScriptableObjectのコードを作成

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu]
public class MoveBase : ScriptableObject
{
    // 技のマスターデータ

    // 名前,詳細,タイプ,威力,正確性,PP(技を使うときに消費するポイント)

    [SerializeField] new string name;

    [TextArea]
    [SerializeField] string description;

    [SerializeField] PokemonType type;
    [SerializeField] int power;
    [SerializeField] int accuracy; // 正確性
    [SerializeField] int pp;

    // 他のファイル(Move.cs)から参照するためにプロパティを使う
    public string Name { get => name; }
    public string Description { get => description; }
    public PokemonType Type { get => type; }
    public int Power { get => power; }
    public int Accuracy { get => accuracy; }
    public int PP { get => pp; }
}

技の生成

ScriptableObjectを生成する

モンスターに適応する技の実装

マスターデータは読み取り専用なので、マスターデータの技はそのまま使わない。そのために技クラスを作成する。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Move
{
    // Pokemonが実際に使うときの技データ

    // 技のマスターデータをもつ
    // 使いやすいようにするためにPPももつ

    // Pokemon.csが参照するのでpublicにしておく
    public MoveBase Base { get; set; }
    public int PP { get; set; }


    // 初期設定
    public Move(MoveBase pBase)
    {
        Base = pBase;
        PP = pBase.PP;
    }
}

モンスターが覚える技を設定

モンスターはレベルに応じて覚える技が異なる。まずは覚える技クラスを作成する。

PokemonBase.csと同じファイルに書いているが、別ファイルでもOK)

// 覚える技クラス:どのレベルで何を覚えるのか
[Serializable]
public class LearnableMove
{
    // ヒエラルキーで設定する
    [SerializeField] MoveBase _base;
    [SerializeField] int level;

    public MoveBase Base { get => _base; }
    public int Level { get => level; }
}

PokemonBaseで覚える技を登録しておく

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// ポケモンのマスターデータ:外部から変更しない(インスペクターだけ変更可能)
[CreateAssetMenu]
public class PokemonBase : ScriptableObject
{
    // 名前,説明,画像,タイプ,ステータス

    [SerializeField] new string name;
    [TextArea]
    [SerializeField] string description;

    // 画像
    [SerializeField] Sprite frontSprite;
    [SerializeField] Sprite backSprite;

    // タイプ
    [SerializeField] PokemonType type1;
    [SerializeField] PokemonType type2;

    // ステータス:hp,at,df,sAT,sDF,sp
    [SerializeField] int maxHP;
    [SerializeField] int attack;
    [SerializeField] int defense;
    [SerializeField] int spAttack;
    [SerializeField] int spDefense;
    [SerializeField] int speed;

    // 覚える技一覧
    [SerializeField] List<LearnableMove> learnableMoves;

    // 他ファイルからattackの値の取得はできるが変更はできない
    public int Attack { get => attack; }
    public int Defense { get => defense; }
    public int SpAttack { get => spAttack; }
    public int SpDefense { get => spDefense; }
    public int Speed { get => speed; }
    public int MaxHP { get => maxHP; }

    public List<LearnableMove> LearnableMoves { get => learnableMoves; }
}

// 覚える技クラス:どのレベルで何を覚えるのか
[Serializable]
public class LearnableMove
{
    // ヒエラルキーで設定する
    [SerializeField] MoveBase _base;
    [SerializeField] int level;

    public MoveBase Base { get => _base; }
    public int Level { get => level; }
}

public enum PokemonType
{
    None,
    Normal,
    Fire,
    Water,
    Electric,
    Grass,
    Ice,
    Fighting,
    Poison,
    Ground,
    Flying,
    Psychic,
    Bug,
    Ghost,
    Dragon,
}

PokemonBaseから使える技をモンスターに反映する

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// レベルに応じたステータスの違うモンスターを生成するクラス
// 注意:データのみ扱う:純粋C#のクラス
public class Pokemon
{
    // ベースとなるデータ
    PokemonBase _base;
    int level;

    public int HP { get; set; }
    // 使える技
    public List<Move> Moves { get; set; }
    

    // コンストラクター:生成時の初期設定
    public Pokemon(PokemonBase pBase, int pLevel)
    {
        _base = pBase;
        level = pLevel;
        HP = pBase.MaxHP;

        // 使える技の設定:覚える技のレベル以上なら、Movesに追加
        foreach (LearnableMove learnableMove in pBase.LearnableMoves)
        {
            if (level >= learnableMove.Level)
            {
                // 技を覚える
                Moves.Add(new Move(learnableMove.Base));
            }

            // 4つい上の技は使えない
            if (Moves.Count >=4)
            {
                break;
            }
        }
    }

    // levelに応じたステータスを返すもの:プロパティ(+処理を加えることができる)
    public int Attack
    {
        get { return Mathf.FloorToInt((_base.Attack * level) / 100f) + 5; }
    }
    public int Defense
    {
        get { return Mathf.FloorToInt((_base.Defense * level) / 100f) + 5; }
    }
    public int SpAttack
    {
        get { return Mathf.FloorToInt((_base.SpAttack * level) / 100f) + 5; }
    }
    public int SpDefense
    {
        get { return Mathf.FloorToInt((_base.SpDefense * level) / 100f) + 5; }
    }
    public int Speed
    {
        get { return Mathf.FloorToInt((_base.Speed * level) / 100f) + 5; }
    }
    public int MaxHP
    {
        get { return Mathf.FloorToInt((_base.MaxHP * level) / 100f) + 10; }
    }

}

おさらいと予告

今回はモンスターの技の多様化を実装したぞ!

次はバトルシステムの実装を行うぞ!

質問対応について

動画質問はYouTubeのメンバーシップのDiscord(音声とチャット)で受け付けています。

個人開発のサポートはオンラインサロンで受け付けています!