1vdlrwnsv1 님의 블로그
유니티 개발 숙련 2. 플레이어에게 데미지 주기 본문
캠프파이어 불 안에 들어갔을때 체력이 닳게 만들것
using System.Collections.Generic;
using UnityEngine;
public class CampFire : MonoBehaviour
{
public int damage;
public float damageRate;
private HashSet<IDamageable> things = new HashSet<IDamageable>();
private void Start()
{
InvokeRepeating(nameof(DealDamage), 0, damageRate);
}
void DealDamage()
{
foreach (var thing in things)
{
thing.TakePhysicalDamage(damage);
}
}
private void OnTriggerEnter(Collider other)
{
if (other.TryGetComponent(out IDamageable damageable))
{
things.Add(damageable);
}
}
private void OnTriggerExit(Collider other)
{
if (other.TryGetComponent(out IDamageable damageable))
{
things.Remove(damageable);
}
}
}
불 오브젝트에 콜라이더 컴포넌트를 넣고 isTrigger 체크
변수
- damage: 한 번의 공격이 줄 피해량
- damageRate: 피해를 주는 주기 (초 단위)
- things: 캠프파이어에 닿아 있는 객체 목록을 저장
Start() 에서 피해 반복 실행
- InvokeRepeating("DealDamage", 0, damageRate);
- InvokeRepeating("함수이름",시작시간,반복주기);
- DealDamage()를 damageRate 간격으로 반복 실행
DealDamage()
- things에 저장된 모든 IDamageable 객체에 damage만큼 피해를 줌
트리거에 닿으면 객체 추가 (OnTriggerEnter)
- Collider가 IDamageable을 가지고 있으면 things 목록에 추가
트리거에서 벗어나면 객체 제거 (OnTriggerExit)
- Collider가 벗어나면 things에서 제거
데미지를 받으면 화면이 빨개지는거 구현
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
public class DamageIndicator : MonoBehaviour
{
public Image image;
public float flashSpeed;
private Coroutine coroutine;
// Start is called before the first frame update
void Start()
{
CharacterManager.instance.player.condition.onTakeDamage += Flash;
}
public void Flash()
{
if(coroutine != null)
{
StopCoroutine(coroutine);
}
image.enabled = true;
image.color = new Color(1f, 100f/255f, 100f/255f);
coroutine = StartCoroutine(FadeAway());
}
private IEnumerator FadeAway()
{
float startAlpha = 0.3f;
float a = startAlpha;
while(a > 0)
{
a -= (startAlpha / flashSpeed) * Time.deltaTime;
image.color = new Color(1f, 100f/255f, 100f/255f, a);
yield return null;
}
image.enabled = false;
}
// Update is called once per frame
void Update()
{
}
}
변수
- image: 데미지 효과를 표시할 UI Image
- flashSpeed: 화면의 붉은 효과가 사라지는 속도
- coroutine: 효과가 진행 중일 때 기존 효과를 중지하기 위한 변수
Start()플레이어가 데미지를 받을 때 Flash() 실행
- CharacterManager.instance.player.condition.onTakeDamage 이벤트에 Flash() 등록
- 플레이어가 데미지를 받으면 자동으로 Flash() 실행
- Start()는 게임이 시작될 때 한 번 실행됨
- CharacterManager.instance.player.condition.onTakeDamage는 플레이어가 데미지를 받을 때 호출되는 이벤트
- onTakeDamage += Flash; → 데미지를 받으면 Flash()가 실행되도록 연결
- CharacterManager.instance.player.condition.onTakeDamage += Flash;
- 이 코드가 실행되면 플레이어가 공격받을 때 자동으로 Flash()가 실행됨
- onTakeDamage 이벤트는 플레이어가 데미지를 입을 때 실행되는 함수 목록을 저장함
- += 연산자로 Flash()를 여기에 추가하면, 데미지를 입을 때마다 Flash()도 같이 실행됨
데미지 효과 표시 Flash()
- 기존 효과가 진행 중이면 중단 (StopCoroutine(coroutine))
- image를 활성화하고, 색상을 **붉은색 (RGB(1, 100/255, 100/255))**으로 설정
- FadeAway() 코루틴 시작 → 화면의 붉은 효과가 점점 사라짐
- float startAlpha = 0.3f;
- 이미지 처음 투명도 0.3으로 설정.
- float a = startAlpha;
- a에 시작 투명도값 할당.
- while(a > 0)
- a가 0보다 클 때까지 반복.
- a -= (startAlpha / flashSpeed) * Time.deltaTime;
- a를 매 프레임마다 감소.
- image.color = new Color(1f, 100f/255f, 100f/255f, a);
- 색상은 빨강, 초록, 파랑 고정, 알파값은 a.
- Color(R, G, B, 투명도);
- yield return null;
- 한 프레임 대기 후 반복.
- image.enabled = false;
- 알파값 0 이하로 되면 이미지 비활성화.
- float startAlpha = 0.3f;
Damage를 5로 damageRate를 1로 설정하고 불 안에 들어가면 1초마다 피가 5씩까이며 화면이 빨개지는 모습
'Unity숙련주차' 카테고리의 다른 글
Unity, 밸브사의 Portal 게임을 클론 해보자잇 (0) | 2025.03.18 |
---|---|
유니티 개발 숙련주차4. 아이템 상호작용 (0) | 2025.03.06 |
유니티 개발 숙련주차 3. 조명기능 만져서 낮과 밤 구현 (0) | 2025.03.05 |
유니티 게임개발 숙련 1. 플레이어 만들기 (0) | 2025.03.04 |