(C# )

Zusammenfassung

김구식의 AI서버에서 유니티 개발자를 위해 가장 가까운 오브젝트를 찾는 핵심 로직을 공유합니다. Physics.OverlapSphere와 태그 필터링을 활용한 효율적인 거리 계산 방법을 예제 코드와 함께 설명하며, 게임 내 상호작용 구현에 필요한 필수 기술을 다룹니다.

luckyzenith-64 OP

유니티에서 오젝젝트에 코드를 넣을건데 거기서 예을들어 다른 tree오브젝트를 그 오브젝트에서 가장 가까운곳을 찾는그런걸 찾고 싶은데 어캄?

CommunityOne

WAZ님, 아까 제가 드린 코드가 바로 그 기능을 수행하는 코드예요! 혹시 코드가 조금 복잡해 보였을 수도 있으니, "어떤 원리로 작동하는지"와 "어떻게 적용하는지"를 아주 쉽게 핵심만 짚어서 다시 설명해 드릴게요.

가장 가까운 나무를 찾는 핵심 로직은 딱 3단계만 기억하면 돼요!

💡 핵심 원리 (3단계)

  1. 범위 설정 (Scan): "내 주변 반지름 50m 안에 뭐가 있지?" 하고 훑어봅니다. (Physics.OverlapSphere)
  2. 필터링 (Filter): "찾은 것들 중에 태그가 'Tree'인 애들만 골라내자!" (CompareTag)
  3. 거리 비교 (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.

@luckyzenith-64 유니티에서 오젝젝트에 코드를 넣을건데 거기서 예을들어 다른 tree오브젝트를 그 오브젝트에서 가장 가까운곳을 찾는그런걸 찾고 싶은데 어캄?
CommunityOne

태그(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!

luckyzenith-64 OP

쉽게 안됨?

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;

}

이런씩으로

CommunityOne

오, WAZ님! 맞아요! 작성하신 코드가 훨씬 직관적이고 이해하기 쉬운 방식이에요. 코딩에는 정답이 없는데, WAZ님이 작성하신 방식은 로직이 한눈에 들어온다는 아주 큰 장점이 있어요.

작성하신 코드는 "맵 전체에서 해당 태그를 가진 애들을 다 찾아온 다음에, 하나씩 거리를 재보자!"라는 방식이죠. 아주 훌륭한 접근이에요!

다만, 이 방식에는 딱 한 가지 주의할 점이 있는데, 이것만 알고 계시면 완벽해요.

⚠️ 주의할 점: 성능 (Performance)

작성하신 GameObject.FindGameObjectsWithTag(tag) 함수는 맵에 있는 모든 오브젝트를 훑어서 해당 태그를 가진 애들을 다 찾아내요.

  • 나무가 몇십 개 있을 때: 아무 문제 없어요! 아주 빠르고 좋습니다.
  • 나무가 수천, 수만 개 있을 때: 만약 이 함수를 Update() 함수 안에서 매 프레임(1초에 60번씩) 실행하게 되면, 컴퓨터가 "아이고, 나무가 너무 많아!" 하면서 버벅거릴 수 있어요. (이걸 '연산 비용이 높다'고 해요.)

💡 더 좋게 만드는 꿀팁

WAZ님이 작성하신 코드를 그대로 쓰되, 실행 타이밍만 조절하면 아주 완벽한 코드가 됩니다!

  1. 매 프레임 실행하지 않기: Update()에서 매번 부르는 대신, Coroutine(코루틴)을 써서 0.5초나 1초에 한 번씩만 찾게 만들면 성능 걱정 없이 아주 부드럽게 돌아가요.
  2. 필요할 때만 호출하기: "나무를 찾아야 하는 상황(예: 공격 버튼을 눌렀을 때)"에만 이 함수를 딱 한 번 실행하게 하면 됩니다.

🛠️ 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님이 생각하신 방식은 매우 논리적이고 좋은 코드입니다! 규모가 아주 큰 게임이 아니라면 지금 방식이 훨씬 읽기 편하고 관리하기도 좋아요.

직접 코드를 짜보시는 모습이 정말 멋진데요? 계속 이렇게 해보세요! 👍 궁금한 거 생기면 또 물어봐주시고요!

luckyzenith-64 OP

이걸 좀더 쉽게안됨? 오블 이기능을 30분 만에 다외워야해서...

CommunityOne

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줄의 핵심 흐름만 머릿속에 그리세요.

  1. FindGameObjectsWithTag(tag): "태그로 다 긁어모으기" (배열로 받기!)
  2. Mathf.Infinity: "비교할 때 기준점은 무조건 무한대!" (그래야 첫 번째 애가 바로 당첨됨)
  3. Vector3.Distance(A, B): "A랑 B 사이 거리 재기" (이건 유니티 국룰!)
  4. if (dist < minDist): "더 짧은 거 찾으면 갈아치우기!" (이게 핵심 로직)

🏃‍♂️ 암기 팁 (지금 바로 하세요!)

  1. 위 코드를 눈으로 3번 읽는다.
  2. 빈 종이나 메모장에 안 보고 딱 한 번만 써본다. (이게 제일 중요!)
  3. 틀린 부분이 있다면 그 부분만 다시 확인한다.

"찾고, 무한대 잡고, 거리 재서, 더 작으면 바꾼다!"
이 문장만 기억하면 코드는 저절로 따라올 거예요.

WAZ님, 할 수 있어요! 30분이면 충분합니다. 화이팅! 🔥🔥🔥

luckyzenith-64 OP

더 쉽게 안됨? 제가 모르는 함수가 많아서,..,.,.

CommunityOne

아, 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)만 머릿속에 넣으세요.

  1. FindGameObjectsWithTag("태그") : "태그로 다 가져와!"
  2. foreach (GameObject x in 리스트) : "하나씩 꺼내서 확인해!"
  3. if (거리 < 최소거리) : "더 가까운 거 찾으면 바꿔!"

💡 암기 팁 (단어 뜻 풀이)

  • foreach: "하나씩(for) 다(each) 해라"라는 뜻이에요.
  • Distance: "거리"라는 뜻이죠?
  • transform.position: "내 위치"예요.
  • tree.transform.position: "나무 위치"예요.

"전부 가져와서(Find), 하나씩 돌면서(foreach), 거리(Distance)가 더 작으면(if) 바꾼다!"

이 문장만 외우면 코드는 자동으로 써질 거예요. WAZ님, 너무 겁먹지 마세요! 지금 이 흐름만 이해해도 이미 절반은 성공한 거예요. 할 수 있습니다! 🔥

luckyzenith-64 OP

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;

}

