Monster M_ V2
Monster M_V2 기본정보
요청사항
- 몬스터는 처음 대기 상태로 DetectingAreaR범위 내 Player 탐색만 수행
- Player 탐색 성공 시 느린 속도로 Player 추격
- 탄환을 발사하고 AttackCoolTime 동안 추격만 진행
- 다시 Player 추격
- 공격 직전에 애니메이션 재생(눈 깜박임)
- 공격 주기(AttackCoolTime), 총알 속도 변수 값이 조절 가능하도록 public으로 선언
필요한 변수들 선언
using System.Collections;
using UnityEngine;
public class M_V2 : MonsterBase
{
public float AttackCoolTime;
public GameObject BulletPrefab; // 발사할 총알 프리팹
public Transform FirePoint; // 총알 발사 위치
public float BulletSpeed = 10f; // 총알 속도
...
}
각각 변수들의 용도는
- AttackCoolTime
- 공격 후 다음 공격까지의 시간
- BulletPrefab
- 총알 프리팹
- BulletSpeed
- 총알 속도
기본 함수(Start, Update)
using System.Collections;
using UnityEngine;
public class M_V2 : MonsterBase
{
...
// Start is called before the first frame update
protected override void Start()
{
base.Start();
monsterType = MonsterType.M_V2;
StartCoroutine(MonsterRoutine());
}
// Update is called once per frame
void Update()
{
}
...
}
M_V1 몬스터와 비슷하게 기본 함수는 MonsterBase의 Start를 호출에 Monster에서 공통적으로 사용하는 변수들을 초기화했다.
이후 MonsterType을 설정하고 Coroutine을 실행해 줬다.
코루틴 관련 함수
using System.Collections;
using UnityEngine;
public class M_V2 : MonsterBase
{
...
public override IEnumerator MonsterRoutine()
{
while (true)
{
if (!DetectionSuccess && DetectionPlayerPosition())
{
DetectionSuccess = true;
DetectingAreaR = 15.0f;
}
if (DetectionSuccess)
{
// Debug.Log("Player 탐지 완료");
yield return AttackPreparation();
}
yield return null;
}
}
public override IEnumerator AttackPreparation()
{
var speed = MoveSpeed * Time.deltaTime;
float elapsedTime = 0f;
Collider2D[] detectedObjects = Physics2D.OverlapCircleAll(transform.position, DetectingAreaR);
rb.bodyType = RigidbodyType2D.Dynamic;
while (Vector3.Distance(transform.position, TargetPosition) > speed)
{
SpriteFlipSetting();
DetectionPlayerPosition();
elapsedTime += Time.deltaTime;
if (elapsedTime >= AttackCoolTime)
{
DetectionPlayerPosition();
MAnimator.SetTrigger("Shot");
float animationTime = 1.4f;
float animElapsedTime = 0f;
while (animElapsedTime < animationTime)
{
DetectionPlayerPosition();
rb.MovePosition(Vector3.MoveTowards(rb.position, TargetPosition, MoveSpeed * Time.fixedDeltaTime));
animElapsedTime += Time.deltaTime;
yield return null;
}
Fire();
elapsedTime = 0;
}
rb.MovePosition(Vector3.MoveTowards(rb.position, TargetPosition, MoveSpeed * Time.fixedDeltaTime));
yield return new WaitForFixedUpdate();
}
yield return null;
}
...
}
몬스터 루틴 함수에서 M_V1과 다른 점은 애니메이션을 재생이 완료되고 총알이 나가야 하며, 재생하는 동안에도 Player를 추적해야 하기에 움직임을 설정해 주는 while문의 구성이 조금 다르다.
공격 함수
using System.Collections;
using UnityEngine;
public class M_V2 : MonsterBase
{
...
// 공격 로직
private void Fire()
{
GameObject bullet = Instantiate(BulletPrefab, FirePoint.position, FirePoint.rotation);
Physics2D.IgnoreCollision(bullet.GetComponent<Collider2D>(), GetComponent<Collider2D>());
Vector2 fireDirection = (TargetPosition - FirePoint.position).normalized;
Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
rb.velocity = fireDirection * BulletSpeed;
}
}
FirePoint에서 Bullet을 생성시켰다. 이 함수에서는 총알이 생성되는 동시에 몬스터가 이동하는 것이 겹치면 충돌 이벤트가 발생했는데, 이를 방지하기 위해 충돌을 무시해 주는 처리를 해줬다.
기타
M_V1과 유사한 로직을 가진 M_V2를 구현하는 것은 어렵지 않았다.
다만 총알이 생성되자마자 몬스터와 부딪히는 원인을 찾느라 고생했다.
참고 사항
MonsterBase
[Unity] Monster Base 구현
MonsterBase의 구현프로젝트에서 몬스터를 구현을 담당하게 되어서 몬스터 스크립트의 베이스가 되는 MonsterBase를 만들어봤다. 필요한 변수들의 선언using System.Collections;using System.Collections.Generic;usin
gdoo.tistory.com
마무리하며..
이것저것 만지면서 우연히 탄막게임 패턴을 구현했다. 이걸 다른 몬스터에 패턴으로 사용할 수 있을 것 같다.
몬스터를 만들어서 배치하고 플레이하니까 게임 만드는 재미가 있었다.
'Unity > Hackers Window' 카테고리의 다른 글
[Unity] Monster 구현 : M_VE - 1 (1) | 2024.11.16 |
---|---|
[Unity] Monster 구현 : M_V3 (0) | 2024.11.15 |
[Unity] Monster 구현 : M_V1 (0) | 2024.11.13 |
[Unity] Hackers Window (0) | 2024.11.10 |
[Unity] Monster Base 구현 (1) | 2024.10.13 |