[멋쟁이사자처럼 부트캠프 TIL] 멋쟁이사자처럼 유니티게임스쿨 9일차

굥지·2024년 10월 14일
0

애니메이션

달리다가 바로 멈췄으면 좋겠다 → Has Exit Time 없애기

Nav Mesh Agent 컴포넌트의 Angular Speed : 초당 돌아볼 수 있는 각도

애니메이션에 따른 코드 추가

using UnityEngine;
using UnityEngine.AI;

public class Enemy : MonoBehaviour
{
    enum State
    {
        idle,
        Follow,
        Attack
    }

    GameObject player;
    NavMeshAgent agent;
    Animator animator;

    State state;
    float currentStateTime;

    public float timeForNextState = 2;

    void Start()
    {
        animator = GetComponent<Animator>();
        player = GameObject.FindWithTag("Player");
        agent = GetComponent<NavMeshAgent>();

        state = State.idle;

        currentStateTime = timeForNextState;
    }

    void Update()
    {
        switch (state)
        {
            case State.idle:
                currentStateTime -= Time.deltaTime;
                if(currentStateTime < 0)
                {
                    float distance = (player.transform.position - transform.position).magnitude;
                    if(distance < 1.5f)
                    {
                        StartAttack();
                    }
                    else
                    {
                        StartFollow();
                    }
                }
                break;
            case State.Follow: 
                if(agent.remainingDistance < 1.5f || !agent.hasPath)
                //agent.hasPath : 갈 수 있는 길
                {
                    StartIdle();
                }
                break;
            case State.Attack:
                currentStateTime -= Time.deltaTime;
                if(currentStateTime < 0)
                {
                    StartIdle();
                }
                break;
        }
    }
    void StartIdle()
    {
        state = State.idle;
        currentStateTime = timeForNextState;
        agent.isStopped = true;
        animator.SetTrigger("Idle");
    }

    void StartFollow()
    {
        state = State.Follow;
        agent.destination = player.transform.position;
        agent.isStopped = false;
        animator.SetTrigger("Run");
    }

    void StartAttack()
    {
        state = State.Attack;
        currentStateTime = timeForNextState;
        animator.SetTrigger("Attack");

    }    
    public void OnDie()
    {
        Debug.Log("주금");
    }
}

인터페이스

using UnityEngine;
using UnityEngine.AI;

public class Enemy : MonoBehaviour, Health.IHealthListener
//Enemy 클래스는 Health.IHealthListener인터페이스를 구현해야한다.
//C#은 상속을 1개밖에 받지 못해 그 단점을 인터페이스로 보완
{
public class Health : MonoBehaviour
{
    public float hp = 10;
    public float maxHp = 10;
    public IHealthListener healthListener;

    void Start()
    {
        healthListener = GetComponent<IHealthListener>();
    }
    public void Damage(float damage)
    {
        if(hp>0)
        {
            hp -= damage;
            if(hp <= 0 )
            {
                //죽음
                Debug.Log("Dead");
               if(healthListener !=null)
                {
                    healthListener.OnDie();
                }
            }
            else
            {
                //다침
                Debug.Log("다침");
            }
        }
    }

    public interface IHealthListener
    {
        void OnDie();
    }
}

interface : 여러 클래스가 공통된 기능을 제공하면서도 서로 다른 방식으로 그 기능을 구현할 수 있도록 하기 위해서

// 1. 인터페이스 정의
public interface IAnimal
{
    void Speak();  // 동물들이 소리를 낼 수 있는 능력을 정의
}

// 2. Dog 클래스에서 IAnimal 인터페이스 구현
public class Dog : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("멍멍");
    }
}

// 3. Cat 클래스에서 IAnimal 인터페이스 구현
public class Cat : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("야옹");
    }
}

// 4. 인터페이스를 사용하는 코드
public class Program
{
    public static void Main()
    {
        IAnimal dog = new Dog();
        IAnimal cat = new Cat();

        dog.Speak();  // 출력: 멍멍
        cat.Speak();  // 출력: 야옹
    }
}

죽고나서 없어지기

    public void OnDie()
    {
        state = State.Die;
        agent.isStopped = true;
        animator.SetTrigger("Die");
        Invoke("DestroyThis", 2);
    }
    void DestroyThis()
    {
        Destroy(gameObject);
    }

펀치 콜라이더 설정

손 쪽에 콜라이더를 넣어준 후, 펀치 애니메이션이 나갈때쯤 콜라이더를 켜주고, 끝날때 쯤 콜라이더를 꺼준다.

무적시간

using UnityEngine;

public class Health : MonoBehaviour
{
    public float hp = 10;
    public float maxHp = 10;
    public float invincibleTime; //무적시간
    
