Skip to content

develop Tile

Seong Hyeok OH edited this page Mar 11, 2023 · 3 revisions

목차

Before

준비

  • "window" >> "2D" >> "Tile Palette"에서 타일 조작
  • 콘솔창 우클릭 >> "2D" >> "Tiles" >> "Rule Tile"
  • 태크 "Ground"와 "Area"
  • "PlayerMovement"에 캐릭터 이동 방향을 알려줄 "movement"를 public으로 변경
  • "Fantasy Environment and Animated Characters"의 타일만 사용

세팅

"Rule Tile" 조작법

  1. 인스펙터 창에서 "Number of Tiling Rules"에 원하는 숫자 대입
  • image
  1. 랜덤 조작을 위해 "output"을 "random"으로 변경
  • image
  1. 랜덤으로 등장할 타일보다 크거나 같게 타일 갯수("size")를 지정한다.
  2. 타일 이미지 지정
  • image
  1. 프로젝트창 우클릭 >> "2D" >> "Tiles Palette"에 이미지 지정
  • image
  1. 배경에 편하게 그리기 위해 "Line Brash"로 설정
  • image
  1. 가로 40 세로 40로 하나의 tilemap 생성(주의! 타일의 좌표가 (0,0)이 되도록)
  • image

무한 맵처럼 보이기 위한 작업

  1. "Tilemap"의 "Tilemap collider 2D"를 추가하고 "Used By Composite"을 체크
  • image
  1. "Composite collider 2D"추가를 추가하고 "Is Trigger" 체크(바닥과 캐릭터간의 상호작용을 막기 위해) 그리고 자동으로 생성된 "Rigidbody 2D"의 "Body Type"을 "Static" 혹은 "Kinematic"으로 변경(타일이 움직이면 안돼니까)
  • image
  1. "Tilemap"에 "Ground"태크
  2. 프리팹 "player" 내부에 "Area"라는 빈 오브젝트 생성하고 태크를 "Area"
  3. "Area"에 "Box Collider 2D"추가 후 사이즈를 Greound와 동일하게 설정와 IsTriggger도 체크
  • image

파괴 가능 오브젝트

  1. 프리팹을 만들기 전에 계층창 우클릭 후 "2D Object" > "Sprites" > "square"를 만든다.
  2. 해당 "square Renderer"의 파괴 가능한 오브젝트 이미지 지정
  3. Box Collider 2D를 적용 후 "Edit Collider"로 히트 박스 지정
  4. Rigidbody 2D를 적용 후 "Body Type"을 "Static"으로 지정하여 움직이지 못하도록 한다.
  5. 프리팹을 한다.
  • image

  • 아래 스크립트를 Tilemap에 적용 후 복제후 적절히 배치

스크립트


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

public class RepositionTile : MonoBehaviour
{
    public float x;   //타일 가로 크기
    public float y;   //타일 세로 크기
    public int probability;
    public GameObject prefab;   //불러올 프리팹
    public GameObject respawn;   //현재 프리팹
    // 태크 Area에서 충돌나서 벗어났을 때만 불러오는 함수
    private void OnTriggerExit2D(Collider2D collision)
    {
        if (!collision.CompareTag("Area")) { return; }  //Area 영역에서 벗어난 것만 아래 코드가 실행됨

        Vector3 playerPos = GameManager.instance.player.transform.position; //주인공 위치
        Vector3 myPos = transform.position; //현재 Tilemap 위치
        float diffX = Mathf.Abs(playerPos.x - myPos.x);
        float diffY = Mathf.Abs(playerPos.y - myPos.y);

        Vector3 playerDir = GameManager.instance.player.Movement;  //주인공 이동방향 저장
        float dirX = playerDir.x > 0 ? 1 : -1;
        float dirY = playerDir.y > 0 ? 1 : -1;

        switch (transform.tag)
        {
            case "Ground":
                if (diffX > diffY)  //x축으로 많이 이동시
                {
                    RemoveObject(collision);
                    transform.Translate(Vector3.right * dirX * x * 2); //주인공 이동 방향 앞에 tilemap을 놓기 위해 x*2 만큼 이동
                    ObjectRespown(transform.position);
                }
                else if (diffX < diffY) //y축으로 많이 이동시
                {
                    RemoveObject(collision);
                    transform.Translate(Vector3.up * dirY * y * 2); //주인공 이동 방향 앞에 tilemap을 놓기 위해 y*2 만큼 이동
                    ObjectRespown(transform.position);
                }
                break;
        }
    }
    private void ObjectRespown(Vector3 myPos) {  //프리팹 생성
        if (respawn == null & (Random.Range(0.0f,100.0f) <= probability))   //probability 확률로 생성
        {
            float randomX = Random.Range(-x/2, x/2); //랜덤 X좌표
            float randomY = Random.Range(-y/2, y/2); //랜덤 Y좌표
            //instantiate함수 (오브젝트 이름, 오브젝트 위치, 오브젝트 회전 값)
            respawn = Instantiate(prefab,new Vector3(myPos.x+randomX,myPos.y+randomY,0f) , Quaternion.identity);
        }
    }
    private void RemoveObject(Collider2D collision) {   //프리팹 삭제
        //if (collision.gameObject.tag == "Object")
        Destroy(respawn);
    }
}

참고 자료

  • 유튜브 무한 맵(35:40부터 해당 유튜브에 캐릭터 따라가며 카메라 조정 및 해상도에 대한 설정도 있다.)

After

Clone this wiki locally