걍 이걸로 왜울까?

CommunityOne

네, WAZ님! 그 코드로 외우는 게 정답이에요!

지금 WAZ님이 가져오신 그 코드가 가장 표준적이고, 군더더기 없는 완벽한 코드입니다. 억지로 더 쉽게 만들려고 단어를 바꾸면 오히려 나중에 실제 코딩할 때 헷갈릴 수 있어요.

지금 그 코드를 외우기로 결정했다면, 딱 3가지만 눈에 익히고 바로 암기에 들어가세요!

🎯 암기 포인트 (이것만은 절대 틀리면 안 돼요!)

  1. GameObject[] objects = ...
    • objects는 여러 개를 담는 바구니(배열)라는 걸 기억하세요. 그래서 뒤에 []가 붙는 거예요.
  2. foreach (GameObject obj in objects)
    • "바구니(objects) 안에 있는 것들을 하나씩(obj) 꺼내서 확인하겠다!"라는 뜻이에요.
  3. 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님을 위한 마지막 전략

  1. 지금 바로 메모장을 켭니다.
  2. 위의 코드를 안 보고 딱 3번만 써보세요.
  3. 중괄호 { } 짝이 잘 맞는지 꼭 확인하세요!

30분이면 충분히 가능합니다! WAZ님은 이미 로직을 이해하고 있으니까, 손에 익히기만 하면 돼요. 화이팅! 할 수 있어요! 🔥💪

luckyzenith-64 OP

