20226.01.29 수정 (공격, 피격, 아이템 드랍 및 획득 구현 완료, 히트박스 트리거 버그 수정완) 다음 작업 : 공중몬스터 구현, 태그 스킬 구현
174 lines
4.7 KiB
C#
174 lines
4.7 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEditor.U2D.Animation;
|
|
using UnityEngine;
|
|
using UnityEngine.PlayerLoop;
|
|
|
|
using Random = UnityEngine.Random;
|
|
|
|
public class Mob : MonoBehaviour
|
|
{
|
|
//[SerializedField] private MobBase mobBase;
|
|
|
|
Rigidbody2D rbody;
|
|
Animator anim;
|
|
SpriteRenderer spriteRenderer;
|
|
List<GameObject> myList;
|
|
|
|
public int nextMove;
|
|
//public float axisH = 0.0f;
|
|
bool isDead = false;
|
|
bool isHit = false;
|
|
|
|
[Header("Temp Stats")]
|
|
public float maxHp = 100f;
|
|
public float currentHp;
|
|
public float moveSpeed = 1f;
|
|
|
|
[Header("Item Drop")]
|
|
[SerializeField] private GameObject dropItemPrefab; // 드랍할 아이템 프리팹 (에디터에서 할당)
|
|
[SerializeField][Range(0, 100)] private float dropChance = 50f; // 드랍 확률 (0~100%)
|
|
|
|
void Start()
|
|
{
|
|
rbody = GetComponent<Rigidbody2D>();
|
|
anim = GetComponent<Animator>();
|
|
spriteRenderer = GetComponent<SpriteRenderer>();
|
|
|
|
currentHp = maxHp; // 체력 초기화
|
|
|
|
Invoke("Think",1);
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
/*axisH = rbody.linearVelocity.x;
|
|
|
|
float direction = axisH > 0 ? 1 : -1;
|
|
transform.localScale = new Vector2(direction, 1);*/
|
|
|
|
if (isDead) return;
|
|
|
|
// 방향 전환
|
|
if (nextMove != 0)
|
|
{
|
|
transform.localScale = new Vector2(nextMove > 0 ? 1 : -1, 1);
|
|
}
|
|
}
|
|
|
|
void FixedUpdate()
|
|
{
|
|
if (isDead || isHit) return;
|
|
|
|
rbody.linearVelocity = new Vector2(nextMove * moveSpeed, rbody.linearVelocity.y);
|
|
|
|
Vector2 frontVec = new Vector2(rbody.position.x + 0.2f*nextMove, rbody.position.y);
|
|
Debug.DrawRay(frontVec, Vector3.down, Color.green);
|
|
RaycastHit2D rayHit = Physics2D.Raycast(frontVec, Vector3.down, 1, LayerMask.GetMask("Ground"));
|
|
|
|
if (rayHit.collider == null)
|
|
{
|
|
nextMove *= -1;
|
|
|
|
CancelInvoke("Think");
|
|
|
|
Invoke("Think", 5);
|
|
}
|
|
}
|
|
|
|
void Think()
|
|
{
|
|
if (isDead || isHit) return;
|
|
|
|
Debug.Log("생각!");
|
|
nextMove = Random.Range(-1, 2);
|
|
|
|
float nextThinkTime = Random.Range(2f, 5f);
|
|
|
|
anim.SetInteger("WalkSpeed", nextMove);
|
|
Invoke("Think", nextThinkTime);
|
|
}
|
|
|
|
private void OnTriggerEnter2D(Collider2D other)
|
|
{
|
|
if (other.CompareTag("Player"))
|
|
{
|
|
PlayerController player = other.GetComponentInParent<PlayerController>();
|
|
|
|
if (player != null)
|
|
{
|
|
player.TakeDamage(1, transform.position);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void TakeDamage(float damageAmount, float stunTime, Vector2 attackerPos) //데미지 크기, 타입, 공격 위치
|
|
{
|
|
if (isDead) return;
|
|
|
|
currentHp -= damageAmount;
|
|
Debug.Log($"몬스터 피격! 남은 체력: {currentHp}");
|
|
|
|
if (currentHp <= 0)
|
|
{
|
|
Die();
|
|
return;
|
|
}
|
|
|
|
StartCoroutine(KnockBack(attackerPos));
|
|
}
|
|
IEnumerator KnockBack(Vector2 attackerPos)
|
|
{
|
|
isHit = true; // 경직 상태 시작 (이동 멈춤)
|
|
anim.SetTrigger("Hit"); // 피격 애니메이션 (있다면)
|
|
|
|
// 넉백 방향 계산 (몬스터 - 공격자 = 밀려날 방향)
|
|
Vector2 knockbackDir = (transform.position - (Vector3)attackerPos).normalized;
|
|
|
|
// 넉백 힘 적용 (수치는 조절 필요)
|
|
rbody.linearVelocity = Vector2.zero; // 기존 속도 초기화
|
|
rbody.AddForce(knockbackDir * 1.5f + Vector2.up * 0.5f, ForceMode2D.Impulse); // 뒤로 살짝 뜨면서 밀림
|
|
|
|
// 피격 효과 (빨갛게 깜빡임)
|
|
if (spriteRenderer != null) spriteRenderer.color = Color.red;
|
|
|
|
yield return new WaitForSeconds(0.5f); // 0.5초 경직
|
|
|
|
if (spriteRenderer != null) spriteRenderer.color = Color.white;
|
|
isHit = false; // 경직 해제
|
|
|
|
// 다시 움직임 시작
|
|
Think();
|
|
}
|
|
|
|
void Die()
|
|
{
|
|
isDead = true;
|
|
anim.SetTrigger("Die");
|
|
rbody.linearVelocity = Vector2.zero;
|
|
GetComponent<Collider2D>().enabled = false; // 시체에 또 안 맞게
|
|
|
|
Invoke("DropItem", 2);
|
|
//DropItem();
|
|
Destroy(gameObject, 2f); // 2초 뒤 삭제
|
|
}
|
|
|
|
void DropItem()
|
|
{
|
|
// 프리팹이 없으면 실행 안 함
|
|
if (dropItemPrefab == null) return;
|
|
|
|
// 0 ~ 100 사이의 난수 생성
|
|
float randomValue = Random.Range(0f, 100f);
|
|
|
|
// 확률 당첨 시
|
|
if (randomValue <= dropChance)
|
|
{
|
|
Debug.Log("아이템 드랍 성공!");
|
|
// 몬스터 위치에 아이템 생성 (Quaternion.identity는 회전 없음)
|
|
Instantiate(dropItemPrefab, transform.position, Quaternion.identity);
|
|
}
|
|
}
|
|
}
|