[unity]2D 플랫폼 - 몬스터AI 구현하기

서희찬·2021년 4월 29일
0

Unity

목록 보기
14/14
post-thumbnail

자!
이제 몬스터의 애니메이션을 구현하고
몬스터 스스로 움직일 수 있게 코드를 짜주자.

먼저, 몬스터에게 애니메이션을 주자.

캐릭터에게 움직임을 부여하는것과 같은 방식이다!!!

그리고 이제 행동설정을 해줘야하는데 우선,
앞으로만 쭉 가는 코드는 다음과 같다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class Enemy : MonoBehaviour
{
    Rigidbody2D rigid;

    void Awake()
    {
        rigid = GetComponent<Rigidbody2D>();

    }

    void FixedUpdate()
    {
        rigid.velocity = new Vector2(-1,rigid.velocity.y);
    }
}

그런데
앞으로만 쭉가면 재미없지 않느냐!!!

그래서 설정을 더 해주자

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class Enemy : MonoBehaviour
{
    Rigidbody2D rigid;
    public int nextMove; // 행동 지표를 결정할 변수 하나 생성
    

    void Awake()
    {
        rigid = GetComponent<Rigidbody2D>();
        Think();

        Invoke("Think", 5); //주어진 시간이 지난뒤 지정된 함수를 실행하는 함수 
    }

    void FixedUpdate()
    {
        rigid.velocity = new Vector2(nextMove,rigid.velocity.y);
    }

    void Think()
    {
        nextMove = Random.Range(-1, 2);

        Think(); // 딜레이 없이 재귀함수 쓰면 에러 난다!
        Invoke("Think", 5);
    }
}

이렇게 재귀함수를 주어서 게속해서 생각해서 방향을 바꾸게 해주었는데!!!
그렇게하면 재귀함수가 무한정 빠르게 호출되서 에러가 뜰것이다.
그렇기에 우리는 invoke함수를 사용해서 5초마다 띵크라는 함수가 실행되게 설정해준다.

그런데 얜 멍청해서
낭떠러지를 감지못하고 떨어지게 된다.
그릴 방지하기위해서
또 레이 함수를 가져와
바닥이 있는지 레이를 통해서 체크하고
바닥이 없다면 몬스터를 뒤로 돌아서 가게 만든다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class Enemy : MonoBehaviour
{
    Rigidbody2D rigid;
    public int nextMove; // 행동 지표를 결정할 변수 하나 생성


    void Awake()
    {
        rigid = GetComponent<Rigidbody2D>();

        Invoke("Think", 3); //주어진 시간이 지난뒤 지정된 함수를 실행하는 함수 
    }

    void FixedUpdate()
    {
        rigid.velocity = new Vector2(nextMove,rigid.velocity.y);

        //지형 체크
        Vector2 frontVec = new Vector2(rigid.position.x + nextMove*0.4f,rigid.position.y);

        Debug.DrawRay(frontVec, Vector3.down, new Color(0, 1, 0)); //에디터 상에서만 레이를 그려준다
        RaycastHit2D rayHit = Physics2D.Raycast(frontVec, Vector3.down, 1, LayerMask.GetMask("Platform"));
        if (rayHit.collider == null) // 바닥 감지를 위해서 레이저를 쏜다! 없다면!!! 바닥이
        {
            nextMove = nextMove * -1;
            CancelInvoke();
            Invoke("Think", 5);
        }
    }

    void Think()
    {
        nextMove = Random.Range(-2, 3);

        float nextThinkTime = Random.Range(2f, 5f);
        Invoke("Think", nextThinkTime);
    }
}

이와 같이 코드를 짜주면 된다.

이제 움직일때 애니메이션을 짜주자.
다음과 같은 코드를 넣어주면된다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class Enemy : MonoBehaviour
{
    Rigidbody2D rigid;
    public int nextMove; // 행동 지표를 결정할 변수 하나 생성
    Animator anim;
    SpriteRenderer spriteRenderer;

    void Awake()
    {
        rigid = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
        spriteRenderer = GetComponent<SpriteRenderer>();

        Invoke("Think", 3); //주어진 시간이 지난뒤 지정된 함수를 실행하는 함수 
    }

    void FixedUpdate()
    {
        rigid.velocity = new Vector2(nextMove,rigid.velocity.y);

        //지형 체크
        Vector2 frontVec = new Vector2(rigid.position.x + nextMove*0.4f,rigid.position.y);

        Debug.DrawRay(frontVec, Vector3.down, new Color(0, 1, 0)); //에디터 상에서만 레이를 그려준다
        RaycastHit2D rayHit = Physics2D.Raycast(frontVec, Vector3.down, 1, LayerMask.GetMask("Platform"));
        if (rayHit.collider == null) // 바닥 감지를 위해서 레이저를 쏜다! 없다면!!! 바닥이
        {
            nextMove = nextMove * -1;
            CancelInvoke();
            Invoke("Think", 5);
        }
    }

    void Think()
    {
        nextMove = Random.Range(-2, 3);


        //애니
        anim.SetInteger("WalkSpeed", nextMove);

        // 방향
        if(nextMove != 0)//안서있을때만 방향 바꾸게 설정
            spriteRenderer.flipX = nextMove == 1; // 1이면 실행

        //재귀함수 
        float nextThinkTime = Random.Range(2f, 5f);
        Invoke("Think", nextThinkTime);
    }
}
profile
Carnegie Mellon University Robotics Institute | Research Associate | Developing For Our Lives, 세상에 기여하는 삶을 살고자 개발하고 있습니다

0개의 댓글