아카이브
[개발일지] Undead Survivor 3일차 본문
몬스터 만들기
Enemy.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public float speed;
public Rigidbody2D target;
bool isLive = true;
Rigidbody2D rigid;
SpriteRenderer spriter;
// Start is called before the first frame update
void Awake()
{
rigid = GetComponent<Rigidbody2D>();
spriter = GetComponent<SpriteRenderer>();
}
// Update is called once per frame
void FixedUpdate()
{
if (!isLive)
return;
Vector2 dirVec = target.position - rigid.position;
Vector2 nextVec = dirVec.normalized * speed * Time.fixedDeltaTime;
rigid.MovePosition(rigid.position + nextVec);
rigid.velocity = Vector2.zero;
}
void LateUpdate()
{
//목표의 x축 값과 자신의 x축값을 비교하여 작으면 true가 되도록 설정
spriter.flipX = target.position.x < rigid.position.x;
}
}
Reposition.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem.Switch;
public class Reposition : MonoBehaviour
{
Collider2D coll;
void Awake()
{
coll = GetComponent<Collider2D>();
}
void OnTriggerExit2D(Collider2D collision)
{
if (!collision.CompareTag("Area")) //Area태그가 아니면 실행하지 않는다
return;
//거리를 구하기 위해 플레이어 위치와 타일맵 위치를 미리 저장
Vector3 playerPos = GameManager.instance.player.transform.position;
Vector3 myPos = transform.position;
//X축과 Y축 각각의 거리, 플레이어 위치 - 타일맵 위치
float diffX = Mathf.Abs(playerPos.x - myPos.x); //Mathf.Abs(): 절대값 함수
float diffY = Mathf.Abs(playerPos.y - myPos.y);
Vector3 playerDir = GameManager.instance.player.inputVec;
//3항 연산자 (조건) ? (true일 때 값) : (false일 때 값)
float dirX = playerDir.x < 0 ? -1 : 1;
float dirY = playerDir.y < 0 ? -1 : 1;
//switch ~ case: 값의 상태에 따라 로직을 나눠주는 키워드
switch (transform.tag)
{
case "Ground":
if(diffX > diffY) //두 오브젝트 거리 사이에서, x축이 y축보다 크면 수평이동
{
transform.Translate(Vector3.right * dirX * 40);
}
else if (diffX < diffY) //x축이 y축보다 작으면 수직이동
{
transform.Translate(Vector3.up * dirY * 40);
}
break;
case "Enemy":
if (coll.enabled)
{
//플레이어의 이동방향에 따라 맞은 편에서 등장하도록 이동
transform.Translate(playerDir * 20 + new Vector3(Random.Range(-3f, 3f), 0f));
}
break;
}
}
}
오브젝트 풀링
프리팹 폴더 생성 후 Enemy A 와 Enemy B를 넣어준다.
오브젝트 풀 만들기
PoolManager 오브젝트와 스크립트를 만든다.
using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PoolManager : MonoBehaviour
{
//프리팹들을 보간할 변수
public GameObject[] prefabs;
//풀 담당을 하는 리스트
List<GameObject>[] pools;
void Awake()
{
pools = new List<GameObject>[prefabs.Length];
for(int index = 0; index < pools.Length; index++)
{
pools[index] = new List<GameObject>();
}
}
public GameObject Get(int index)
{
GameObject select = null;
// 선택한 풀의 비활성화 된 게임 오브젝트 접근
foreach(GameObject item in pools[index])
{
if (!item.activeSelf)
{
// 발견하면 select 변수에 할당
select = item;
select.SetActive(true);
break;
}
}
// 못 찾았으면
if (!select)
{
// 새롭게 생성하고 select 변수에 할당
select = Instantiate(prefabs[index], transform); //Instantiate: 원본 오브젝트 복제하여 장면에 생성
pools[index].Add(select);
}
return select;
}
}
풀링 사용해보기
플레이어의 자식으로 Spowner 오브젝트, 스크립트를 만든다
GameManager에 PoolManager 추가
GameManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameManager instance; //static: 정적으로 사용하겠다는 키워드. 바로 메모리에 얹어버림
public PoolManager pool;
public Player player;
void Awake()
{
//Awake 생명주기에서 인스턴스 변수를 자기자신 this로 초기화
instance = this;
}
}
Spawner.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Spawner : MonoBehaviour
{
void Update()
{
if (Input.GetButtonDown("Jump"))
{
GameManager.instance.pool.Get(0);
}
}
}
Enemy 스크립트에서 스스로 타겟을 초기화하는 코드 추가
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public float speed;
public Rigidbody2D target;
bool isLive = true;
Rigidbody2D rigid;
SpriteRenderer spriter;
// Start is called before the first frame update
void Awake()
{
rigid = GetComponent<Rigidbody2D>();
spriter = GetComponent<SpriteRenderer>();
}
// Update is called once per frame
void FixedUpdate()
{
if (!isLive)
return;
Vector2 dirVec = target.position - rigid.position;
Vector2 nextVec = dirVec.normalized * speed * Time.fixedDeltaTime;
rigid.MovePosition(rigid.position + nextVec);
rigid.velocity = Vector2.zero;
}
void LateUpdate()
{
//목표의 x축 값과 자신의 x축값을 비교하여 작으면 true가 되도록 설정
spriter.flipX = target.position.x < rigid.position.x;
}
void OnEnable()
{
target = GameManager.instance.player.GetComponent<Rigidbody2D>();
}
}
주변에 생성하기
스포너의 자식으로 Point 오브젝트를 만든다
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Spawner : MonoBehaviour
{
public Transform[] spawnPoint;
float timer;
void Awake()
{
spawnPoint = GetComponentsInChildren<Transform>();
}
void Update()
{
timer += Time.deltaTime;
if(timer > 0.2f)
{
Spawn();
timer = 0;
}
}
void Spawn()
{
GameObject enemy = GameManager.instance.pool.Get(Random.Range(0, 2));
enemy.transform.position = spawnPoint[Random.Range(1, spawnPoint.Length)].position;
}
}
'2D 콘텐츠 제작' 카테고리의 다른 글
2D 프로젝트 개발 발표 (0) | 2023.09.21 |
---|---|
[개발일지] Undead Survivor 5일차 (0) | 2023.09.19 |
[개발일지] Undead Survivor 4일차 (0) | 2023.09.19 |
[개발일지] Undead Survivor 2일차 (0) | 2023.09.14 |
[개발일지] Undead Survivor 1일차 (0) | 2023.09.13 |