어제 발견된 오류들을 정리해보았다.
데미지 텍스트 문제부터 해결하기로 한다. (나머지 문제와 연결되어 있다고 판단)
ShowDamageText() 함수는 호출되었고, 프리팹도 생성되었다.
하지만 화면에는 아무것도 보이지 않았다.
문제 원인 의심
Debug.Log를 이용하여 텍스트가 생성된 좌표를 확인해보았다.
좌표를 찍어보니 (-960, -540)처럼 화면 밖에 생성되고 있었다.
transform.position + Vector3.up * 2f로 위치 조정해도 해결되지 않았다.
Canvas 설정을 확인한다.
Screen Space - Overlay로 되어 있었고 문제 없음프리팹 문제라고 판단하여 프리팹의 세부 내용을 확인해보았다.
Canvas (Environment)라는 부모 항목이 존재함을 알았다.Canvas와 다르기 때문에 발생하는 문제라고 판단하였다.Canvas (Environment)는 실제 게임에선 생성되지 않는 임시 UI였다. → 문제X결국 문제는 좌표 변환 코드
Canvas에 특정 좌표에 생성된 텍스트가 게임 화면에 출력이 되기 위해서는 좌표 변환이 제대로 이루어져야 했다.하지만 원인을 정확히 파악할 수 없어서 조건 분기를 이용하기로 하였다.
수정한 코드:
Vector3 worldPos = transform.position + Vector3.up * 2f;
Vector3 screenPos = Camera.main.WorldToScreenPoint(worldPos);
if (canvas.renderMode == RenderMode.ScreenSpaceOverlay)
{
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, screenPos, null, out anchoredPos);
}
else
{
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, screenPos, Camera.main, out anchoredPos);
}
수정 후:
결국 문제는 좌표 변환 로직 이었다.
이걸 고치고 나니 다른 문제도 다 해결되었다.
다음은 실행 결과이다.

다음으로, 다른 방식의 투사체를 생성해보도록 하겠다. 먼저 이 투사체의 특징을 정해보겠다.
처음에는 기존 Bullet 스크립트와는 별개로 새로운 스크립트를 만들까 고민했다. 하지만 앞으로 투사체 종류가 점점 늘어날 것을 생각하면, 매번 새로운 스크립트를 만드는 방식은 관리가 어렵다고 판단했다.
그래서 추상 클래스를 이용하기로 했다.
추상 클래스의 장점
abstract 키워드를 이용하면 해당 클래스는 설계용으로만 사용할 수 있음OnHit()처럼 반드시 오버라이드해야 하는 메서드를 강제할 수 있음추상 클래스 BulletManager.cs
public abstract class BulletManager : MonoBehaviour
{
public float speed = 5f;
public int damage = 1;
public string targetTag;
public GameObject hitEffectPrefab;
public float lifetime = 3f;
protected virtual void Start()
{
Destroy(gameObject, lifetime);
}
protected virtual void Update()
{
transform.Translate(Vector2.right * speed * Time.deltaTime);
}
protected virtual void OnTriggerEnter2D(Collider2D collision)
{
if (!collision.CompareTag(targetTag)) return;
if (hitEffectPrefab != null)
{
GameObject fx = Instantiate(hitEffectPrefab, transform.position, Quaternion.identity);
Destroy(fx, 0.5f);
}
OnHit(collision);
}
protected abstract void OnHit(Collider2D col);
}
각 코드 별 기능
OnHit() 내부에서 Destroy(gameObject) 호출 여부로 결정targetTag 변경으로 아군/적군 구분Inspector 또는 코드에서 설정 가능hitEffectPrefab에 프리팹 연결이에 따라 기존 Bullet.cs를 BulletManager.cs에게서 상속받은 일반 투사체로 기능할 수 있도록 수정한다.
public class Bullet : BulletManager
{
protected override void OnHit(Collider2D col)
{
UnitHealth unit = col.GetComponent<UnitHealth>();
if (unit != null)
{
unit.TakeDamage(damage);
}
Destroy(gameObject);
}
}
BulletManager를 상속받는다.TargetTag를 통해 적군/아군 판별OnHit()을 통해 적군과 충돌했을 때 데미지를 주고 투사체 제거일단 여기까지 구현해보고 나머지는 내일 구현해보도록 하겠다. 글에는 잘 표현이 안 됐지만, 오류를 고치는 데에 시간이 너무 많이 들어간다. 원인을 찾는 데에 시간이 많이 걸리곤 하는데, 이 시간을 줄이기 위해서 다양한 기능들을 구현해보며 연습해보겠다.