Repository navigation
2 ‐ PlayerManager
문현우 edited this page Sep 13, 2023
·
15 revisions
🎇 Managed by 김광수
- PlayerManager는 플레이어를 생성하고 관리하는 기능을 담당합니다.
-
PlayerType Enum
- 플레이어의 유형을 정의하는 열거형입니다.
- 각 플레이어를 대표하는 상수 값을 가지고 있습니다.
-
Awake()
- PlayerManger의 인스턴스를 생성합니다.
- 플레이어 매니저의 인스턴스를 설정하여, 다른 스크립트에서 PlayerManager에 접근할 수 있게됩니다.
-
CreatePlayer()
- 지정된 유형의 플레이어를 생성합니다.
- 미리 지정된 플레이어 Prefab을 가져와 인스턴화합니다.
- 인스턴스화된 GameObject에 Player 컴포넌트를 추가합니다.
- 이후 해당 컴포넌트를 반환합니다.
PlayerManager.cs
using UnityEngine;
public enum PlayerType
{
ZombiePlayer1,
ZombiePlayer2,
SkelletionPlayer1,
SkelletionPlayer2,
MonsterPlayer,
}
public class PlayerManager : MonoBehaviour
{
public static PlayerManager Instance { get; private set; }
[SerializeField] private GameObject[] playerPrefabs = new GameObject[5];
public Player player{ get; private set; }
private void Awake()
{
if (Instance == null) Instance = this;
}
public Player CreatePlayer(PlayerType type)
{
GameObject go = Instantiate(playerPrefabs[(int)type]);
player = go.GetComponent<Player>();
return player;
}
}🎇 Managed by 김광수
- 플레이어 캐릭터를 정의하며, 캐릭터의 체력, 이동 속도, 공격 및 피해 관련 동작을 다룹니다.
-
Start()
- IsAttack 변수를 false로 초기화하고, maxHp를 hp 값으로 설정합니다.
-
Update()
- 매 프레임마다 호출되며, attack_cool_time 변수를 업데이트합니다.
-
AttackCharacter()
- 플레이어의 공격 동작을 처리합니다.
- attack_cool_time이 0보다 크면 공격을 실행하지 않습니다.
- IsAttack를 true로 설정하고 1초 후에 CompleteAttack 메서드를 호출하여 공격을 완료합니다.
- attack_cool_time을 3초로 설정하여 쿨다운을 시작합니다.
-
TakeDamage()
- 플레이어가 피해를 받았을 때 호출됩니다.
- 애니메이션 트리거 "Hit"을 활성화하고 체력(hp)을 감소시킵니다.
- 체력이 0 이하로 내려가면 0으로 설정하고, GameManager의 HitPlayer() 메서드를 호출하여 게임 매니저에게 플레이어가 피해를 받았음을 알립니다.
-
TakePotion()
- 플레이어가 포션을 먹었을 때 호출됩니다.
- 현재 체력(hp)이 최대 체력(maxHp)보다 작으면 체력을 1 증가시킵니다.
- GameManager의 TakePotion() 메서드를 호출하여 게임 매니저에게 포션을 먹었다는 정보를 전달합니다.
-
CompleteAttack()
- 공격 동작이 완료되었을 때 호출됩니다.
- IsAttack을 false로 설정하여 플레이어가 더 이상 공격 중이 아님을 나타냅니다.
Player.cs
using UnityEngine;
public class Player : MonoBehaviour, ICharacter
{
[SerializeField] private int hp;
[SerializeField] private float speed;
[SerializeField] Animator anim;
[SerializeField] Animator atkAnim;
public int maxHp;
public int Hp { get { return hp; } }
public float Speed { get { return speed; } }
public bool IsAttack { get; private set; }
float attack_cool_time = 0f;
private void Start()
{
IsAttack = false;
maxHp = hp;
}
private void Update()
{
attack_cool_time-= Time.deltaTime;
}
public void AttackCharacter()
{
if (attack_cool_time > 0f) return;
IsAttack = true;
Invoke("CompleteAttack", 1f);
attack_cool_time = 3f;
}
public void TakeDamage()
{
anim.SetTrigger("Hit");
hp -= 1;
if (hp < 0) { hp = 0; }
GameManager.Instance.HitPlayer();
}
public void TakePotion()
{
if(hp < maxHp)
{
hp += 1;
}
GameManager.Instance.TakePotion();
}
public void CompleteAttack()
{
IsAttack=false;
}
}🎇 Managed by 김광수
- 플레이어를 향해 이동하고, 공격하는 적을 구현합니다.
-
AttackCharacter()
- 적을 공격합니다. 대기시간이 끝났는지 확인합니다.
- 만약 대기시간이 끝났다면, 플레이어에게 탄환을 발사합니다. 이후 다시 대기시간을 설정합니다.
-
RotateEnemyToPalyer()
- 적이 플레이를 바라보도록 회전하는 메서드입니다.
- 플레이어와 적의 방향 벡터를 계산하여 적을 회전시킵니다.
-
FlipXEnemy()
- 적이 왼쪽을 바라보고 있다면, 수평으로 뒤집습니다.
- 적의 몸체, 팔 스프라이트를 뒤집습니다.
-
TakeDamage()
- 적이 플레이어 공격의 피해를 받습니다.
- 적을 게임에서 제거하고 게임 오브젝트를 파괴합니다.
Player.cs
using UnityEngine;
public class Enemy : MonoBehaviour, ICharacter
{
float remainCoolTime = 0f;
float COOL_TIME = 4.5f;
Vector3 moveDirection = Vector3.right;
[SerializeField] private SpriteRenderer body;
[SerializeField] private SpriteRenderer left;
[SerializeField] private SpriteRenderer right;
[SerializeField] private Transform spawnBullet;
Vector3 leftPos = Vector3.zero;
Vector3 rightPos = Vector3.zero;
bool isFlip = false;
private void Start()
{
leftPos = left.transform.position;
rightPos = right.transform.position;
}
private void Update()
{
remainCoolTime -= Time.deltaTime;
if (remainCoolTime <= 0f) AttackCharacter();
}
private void FixedUpdate()
{
RotateEnemyToPlayer();
}
public void AttackCharacter()
{
int rate = Random.Range(0, 100);
BulletType type;
float speed;
if (rate >= 98)
{
type = BulletType.Bomb;
speed = Random.Range(3.5f, 4.5f);
}
else if(rate >= 95)
{
type = BulletType.Potion;
speed = Random.Range(3.5f, 4.5f);
}
else
{
type = BulletType.Enemy;
speed = Random.Range(0.5f, 2f);
}
BulletManager.Instance.ShotBullet(type, spawnBullet.position, speed);
remainCoolTime = COOL_TIME;
}
private void RotateEnemyToPlayer()
{
moveDirection = (PlayerManager.Instance.player.transform.position - transform.position).normalized;
float rotZ = Mathf.Atan2(moveDirection.y, moveDirection.x) * Mathf.Rad2Deg;
FlipXEnemy(Mathf.Abs(rotZ) > 90);
}
private void FlipXEnemy(bool result)
{
if (isFlip != result)
{
body.flipX = result;
left.flipX = result;
right.flipX = result;
if (result == true)
{
left.transform.position = rightPos;
right.transform.position = leftPos;
right.transform.rotation = Quaternion.Euler(0, 0, 45f);
isFlip = true;
}
else
{
left.transform.position = leftPos;
right.transform.position = rightPos;
right.transform.rotation = Quaternion.Euler(0, 0, -45f);
isFlip = false;
}
}
}
public void TakeDamage()
{
EnemyManager.Instance.Enemies.Remove(this);
Destroy(gameObject);
}
}🎇 Managed by 김광수
- ICharacter 인터페이스는 게임 캐릭터의 기본적인 동작을 정의하는 인터페이스입니다.
- ICharacter 인터페이스는 게임 캐릭터를 구현하는 데 사용할 수 있습니다.
- 이 인터페이스를 구현하는 클래스는 AttackCharacter() 메서드를 사용하여 캐릭터를 공격하고, TakeDamage() 메서드를 사용하여 캐릭터가 피해를 받았을 때 처리할 수 있습니다.
-
AttackCharacter()
- 캐릭터를 공격합니다.
-
TakeDamage()
- 캐릭터가 피해를 받습니다.
ICharacter
interface ICharacter
{
void AttackCharacter();
void TakeDamage();
}🎇 Managed by 이성권
- 캐릭터의 조준을 구현을 담당합니다.
-
Awake()
- OnAim()에 대한 리스너를 등록합니다.
-
Start(0
- OnAIm() 메서드를 호출하여 캐릭터를 조준합니다.
-
_controller
- 캐릭터의 이동과 조준을 처리하는 컴포넌트입니다.
-
OnAim()
- 캐릭터가 조준할 때 호출되는 메서드입니다. 캐릭터를 새로운 조준 방향으로 회전합니다.
-
RotatePlayer()
- 캐릭터를 새로운 조준 방향으로 회전하는 메서드입니다. 캐릭터의 SpriteRenderer 컴포넌트의 FlipX 속성을 사용하여 캐릭터를 수평으로 뒤집습니다.
TopDownAimRotation.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TopDownAimRotation : MonoBehaviour
{
private TopDownCharacterController _controller;
private void Awake()
{
_controller = GetComponent<TopDownCharacterController>();
}
void Start()
{
_controller.OnLookEvent += OnAim;
}
public void OnAim(Vector2 newAimDirection)
{
RotatePlayer(newAimDirection);
}
private void RotatePlayer(Vector2 direction)
{
float rotZ = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
gameObject.GetComponentInChildren<SpriteRenderer>().flipX = Mathf.Abs(rotZ) > 90f;
}
}🎇 Managed by 이성권
- 캐릭터의 이동을 담당합니다.
-
Awake()
- Rigidbody2D 컴포넌트를 검색합니다.
-
Start(
- _controller.OnMoveEvent 리스너를 등록합니다.
-
Move()
- 캐릭터의 이동 방향을 설정하는 메서드입니다.
- _movementDirection 변수에 캐릭터의 이동 방향을 설정합니다.
-
ApplyMovment()
- 캐릭터를 이동시키는 메서드입니다.
- _movementDirection 변수에 따라 캐릭터의 Rigidbody2D 컴포넌트의 velocity 속성을 설정합니다.
TopDownMovement.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TopDownMovement : MonoBehaviour
{
private TopDownCharacterController _controller;
private Vector2 _movementDirection = Vector2.zero;
private Rigidbody2D _rigidbody;
private void Awake()
{
_controller = GetComponent<TopDownCharacterController>();
_rigidbody = GetComponent<Rigidbody2D>();
}
private void Start()
{
_controller.OnMoveEvent += Move;
}
private void FixedUpdate()
{
ApplyMovment(_movementDirection);
}
private void Move(Vector2 direction)
{
_movementDirection = direction;
}
private void ApplyMovment(Vector2 direction)
{
direction = direction * 5;
_rigidbody.velocity = direction;
}
}