[Unity][2D-Game] Undead Survivor (5)

suhan0304·2023년 11월 4일
0
post-thumbnail
post-custom-banner

preview Link : https://velog.io/@suhan0304/Unity2D-GameUndead-Survivor-5
gitHub Link : https://github.com/suhan0304/Undead-Survivor


Review

  • Tilemap을 Random Rule로 깔아주었다.
  • GameManager 스크립트를 만들고 메모리를 통해 스크립트에서 접근할 수 있는 static으로 instance를 선언해주었다.
  • 20*20 타일맵을 4개만들어 40*40의 형태로 배치한 후 Reposition 스크립트를 작성해 플레이어의 이동에 따라 재배치 될 수 있도록 구련했다.
  • 메인 카메라가 플레이어를 잘 따라다닐 수 있도록 Chinemachine 패키지를 받아와 virtual camera 오브젝트를 사용했다.

강의영상(5) - 무한 맵 이동하기


개발

오브젝트 만들기

Sprite의 Enemy 1의 Run 0을 끌어와 Enemy 오브젝트를 생성해 준 후 다음과 같이 설정한다.

  • Shadow 스프라이트를 자식 오브젝트로 넣고 위치를 (0, -0.45, 0), Order in Layer는 0 그대로 설정
  • 애니메이터 컴포넌트를 추가해서 AcEnemy 1을 Controller에 연결해준다
  • Rigidbody 2D 컴포넌트를 추가해준 후 중력과 회전을 제거한다.
    - 인스펙터에서 Gravity Ssale = 0 , Constaints의 Freeze Rotation Z를 체크해준다.
    • Player의 Freeze Rotation Z 또한 체크해준다.
  • Capsule Collider을 추가한 후 Size를 (0.7, 0.9)로 설정
  • Player의 Rigidbody2D의 Mass를 15로 설정
    - 플레이어가 몬스터를 밀 수 있도록 해야한다.
  • Enemy 태그를 Add 해준후 Enemey로 설정

위와 같이 동일한 방법으로 Enemey (1)을 만들어준다.


플레이어 추적 로직

몬스터 스크립트 Enemy를 다음과 같이 만들어준다.

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

public class Enemy : MonoBehaviour
{
    public float speed;         //속도
    public Rigidbody2D target;  //목표 Rigidbody

    bool isLive = true; //생존여부

    Rigidbody2D rigid;
    SpriteRenderer spriter;

    void Awake()
    {
        rigid = GetComponent<Rigidbody2D>();
        spriter = GetComponent<SpriteRenderer>();
    }
    
    void FixedUpdate()
    {
        if (!isLive) //죽었으면 종료
            return;

        Vector2 dirVec = target.position - rigid.position; // 방향 = 위치 차이의 정규화 (위치 차이 = 타겟 위치 - 나의 위치)
        Vector2 nextVec = dirVec.normalized * speed * Time.fixedDeltaTime; //방향(정규화) * 속도 * 프레임 시간 보정
        rigid.MovePosition(rigid.position + nextVec); //현재 위치에 next벡터를 더한다.
        //다른 리지드바디와 부딪히게 되면 물리 속도가 생기는데 우리는 위치 이동을 채용하고 있으므로 물리 속도로 위치가 변화하면 안되므로 velocity를 0 만들기
        rigid.velocity = Vector2.zero; //물리 속도가 이동에 영향을 주지 않도록 속도는 제거 
    }

    private void LateUpdate()
    {
        if (!isLive) //죽었으면 종료
            return;

        //목표의 x축과 자신의 x축 값을 비교하여 작으면 X축을 기준으로 Flip 되도록 FlipX를 True로 설정
        spriter.flipX = target.position.x < rigid.position.x;
    }
}

이후 해당 스크립트를 Enemy와 Enemy (1)에 넣어준 후 Speed를 2.5, Target에 Player를 드래그드랍해서 초기화시켜준다.


몬스터 재배치

몬스터가 플레이어보다 느리게 되면 나중에 플레이어로부터 너무 멀어져 타일맵 밖에서 계속 따라오게 된다. 따라서 너무 벗어나게 되면 다시 가까이 재배치 시켜주는 로직이 필요하다. 따라서 기존의 Reposition 스크립트의 Enemy 부분을 업데이트해준다.

Reposition.cs
Collider2D coll;

void Awake()
{
	coll = GetComponent<Collider2D>();
}
case "Enemy": //collsion의 태그가 Enemy일 경우
	if (coll.enabled) // 콜라이더가 활성화 되어있는지 조건 먼저 작성 - 몬스터가 죽었으면 비활성화 되어있음 => 재배치 필요가 없음
	{
		transform.Translate(playerDir * 20 + new Vector3(Random.Range(-3f, 3f), Random.Range(-3f, 3f), 0f)); 
		//적어도 맵 크기만큼은 이동 -> 플레이어의 시야 밖에서 재배치 되도록 
	}
	break;

결과물

profile
Be Honest, Be Harder, Be Stronger
post-custom-banner

0개의 댓글