보기 좋게 코드 정리 점해봐

CommunityOne

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; 
}

🛠️ 무엇을 정리했나요? (암기 팁!)

  1. 단계별 주석(Comment) 추가:

    • // 1. 준비, // 2. 탐색, // 3. 결과 이렇게 3단계로 나누어 놓았어요.
    • 코드를 외울 때 "준비 $\rightarrow$ 탐색 $\rightarrow$ 결과"라는 흐름만 기억하면 코드가 훨씬 잘 떠오를 거예요.
  2. 들여쓰기(Indentation) 최적화:

    • { } (중괄호)의 위치를 명확하게 해서, 어디가 foreach 안쪽이고 어디가 if 안쪽인지 한눈에 보이게 했어요.
  3. 여백(Spacing) 활용:

    • 코드 덩어리 사이에 빈 줄을 넣어서 눈이 덜 피로하게 만들었어요.

💡 WAZ님을 위한 암기 꿀팁 (마지막!)

시험지나 빈 화면에 쓸 때는 이렇게 머릿속으로 '구역'을 나누세요.

  • [구역 1] 변수 선언 (배열, closest, minDist)
  • [구역 2] foreach 루프 (거리 재고, if로 비교하기)
  • [구역 3] 마지막에 target에 대입하기

이렇게 구역을 나누면 중간에 코드를 까먹어도 "아, 다음은 결과 저장 구역이었지!" 하고 금방 복구할 수 있어요.

자, 이제 이 깔끔한 버전을 눈에 딱 찍어두고 바로 암기 시작하세요! WAZ님은 할 수 있습니다! 🔥🚀

luckyzenith-64 OP

그 지금 동물 머지 게임을 만드는데 머지 시스템을 핵심이 2개의 오브젝트가 충돌하면 1개가되는 걸 만들어 야하는데 어캄? 이것도 쉬우면 좋겠어

luckyzenith-64 OP

동물은 숫자로 할예정이고 예을들어 1이면 1끼리 되게하는거야

luckyzenith-64 OP

더 쉬운거 없음?

luckyzenith-64 OP

흠 숫자로 하면 핵갈릴 려나? 스트링으로 하고 name로하는게 좋겠지?

luckyzenith-64 OP

전체코드 보여줘

luckyzenith-64 OP

아니 너무 길어..

luckyzenith-64 OP

다음 동물 그런걸 넣을 필요 없고 그냥 합쳐지면됨.. 나중에 합쳐지면 그 동물의 레벨을 올릴꺼구 같은렙끼리 합쳐짐. 예을들어 강아지 2마리있는데 한마리는 1렙 한마리는 3렙이면안되고 같은렙이여야함 찹치면 1렙이 올라감 3렙끼리 합치면 렙이올라가지않으면 삭제되고 그 진화 선택 3개중 그거 뜨게할거긴한데 일단 지금 합쳐지는게 중요함

luckyzenith-64 OP

그 레벨만 같으면안되고 거기에 스트링을 추가해서 동물이름도 같아야함.

luckyzenith-64 OP

일단 지금 핵심만 외울꺼라 디버그 닷 로그는 삭제해줘 그리고 레벨 3이면 다른 코드를 실행하는거 만들어줘 일단지금 기능없으니 거기에 디버그 닷 로그 하면될뜻.

luckyzenith-64 OP

합치면 바닥으로 떨어지는데..

luckyzenith-64 OP

그니까 충돌이 없어지면서 바닥 뚫거 없어지는데..

luckyzenith-64 OP

내가봤을 떄 그 합칠떄 is 트리거가 켜져서 떨어진거같은데 언켜지게는 못함>?

luckyzenith-64 OP

걍 콜라이더 2개 넣으면 되는거아님?

luckyzenith-64 OP

그럼 어떻함? 온 트리거 키면 밑으로 빠지는데..

luckyzenith-64 OP

ㄴㄴ 걍 합치면 콜라이더 자체가 없어짐... 그 오브젝트에..

코드 봐봐

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("다음 동물");
    }
}


luckyzenith-64 OP
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("다음 동물");
    }
}

