-
플레이어를 추적하는 몬스터 만들기쾌락없는 책임 (공부)/Unity 2020. 11. 27. 22:08반응형
<이전에 만들었던건 왜 문제인가?>
이전에 만든 추적 시스템은 Monster 오브젝트에 콜라이더를 2개 넣었고 한 콜라이더는 추적 범위를 나타내는 trigger였습니다. 여기서 바로 문제가 발생하는데 추적을 위해 만든 콜라이더에도 공격이 적용되어서 몬스터랑 멀리 떨어져 있는데도 데미지가 들어가는 오류가 있었습니다.
<이전에 만든 미친 코드>
// 플레이어를 쫒아다니는 몬스터 구현 // 몬스터용 콜라이더랑 감지용 원형 콜라이더(이건트리거) using System.Collections; using System.Collections.Generic; using UnityEngine; public class AttackingMonster : MonoBehaviour { Rigidbody2D rigid; SpriteRenderer spriteRenderer; public int moveDir; // Moving direction, Random public Transform target; //target = player void Awake() { rigid = GetComponent<Rigidbody2D>(); spriteRenderer = GetComponent<SpriteRenderer>(); monsterAI(); } void Update() { if (rigid.velocity.x > 0.1f) { spriteRenderer.flipX = true; } else { spriteRenderer.flipX = false; } } void FixedUpdate() { rigid.velocity = new Vector2(moveDir, rigid.velocity.y); // no jump monster } void monsterAI() { moveDir = Random.Range(-1, 2); // -1<= ranNum <2 Invoke("monsterAI", 3); } private void OnTriggerEnter2D(Collider2D collision) { // find player if (collision.gameObject.tag == "Player") { CancelInvoke("monsterAI"); // 이 부분에서 함수를 바로 취소하지 못해 왔다갔다 하면 딜레이가 조금 있다. if(target.position.x > transform.position.x) { moveDir = 3; // speed up } else if (target.position.x < transform.position.x) { moveDir = -3; } } } private void OnTriggerExit2D(Collider2D collision) { if (collision.gameObject.tag == "Player") monsterAI(); // return to normal } }
<어디를 개선해야 하는가>
- 이전에 gameobject로 타겟을 받아오면 캐릭터가 달리질 시 기능이 작동하지 않을 수 있다.
> 그래서 player 태그인 물체를 추적하게끔 만들어야 합니다.
- 추적범위를 다른 오브젝트로 만들어야 합니다.
> 정확히는 trigger인 monster레이어가 아니어야 플레이어의 공격을 받지 않습니다.
<해결방안>
1. 몬스터에 자식 오브젝트로 빈 오브젝트를 만든 뒤 여기에 trigger인 콜라이더를 하나 만듭니다.
- 이 콜라이더가 플레이어 추적 범위가 됩니다
2. OntriggerEnter2D를 이용해서 플레이어가 들어오는걸 감지하고 플레이어 포지션을 받아온다
받아온 플레이어의 포지션이 몬스터 기준으로 오른쪽이면 몬스터의 속도를 3으로(오른쪽으로 움직이게) 왼쪽이면 -3으로 속도를 설정
위 2가지를 통해 플레이어를 추적하는 코드를 작성했습니다.
<핵심>
1. 몬스터의 움직임은 -1, 0, 1 세가지 값중 한개를 랜덤으로 가지고 있으며 이와 관련한 스크립트는 상위 오브젝트에 있다.
- 따라서 범위로 지정한 GameObject, 즉 하위 오브젝트에서는 상위 오브젝트의 변수에 접근해야 한다.
- 이때 사용한 기능이 유니티의 transform.parent.GetComponent<>() 이다.
2. 몬스터의 스크립트는 코루틴으로 작성했다.
<코드>
-몬스터의 스크립트
using System.Collections; using System.Collections.Generic; using UnityEngine; public class MonsterMove : MonoBehaviour { Rigidbody2D rigid; SpriteRenderer spriteRenderer; public int moveDir; // Moving direction, Random void Awake() { rigid = GetComponent<Rigidbody2D>(); spriteRenderer = GetComponent<SpriteRenderer>(); } void Start(){ StartCoroutine("monsterAI"); } void Update() { if (rigid.velocity.x > 0.1f) { spriteRenderer.flipX = true; } else { spriteRenderer.flipX = false; } } void FixedUpdate() { rigid.velocity = new Vector2(moveDir, rigid.velocity.y); // no jump monster } IEnumerator monsterAI() { moveDir = Random.Range(-1, 2); // -1<= ranNum <2 yield return new WaitForSeconds(5f); StartCoroutine("monsterAI"); } public void startMove(){ StartCoroutine("monsterAI"); } public void stopMove(){ StopCoroutine("monsterAI"); } }
- 하위 오브젝트 ( 몬스터 아래 빈 오브젝트의 콜라이더용 스크립트)
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerChase : MonoBehaviour { private void OnTriggerEnter2D(Collider2D collision) { // find player if (collision.gameObject.tag == "Player") { transform.parent.GetComponent<MonsterMove>().stopMove(); Vector3 playerPos = collision.transform.position; if(playerPos.x > transform.position.x) { transform.parent.GetComponent<MonsterMove>().moveDir = 3; // speed up } else if (playerPos.x < transform.position.x) { transform.parent.GetComponent<MonsterMove>().moveDir = -3; } } } private void OnTriggerExit2D(Collider2D collision) { if (collision.gameObject.tag == "Player") transform.parent.GetComponent<MonsterMove>().startMove(); } }
<무엇이 부족한가>
1. 다른 스크립트의 코루틴 함수에 접근하는 법은 없는가
- 현재 코루틴을 다른 스크립트에서 간접적으로 접근하고 있는데 직접적으로 실행할 수는 없는지 궁금하다
2. parent로 받아온 스크립트를 변수화 할 수는 없는가
- 하위 오브젝트의 스크립트의 코드가 너무 더럽다. 자료구조적으로 변수 하나를 아끼게 된다고 하는데 가독성이 너무 떨어져 오히려 유지보수에 좋지 못할 듯 하다.
2020.11.27 첫 작성
반응형'쾌락없는 책임 (공부) > Unity' 카테고리의 다른 글
유니티 UI에 변수 표시 (0) 2020.12.28 유니티2D 다운점프/아래점프 플랫폼 구현 (0) 2020.12.23 [유니티] 플레이어 능력치 버프/ui표현 (0) 2020.12.01 유니티에 VS code 사용법 (in Mac) (0) 2020.11.30 게임 개발일지 [0] (0) 2020.10.31