1-1. 기본 좌우 랜덤 이동코드
Rigidbody2D rigid; public int nextMove;
void Awake() { rigid = GetComponent<Rigidbody2D>(); Invoke("Think", 5) }
void FixedUpdate() { rigid.velocity = new Vector2(nextMove, rigid.velocity.y); }
void Think() { nextMove = Random.Range(-1, 2); Invoke("Think", 5); }
- 몬스터의 랜덤 x값좌우이동을 정해줄 int형 변수 nextMove 선언.
- Random클래스 : 랜덤 수를 생성하는 로직 관련 클래스.
- Range(최소값, 최대값) : 최소 ~최대 범위의 랜덤수 생성(최대 제외) ,
- Think()라는 함수를 선언하여, Random.Range()를 이용해 최소값과 최대값 결정, int형 float형 등 가능.- 위 코드의 경우, -1~1까지.
- Invoke(함수, 시간) : 원하는 시간에 함수 호출.
- FixedUpdate()에 velocity x좌표 인자값에 랜덤수인 nextMove를 넣고, Awake()함수와 Think()함수에 Invoke()함수를 통해 원하는 시간마다 랜덤으로 X좌표 이동.
- Think()함수는 Invoke()를 통한 재귀함수로 위 코드상, 5초마다 함수호출.
1-2. 낭떠러지 확인
void FixedUpdate() { rigid.velocity = new Vector2(nextMove, rigid.velocity.y); Vector2 frontVec = new Vector2(rigid.position.x + nextMove, 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 *= -1; CancelInvoke(); Invoke("Think", 5); } }
- Raycast 관련 설명은 https://velog.io/@ohjh1744/%EC%9C%A0%EB%8B%88%ED%8B%B02D-%EC%A0%90%ED%94%84%EA%B5%AC%ED%98%84feat.-%EC%A4%91%EB%A0%A5-Laycast-%EB%AC%B4%ED%95%9C%EC%A0%90%ED%94%84-%EA%B8%88%EC%A7%80
- 현재 위치에서 앞에 위치를 알려주는 변수 frontVec 선언.
- Raycast 를 통해,현재 위치에서 앞의 위치에 아래로 빔을 쏘았을 때, 낭떠러지인지 확인.
- 만약, 바닥이 빔과 닿지 않는다면(바닥이 없다면), -1을 곱해 x좌표 방향을 바꿔줌.
- -1 -> 1, 1 -> -1, 0 -> 0
- CancelInvoke() : 현재 작동 중인 모든 Invoke함수 멈춤.
- 방향을 바꿔주고 CancelInvoke()로 invoke()함수 멈추고 새로 invoke()함수를 다시 선언하여 방향 바뀔때 마다 시간 초기화.
2-1. 애니메이터 준비
- Animator에서 멈춘 상태와 걷는 상태를 서로 Make Transition 으로 연결 시켜 준뒤, WalkSpeed라는 int형 변수를 추가해 상태가 0이면 멈춘상태, 0이아니면 걷는 상태의 애니메이션을 적용.
2-2. 코드
Animator anim; SpriteRenderer spriteRenderer; void Awake() { anim = GetComponent<Animator>(); spriteRenderer = GetComponent<SpriteRenderer>(); Invoke("Think", 5); }
void FixedUpdate() { .... .... if (rayHit.collider == null) { nextMove *= -1; spriteRenderer.flipX = nextMove == 1; CancelInvoke(); Invoke("Think", 2); } }
void Think() { nextMove = Random.Range(-1, 2); anim.SetInteger("WalkSpeed", nextMove); if(nextMove != 0) { spriteRenderer.flipX = nextMove == 1; } float nextThinkTime = Random.Range(2f, 5f); Invoke("Think", nextThinkTime); }
- Animator 변수 anim와 SpriteRenderer 변수 spriteRenderer 선언 후 awake()함수에서 초기화.
- Think()함수에서 SetInteger()함수를 통해 몬스터가 움직이지 않으면( WalkSpeed = 0) 멈춘 상태를, 몬스터가 움직이면(WalkSpeed != 0) 걷는 상태를 적용.
- 현재 몬스터는 왼쪽을 바라보고 있는 상태, 오른쪽으로 이동한다면(nextMove = 1), flipX를 true로 변경해 몬스터가 바라보는 방향을 반대로 바꿔줌.
- 방향을 바꿔주는 함수가 있는 곳 즉, Fixedupdate()의 nextMove *= -1 과, Think()함수에 적용해줌.
(랜덤으로 움직이는 AI몬스터 모습)
<참고>
골드 메탈님 강의 영상: https://www.youtube.com/watch?v=7MYUOzgZTf8&list=PLO-mt5Iu5TeYI4dbYwWP8JqZMC9iuUIW2&index=20
사용한 텍스처 소스 : http://u3d.as/2mvJ (by골드메탈님)