    public IHealthListener healthListener;
    float lastDamageTime;

    void Start()
    {
        healthListener = GetComponent<IHealthListener>();
    }
    public void Damage(float damage)
    {
        //마지막으로 얻어 맞은 시간 + 무적 시간이 현재 시간보다 적으면
        if(hp>0 && lastDamageTime+invincibleTime < Time.time)
        {
            hp -= damage;
            lastDamageTime = Time.time;

            if (hp <= 0 )
            {
                //죽음
                Debug.Log("Dead");
               if(healthListener !=null)
                {
                    healthListener.OnDie();
                }
            }
            else
            {
                //다침
                Debug.Log("다침");
            }
        }
    }

    public interface IHealthListener
    {
        void OnDie();
    }
    void Update()
    {
        
    }
}

Hp 구현

filed → Horizontal

맞으면 피가 줄어들게

public class Health : MonoBehaviour
{

    public void Damage(float damage)
    {
        //마지막으로 얻어 맞은 시간 + 무적 시간이 현재 시간보다 적으면
        if (hp > 0 && lastDamageTime + invincibleTime < Time.time)
        {
            hp -= damage;

            if (hpGauge != null)
            {
                hpGauge.fillAmount = hp / maxHp;
            }
            //마지막으로 피해를 입은 시간을 기록
            lastDamageTime = Time.time;

            if (hp <= 0)
            {
                //죽음
                Debug.Log("Dead");
                if (healthListener != null)
                {
                    healthListener.OnDie();
                }
            }
            else
            {
                //다침
                Debug.Log("다침");
            }
        }
    }
}

HP 게이지의 Amount값에 따라 색 바뀌도록

using UnityEngine;
using UnityEngine.UI;

public class GaugeColor : MonoBehaviour
{
    void Update()
    {
        Image image = GetComponent<Image>();

        image.color = Color.HSVToRGB(image.fillAmount / 3, 1.0f, 1.0f);
    }
}


무서워 아저씨. ..

Render Mode

Screen Space - Camera 일때


거리를 설정하면 거리에 따라 캔버스가 뒤로 가보이게 됨

World Space 일때

Enemy HP 구현

Enemy아래 캔버스를 달아주고, Hp를 똑같이 해준다.

여기서 Canvas는 world space로 해줌

using UnityEngine;
using UnityEngine.UI;

public class Health : MonoBehaviour
{
    public float hp = 10;
    public float maxHp = 10;
    public float invincibleTime; //무적시간

    public Image hpGauge;

    public IHealthListener healthListener;
    float lastDamageTime;

    void Start()
    {
        healthListener = GetComponent<IHealthListener>();
    }
    public void Damage(float damage)
    {
        //마지막으로 얻어 맞은 시간 + 무적 시간이 현재 시간보다 적으면
        if (hp > 0 && lastDamageTime + invincibleTime < Time.time)
        {
            hp -= damage;

            if (hpGauge != null)
            {
                hpGauge.fillAmount = hp / maxHp;
            }

            //마지막으로 피해를 입은 시간을 기록
            lastDamageTime = Time.time;

            if (hp <= 0)
            {
                //죽음
                Debug.Log("Dead");
                if (healthListener != null)
                {
                    healthListener.OnDie();
                }
            }
            else
            {
                //다침
                Debug.Log("다침");
            }
        }
    }

    public interface IHealthListener
    {
        void OnDie();
    }
    void Update()
    {

    }
}

저 게이지가 나를 보도록

using UnityEngine;

public class LookCamera : MonoBehaviour
{
    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        transform.LookAt(transform.position + Camera.main.transform.forward);
        //HP 게이지가 나를 보도록
    }
}

위 코드 사용X(게이지를 보세용)

사용

Player 죽음

플레이어가 쓰러지면서 화면이 어두워지도록 만들어줌

이렇게하면 Player가 안 움직이는데 Apply Root Motion을 켜주면 움직인다.

Apply Root Motion : 오브젝트의 위치와 회전을 애니메이션이 제어하도록 할 것이냐를 결정

죽었을때 조작 불가능하도록

public class PlayerController : MonoBehaviour, Health.IHealthListener
{
......
    void Update()
    {
        if (GameManager.Instance.isPlaying)
        {
            Vector3 moveVector = moveAction.ReadValue<Vector2>(); //move 입력 감지
            Vector3 move = new Vector3(moveVector.x, 0, moveVector.y);
........

    public void OnDie()
    {
        GetComponent<Animator>().SetTrigger("Die");
        GameManager.Instance.PlayerDie();
    }
}



Sort Order가 2여야함

0개의 댓글

관련 채용 정보