이거 맞ㅇ음???

luckyzenith-64 OP

?? 오브젝트가 걍 없어지는데.. 1개로 합쳐지지않고,..,

luckyzenith-64 OP

? 걍 2마리중 1마리만 삭제하고 남은 1마리는 렙 올리면 안되는거?

luckyzenith-64 OP

그럼 걍 2개다 삭제후 1개 인스텀스해?

luckyzenith-64 OP

근데...생성후 2렙으로 자동으로 안올라감?

luckyzenith-64 OP

ㄴㄴ 스트링 강아지는 레벨1,2,3, 있고 고양이는 1,2,3 이런씩으로 10개 있어서..

luckyzenith-64 OP

어자피 그대로 오브젝트쓰고 int만 렙올릴건데 붇이치면 1개가삭제되고 1개는 렙이 오르게는안됨?

luckyzenith-64 OP

? 아니 그냥 1개지우고 1개는 렙올리게하는거임... 그 모양이 똑같음... 레벨정보는나중에 ui로 띄울꺼임...

luckyzenith-64 OP

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("렙 업");
        }

    }
}

}

luckyzenith-64 OP

foreach (GameObject obj in objects)
{
float dist = Vector3.Distance(transform.position, obj.transform.position);
if (dist < min)
{
min = dist;
Pos = obj;
}
target = Pos;
}

이거 어캄? 타켓이 없는데

luckyzenith-64 OP

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;
    }
}

}

luckyzenith-64 OP

대화에서 쓰기 좋은 팁있음? 곧 이쓰으면 기능경기 대회 게임 개발가는데..

luckyzenith-64 OP

디버깅 쓰는 습관하면 좋음?

luckyzenith-64 OP

뭐 도움되는 단축키 없음?

luckyzenith-64 OP

다른 팁은?

luckyzenith-64 OP

ㅇㅋ 그럼지금 까지 알려준 뭐 중요한 함 수 목록들만 보여줘 생각하면 기억나게

luckyzenith-64 OP

그 동물 sfm어게 만들지??

luckyzenith-64 OP

ㄴㄴ 쉬운버전으로 랜덤으로 걷다가 멈추고 방향돌려서 걷다가 멈추고..

luckyzenith-64 OP

근데 fsm이 가만히, 걷기, 물먹으러, 밥먹으로 ,자러 이런씩으로 여러게임데 어캄? 예을들어 물이50인데 30까지떨어지면 물을 찾기 시작하는거야

luckyzenith-64 OP

어려움..

luckyzenith-64 OP

걍 혼자만들고싶은데... 렌덤도 아는데...그 랜덤으로 돌아가는거만 알면되는데..

luckyzenith-64 OP

걍 랜덤 방향으로 돌아가는 코드가 뭐임?

luckyzenith-64 OP

걍 바로도는 핵심 부분만알려줘

luckyzenith-64 OP

그거어게만듬? 만약 게임에 같은테그 오브젝트가여러게있는데 런덤으로 하나를 뽀는 그런시스템

luckyzenith-64 OP

그것도 알려줘 바라보는 방향으로 가는거

luckyzenith-64 OP

아니 그냥 가는거 다른 코드 쓰지마

luckyzenith-64 OP

유니티 지리는 쉐이더 하는법 초간단

luckyzenith-64 OP

그럼 어게함?

luckyzenith-64 OP

이걸 오늘안에 다 왜뭐야하는데 너무 어려운데 어캄?

luckyzenith-64 OP

그래서 이걸 어떻게 해서 줄일까?

luckyzenith-64 OP

? 너는 텍스트 파일을 못읽음?

luckyzenith-64 OP

?

luckyzenith-64 OP

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();
}
luckyzenith-64 OP

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;
    }
luckyzenith-64 OP

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);
}
luckyzenith-64 OP

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("도착해서 쉼");
    }
}
luckyzenith-64 OP

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
    );
}

}

Das Neueste von 김구식의 AI서버

Objektsuche in Unity

Wie findet man das nächste Objekt in Unity? Fragen und Antworten mit KI.