Skip to content

develop Pick Up System

Jeon-YJ1004 edited this page Jul 30, 2023 · 9 revisions

리팩토링 전 로직

  • Icollectible 인터페이스 생성
public interface ICollectible
{
    void Collect();
}
  • Scripts>PickUps> 에 수집 가능한 오브젝트 스크립트 작성, 위의 인터페이스 상속
    ex) 경험치 관련 스크립트
public class ExperiencePickUp : MonoBehaviour,ICollectible
{
   public int expGranted;

   public void Collect()
   {
       //스크립트 명으로 오브젝트 찾기
       Character character = FindObjectOfType<Character>();
       character.GetExp(expGranted);
       Destroy(gameObject);
   }
}
  • 캐릭터에 수집 스크립트 추가
public class PlayerCollector : MonoBehaviour
{

    private void OnTriggerEnter2D(Collider2D col)
    {
        if (col.gameObject.TryGetComponent(out ICollectible collectible))
            collectible.Collect();
    }
}

hp pickup

//[character.cs]
 public void RestoreHealth(float amount)
    {
        if(currentHealth< (int)Enums.Stat.MaxHealth)
        { 
            currentHealth += amount;
            if (currentHealth > (int)Enums.Stat.MaxHealth) currentHealth = (int)Enums.Stat.MaxHealth;

        }
       
    }

exp pickup

//[character.cs]
public void GetExp(int exp)
    {
        mExp += exp;
        while (mExp >= mMaxExp)
        {
            mExp -= mMaxExp;
            mMaxExp += Constants.DeltaExp;
            LevelUp();
        }
        Debug.Log(mExp);
    }

리팩토링 후 로직

  1. 습득 가능한 object는 MoveToPlaer.cs를 갖고 있다.
  2. 이 스크립트에서, 플레이어와의 거리를 두 가지의 기준으로 구분한다. 2-1 object와 플레이어와의 거리가 mPickupDistance보다 작아지면 플레이어에게 이동한다. 2-2 object와 플레이어와의 거리가 mCollectDistacne보다 작아지면 플레이어가 습득한다=>collect() 실행 2-3. mCollectDistacne는 Magnet 스탯에 따라 결정된다.
  3. icollectible의 collect() 실행하여 각 object에 맞게 플레이어에게 적용되고 object.SetActive(false)로 설정한다.
  4. 리팩토링 전과 달라진 점은 플레이어가 갖고 있던 코드를 삭제했다는 것이다.
    즉 거리를 플레이어가 아닌 오브젝트가 계산하고 collect여부를 확인한다.
public class GoToPlayer : MonoBehaviour
{
    private Transform mPlayer;
    private const float mCollectDistacne = 0.5f;
    private const float mSpeed = 7f;
    private float mPickupDistance = 2.5f;
    private void Awake()
    {
        if(GameManager.instance.Player!=null) mPlayer = GameManager.instance.Player.transform;
    }
    private void OnEnable()
    {
        if (GameManager.instance.Player != null) mPlayer = GameManager.instance.Player.transform;
    }
    private void Update()
    {
        if (mPlayer != null)
        {
            //magnet 스탯을 기본 거리에 곱해 최종 거리를 계산한다.
            mPickupDistance *= GameManager.instance.CharacterStats[(int)Enums.EStat.Magnet];
            //플레이어와 오브젝트와의 거리
            float distance = Vector3.Distance(transform.position, mPlayer.position);
            if (distance > mPickupDistance) return; //이동 가능한 거리보다 크면 아래 코드 실행 안함
            transform.position = Vector3.MoveTowards(transform.position, mPlayer.position, mSpeed * Time.deltaTime);
            if (distance < mCollectDistacne) {
                if(gameObject.TryGetComponent(out ICollectible collectible))
                    collectible.Collect();
            }
        }
    }
}
[ExpPickUp.cs]
public void Collect()
    {
        Character character = GameManager.instance.Character;
        character.GetExp(ExpGranted);
        gameObject.SetActive(false);
        SoundManager.instance.PlaySoundEffect(mClip);
    }
Clone this wiki locally