EnemyData 클래스
EnemyData 클래스는 적 캐릭터의 움직임을 관리하는 역할을 합니다. Rigidbody2D를 이용하여 주어진 방향과 속도에 따라 적을 이동시키는 Move 메서드를 포함하고 있습니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyData : MonoBehaviour
{
public float moveSpeed = 3.0f;
private Rigidbody2D rb;
private void Start()
{
rb = GetComponent<Rigidbody2D>();
}
public void Move(Vector2 dir)
{
if(rb == null) { return; }
rb.velocity = dir * moveSpeed;
}
}
EnemyController 클래스는 적의 행동을 결정하고 플레이어를 추적하는 로직을 포함하고 있습니다. 플레이어와의 거리에 따라 멈춤, 추적, 손실 처리를 결정하며, 추적 중일 때는 애니메이션을 업데이트합니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyController : EnemyDetector
{
private Vector2 targetPos;
[Header("Detect")]
[SerializeField][Range(0f, 2.0f)] private float stopRange = 2.0f;
[SerializeField][Range(0f, 100f)] private float followRange = 50f;
[SerializeField] private SpriteRenderer characterRenderer;
private bool wasChasing = false;
public GameObject enemySightObj;
public int lostCount = 0;
private void FixedUpdate()
{
Vector2 direction = Vector2.zero;
if (DistanceToTarget() < stopRange)
{
direction = Vector2.zero;
enemySightObj.SetActive(true);
}
else if (DistanceToTarget() < followRange)
{
direction = DirectionToTarget();
wasChasing = true;
enemySightObj.SetActive(false);
targetPos = ClosestTarget.transform.position;
UpdateAnimation();
}
else
{
if (!Achievement.Instance.isAchievementComplete[3])
{
if (wasChasing)
{
lostCount++;
wasChasing = false;
StopAnimation(AnimationData.WalkParameterHash);
StartAnimation(AnimationData.IdleParameterHash);
}
}
}
enemyData.Move(direction);
}
private void UpdateAnimation()
{
StopAnimation(AnimationData.IdleParameterHash);
float dirX = targetPos.x - enemyData.transform.position.x;
float dirY = targetPos.y - enemyData.transform.position.y;
StartAnimation(AnimationData.WalkParameterHash);
SetAnimation(AnimationData.DirXParameterHash, AnimationData.DirYParameterHash, dirX, dirY);
}
}
EnemyDetector 클래스
EnemyDetector 클래스는 적이 특정 대상을 감지하고 이에 대한 정보를 제공하는 기능을 제공합니다. 대상과의 거리 계산, 애니메이션 제어 등의 기본적인 기능을 포함하고 있습니다
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyDetector : MonoBehaviour
{
public Transform ClosestTarget { get; private set; }
public EnemyData enemyData;
[SerializeField] public string playerTag = "Player";
[field: SerializeField] public AnimationData AnimationData { get; private set; }
public Animator Animator { get; private set; }
private void Awake()
{
AnimationData.Initialize();
Animator = GetComponentInChildren<Animator>();
}
private void Start()
{
enemyData = GetComponent<EnemyData>();
ClosestTarget = GameObject.FindGameObjectWithTag(playerTag).transform;
}
public float DistanceToTarget()
{
return Vector3.Distance(transform.position, ClosestTarget.position);
}
public Vector2 DirectionToTarget()
{
return (ClosestTarget.position - transform.position).normalized;
}
public void StartAnimation(int animatorHash)
{
Animator.SetBool(animatorHash, true);
}
public void SetAnimation(int animatorHashX, int animatorHashY, float DirX, float DirY)
{
Animator.SetFloat(animatorHashX, DirX);
Animator.SetFloat(animatorHashY, DirY);
}
public void StopAnimation(int animatorHash)
{
Animator.SetBool(animatorHash, false);
}
}
EnemySight 클래스
EnemySight 클래스는 적이 시각적으로 플레이어를 감지하고 상호작용하는 기능을 제공합니다. 플레이어와의 충돌 검사를 통해 플레이어의 체력을 감소시키고, 시각적 표시를 변경하는 등의 기능을 구현합니다.
using Unity.VisualScripting;
using UnityEngine;
public class EnemySight : EnemyDetector
{
[SerializeField][Range(0f, 1.0f)] private float detactedOpacity = 1.0f;
[SerializeField] private float detactSpeed = 200.0f;
public PlayerSO playerData;
private SpriteRenderer sightRenderer;
private Transform parentTransform;
private float opacity;
private SoundDB soundDB;
private LifeController _lifeController;
private int health;
private int calledDecreaseHealth;
private void Start()
{
soundDB = SoundManager.Instance.soundDB;
health = StatManager.Instance.health;
calledDecreaseHealth = StatManager.Instance.calledDecreaseHealth;
sightRenderer = GetComponent<SpriteRenderer>();
parentTransform = transform.parent;
opacity = 0f;
}
private void Update()
{
ChangeOpacity(opacity);
transform.RotateAround(parentTransform.position, Vector3.forward, detactSpeed * Time.deltaTime);
CheckPlayerDead();
}
private void CheckPlayerDead()
{
if (health == 0 && StatManager.Instance.loseHeartByEnemy)
{
StatManager.Instance.isGameOver = true;
GameManagerTest.Instance.GameOver("불시검문에 걸렸다!!!");
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (health > 0 && collision.CompareTag(playerTag))
{
SoundManager.Instance.PlayEffect(soundDB.enemyAttackSound, 0.5f, false);
opacity = detactedOpacity;
health--;
calledDecreaseHealth++;
StatManager.Instance.lifeController.ChangeLifeUI(--StatManager.Instance.health);
StatManager.Instance.loseHeartByEnemy = true;
}
}
private void OnTriggerExit2D(Collider2D collision)
{
opacity = 0f;
}
private void ChangeOpacity(float opacity)
{
Color color = sightRenderer.color;
color.a = opacity;
sightRenderer.color = color;
}
}
Spawner 클래스
Spawner 클래스는 게임 내에서 필요한 오브젝트를 랜덤 위치에 생성하는 기능을 제공합니다. 게임 시작 시 설정된 프리팹을 이용하여 여러 개의 오브젝트를 생성합니다.
using UnityEngine;
public class Spawner: MonoBehaviour
{
public GameObject prefab;
private void Start()
{
for(int i=0;i<3;i++)
SpawnObject();
}
private Vector3 SetRandomPos()
{
float X = Random.Range(-25.5f, 26f);
float Y = Random.Range(.5f, 18.5f);
Vector3 randomPos = new Vector3(X, Y);
return randomPos;
}
private void SpawnObject()
{
Instantiate(prefab, SetRandomPos(), Quaternion.identity);
}
}
위 코드들은 2D 방치형 게임에서 적의 움직임, 추적, 감지, 애니메이션 처리 및 스폰을 담당하는 클래스들입니다. 각 클래스는 특정 기능을 구현하며, 적의 행동 패턴과 게임의 상호작용을 정의하는 데 사용됩니다.
댓글 영역