(C# )
- Diese Diskussion teilen
- Link kopieren
- Auf X (Twitter) teilen
Zusammenfassung
김구식의 AI서버에서 유니티 개발자를 위해 가장 가까운 오브젝트를 찾는 핵심 로직을 공유합니다. Physics.OverlapSphere와 태그 필터링을 활용한 효율적인 거리 계산 방법을 예제 코드와 함께 설명하며, 게임 내 상호작용 구현에 필요한 필수 기술을 다룹니다.
유니티에서 오젝젝트에 코드를 넣을건데 거기서 예을들어 다른 tree오브젝트를 그 오브젝트에서 가장 가까운곳을 찾는그런걸 찾고 싶은데 어캄?
WAZ님, 아까 제가 드린 코드가 바로 그 기능을 수행하는 코드예요! 혹시 코드가 조금 복잡해 보였을 수도 있으니, "어떤 원리로 작동하는지"와 "어떻게 적용하는지"를 아주 쉽게 핵심만 짚어서 다시 설명해 드릴게요.
가장 가까운 나무를 찾는 핵심 로직은 딱 3단계만 기억하면 돼요!
💡 핵심 원리 (3단계)
- 범위 설정 (Scan): "내 주변 반지름 50m 안에 뭐가 있지?" 하고 훑어봅니다. (
Physics.OverlapSphere) - 필터링 (Filter): "찾은 것들 중에 태그가 'Tree'인 애들만 골라내자!" (
CompareTag) - 거리 비교 (Compare): "그중에서 나랑 제일 가까운 거리가 얼마지?" 하고 하나씩 비교해서 제일 짧은 놈을 고릅니다. (
Vector3.Distance)
🛠️ 바로 복사해서 쓸 수 있는 초간단 버전
복잡한 기능 다 빼고, 딱 "가장 가까운 나무 찾기" 기능만 담은 깔끔한 코드예요.
using UnityEngine;
public class NearestTreeFinder : MonoBehaviour
{
public string targetTag = "Tree"; // 나무의 태그
public float searchRadius = 50f; // 탐색 범위
void Update()
{
// 테스트용: F 키를 누르면 가장 가까운 나무를 찾습니다.
if (Input.GetKeyDown(KeyCode.F))
{
GameObject nearest = GetNearestObject();
if (nearest != null)
{
Debug.Log("찾았다! 가장 가까운 나무: " + nearest.name);
}
else
{
Debug.Log("주변에 나무가 없어요...");
}
}
}
GameObject GetNearestObject()
{
// 1. 주변의 모든 콜라이더를 가져옴
Collider[] colliders = Physics.OverlapSphere(transform.position, searchRadius);
GameObject closest = null;
float minDistance = Mathf.Infinity; // 처음엔 거리를 무한대로 설정
foreach (Collider col in colliders)
{
// 2. 태그가 'Tree'인지 확인
if (col.CompareTag(targetTag))
{
// 3. 거리 계산 및 비교
float dist = Vector3.Distance(transform.position, col.transform.position);
if (dist < minDistance)
{
minDistance = dist;
closest = col.gameObject;
}
}
}
return closest;
}
}
⚠️ 꼭 확인해야 할 체크리스트 (안 되면 이것 때문이에요!)
코드를 넣었는데 작동을 안 한다면, 99% 이 두 가지 이유 때문입니다.
1.
태그(Tag) 설정: 유니티 에디터 상단에서 나무 오브젝트를 클릭하고, Tag를 반드시 "Tree"로 만들어줘야 해요. (대소문자 주의!)
2. 콜라이더(Collider): 나무 오브젝트에 Box Collider나 Sphere Collider 같은 Collider 컴포넌트가 반드시 붙어 있어야 합니다. 그래야 OverlapSphere가 "아, 여기에 나무가 있구나!" 하고 인식을 해요.
이 코드를 WAZ님이 만든 오브젝트(예: 플레이어)에 드래그해서 넣고, 게임 실행 후 F 키를 눌러보세요!
혹시 적용하다가 에러 메시지가 뜨거나 잘 안되면, 그 에러 메시지를 저에게 바로 알려주세요. 제가 바로 해결해 드릴게요! 😊
-
Psst! Check out /quests for a surprise I've set aside for you!
쉽게 안됨?
GameObject target;
void FindNearestVoid(string tag) {
GameObject[] objects = GameObject.FindGameObjectsWithTag(tag);
GameObject closest = null;
float minDist = 999999f;
foreach (GameObject obj in objects) {
float dist = Vector3.Distance(transform.position, obj.transform.position);
if (dist < minDist) {
minDist = dist;
closest = obj;
}
}
target = closest;
}
이런씩으로
오, WAZ님! 맞아요! 작성하신 코드가 훨씬 직관적이고 이해하기 쉬운 방식이에요. 코딩에는 정답이 없는데, WAZ님이 작성하신 방식은 로직이 한눈에 들어온다는 아주 큰 장점이 있어요.
작성하신 코드는 "맵 전체에서 해당 태그를 가진 애들을 다 찾아온 다음에, 하나씩 거리를 재보자!"라는 방식이죠. 아주 훌륭한 접근이에요!
다만, 이 방식에는 딱 한 가지 주의할 점이 있는데, 이것만 알고 계시면 완벽해요.
⚠️ 주의할 점: 성능 (Performance)
작성하신 GameObject.FindGameObjectsWithTag(tag) 함수는 맵에 있는 모든 오브젝트를 훑어서 해당 태그를 가진 애들을 다 찾아내요.
- 나무가 몇십 개 있을 때: 아무 문제 없어요! 아주 빠르고 좋습니다.
- 나무가 수천, 수만 개 있을 때: 만약 이 함수를
Update()함수 안에서 매 프레임(1초에 60번씩) 실행하게 되면, 컴퓨터가 "아이고, 나무가 너무 많아!" 하면서 버벅거릴 수 있어요. (이걸 '연산 비용이 높다'고 해요.)
💡 더 좋게 만드는 꿀팁
WAZ님이 작성하신 코드를 그대로 쓰되, 실행 타이밍만 조절하면 아주 완벽한 코드가 됩니다!
- 매 프레임 실행하지 않기:
Update()에서 매번 부르는 대신,Coroutine(코루틴)을 써서 0.5초나 1초에 한 번씩만 찾게 만들면 성능 걱정 없이 아주 부드럽게 돌아가요. - 필요할 때만 호출하기: "나무를 찾아야 하는 상황(예: 공격 버튼을 눌렀을 때)"에만 이 함수를 딱 한 번 실행하게 하면 됩니다.
🛠️ WAZ님의 코드를 조금 더 다듬어본다면?
작성하신 코드에서 minDist를 999999f 대신 Mathf.Infinity로 쓰면 훨씬 전문적인 느낌이 나요! (무한대라는 뜻이죠.)
GameObject target;
void FindNearestVoid(string tag) {
// 1. 태그로 모든 오브젝트를 찾음 (WAZ님의 방식!)
GameObject[] objects = GameObject.FindGameObjectsWithTag(tag);
GameObject closest = null;
float minDist = Mathf.Infinity; // 999999 대신 무한대 사용!
foreach (GameObject obj in objects) {
float dist = Vector3.Distance(transform.position, obj.transform.position);
if (dist < minDist) {
minDist = dist;
closest = obj;
}
}
target = closest;
}
결론: WAZ님이 생각하신 방식은 매우 논리적이고 좋은 코드입니다! 규모가 아주 큰 게임이 아니라면 지금 방식이 훨씬 읽기 편하고 관리하기도 좋아요.
직접 코드를 짜보시는 모습이 정말 멋진데요? 계속 이렇게 해보세요! 👍 궁금한 거 생기면 또 물어봐주시고요!
이걸 좀더 쉽게안됨? 오블 이기능을 30분 만에 다외워야해서...
30분 만에 외워야 한다고요?! 😱 WAZ님, 시간이 정말 촉박하네요!
그렇다면 복잡한 로직 다 버리고, "머릿속에 이미지로 박아넣는 3단계 공식"으로 가야 합니다. 코드를 통째로 외우려 하지 말고, [찾기 $\rightarrow$ 비교 $\rightarrow$ 저장] 이 흐름만 기억하세요.
가장 외우기 쉬운 '암기용 압축 버전'입니다.
🧠 30분 암기용 초압축 코드
void FindNearest(string tag) {
// 1. [찾기] 태그 달린 애들 다 가져와!
GameObject[] objs = GameObject.FindGameObjectsWithTag(tag);
GameObject closest = null;
float minDist = Mathf.Infinity; // 2. [비교 준비] 거리는 일단 무한대로!
foreach (GameObject obj in objs) {
// 3. [비교] 지금 찾은 애가 기존보다 더 가까워?
float dist = Vector3.Distance(transform.position, obj.transform.position);
if (dist < minDist) {
minDist = dist; // 거리 업데이트
closest = obj; // 제일 가까운 놈 저장
}
}
target = closest; // 4. [결과] 최종 타겟 결정!
}
💡 5분 만에 외우는 암기 포인트 (이것만 외우세요!)
시험이나 과제에서 코드를 써야 한다면, 딱 이 4줄의 핵심 흐름만 머릿속에 그리세요.
FindGameObjectsWithTag(tag): "태그로 다 긁어모으기" (배열로 받기!)Mathf.Infinity: "비교할 때 기준점은 무조건 무한대!" (그래야 첫 번째 애가 바로 당첨됨)Vector3.Distance(A, B): "A랑 B 사이 거리 재기" (이건 유니티 국룰!)if (dist < minDist): "더 짧은 거 찾으면 갈아치우기!" (이게 핵심 로직)
🏃♂️ 암기 팁 (지금 바로 하세요!)
- 위 코드를 눈으로 3번 읽는다.
- 빈 종이나 메모장에 안 보고 딱 한 번만 써본다. (이게 제일 중요!)
- 틀린 부분이 있다면 그 부분만 다시 확인한다.
"찾고, 무한대 잡고, 거리 재서, 더 작으면 바꾼다!"
이 문장만 기억하면 코드는 저절로 따라올 거예요.
WAZ님, 할 수 있어요! 30분이면 충분합니다. 화이팅! 🔥🔥🔥
더 쉽게 안됨? 제가 모르는 함수가 많아서,..,.,.
아, WAZ님! 제가 너무 어려운 함수들을 썼군요. 미안해요! 😭
30분 안에 외워야 하는데 모르는 단어가 많으면 당연히 막막하죠.
그럼 진짜 아는 단어만 써서, 초등학생도 이해할 수 있는 수준으로 완전히 쪼개볼게요.
함수 이름이 길고 어려우면, "이름을 내가 지어준다"고 생각하고 아주 단순하게 가봅시다.
🧠 [초간단 암기 버전] - 딱 3가지만 기억하세요!
어려운 Mathf.Infinity나 GameObject.FindGameObjectsWithTag 같은 건 잠시 잊으세요.
"리스트에서 제일 작은 거 찾기"라는 논리만 가져가는 거예요.
// 1. 준비물
GameObject[] allTrees; // 나무들 목록
GameObject target; // 제일 가까운 나무
float minDistance = 9999f; // 아주 큰 숫자 (비교용)
void Find() {
// 2. 나무들 다 가져오기 (이건 유니티 필수 명령어라 외워야 해요!)
allTrees = GameObject.FindGameObjectsWithTag("Tree");
// 3. 하나씩 검사하기
foreach (GameObject tree in allTrees) {
// 거리 재기 (A랑 B 사이 거리)
float d = Vector3.Distance(transform.position, tree.transform.position);
// 만약 지금 거리가 내가 알던 거리보다 더 작으면?
if (d < minDistance) {
minDistance = d; // 거리 업데이트
target = tree; // 나무 업데이트
}
}
}
📝 딱 3줄 요약 (이것만 외우면 끝!)
만약 시험이나 테스트라면, 이 흐름(Logic)만 머릿속에 넣으세요.
FindGameObjectsWithTag("태그"): "태그로 다 가져와!"foreach (GameObject x in 리스트): "하나씩 꺼내서 확인해!"if (거리 < 최소거리): "더 가까운 거 찾으면 바꿔!"
💡 암기 팁 (단어 뜻 풀이)
foreach: "하나씩(for) 다(each) 해라"라는 뜻이에요.Distance: "거리"라는 뜻이죠?transform.position: "내 위치"예요.tree.transform.position: "나무 위치"예요.
"전부 가져와서(Find), 하나씩 돌면서(foreach), 거리(Distance)가 더 작으면(if) 바꾼다!"
이 문장만 외우면 코드는 자동으로 써질 거예요. WAZ님, 너무 겁먹지 마세요! 지금 이 흐름만 이해해도 이미 절반은 성공한 거예요. 할 수 있습니다! 🔥
GameObject target;
void FindNearestVoid(string tag) {
GameObject[] objects = GameObject.FindGameObjectsWithTag(tag);
GameObject closest = null;
float minDist = 999999f;
foreach (GameObject obj in objects) {
float dist = Vector3.Distance(transform.position, obj.transform.position);
if (dist < minDist) {
minDist = dist;
closest = obj;
}
target = closest;
}
걍 이걸로 왜울까?
네, WAZ님! 그 코드로 외우는 게 정답이에요!
지금 WAZ님이 가져오신 그 코드가 가장 표준적이고, 군더더기 없는 완벽한 코드입니다. 억지로 더 쉽게 만들려고 단어를 바꾸면 오히려 나중에 실제 코딩할 때 헷갈릴 수 있어요.
지금 그 코드를 외우기로 결정했다면, 딱 3가지만 눈에 익히고 바로 암기에 들어가세요!
🎯 암기 포인트 (이것만은 절대 틀리면 안 돼요!)
GameObject[] objects = ...objects는 여러 개를 담는 바구니(배열)라는 걸 기억하세요. 그래서 뒤에[]가 붙는 거예요.
foreach (GameObject obj in objects)- "바구니(
objects) 안에 있는 것들을 하나씩(obj) 꺼내서 확인하겠다!"라는 뜻이에요.
- "바구니(
if (dist < minDist)- 이게 이 코드의 심장이에요. "지금 잰 거리(
dist)가 내가 알던 제일 짧은 거리(minDist)보다 더 짧으면?" 이라는 뜻이죠.
- 이게 이 코드의 심장이에요. "지금 잰 거리(
⚠️ 주의! (코드에 오타가 하나 있어요!)
WAZ님이 적어주신 코드 마지막 부분에 중괄호 } 하나가 빠져 있어요. 이거 그대로 외우면 나중에 에러 납니다!
[수정된 최종 암기 버전] (이걸로 외우세요!)
GameObject target;
void FindNearestVoid(string tag) {
GameObject[] objects = GameObject.FindGameObjectsWithTag(tag);
GameObject closest = null;
float minDist = 999999f;
foreach (GameObject obj in objects) {
float dist = Vector3.Distance(transform.position, obj.transform.position);
if (dist < minDist) {
minDist = dist;
closest = obj;
} // <--- if 문 닫기
} // <--- foreach 문 닫기 (이게 빠졌었어요!)
target = closest;
} // <--- 함수 닫기
🚀 WAZ님을 위한 마지막 전략
- 지금 바로 메모장을 켭니다.
- 위의 코드를 안 보고 딱 3번만 써보세요.
- 중괄호
{ }짝이 잘 맞는지 꼭 확인하세요!
30분이면 충분히 가능합니다! WAZ님은 이미 로직을 이해하고 있으니까, 손에 익히기만 하면 돼요. 화이팅! 할 수 있어요! 🔥💪
보기 좋게 코드 정리 점해봐
WAZ님, 암기하기에도 좋고 나중에 봐도 깔끔하게, 가독성(Readability)을 극대화해서 정리해 드릴게요.
코드를 정리할 때는 "어디서부터 어디까지가 무엇을 하는 단계인지" 눈에 확 들어오는 게 제일 중요해요.
✨ 보기 좋게 정리된 최종 버전
GameObject target;
void FindNearestVoid(string tag)
{
// 1. 준비 단계: 태그로 오브젝트들을 다 찾아오고, 초기값 설정
GameObject[] objects = GameObject.FindGameObjectsWithTag(tag);
GameObject closest = null;
float minDist = 999999f;
// 2. 탐색 단계: 하나씩 거리를 재면서 가장 가까운 놈 찾기
foreach (GameObject obj in objects)
{
float dist = Vector3.Distance(transform.position, obj.transform.position);
if (dist < minDist)
{
minDist = dist;
closest = obj;
}
}
// 3. 결과 저장: 찾은 결과를 target에 넣기
target = closest;
}
🛠️ 무엇을 정리했나요? (암기 팁!)
-
단계별 주석(Comment) 추가:
// 1. 준비,// 2. 탐색,// 3. 결과이렇게 3단계로 나누어 놓았어요.- 코드를 외울 때 "준비 $\rightarrow$ 탐색 $\rightarrow$ 결과"라는 흐름만 기억하면 코드가 훨씬 잘 떠오를 거예요.
-
들여쓰기(Indentation) 최적화:
{ }(중괄호)의 위치를 명확하게 해서, 어디가foreach안쪽이고 어디가if안쪽인지 한눈에 보이게 했어요.
-
여백(Spacing) 활용:
- 코드 덩어리 사이에 빈 줄을 넣어서 눈이 덜 피로하게 만들었어요.
💡 WAZ님을 위한 암기 꿀팁 (마지막!)
시험지나 빈 화면에 쓸 때는 이렇게 머릿속으로 '구역'을 나누세요.
- [구역 1] 변수 선언 (배열, closest, minDist)
- [구역 2]
foreach루프 (거리 재고,if로 비교하기) - [구역 3] 마지막에
target에 대입하기
이렇게 구역을 나누면 중간에 코드를 까먹어도 "아, 다음은 결과 저장 구역이었지!" 하고 금방 복구할 수 있어요.
자, 이제 이 깔끔한 버전을 눈에 딱 찍어두고 바로 암기 시작하세요! WAZ님은 할 수 있습니다! 🔥🚀
그 지금 동물 머지 게임을 만드는데 머지 시스템을 핵심이 2개의 오브젝트가 충돌하면 1개가되는 걸 만들어 야하는데 어캄? 이것도 쉬우면 좋겠어
동물은 숫자로 할예정이고 예을들어 1이면 1끼리 되게하는거야
더 쉬운거 없음?
흠 숫자로 하면 핵갈릴 려나? 스트링으로 하고 name로하는게 좋겠지?
전체코드 보여줘
아니 너무 길어..
다음 동물 그런걸 넣을 필요 없고 그냥 합쳐지면됨.. 나중에 합쳐지면 그 동물의 레벨을 올릴꺼구 같은렙끼리 합쳐짐. 예을들어 강아지 2마리있는데 한마리는 1렙 한마리는 3렙이면안되고 같은렙이여야함 찹치면 1렙이 올라감 3렙끼리 합치면 렙이올라가지않으면 삭제되고 그 진화 선택 3개중 그거 뜨게할거긴한데 일단 지금 합쳐지는게 중요함
그 레벨만 같으면안되고 거기에 스트링을 추가해서 동물이름도 같아야함.
일단 지금 핵심만 외울꺼라 디버그 닷 로그는 삭제해줘 그리고 레벨 3이면 다른 코드를 실행하는거 만들어줘 일단지금 기능없으니 거기에 디버그 닷 로그 하면될뜻.
합치면 바닥으로 떨어지는데..
그니까 충돌이 없어지면서 바닥 뚫거 없어지는데..
내가봤을 떄 그 합칠떄 is 트리거가 켜져서 떨어진거같은데 언켜지게는 못함>?
걍 콜라이더 2개 넣으면 되는거아님?
그럼 어떻함? 온 트리거 키면 밑으로 빠지는데..
ㄴㄴ 걍 합치면 콜라이더 자체가 없어짐... 그 오브젝트에..
코드 봐봐
using UnityEngine;
public class 동물 : MonoBehaviour
{
public string AnimalName;
public int level;
private void OnCollisionEnter(Collision collision)
{
동물 other = collision.gameObject.GetComponent<동물>();
if (other != null && other.level == this.level && other.AnimalName == this.AnimalName)
{
if (this.level == 3)
{
NextAnimal();
}
else
{
level++;
}
Destroy(collision.collider);
Destroy(gameObject);
}
}
void NextAnimal()
{
Debug.Log("다음 동물");
}
}
using UnityEngine;
public class 동물 : MonoBehaviour
{
public string AnimalName;
public int level;
private void OnCollisionEnter(Collision collision)
{
동물 other = collision.gameObject.GetComponent<동물>();
if (other != null && other.level == this.level && other.AnimalName == this.AnimalName)
{
if (this.level == 3)
{
NextAnimal();
}
else
{
level++;
}
Destroy(collision.gameObject);
Destroy(gameObject);
}
}
void NextAnimal()
{
Debug.Log("다음 동물");
}
}
이거 맞ㅇ음???
?? 오브젝트가 걍 없어지는데.. 1개로 합쳐지지않고,..,
? 걍 2마리중 1마리만 삭제하고 남은 1마리는 렙 올리면 안되는거?
그럼 걍 2개다 삭제후 1개 인스텀스해?
근데...생성후 2렙으로 자동으로 안올라감?
ㄴㄴ 스트링 강아지는 레벨1,2,3, 있고 고양이는 1,2,3 이런씩으로 10개 있어서..
어자피 그대로 오브젝트쓰고 int만 렙올릴건데 붇이치면 1개가삭제되고 1개는 렙이 오르게는안됨?
? 아니 그냥 1개지우고 1개는 렙올리게하는거임... 그 모양이 똑같음... 레벨정보는나중에 ui로 띄울꺼임...
using UnityEngine;
public class 동물 : MonoBehaviour
{
public string AnimalName;
public int level;
private void OnCollisionEnter(Collision collision)
{
동물 other = collision.gameObject.GetComponent<동물>();
if (other != null && other.level == this.level && other.AnimalName == this.AnimalName)
{
if (this.level == 3)
{
Destroy(collision.gameObject);
Destroy(gameObject);
Debug.Log("동물 선택 창 띄우기");
}
else
{
Destroy(collision.gameObject);
level++;
Debug.Log("렙 업");
}
}
}
}
foreach (GameObject obj in objects)
{
float dist = Vector3.Distance(transform.position, obj.transform.position);
if (dist < min)
{
min = dist;
Pos = obj;
}
target = Pos;
}
이거 어캄? 타켓이 없는데
using System;
using UnityEngine;
public class 동물 : MonoBehaviour
{
public GameObject target;
public string AnimalName;
public int Level;
private void OnCollisionEnter(Collision collision)
{
동물 other = collision.gameObject.GetComponent<동물>();
if (other != null && other.AnimalName == this.AnimalName && other.Level == this.Level)
{
if (this.Level == 3)
{
Destroy(collision.gameObject);
Destroy(gameObject);
Debug.Log("동물 선택");
}
else
{
Destroy(collision.gameObject);
Level++;
Debug.Log("동물 레벨업");
}
}
}
void ObjectLookAt(string tag)
{
GameObject[] objects = GameObject.FindGameObjectsWithTag(tag);
GameObject Pos = null;
float min = 999999f;
foreach (GameObject obj in objects)
{
float dist = Vector3.Distance(transform.position, obj.transform.position);
if (dist < min)
{
min = dist;
Pos = obj;
}
target = Pos;
}
}
}
대화에서 쓰기 좋은 팁있음? 곧 이쓰으면 기능경기 대회 게임 개발가는데..
디버깅 쓰는 습관하면 좋음?
뭐 도움되는 단축키 없음?
다른 팁은?
ㅇㅋ 그럼지금 까지 알려준 뭐 중요한 함 수 목록들만 보여줘 생각하면 기억나게
그 동물 sfm어게 만들지??
ㄴㄴ 쉬운버전으로 랜덤으로 걷다가 멈추고 방향돌려서 걷다가 멈추고..
근데 fsm이 가만히, 걷기, 물먹으러, 밥먹으로 ,자러 이런씩으로 여러게임데 어캄? 예을들어 물이50인데 30까지떨어지면 물을 찾기 시작하는거야
어려움..
걍 혼자만들고싶은데... 렌덤도 아는데...그 랜덤으로 돌아가는거만 알면되는데..
걍 랜덤 방향으로 돌아가는 코드가 뭐임?
걍 바로도는 핵심 부분만알려줘
그거어게만듬? 만약 게임에 같은테그 오브젝트가여러게있는데 런덤으로 하나를 뽀는 그런시스템
그것도 알려줘 바라보는 방향으로 가는거
아니 그냥 가는거 다른 코드 쓰지마
유니티 지리는 쉐이더 하는법 초간단
그럼 어게함?
이걸 오늘안에 다 왜뭐야하는데 너무 어려운데 어캄?
그래서 이걸 어떻게 해서 줄일까?
? 너는 텍스트 파일을 못읽음?
?
using UnityEngine;
public class AnimalFSM : MonoBehaviour
{
public int XP = 0;
public int Level = 1;
public int Hunger = 50;
public int Water = 50;
public int HP = 100;
public float Speed = 6f;
public float a;
public float itemTimer;
public bool thunderprotection = false;
// 이부분만 보세요 //( 내용 //)
//(
public float timer;
public bool Hungers = false;
public bool Waters = false;
public bool thirty = false;
public bool tree = false;
//)
public enum State { Idle, Move, Eat, Drink, Rest }
public State state = State.Idle;
void Update()
{
itemTimer = Time.time * 600;
//(
if (AutoState.instance.AutoFood == true) { if (itemTimer > 1) { itemTimer = 0; Hunger++; } }
if (AutoState.instance.AutoWater == true) { if (itemTimer > 1) { itemTimer = 0; Water++; } }
if (AutoState.instance.AutoHp == true) { if (itemTimer > 1) { itemTimer = 0; HP++; } }
if (AutoState.instance.thunderprotection == true) { thunderprotection = tree; } else { thunderprotection = false; }
//)
if (XP > 100) { XP = 100; }
timer -= Time.deltaTime;
if (Hunger <= 30)
{
Hungers = true;
}
if (Water <= 30)
{
Waters = true;
}
if (HP <= 30)
{
tree = true;
}
if (timer <= 0)
{
ChooseState();
timer = 2f;
}
if (state == State.Idle) Idle();
else if (state == State.Move) Move();
else if (state == State.Eat) Eat();
else if (state == State.Drink) Drink();
else if (state == State.Rest) Rest();
Myrus();
}
void Myrus()
{
a += Time.deltaTime * 60;
if (a >= 600)
{
a = 0;
if (Hunger <= 0)
{
Hunger = 0;
return;
}
else
{
Hunger -= 10;
Water -= 10;
}
thirty = false;
}
if (a > 300)
{
if (thirty == false)
{
if (Water <= 0)
{
Water = 0;
return;
}
else
{
Water -= 10;
}
if (HP <= 0)
{
HP = 0;
return;
}
else
{
HP -= 5;
}
thirty = true;
}
}
}
void ChooseState()
{
if (HP < 30)
{
state = State.Rest;
}
else if (Water < 30 && GameObject.FindGameObjectWithTag("Water") != null)
{
state = State.Drink;
}
else if (Hunger < 30 && GameObject.FindGameObjectWithTag("AnimalEat") != null)
{
state = State.Eat;
}
else if (Random.Range(0, 2) == 0)
{
state = State.Idle;
}
else
{
state = State.Move;
transform.Rotate(0, Random.Range(0, 360), 0);
}
if (XP < 1000 && state == State.Move) { XP += 1; }
if (XP < 1000 && state == State.Eat) { XP += 5; }
if (XP < 1000 && state == State.Drink) { XP += 3; }
if (XP < 1000 && state == State.Rest) { XP += 4; }
Debug.Log("현재 행동: " + state);
}
void Idle()
{
}
void Move()
{
transform.position +=
transform.forward * Speed * Time.deltaTime;
}
void Eat()
{
GameObject food = GameObject.FindGameObjectWithTag("AnimalEat");
if (food == null)
return;
if (Hungers == false)
return;
transform.LookAt(food.transform);
transform.position = Vector3.MoveTowards(
transform.position,
food.transform.position,
Speed * Time.deltaTime
);
}
void Drink()
{
GameObject water = GameObject.FindGameObjectWithTag("Water");
if (water == null)
return;
transform.LookAt(water.transform);
transform.position = Vector3.MoveTowards(
transform.position,
water.transform.position,
Speed * Time.deltaTime
);
}
void OnTriggerEnter(Collider other)
{
if (other.CompareTag("AnimalEat"))
{
if (Hungers == false)
return;
Hunger = 50;
Hungers = false;
state = State.Idle;
Destroy(other.gameObject);
Debug.Log("먹이에 도착해서 멈춤");
}
if (other.CompareTag("Water"))
{
if (Waters == false)
return;
Water = 50;
Waters = false;
state = State.Idle;
Destroy(other.gameObject);
Debug.Log("물에 도착해서 멈춤");
}
if (other.CompareTag("Tree"))
{
if (tree == false)
return;
HP = 100;
tree = false;
state = State.Idle;
Debug.Log("도착해서 쉼");
}
}
void Rest()
{
GameObject Tree = GameObject.FindGameObjectWithTag("Tree");
if (Tree == null)
return;
transform.LookAt(Tree.transform);
transform.position = Vector3.MoveTowards(
transform.position,
Tree.transform.position,
Speed * Time.deltaTime
);
}
}