달리다가 바로 멈췄으면 좋겠다 → 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()
{
}
}
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);
}
}
무서워 아저씨. ..
Screen Space - Camera 일때
거리를 설정하면 거리에 따라 캔버스가 뒤로 가보이게 됨
World Space 일때
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가 안 움직이는데 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여야함