본문 바로가기

Unity 공부/Unity_2D

[Day 2] 몬스터 제작

[ 몬스터 제작 ] --> 플레이어를 알아서 추적하는 몬스터 만들기

  • sprite의 모션 중 하나를 Hierachy로 드래그&드랍
  • Sprite Renderer의 Order in Layer를 2로 설정
  • 그림자 sprite를 Hierachy의 몬스터 오브젝트로 드래그&드랍
  • 몬스터 오브젝트 Add Component
        - Animator --> Animator Controller 드래그&드랍
        - Rigidbody 2D --> Gravity Scale을 0으로 변경, Mass 적당히 변경(Player도 마찬가지)
        - Capsule Collidar 2D --> 몬스터 크기에 맞게 Size 변경
  • C# 스크립트 생성(Enemy) --> 플레이어를 추적
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemy : MonoBehaviour
{
    public float speed; // 몬스터에게 필요한 speed 변수
    public Rigidbody2D target; // 몬스터에게 필요한 target 변수

    bool isLive = true; // 몬스터가 살아있는지를 확인하는 bool 변수 isLive

    Rigidbody2D rigid; // 오브젝트 변수 rigid
    SpriteRenderer spriter; // 오브젝트 변수 spriter

    void Awake()
    {
        rigid = GetComponent<Rigidbody2D>(); // 오브젝트 변수 초기화
        spriter = GetComponent<SpriteRenderer>(); // 오브젝트 변수 초기화
    }

    private void FixedUpdate(){

        if (!isLive){ // 몬스터가 살아있지 않으면 FixedUpdate를 빠져나감
            return;
        }

        Vector2 dirVec = target.position - rigid.position; // target과 자신의 위치 차이
        Vector2 nextVec = dirVec.normalized * speed * Time.fixedDeltaTime; // 한 프레임 뒤에 움직여아 하는 방향
        rigid.MovePosition(rigid.position + nextVec); // 한 프레임 뒤에 움직여아 하는 방향을 기존의 위치에 더해줌
        rigid.velocity = Vector2.zero; // 물리 속도가 이동에 영향을 주지 않도록 속도 제거
    }

    private void LateUpdate()
    {
        if (!isLive){
            return;
        }
        spriter.flipX = target.position.x < rigid.position.x;
    }
}
  • 기존의 Reposition 스크립트에 코드 추가
    적이 화면 밖으로 벗어나면 다시 만나기 어렵기 때문에 플레이어의 이동 방향으로 다시 나타나는 코드 작성
    아래는 완성된 Reposition 코드
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Reposition : MonoBehaviour{

    Collider2D coll; // Collider2D 변수

    private void Awake(){
        coll = GetComponent<Collider2D>(); // 오브젝트 변수 초기화
    }
    private void OnTriggerExit2D(Collider2D collision){
        if (!collision.CompareTag("Area")){
            return;
        }

        Vector3 playerPos = GameManager.instance.player.transform.position;
        Vector3 myPos = transform.position;
        float diffX = Mathf.Abs(playerPos.x - myPos.x);
        float diffY = Mathf.Abs(playerPos.y - myPos.y);

        Vector3 playerDir = GameManager.instance.player.inputVec;
        float dirX = playerDir.x < 0 ? -1 : 1;
        float dirY = playerDir.y < 0 ? -1 : 1;

        switch (transform.tag){
            case "Ground":
                if(diffX > diffY){
                    transform.Translate(Vector3.right * dirX * 40);
                }
                else if (diffX < diffY){
                    transform.Translate(Vector3.up * dirY * 40);
                }
                break;
            case "Enemy":
                if (coll.enabled){
                    transform.Translate(playerDir * 20 + new Vector3(Random.Range(-3f, 3f), 0f)); // 랜덤한 위치에서 재배치 되도록 벡터 더하기 
                }
                break;
        }
    }
}
  • 몬스터 오브젝트에 Reposition 스크립트 드래그&드랍

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

 

★Slow and Steady★