https://www.youtube.com/watch?v=dBQHtMI-Og4&list=PLO-mt5Iu5TeZF8xMHqtT_DhAPKmjF6i3x&index=11
1. 몬스터 검색 구현
레이어 : 물리, 시스템 상으로 구분짓기 위한 요소
Tag 옆 Layer에서 Add Layer
Enemy 레이어 추가 후 Enemy 프리펩에서 지정(자식까지 Yes)
Scanner 스크립트 생성
범위, 레이어, 스캔 결과 배열, 가장 가까운 목표를 담을 변수 선언
public class Scanner : MonoBehaviour
{
public float scanRange;
public LayerMask targetLayer;
public RaycastHit2D[] targets;
public Transform nearestTarget;
}
Enemy들을 검색하는 로직
private void FixedUpdate()
{
targets = Physics2D.CircleCastAll(transform.position, scanRange, Vector2.zero, 0, targetLayer);
nearestTarget = GetNearst();
}
- CircleCastAll(1,2,3,4,5) : 원형의 캐스트를 쏘고 모든 결과를 반환하는 함수
1. 캐스팅 시작 위치
2. 원의 반지름
3. 캐스팅 방향
4. 캐스팅 길이
5. 대상 레이어
가장 가까운 것을 찾는 함수 추가
Transform GetNearst()
{
Transform result = null;
float diff = 100;
foreach (RaycastHit2D target in targets)
{
Vector3 myPos = transform.position;
Vector3 targetPos = target.transform.position;
float curDiff = Vector3.Distance(myPos, targetPos);
if (curDiff < diff)
{
diff = curDiff;
result = target.transform;
}
}
return result;
}
- foreach 문으로 캐스팅 결과 오브젝트를 하나씩 접근
- Distance(A, B) : 벡터 A와 B의 거리를 계산해주는 함수
- 반복문을 돌며 가져온 거리가 저장된 거리보다 작으면 교체
완성된 검색 스크립트는 플레이어 오브젝트에 추가
Scan Range 설정(7)
인스펙터에서 Target Layer Enemy 설정
2. 프리펩 만들기
근접무기 프리펩 하나를 장면에 드래그하기
Props의 Bullet 3로 Sprite Renderer의 Sprite 변경
콜라이더를 리셋하면 스프라이트 크기에 맞춰집니다.
Box Collider 삭제후 Capsule Collider 2D로 변경
이름 변경(Bullet 1) 후 프로젝트 창으로 드래그 드랍하여 새로운 프리펩으로 생성
총탄 프리펩의 콜라이더에도 Is Trigger 체크
3. 총탄 생성하기
Weapon 0를 복사해서 Weapon 1로 변경
원거리 공격에 맞도록 속성 변경 (id=1, Prefab id=2, damage=3)
만들어둔 총탄 프리펩을 오브젝트 풀링 매니저에 등록
- PoolManager 들어가서 Element 2 에 추가
Weapon 스크립트의 switch 문을수정
타이머를 변수, 로직 추가
float timer;
void Update()
{
switch (id)
{
...
default:
timer += Time.deltaTime;
if (timer > speed)
{
timer = 0f;
Fire();
}
break;
}
Fire() 함수 추가
nearestTarget이 있는지 확인이 필요한데
nearestTarget은 Scanner에 있어 바로 접근할 수 가 없다.
이 때 Weapon1 의 부모가 Player인것을 이용하여 쉽게 쓸 수 있다.
//Player
public Scanner scanner;
void Awake()
{
scanner = GetComponent<Scanner>();
}
- 직접 만든 스크립트도 컴포넌트로 동일하게 취급해요
//Weapon
Player player;
private void Awake()
{
player = GetComponentInParent<Player>();
}
void Fire()
{
if (!player.scanner.nearestTarget)
return;
}
- GetComponentInParent 함수로 부모의 컴포넌트 가져오기
- 저장된 목표가 없으면 넘어가는 조건 로직 작성
Fire()을 기존 생성 로직을 그대로 활용하면서 위치는 플레이어 위치로 지정
void Fire()
{
if (!player.scanner.nearestTarget)
return;
Transform bullet = GameManager.instance.pool.Get(prefabId).transform;
bullet.position = transform.position;
}
Init() 함수의 speed 조정하여 연사속도 조절
public void Init()
{
switch (id)
{
case 0:
speed = 150;
Batch();
break;
default:
speed = 0.3f;
break;
}
}
4. 총탄 발사하기
총탄은 속도가 필요하므로 Rigidbody 2D 추가
Rigidbody 2D 의 Gravity Scale을 0으로 설정
Bullet 스크립트에서 Rigidbody 2D 변수 선언 및 초기화
Rigidbody2D rigid;
private void Awake()
{
rigid = GetComponent<Rigidbody2D>();
}
Init() 초기화 함수에 속도 관련 매개변수 추가
public void Init(float daamage,int per,Vector3 dir)
{
this.damage = daamage;
this.per = per;
if(per > -1)
{
rigid.velocity = dir * 15f;
}
}
- 관통이 -1 (무한)보다 큰 것에 대해서는 속도 적용
관통에 대한 내용
//관통
private void OnTriggerEnter2D(Collider2D collision)
{
if(!collision.CompareTag("Enemy") || per==-1)
return;
per--;
if (per == -1)
{
rigid.velocity = Vector2.zero;
gameObject.SetActive(false);
}
}
- Enemy 에게만 작동하기 위해 if문 작성 (에너미 아니거나 per -1 이 일때 실행 안함)
- 관통 값이 하나씩 줄어들면서 -1 이 되면 비활성화
- 풀링 사용시 문제 발생 방지를 위해, 비활성화 이전에 물리 속도 초기화
- Destroy가 아니라 SetActive(false) 할것
- Weapon의 근접무기 초기화의 인자값 고쳐주기(Vector3.zero)
Fire() 함수 완성
void Fire()
{
if (!player.scanner.nearestTarget)
return;
Vector3 targetPso = player.scanner.nearestTarget.position;
Vector3 dir = (targetPso - transform.position).normalized;
dir = dir.normalized;
Transform bullet = GameManager.instance.pool.Get(prefabId).transform;
bullet.position = transform.position;
bullet.rotation = Quaternion.FromToRotation(Vector3.up, dir);
bullet.GetComponent<Bullet>().Init(damage, count, dir);
}
- 위치로 방향을 구하고 normalized를 통해서 정규화한다.
- normalized : 현재 벡터의 방향은 유지하고 크기를 1로 변환된 속성
- Quaternion.FromToRotation(Vector3.up, dir) : 지정된 축을 중심으로 목표를 향해 회전하는 함수
Bullet 스크립트의 탄환 속도 조정
public class Bullet : MonoBehaviour
{
public void Init(float daamage,int per,Vector3 dir)
{
this.damage = daamage;
this.per = per;
if(per > -1)
{
rigid.velocity = dir * 15f;
}
}
}
- dir * 15f
Weapon 스크립트의 Update의 LevelUp의 파라미터인 Damage, Count 조정
깃허브 올리기
Commit : ver 1.8
Description : Auto Range Attack
https://github.com/mekain80/CloneCode_Undead_Survivor
'게임개발 > 언데드서바이벌_골드메탈_클론코딩' 카테고리의 다른 글
[클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 10 (HUD📐제작하기) (0) | 2023.05.06 |
---|---|
[클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 9 (타격감🌟있는 몬스터 처치 만들기) (0) | 2023.05.06 |
[클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 7 (회전하는🪓근접무기 구현) (0) | 2023.04.10 |
[클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 6+ (소환 레벨⏳적용하기) (0) | 2023.04.09 |
[클론코딩_유니티_골드메탈] 뱀서라이크 따라만들기 6 (오브젝트 풀링🏊으로 소환하기) (0) | 2023.04.09 |