다양한 기록

[Fortress Craft] Normal Monster With Scriptable Object 본문

유니티 엔진/Fortress Craft

[Fortress Craft] Normal Monster With Scriptable Object

라구넹 2025. 2. 6. 01:42

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

namespace Agit.FortressCraft
{
    public enum MonsterType
    {
        NORMAL,
        SWORD,
        BOW,
        MAGIC,
        NON
    }

    public enum BuffType
    {
        NON,
        ATTACK,
        DEFENSE
    }

    [CreateAssetMenu( fileName = "MonsterData", menuName = "Scriptable Object/Monster Data" )]
    public class MonsterData : ScriptableObject
    {
        [SerializeField] private float hpMax = 3000;
        public float HPMax { get { return hpMax; } }
        [SerializeField] private float movingWeight = 1.0f;
        public float MovingWeight { get { return movingWeight; } }
        [SerializeField] private float damage = 10.0f;
        public float Damage { get { return damage; } }

        [SerializeField] private float idleDelay= 1.0f;
        public float IdleDelay { get { return idleDelay; } }
        [SerializeField] private float runDelay = 1.0f;
        public float RunDelay { get { return runDelay; } }
        [SerializeField] private float attackDelay = 1.0f;
        public float AttackDelay { get { return attackDelay; } }

        [SerializeField] private int gold = 10;
        public int Gold { get { return gold; } }
        [SerializeField] private float exp = 10.0f;
        public float Exp { get { return exp; } }

        [SerializeField] private MonsterType type = MonsterType.NON;
        public MonsterType Type { get { return type; } }

        [SerializeField] private BuffType buff = BuffType.NON;
        public BuffType Buff { get { return buff; } }
    }
}

여러 종류의 노말 몬스터를 한 종류의 스크립트로 관리하고 싶다

그래서 스크립터블 오브젝트를 사용했다

Scriptable Object에서 여러 수치를 지정해주는 것 뿐만 아니라, 노말 몬스터의 타입까지 지정해서

발동하는 함수를 다른 것으로 만들 수 있다

 

일단 노말 몬스터는 전부 NormalMonsterController와 NormalMonsterMain 으로 작동한다

 

스크립터블 오브젝트를 통해 활을 쓰는지, 검을 쓰는지, 주먹을 쓰는지 지정 ⇒ 애니메이션 트리거 달라짐

 

각각 함수들이 다른 트리거를 작동시키는데 Spawned에서 delegate 이용해서 처리

 

그에 따라 실행되는 애니메이션도 달라지기 때문에

애니메이션 딜레이도 몬스터 데이터에 담아서 처리

보스 몬스터 FrostLizard를 제외하고는 다 같은 종류의 스크립트를 사용한다

FrostLizard는 쓰는 애니메이션이 많아서 같은 종류로 사용할 수 없다

 

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

namespace Agit.FortressCraft
{
    public class ArcherArrowAttackCollider : AttackCollider
    {
        public Player ClientPlayer { get; set; }

        private void OnTriggerEnter2D(Collider2D collision)
        {
            if (OwnType == null) return;
            if( collision.tag.StartsWith("Unit") )
            {
                if (collision.CompareTag("Unit_" + OwnType))
                {
                    return;
                }

                Debug.Log("Hit!");

                if (collision.TryGetComponent<BodyCollider>(out BodyCollider bodycollider))
                {
                    if (collision.transform.parent != null)
                    {
                        if (collision.transform.parent.TryGetComponent<NormalUnitRigidBodyMovement>(
                        out NormalUnitRigidBodyMovement normal))
                        {
                            if (normal.HP - Damage * normal.Defense <= 0.0f && !normal.NoReward)
                            {
                                normal.NoReward = true;
                                RewardManager.Instance.Gold += normal.gold;
                                RewardManager.Instance.Exp += normal.exp;
                            }
                        }
                        else if (collision.transform.parent.TryGetComponent<MonsterController>(
                        out MonsterController monster))
                        {
                            if (monster.HP - Damage <= 0.0f && !monster.NoReward)
                            {
                                monster.NoReward = true;
                                RewardManager.Instance.Gold += monster.Gold;
                                RewardManager.Instance.Exp += monster.Exp;

                                if (monster.Buff == BuffType.ATTACK)
                                {
                                    ClientPlayer.BuffAttackTimer = TickTimer.CreateFromSeconds(Runner, ClientPlayer.BuffAttackTime);
                                }
                                else if( monster.Buff == BuffType.DEFENSE )
                                {
                                    ClientPlayer.BuffDefenseTimer = TickTimer.CreateFromSeconds(Runner, ClientPlayer.BuffDefenseTime);
                                }
                            }
                        }
                    }
                    //Debug.Log("Player Damage: " + Damage);
                    bodycollider.RPCSetDamage(Damage);
                    bodycollider.CallDamageCheck();
                }
                
            }
        }
    }
}

또한, 스크립터블 오브젝트에 버프 타입이 지정된 경우 쓰러트릴 경우 버프 또한 얻을 수 있다