자!
이제 몬스터의 애니메이션을 구현하고
몬스터 스스로 움직일 수 있게 코드를 짜주자.
먼저, 몬스터에게 애니메이션을 주자.
캐릭터에게 움직임을 부여하는것과 같은 방식이다!!!
그리고 이제 행동설정을 해줘야하는데 우선,
앞으로만 쭉 가는 코드는 다음과 같다.
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);
}
}