<Player 사망시 Monster가 강남스타일을 춥니다.>

using System;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [SerializeField]
    private float moveSpeed = 1f;
    [SerializeField]
    private float turnSpeed = 150f;
    [SerializeField]
    private Transform mainCamera; 

    private Animation anim;
    private Transform tr;

    private readonly float initHp = 100.0f;
    public float currHp;

    public delegate void PlayerDieHandler();

    public static event PlayerDieHandler OnPlayerDie;

    public enum eAnimState
    {
        Idle,
        RunB,
        RunF,
        RunL,
        RunR
    }

    private void Start()
    {

        currHp = initHp;
        this.tr = this.GetComponent<Transform>();
        this.anim = this.GetComponent<Animation>();

        this.anim.clip = this.anim.GetClip(eAnimState.Idle.ToString());
        this.anim.Play();

        if (mainCamera == null)
        {
            mainCamera = Camera.main.transform;
        }


        Cursor.visible = false;
        Cursor.lockState = CursorLockMode.Locked;
    }


    private void Update()
    {
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        float mouseX = Input.GetAxis("Mouse X");

        var dir = new Vector3(h, 0, v);

        Vector3 moveDir = (Vector3.forward * v) + (Vector3.right * h);
        this.transform.Translate(moveDir.normalized * this.moveSpeed * Time.deltaTime);


        tr.Rotate(Vector3.up * mouseX * turnSpeed * Time.deltaTime);

        this.PlayAnimation(dir);


        if (mainCamera)
        {
            mainCamera.LookAt(tr.position);
        }
    }

    private void PlayAnimation(Vector3 dir)
    {
        if (dir.x > 0)
        {    //right
            this.anim.CrossFade(eAnimState.RunR.ToString(), 0.25f);
        }
        else if (dir.x < 0)
        {   //left
            this.anim.CrossFade(eAnimState.RunL.ToString(), 0.25f);
        }
        else if (dir.z > 0)
        {
            //forward
            this.anim.CrossFade(eAnimState.RunF.ToString(), 0.25f);
        }
        else if (dir.z < 0)
        {
            //back
            this.anim.CrossFade(eAnimState.RunB.ToString(), 0.25f);
        }
        else
        {
            //idle 
            this.anim.CrossFade(eAnimState.Idle.ToString(), 0.25f);
        }
    }
   
    private void OnTriggerExit(Collider other)
    {
            if(currHp >= 0.0f && other.CompareTag("PUNCH"))
        {
            currHp -= 10.0f;
            Debug.Log("Player hp = " + currHp/initHp);

            if(currHp <= 0.0f)
            {
                PlayerDie();
            }
        }
    }

    void PlayerDie()
    {
        Debug.Log("Player Die!");

        //GameObject[] monsters = GameObject.FindGameObjectsWithTag("Monster");
        //foreach (GameObject monster in monsters)
        //{
        //    monster.SendMessage("OnPlayerDie", SendMessageOptions.DontRequireReceiver);
        //}
        OnPlayerDie();
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.UIElements;

public class MonsterController : MonoBehaviour
{
    private Transform monsterTr;
    private Transform playerTr;
    private NavMeshAgent agent;
    private Animator animator;
    private float attackDelay = 2.0f;
    public enum State { 
        Idle,
        Trace,
        Attack,
        Die
    }
    public State state = State.Idle;
    public float tranceDist = 10.0f;
    public float attckDist = 2.0f;
    public bool isDie = false;
    public int EnemyHP = 3;
    private GameObject bloodEffect;
    private readonly int hashPlayerDie = Animator.StringToHash("PlayerDie");
    private readonly int hashSpeed = Animator.StringToHash("Speed");


    private void OnEnable()
    {
        PlayerController.OnPlayerDie += this.OnPlayerDie;
    }
    private void OnDisable()
    {
        PlayerController.OnPlayerDie -= this.OnPlayerDie;
    }






    void Start()
    {
        animator = GetComponent<Animator>();
        monsterTr = GetComponent<Transform>();
        playerTr = GameObject.FindWithTag("Player").GetComponent<Transform>();
        agent = GetComponent<NavMeshAgent>();
        bloodEffect = Resources.Load<GameObject>("BloodSprayEffect");
        Debug.Log(bloodEffect + "로드완료");
        StartCoroutine(CheckMonsterState());
    }

    IEnumerator CheckMonsterState()
    {
        while (!isDie)
        {
            yield return new WaitForSeconds(0.3f);
            float distance = Vector3.Distance(playerTr.position, monsterTr.position);

            if (distance <= attckDist && state != State.Attack)
            {
                LookAtPlayer();
                state = State.Attack;
                animator.SetInteger("state", (int)state);
                agent.SetDestination(transform.position);

                yield return new WaitForSeconds(attackDelay);  // 공격 후 지정한 시간만큼 대기

                state = State.Idle;  // 대기 시간 후 Idle 상태로 변경
                animator.SetInteger("state", (int)state);
            }
            else if (distance <= tranceDist)
            {
                state = State.Trace;
                animator.SetInteger("state", (int)state);
                LookAtPlayer();
                agent.destination = playerTr.position;
            }
            else
            {
                state = State.Idle;
                animator.SetInteger("state", (int)state);
            }
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("BULLET"))
        {
            Destroy(other.gameObject);

            // Blood effect logic
            Vector3 pos = other.ClosestPointOnBounds(transform.position); 
            Quaternion rot = Quaternion.LookRotation(-other.transform.forward); // 방향을 역으로 설정
            ShowBloodEffect(pos, rot);

            EnemyHP--;
            // 넉백 효과 추가
            Vector3 knockbackDirection = (monsterTr.position - playerTr.position).normalized; // 플레이어와의 반대 방향 계산
            float knockbackDistance = 2.0f; // 넉백 거리
            Vector3 knockbackPosition = monsterTr.position + knockbackDirection * knockbackDistance;
            this.transform.position = knockbackPosition; // 넉백 위치로 이동

            if (EnemyHP <= 0)
            {
                isDie = true;
                state = State.Die;
                animator.SetInteger("state", (int)state);
                Collider enemyCollider = GetComponent<Collider>();
                if (enemyCollider != null)
                {
                    Destroy(enemyCollider);
                }

                Destroy(this.gameObject,2f);

                // NavMeshAgent 비활성화
                agent.enabled = false;

                // 코루틴 정지
                StopAllCoroutines();
            }
        }
    }

    void ShowBloodEffect(Vector3 pos, Quaternion rot)
    {
        GameObject blood = Instantiate<GameObject>(bloodEffect, pos, rot, monsterTr);
        Destroy(blood,1f);
    }

    private void LookAtPlayer()
    {
        Vector3 direction = (playerTr.position - transform.position).normalized; // 플레이어 방향 계산
        Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z)); // 회전값
        transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * 5f); //회전
    }

    private void OnDrawGizmos()
    {
        if(state == State.Trace)
        {
            Gizmos.color = Color.blue;
            Gizmos.DrawWireSphere(transform.position, tranceDist);
        }

        if(state == State.Attack)
        {
            Gizmos.color = Color.red;
            Gizmos.DrawWireSphere(transform.position, attckDist);
        }
    }

    void OnPlayerDie()
    {

        StopAllCoroutines();
        agent.isStopped = true;
        animator.SetFloat(hashSpeed, Random.Range(0.8f, 1.2f));
        animator.SetTrigger(hashPlayerDie);
    }
    
}
반응형

+ Recent posts