오늘 학습 키워드

최종 팀 프로젝트

오늘 학습 한 내용을 나만의 언어로 정리하기

플레이어 포션 먹기

  • 플레이어가 포션 먹을 때 다른 행동 못하게 해서 오히려 쉬웠음
public class PotionState : IPlayerState  
{  
    private float startStateTime;  
    private float startPotionTime = 0.01f;  
    private float animRunningTime = 0f;  
    private float potionAnimationLength;  
      
    public void Enter(PlayerController controller)  
    {  
        animRunningTime = 0f;  
        startStateTime = Time.time;  
        potionAnimationLength =   
            controller.Animator.animator.runtimeAnimatorController  
                .animationClips.First(c => c.name == "Potion").length;  
        controller.Animator.ClearBool();  
        controller.Animator.SetTriggerAnimation(PlayerAnimID.Potion);  
        Debug.Log("[플레이어] 체력 회복 시도");  
    }  
      
    public void HandleInput(PlayerController controller)  
    {  
    
    }  
  
    public void LogicUpdate(PlayerController controller)  
    {  
        animRunningTime += Time.deltaTime;  
          
        if (Time.time - startStateTime > startPotionTime)  
        {  
            AnimatorStateInfo curAnimInfo = controller.Animator.animator.GetCurrentAnimatorStateInfo(0);  
  
            if (curAnimInfo.IsName("Potion"))  
            {   
                float animTime = curAnimInfo.normalizedTime;  
  
                if (animTime >= 1.0f)  
                {  
                    controller.Condition.potionCount--;  
                    controller.Condition.health.Add(controller.Condition.potionHealthRecovery);  
                    Debug.Log($"[플레이어] 체력 회복됨 {controller.Condition.health.CurValue()}");  
                    controller.ChangeState<IdleState>();  
                    return;  
                }  
            }  
  
            if (animRunningTime >= potionAnimationLength)  
            {  
                controller.Condition.potionCount--;   
                controller.Condition.health.Add(controller.Condition.potionHealthRecovery);  
                Debug.Log($"[플레이어] 체력 회복됨 {controller.Condition.health.CurValue()}");  
                controller.ChangeState<IdleState>();  
                return;  
            }  
                  
        }  
    }  
    public void Exit(PlayerController controller)  
    {  
          
    }  
}
  • 애니메이션 송출이 다 끝나야지 체력이 회복되도록 했음

추가 스킬 만들기

  • 리플렉션을 쓰기로 함
  • 우선 모든 스킬은 SkillBase를 상속하게 함
  • 그리고 Skill Name과 동일한 이름의 스킬 클래스를 만듬
  • 게임이 시작할 때 PlayerSkillManager에 모든 스킬들을 다 박아둠
  • 그리고 로그인하면 플레이어가 어떤 스킬을 가지고 있는지가 나옴.
  • 거기서 어떤 스킬을 사용할지 선택할 수 있음.

그래서 리플렉션 어떻게 쓰는데요

  • Assembly.GetExecutingAssembly().GetType() : 어셈블리에서 이름이 같은 클래스 타입을 찾아서 타입 정보 를 돌려줌. 인스턴스 없음.
  • Assembly.GetExecutingAssembly().CreateInstance() : 인스턴스까지 만들어줌. 대신 기본 생성자를 씀
  • 커스텀 생성자 쓰고싶으면 Activator.CreateInstance(type, args) 를 써야함
  • 이번 경우에는 기본 생성자를 쓰는 대신에 그 클래스의 Init 함수를 불러주는 형식으로 했음.
private void LoadSkills()  
{  
    List<PlayerSkillModel> skillModels = DataManager.Instance.PlayerSkillDataList.DataList;  
    foreach (var skillModel in skillModels)  
    {  
        skills[skillModel.skillId] = CreateSkill(skillModel.skillId, skillModel.skillName);  
    }  
    Debug.Log($"[플레이어] 스킬 세트 준비 완료");  
}  
  
private SkillBase CreateSkill(int skillId, string skillName)  
{  
    if (!skills.TryGetValue(skillId, out SkillBase skill))  
    {  
        Type skillType = Assembly.GetExecutingAssembly().GetType(skillName);  
        if (skillType == null)  
        {  
            Debug.LogError($"[플레이어] 스킬 클래스 {skillName} 을 찾을 수 없삼");  
            return null;  
        }  
  
        if (!DataManager.Instance.PlayerSkillDataList.TryGetPlayerSkillModelData(skillId, out var skillModel))  
        {  
            Debug.LogError($"[플레이어] 스킬 아이디 {skillId} 는 없는 아이디임");  
            return null;  
        }  
          
        SkillBase newSkill = Activator.CreateInstance(skillType) as SkillBase;  
        if (newSkill == null) return null;  
          
        newSkill.Init(  
            skillModel.skillId, skillModel.damage, skillModel.damage2, skillModel.buffValue,  
            skillModel.stamina, skillModel.cooldown, skillModel.duration  
            );  
  
        Debug.Log($"[플레이어] 스킬 클래스 {skillName} 을 생성함");  
        return newSkill;  
    }  
    else return skill;  
}

포션 먹는걸 티내봐요

  • 포션을 먹을 때 바로 Observable을 써서 이벤트버스 발동하게 함
// PlayerCondition.cs
[Header("Potion Settings")]   
[HideInInspector] public Observable<bool> getPotion;  
  
public int potionCount = 1;  
public int potionHealthRecovery = 3;  
  
  
private PlayerController controller;  
private Coroutine invincibleCoroutine;  
[HideInInspector] public Observable<bool> isDead;
 
private void Awake()  
{  
    canStaminaRecovery = new Observable<bool>(EventBusKey.ChangeStaminaRecovery, false);  
    isDead = new Observable<bool>(EventBusKey.ChangePlayerDead, false);  
    getPotion = new Observable<bool>(EventBusKey.GetPotion, false);  
    controller = GetComponent<PlayerController>();  
}