📝 24.04.18
Skill 오브젝트에 들어갈 Skill이라는 클래스 스크립트를 Player Skill과 Enemy Skill이라는 자식 스크립트로 분리해야할 필요를 느껴서 수정했다.
기존의 Skill.cs
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
public class Skill : MonoBehaviour
{
public Animator anim;
public SkillInfoData data { get; set; }
private Player player;
private Vector3 leftDirection = new Vector3(2f, 2f, 1f);
private Vector3 rightDirection = new Vector3(-2f, 2f, 1f);
private void OnEnable()
{
player = GameManager.Instance.player;
if(player != null)
{
SetTransform();
CheckType();
}
}
private void CheckType()
{
switch(player.Data.StatusData.JobType)
{
case JobType.Archer:
StartCoroutine(ShootSkill());
break;
default:
StartCoroutine(WaitForAnimationEnd());
break;
}
}
IEnumerator WaitForAnimationEnd()
{
do
{
yield return null;
} while (anim.GetCurrentAnimatorStateInfo(0).normalizedTime < 1);
gameObject.SetActive(false);
}
IEnumerator ShootSkill()
{
if(data != null)
{
Vector3 originalPosition = transform.position;
Vector3 targetPosition = originalPosition + (player.Controller.isLeft ? new Vector3(data.Range * -1, 0, 0) : new Vector3(data.Range, 0, 0));
do
{
transform.position = Vector3.MoveTowards(transform.position, targetPosition, Time.deltaTime * 7f);
yield return null;
} while (transform.position != targetPosition);
gameObject.SetActive(false);
}
}
private void SetTransform()
{
Vector3 plus = new Vector3(-0.5f, 0, 0);
if (!player.Controller.isLeft)
{
plus.x *= -1f;
Flip(false);
}
else Flip(true);
transform.position = player.transform.position + plus;
}
private void Flip(bool isLeft)
{
transform.localScale = isLeft ? leftDirection : rightDirection;
}
private void OnCollisionEnter2D(Collision2D collision)
{
IDamageable damageable = collision.gameObject.GetComponent<IDamageable>();
if(damageable != null)
{
damageable.TakeDamage(player.Data.StatusData.Atk + data.Damage);
gameObject.SetActive(false);
}
}
}
리팩토링 Skill.cs
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
public class Skill : MonoBehaviour
{
public Animator anim;
[SerializeField]
public SkillInfoData data;
protected IDamageable damageable;
protected void CheckType()
{
if(data.Range > 0)
{
StartCoroutine(ShootSkill());
} else
{
StartCoroutine(WaitForAnimationEnd());
}
}
IEnumerator WaitForAnimationEnd()
{
do
{
yield return null;
} while (anim.GetCurrentAnimatorStateInfo(0).normalizedTime < 1);
gameObject.SetActive(false);
}
IEnumerator ShootSkill()
{
if(data != null)
{
Vector3 originalPosition = transform.position;
Vector3 targetPosition = originalPosition + GetTargetPosition();
do
{
transform.position = Vector3.MoveTowards(transform.position, targetPosition, Time.deltaTime * 7f);
yield return null;
} while (transform.position != targetPosition);
gameObject.SetActive(false);
}
}
protected virtual void SetTransform() { }
protected virtual Vector3 GetTargetPosition() { return Vector3.left; }
protected virtual void OnCollisionEnter2D(Collision2D collision)
{
damageable = collision.gameObject.GetComponent<IDamageable>();
}
}
대충 가상메서드로 여럿 변경한 것이 주요하고 GetTargetPosition()이라는 새로운 메서드를 만들어서 PlayerSkill과 EnemySkill이 각각 다른 설정을 할 수 있도록 수정했다.
PlayerSkill.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerSkill : Skill
{
private Player player;
private Vector3 leftDirection = new Vector3(2f, 2f, 1f);
private Vector3 rightDirection = new Vector3(-2f, 2f, 1f);
private void OnEnable()
{
player = GameManager.Instance.player;
if (player != null)
{
SetTransform();
CheckType();
}
}
protected override void SetTransform()
{
Vector3 plus = new Vector3(-0.5f, 0, 0);
if (!player.Controller.isLeft)
{
plus.x *= -1f;
Flip(false);
}
else Flip(true);
transform.position = player.transform.position + plus;
}
private void Flip(bool isLeft)
{
transform.localScale = isLeft ? leftDirection : rightDirection;
}
protected override void OnCollisionEnter2D(Collision2D collision)
{
base.OnCollisionEnter2D(collision);
if (damageable != null)
{
damageable.TakeDamage(player.Data.StatusData.Atk + data.Damage);
gameObject.SetActive(false);
}
}
protected override Vector3 GetTargetPosition()
{
return player.Controller.isLeft ? new Vector3(data.Range * -1, 0, 0) : new Vector3(data.Range, 0, 0);
}
}
아직 EnemySkill
는 스킬 오브젝트 프리팹 작업이 더 급해서 못만들고 있지만 얼추 GetTargetPosition()
메서드를 적절하게 재정의하고, OnCollisionEnter2D()
메서드의 damage
도 다르게 계산하도록 수정해야 할 듯 하다.