오늘은 데이터를 더 효율적으로 관리하고 시각적으로 디버깅하며 게임의 흐름(시간)을 제어하는 핵심 기술들을 정리해보겠습니다.
비트 연산자는 데이터를 비트(0과 1) 단위로 직접 조작하는 연산자입니다. 컴퓨터가 가장 빠르게 처리할 수 있는 연산 방식이며, 주로 여러 상태를 하나의 정수 변수에 담는 플래그(Flag) 처리나 레이어 마스크(LayerMask) 계산에 사용됩니다.
비트 연산자는 다음과 같은 논리연산자를 사용할 수 있습니다.
<< (비트 왼쪽 시프트): 비트를 왼쪽으로 밀어냅니다. 한 칸 밀 때마다 값이 2배가 됩니다. (예: 1 << 3은 3번 레이어를 의미)
| (OR): 두 비트 중 하나만 1이어도 1이 됩니다. 여러 개의 레이어를 하나로 합칠 때 사용합니다.
& (AND): 두 비트가 모두 1이어야 1이 됩니다. 특정 레이어가 포함되어 있는지 확인할 때 사용합니다.
~ (NOT): 모든 비트를 반전시킵니다. 특정 레이어만 제외하고 싶을 때 사용합니다.
<style>
using UnityEngine;
public class BitwiseTest : MonoBehaviour
{
void Start()
{
// 8번 레이어와 10번 레이어만 포함하는 마스크 만들기
int mask = (1 << 8) | (1 << 10);
// 특정 레이어가 포함되어 있는지 확인
bool hasLayer = (mask & (1 << 8)) != 0;
// 특정 레이어만 제외하기
int everythingExceptEight = ~ (1 << 8);
}
}
</style>
기즈모는 씬(Scene) 뷰에서만 보이는 그래픽 보조 도구입니다. 실제 게임 화면에는 나타나지 않지만, 개발자가 오브젝트의 감지 범위, 이동 경로, 충돌 영역 등을 시각적으로 확인하며 작업할 수 있게 도와줍니다. 개발자를 위한 시각적인 디버깅이라고 볼 수 있습니다.
OnDrawGizmos(): 오브젝트가 활성화되어 있다면 씬 뷰에서 항상 그려집니다.
OnDrawGizmosSelected(): 오브젝트를 클릭하여 선택했을 때만 기즈모를 그립니다. 화면이 복잡해지는 것을 막을 때 유용합니다.
<style>
using UnityEngine;
public class GizmoExample : MonoBehaviour
{
public float detectRange = 5f;
public Vector2 boxSize = new Vector2(2, 2);
// 항상 보이는 기즈모
private void OnDrawGizmos()
{
Gizmos.color = Color.grey;
// 캐릭터의 위치에 원형 범위를 그림
Gizmos.DrawWireSphere(transform.position, detectRange);
}
// 선택했을 때만 보이는 기즈모
private void OnDrawGizmosSelected()
{
// 색상 지정
Gizmos.color = Color.red;
// 특정 영역을 박스 형태로 시각화
Gizmos.DrawWireCube(transform.position, boxSize);
}
}
</style>
프리팹(Prefab)은 게임 오브젝트와 그에 붙은 컴포넌트, 설정값들을 하나의 에셋(Asset)으로 저장해둔 템플릿입니다. 동일한 속성을 가진 오브젝트를 여러 번 복제해서 써야 할 때 사용합니다.
프리팹은 단순히 복사 붙여넣기를 넘어 설계의 책임 분리 측면에서 매우 중요합니다.
씬(Scene)은 '배치와 실행'의 책임을 갖고, 프리팹은 '데이터와 구조'의 책임을 갖습니다.
프리팹 원본만 수정하면 씬에 배치된 수백 개의 복사본이 한 번에 업데이트되므로 관리가 용이하며, 코드에서 Instantiate() 함수를 통해 동적으로 생성하는 처리를 분리하여 시스템의 유연성을 높일 수 있습니다.
예시)

유니티는 게임 내 시간을 관리하기 위해 Time 클래스를 제공하고 있으며 다음과 같은 방식으로 사용할 수 있습니다.
Time.time: 게임이 시작된 후 지금까지 흐른 전체 시간(초)입니다. 쿨타임 계산이나 특정 시간 이후의 이벤트를 체크할 때 사용합니다.
Time.deltaTime: 이전 프레임에서 현재 프레임까지 걸린 시간입니다. 컴퓨터 성능에 따라 프레임이 달라도 이동 속도를 일정하게 유지하기 위해 이동 로직에 반드시 곱해줘야 합니다.
Time.timeScale: 게임 속 시간이 흐르는 속도 배율입니다. 1.0은 정상 속도이며, 0으로 만들면 일시정지(Pause), 0.5로 만들면 슬로우 모션 효과를 줄 수 있습니다.
<style>
using UnityEngine;
public class TimeControl : MonoBehaviour
{
public float speed = 5f;
private float nextAttackTime = 0f;
void Update()
{
// 1. 프레임 독립적 이동 (deltaTime 활용)
transform.Translate(Vector3.right * speed * Time.deltaTime);
// 2. 쿨타임 체크 (time 활용)
if (Time.time >= nextAttackTime)
{
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("공격!");
nextAttackTime = Time.time + 1.5f; // 1.5초 쿨타임
}
}
// 3. 일시정지 테스트
if (Input.GetKeyDown(KeyCode.P))
{
Time.timeScale = (Time.timeScale == 0) ? 1.0f : 0f;
}
}
}
</style>
오늘은 비트연산자부터 프리팹, 기즈모 등 다양한 학습을 진행했습니다.
그 중에서도 비트 연산자의 논리 연산식이 일반적으로 알고 있던 논리연산자와 비슷하게 생겼지만 엄연히 다른점이 인상적이었고 코드를 작성함에 있어 혼동이 되지 않도록 정확하게 알고 있어야 할 필요성을 느꼈습니다. 또한 기즈모와 프리팹의 경우 아직 필요성에 대한 느낌을 많이 받지 못하고 있어 공부를 더 해보고 실사용을 진행해보아야 개발에 있어 얼마나 필요한지를 느낄 수 있을 것 같습니다.