Luna
[TIL Day44] Unity 3D 강의 ~ing (2) 본문
오늘의 학습 키워드
- 강의 내용 중 중요개념 정리
- 강의 계속 잘 듣기!
공부한 내용 본인의 언어로 정리하기
🎮 Unity에서 알아두면 유용한 기능들
1️⃣ TryGetComponent 🛠️
TryGetComponent는 Unity에서 게임 오브젝트의 특정 컴포넌트를 가져오는 기능을 제공합니다. 이 메서드를 사용하면 컴포넌트가 게임 오브젝트에 연결되어 있는지 확인하고, 연결되어 있다면 해당 컴포넌트를 안전하게 가져올 수 있습니다.
📌 TryGetComponent 메서드 형식
public bool TryGetComponent<T>(out T component) where T : Component;
🔹 매개변수 설명
- T: 가져오려는 컴포넌트의 타입 (예: Rigidbody, Collider 등)
- component: 가져온 컴포넌트를 저장할 out 매개변수
✅ 사용 예시
using UnityEngine;
public class ExampleScript : MonoBehaviour
{
private void Start()
{
Rigidbody rb;
if (TryGetComponent<Rigidbody>(out rb))
{
rb.AddForce(Vector3.up * 100f);
}
else
{
Debug.Log("Rigidbody component not found.");
}
}
}
🎯 TryGetComponent의 장점
✔️ 컴포넌트가 없을 경우 예외가 발생하지 않음
✔️ 불필요한 GetComponent 호출을 줄여 성능 최적화 가능
2️⃣ 카메라 절두체(뷰 절두체) 🎥
📷 카메라 절두체란?
카메라 절두체(Frustum)는 피라미드 형태의 윗부분을 자른 입체 형상으로, 카메라가 렌더링할 수 있는 공간을 의미합니다. 이 공간을 벗어난 객체는 렌더링되지 않습니다.
🔍 카메라 절두체의 주요 구성 요소
1️⃣ 시야각(FOV, Field of View): 카메라가 포착하는 시야 범위
2️⃣ Near Clipping Plane: 카메라에서 가까운 절단면
3️⃣ Far Clipping Plane: 카메라에서 먼 절단면
💡 카메라 절두체 활용
- 🎯 뷰 절두체 컬링(View Frustum Culling): 카메라 시야 밖에 있는 오브젝트를 렌더링하지 않아 성능 최적화
- ☀️ 광원 처리 및 그림자 연산: 빛과 그림자가 특정 영역에 영향을 미치는지 판단하는 데 사용
3️⃣ Coroutine (코루틴) ⏳
🌀 Coroutine이란?
코루틴(Coroutine)은 특정 작업을 여러 프레임에 걸쳐 실행할 수 있도록 하는 기능입니다. 코루틴을 사용하면 특정 시점에서 실행을 일시 정지하고, 다음 프레임에서 다시 실행을 재개할 수 있습니다.
⚡ Coroutine의 특징
🔸 비동기적 작업 수행 가능 (ex. 일정 시간 후 작업 실행)
🔸 멀티스레딩이 아님 (메인 스레드에서 실행됨)
🎯 Coroutine의 활용
- ⏳ 일정 시간 후 동작 수행 (WaitForSeconds)
- 🎬 특정 프레임이 끝난 후 실행 (WaitForEndOfFrame)
- ⏲️ 특정 조건이 충족될 때까지 대기 (WaitUntil, WaitWhile)
동기와 비동기
코루틴은 동기? 비동기?
코루틴에 대한 개념을 좀 더 알아보기 위해 정리한 글 ↓
🌀 Unity Coroutine(코루틴) 정리
1️⃣ Coroutine(코루틴)이란? 🤔
코루틴(Coroutine)은 Unity에서 특정 작업을 여러 프레임에 걸쳐 실행할 수 있도록 하는 기능입니다. 일반적인 함수는 한 번 호출되면 모든 코드가 즉시 실행되지만, 코루틴은 실행을 중단했다가 이후 특정 조건이 충족되면 다시 실행을 재개할 수 있습니다.
💡 코루틴의 핵심 개념
- 비동기적 실행 가능: 특정 시간 동안 대기하거나 조건을 만족할 때까지 실행을 멈출 수 있음
- 멀티스레드가 아님: 여전히 메인 스레드에서 실행됨
- 게임 루프와 자연스럽게 연동됨: 애니메이션, 로딩, 시간 지연 등에 효과적
2️⃣ Coroutine 기본 사용법
코루틴을 사용하려면 IEnumerator를 반환하는 메서드를 정의하고, yield return 키워드를 사용해야 합니다.
using UnityEngine;
using System.Collections;
public class CoroutineExample : MonoBehaviour
{
void Start()
{
StartCoroutine(MyCoroutine());
}
IEnumerator MyCoroutine()
{
Debug.Log("코루틴 시작");
yield return new WaitForSeconds(2f); // 2초 대기
Debug.Log("2초 후 실행");
}
}
📝 설명:
- StartCoroutine(MyCoroutine())을 호출하면 MyCoroutine이 실행됨
- yield return new WaitForSeconds(2f);에서 2초 동안 대기
- 2초 후 Debug.Log("2초 후 실행")이 출력됨
3️⃣ 다양한 yield return 키워드 활용법
yield return 키워드 설명
WaitForSeconds(x) | x초 동안 대기 |
WaitForEndOfFrame() | 현재 프레임이 끝날 때까지 대기 |
WaitForFixedUpdate() | 다음 FixedUpdate() 실행까지 대기 |
WaitUntil(condition) | 특정 조건이 참이 될 때까지 대기 |
WaitWhile(condition) | 특정 조건이 거짓이 될 때까지 대기 |
✅ WaitUntil과 WaitWhile 활용 예시
IEnumerator WaitForPlayerHealth()
{
yield return new WaitUntil(() => playerHealth <= 0);
Debug.Log("플레이어 사망!");
}
💡 설명: playerHealth가 0 이하가 될 때까지 대기한 후 실행됩니다.
4️⃣ 코루틴 중지 및 관리
🛠️ 코루틴 중지 방법
메서드 설명
StopCoroutine(method) | 특정 코루틴 중지 |
StopAllCoroutines() | 현재 실행 중인 모든 코루틴 중지 |
void StopMyCoroutine()
{
StopCoroutine(MyCoroutine());
}
💡 StopCoroutine()을 사용하려면, StartCoroutine()에서 반환된 IEnumerator를 저장하는 것이 좋습니다.
private Coroutine myCoroutine;
void Start()
{
myCoroutine = StartCoroutine(MyCoroutine());
}
void StopManually()
{
if (myCoroutine != null)
{
StopCoroutine(myCoroutine);
}
}
5️⃣ 코루틴을 활용한 응용 예제
1. 점진적인 오브젝트 이동
IEnumerator MoveObject(Transform obj, Vector3 target, float duration)
{
Vector3 start = obj.position;
float elapsed = 0f;
while (elapsed < duration)
{
obj.position = Vector3.Lerp(start, target, elapsed / duration);
elapsed += Time.deltaTime;
yield return null; // 한 프레임 대기
}
obj.position = target;
}
Vector3.Lerp를 사용하여 duration 동안 부드럽게 이동합니다.
2. 페이드 인/아웃 효과
IEnumerator FadeCanvasGroup(CanvasGroup canvasGroup, float targetAlpha, float duration)
{
float startAlpha = canvasGroup.alpha;
float elapsed = 0f;
while (elapsed < duration)
{
canvasGroup.alpha = Mathf.Lerp(startAlpha, targetAlpha, elapsed / duration);
elapsed += Time.deltaTime;
yield return null;
}
canvasGroup.alpha = targetAlpha;
}
CanvasGroup.alpha 값을 조정하여 부드러운 페이드 효과를 만듭니다.
6️⃣ 코루틴을 사용할 때 주의할 점 ⚠️
✅ 남발하지 않기: 너무 많은 코루틴을 사용하면 성능 저하 발생 가능
✅ StopCoroutine을 활용: 불필요한 코루틴은 중지하여 리소스 낭비 방지
✅ 무한 루프 주의: 조건 없이 while(true)를 사용할 경우 주의
✅ 코루틴은 메인 스레드에서 실행됨: 멀티스레딩이 필요한 경우 Task나 Thread 활용 고려
코루틴과 동기(Synchronous) & 비동기(Asynchronous) 처리
1. 동기(Synchronous)와 비동기(Asynchronous)란?
동기(Synchronous)란?🤔
- 하나의 작업이 끝나야 다음 작업이 실행됨
- 코드가 순차적으로 실행되므로 예측하기 쉬움
- 단점: 시간이 오래 걸리는 작업이 있으면 전체 흐름이 멈출 수 있음
비동기(Asynchronous)란?🤔
- 여러 작업이 동시에 실행될 수 있음
- UI 응답성 향상, 멀티태스킹 가능
- 단점: 복잡한 제어 흐름을 관리해야 함
2. Unity 코루틴과 동기 & 비동기
코루틴은 일반적인 비동기 프로그래밍처럼 멀티스레딩이 아닌 메인 스레드에서 실행되지만,
특정 작업을 지연시키거나 여러 프레임에 걸쳐 실행할 수 있도록 만들어줍니다.
동기적 실행 예시
void NormalFunction()
{
Debug.Log("작업 A 시작");
TaskA();
Debug.Log("작업 A 종료 후 작업 B 실행");
TaskB();
Debug.Log("모든 작업 완료");
}
출력 결과:
작업 A 시작
작업 A 종료 후 작업 B 실행
모든 작업 완료
모든 작업이 순차적으로 실행됩니다.
코루틴을 활용한 비동기적 실행 예시
IEnumerator CoroutineExample()
{
Debug.Log("작업 A 시작");
yield return new WaitForSeconds(2f);
Debug.Log("작업 A 종료 후 작업 B 실행");
yield return new WaitForSeconds(1f);
Debug.Log("모든 작업 완료");
}
void Start()
{
StartCoroutine(CoroutineExample());
Debug.Log("메인 루프 계속 실행 중");
}
출력 결과:
작업 A 시작
메인 루프 계속 실행 중
(2초 후)
작업 A 종료 후 작업 B 실행
(1초 후)
모든 작업 완료
메인 루프가 중단되지 않고 계속 실행되면서 특정 작업만 대기하며 실행됩니다.
3. 코루틴 vs 비동기 프로그래밍(Async/Await) 비교
비교 항목 코루틴 (Coroutine) 비동기 프로그래밍 (Async/Await)
실행 방식 | 단일 스레드에서 실행됨 | 멀티스레드 활용 가능 |
제어 방식 | yield return을 통해 흐름 제어 | await를 통해 비동기 실행 |
사용 목적 | Unity의 프레임 기반 실행 관리 | 네트워크, 파일 I/O 등의 비동기 처리 |
중단 가능 여부 | 가능 (프레임 단위로 실행) | 가능 (완료 시까지 대기) |
Unity의 코루틴은 동기적 코드 실행을 비동기적 방식으로 연장하는 역할을 하지만,
네트워크 요청 같은 진정한 비동기 작업에는 async/await가 적절합니다.
Light와 AnimationCurve 정리
1. Unity의 Light 기능
Light란?🤔
Unity에서 Light는 3D 공간에서 조명을 설정하여 오브젝트를 밝히고 그림자를 생성하는 중요한 요소입니다.
다양한 조명 유형과 설정을 통해 씬의 분위기와 현실감을 조절할 수 있습니다.
Light의 주요 유형
유형 설명
Directional Light | 태양광과 같은 무한한 거리에서 평행하게 오는 빛 |
Point Light | 전구처럼 모든 방향으로 빛을 방출하는 광원 |
Spot Light | 손전등과 같이 원뿔 형태로 빛을 비추는 광원 |
Area Light | 직사각형 또는 원형 면적에서 빛을 방출하는 광원 (Realtime 지원 안됨) |
Light의 주요 속성
- Intensity: 빛의 밝기를 조절
- Range: 빛이 영향을 미치는 거리 (Point, Spot Light에서 사용)
- Spot Angle: 스포트라이트의 각도 (Spot Light 전용)
- Color: 빛의 색상을 변경 가능
- Shadows: 그림자 활성화 여부 및 품질 설정 가능
Light 활용 예시
using UnityEngine;
public class LightControl : MonoBehaviour
{
public Light sceneLight;
void Update()
{
if (Input.GetKeyDown(KeyCode.L))
{
sceneLight.enabled = !sceneLight.enabled; // 조명 ON/OFF
}
}
}
2. AnimationCurve 기능
AnimationCurve란?🤔
AnimationCurve는 시간에 따라 값이 변화하는 곡선을 정의하는 기능으로, 애니메이션, 물리 효과, 조명 변화 등에 활용됩니다. 보통 float 값의 변화량을 그래프 형태로 제어할 때 사용됩니다.
AnimationCurve 생성 및 사용 방법
using UnityEngine;
public class CurveExample : MonoBehaviour
{
public AnimationCurve curve;
private float time = 0f;
void Update()
{
time += Time.deltaTime;
float value = curve.Evaluate(time); // 현재 시간에 따른 곡선 값 반환
Debug.Log("Curve Value: " + value);
}
}
AnimationCurve의 주요 활용 예시
활용 분야 설명
UI 애니메이션 | 버튼 크기 변화, 투명도 조절 등 |
카메라 움직임 | 부드러운 줌 효과, 이동 경로 조절 |
물리 엔진 조작 | 점프 곡선, 힘의 변화 적용 |
조명 변화 | 조명의 점멸 또는 서서히 밝아지는 효과 |
AnimationCurve 직접 설정하기
AnimationCurve myCurve = new AnimationCurve(
new Keyframe(0f, 0f),
new Keyframe(1f, 1f)
);
- Keyframe(시간, 값): 특정 시간에서의 값을 정의
- Evaluate(시간): 해당 시간의 값을 가져옴
AnimationCurve 활용 예시 (빛의 강도 변화)
using UnityEngine;
public class LightAnimation : MonoBehaviour
{
public Light sceneLight;
public AnimationCurve lightCurve;
private float time = 0f;
void Update()
{
time += Time.deltaTime;
sceneLight.intensity = lightCurve.Evaluate(time % 1f); // 0~1 구간 반복
}
}
코드 분석
이 코드는 Unity에서 주기적인 낮과 밤의 변화(주야 시스템, Day-Night Cycle)를 구현하는 스크립트입니다.
태양(sun)과 달(moon)의 색상과 밝기를 조절하여 시간의 흐름에 따른 조명 변화를 시뮬레이션하는 역할을 합니다.
🔹 DayNightCycle 코드 분석
1. 변수 선언
[Range(0.0f, 1.0f)]
public float time;
public float fullDayLength;
public float startTime = 0.4f;
private float timeRate;
public Vector3 noon;
- time: 현재 시간(0.0f ~ 1.0f 사이의 값, 하루를 기준으로 0은 자정, 0.5는 정오)
- fullDayLength: 하루가 얼마나 오래 지속되는지를 초 단위로 정의
- startTime: 시뮬레이션이 시작될 때의 시간 (기본값 0.4, 아침과 낮 사이)
- timeRate: fullDayLength를 기반으로 시간이 흐르는 속도를 계산하는 내부 변수
- noon: 정오의 태양 방향을 나타내는 벡터
2. Light 및 조명 관련 변수
[Header("Sun")]
public Light sun;
public Gradient sunColor;
public AnimationCurve sunIntensity;
[Header("Moon")]
public Light moon;
public Gradient moonColor;
public AnimationCurve moonIntensity;
[Header("Other Lighting")]
public AnimationCurve lightingIntensityMultiplier;
public AnimationCurve reflectionIntensityMultiplier;
- sun: 태양을 나타내는 Light 컴포넌트
- sunColor: 태양의 색 변화를 정의하는 Gradient(예: 낮에는 노란색, 저녁에는 붉은색)
- sunIntensity: 태양 밝기의 변화를 나타내는 AnimationCurve
- moon: 달을 나타내는 Light 컴포넌트
- moonColor: 달의 색 변화를 정의하는 Gradient
- moonIntensity: 달의 밝기를 조절하는 AnimationCurve
- lightingIntensityMultiplier: 전체적인 광원의 강도를 조절하는 AnimationCurve
- reflectionIntensityMultiplier: 반사광의 강도를 조절하는 AnimationCurve
3. Start() 메서드: 초기화
private void Start()
{
timeRate = 1.0f / fullDayLength; // 하루 길이에 따라 시간 흐름 속도 설정
time = startTime; // 시작 시간을 설정
}
- timeRate를 하루 길이에 맞춰 시간의 흐름을 조절하는 비율로 설정
- time을 startTime 값으로 초기화하여 특정 시간에서 시작
4. Update() 메서드: 시간 흐름 및 조명 업데이트
private void Update()
{
time = (time + timeRate * Time.deltaTime) % 1.0f;
- timeRate * Time.deltaTime을 더하여 시간이 지속적으로 흐르도록 설정
- % 1.0f를 통해 time이 1을 넘어가면 다시 0으로 순환 (하루가 반복됨)
UpdateLighting(sun, sunColor, sunIntensity);
UpdateLighting(moon, moonColor, moonIntensity);
- 태양과 달의 조명을 업데이트하는 UpdateLighting() 메서드를 호출
RenderSettings.ambientIntensity = lightingIntensityMultiplier.Evaluate(time);
RenderSettings.reflectionIntensity = reflectionIntensityMultiplier.Evaluate(time);
}
- lightingIntensityMultiplier와 reflectionIntensityMultiplier를 이용하여 환경광과 반사광의 강도를 조절
(예: 밤에는 어두워지고, 낮에는 밝아짐)
5. UpdateLighting() 메서드: 태양과 달의 조명 업데이트
void UpdateLighting(Light lightSource, Gradient colorGradiant, AnimationCurve intensityCurve)
{
float intensity = intensityCurve.Evaluate(time);
- intensityCurve.Evaluate(time)을 사용하여 현재 시간에 따른 조명의 밝기를 가져옴
lightSource.transform.eulerAngles = (time - (lightSource == sun ? 0.25f : 0.75f)) * noon * 4.0f;
- 태양과 달의 회전 방향을 설정
- 태양: 0.25f (새벽 6시 기준)
- 달: 0.75f (오후 6시 기준)
- noon * 4.0f를 곱해 하루 동안 360도 회전하도록 조절
lightSource.color = colorGradiant.Evaluate(time);
lightSource.intensity = intensity;
- colorGradiant.Evaluate(time): 현재 시간에 따른 색상 변화를 설정
- intensity: 밝기를 조절
GameObject go = lightSource.gameObject;
if (lightSource.intensity == 0 && go.activeInHierarchy)
go.SetActive(false);
else if (lightSource.intensity > 0 && !go.activeInHierarchy)
go.SetActive(true);
}
- 조명의 밝기가 0이면 꺼지고, 밝기가 있으면 켜짐
(예: 낮에는 달을 끄고, 밤에는 태양을 끄는 역할)
🔹 코드 실행 흐름
- Start(): 하루 길이에 맞춰 timeRate를 설정하고 초기 시간을 지정
- Update():
- time 값을 증가시켜 낮과 밤의 주기를 만듦
- 태양(sun)과 달(moon)의 조명을 업데이트
- RenderSettings를 변경하여 전체적인 조명 환경을 조절
- UpdateLighting():
- 태양과 달의 회전, 색상, 밝기를 조절
- 태양과 달의 활성화 여부를 결정
🔹 코드의 주요 기능
✅ Gradient와 AnimationCurve를 활용하여 자연스러운 색상 및 밝기 변화 구현
✅ RenderSettings를 조절하여 환경광 및 반사광의 변화 적용
✅ 태양과 달을 회전 및 활성/비활성 처리하여 낮과 밤의 주기적 변화 구현
✅ 낮이 되면 태양이 활성화되고, 밤이 되면 달이 활성화됨
// 전체 코드
using UnityEngine;
public class DayNightCycle : MonoBehaviour
{
[Range(0.0f, 1.0f)] // time 값이 0~1 사이에서 조정될 수 있도록 함
public float time; // 현재 시간 (0 = 자정, 0.5 = 정오, 1 = 다시 자정)
public float fullDayLength; // 하루의 길이 (초 단위)
public float startTime = 0.4f; // 시작 시간 (기본적으로 오전 10시 정도로 설정)
private float timeRate; // 시간 진행 속도
public Vector3 noon; // 정오의 태양 방향을 나타내는 벡터
[Header("Sun")]
public Light sun; // 태양 조명
public Gradient sunColor; // 태양의 색상 변화
public AnimationCurve sunIntensity; // 태양 밝기 변화 곡선
[Header("Moon")]
public Light moon; // 달 조명
public Gradient moonColor; // 달의 색상 변화
public AnimationCurve moonIntensity; // 달 밝기 변화 곡선
[Header("Other Lighting")]
public AnimationCurve lightingIntensityMultiplier; // 전체 광원 강도 조절 곡선
public AnimationCurve reflectionIntensityMultiplier; // 반사광 강도 조절 곡선
private void Start()
{
timeRate = 1.0f / fullDayLength; // 하루 길이에 따라 시간 진행 속도 설정
time = startTime; // 시작 시간을 초기화
}
private void Update()
{
time = (time + timeRate * Time.deltaTime) % 1.0f; // 시간이 계속 흐르도록 설정 (0~1 범위 유지)
// 태양과 달의 조명 업데이트
UpdateLighting(sun, sunColor, sunIntensity);
UpdateLighting(moon, moonColor, moonIntensity);
// 환경광 및 반사광 강도 조절
RenderSettings.ambientIntensity = lightingIntensityMultiplier.Evaluate(time);
RenderSettings.reflectionIntensity = reflectionIntensityMultiplier.Evaluate(time);
}
void UpdateLighting(Light lightSource, Gradient colorGradiant, AnimationCurve intensityCurve)
{
float intensity = intensityCurve.Evaluate(time); // 현재 시간에 따른 광원 밝기 값 가져오기
// 태양과 달의 회전 (정오를 기준으로 360도 회전하도록 설정)
lightSource.transform.eulerAngles = (time - (lightSource == sun ? 0.25f : 0.75f)) * noon * 4.0f;
lightSource.color = colorGradiant.Evaluate(time); // 현재 시간에 따른 광원 색상 설정
lightSource.intensity = intensity; // 광원 밝기 설정
GameObject go = lightSource.gameObject;
if (lightSource.intensity == 0 && go.activeInHierarchy) // 밝기가 0이면 비활성화
go.SetActive(false);
else if (lightSource.intensity > 0 && !go.activeInHierarchy) // 밝기가 있으면 활성화
go.SetActive(true);
}
}
인터페이스 복습 (정석 정리 ...)
1. 인터페이스란?
인터페이스를 통해 클래스들은 공통적인 동작을 정의하고,
이를 구현하는 클래스들은 해당 인터페이스를 구현함으로써 공통 규약을 준수할 수 있습니다.
인터페이스의 주요 특징
- 추상화: 인터페이스는 메서드의 시그니처만을 가지며, 실제 구현이 없습니다.
- 메서드 시그니처 제공: 인터페이스는 구현 클래스가 반드시 구현해야 할 메서드를 정의합니다.
- 다중 상속 가능: 여러 인터페이스를 동시에 구현할 수 있어 다중 상속을 흉내낼 수 있습니다.
- 강제적 구현: 인터페이스를 구현한 클래스는 반드시 모든 메서드를 구현해야 합니다.
- 인터페이스 확장 가능: 하나의 인터페이스가 다른 인터페이스를 확장(extends)할 수 있습니다.
2. 인터페이스를 사용하는 이유
결합도를 낮추고 유연성을 높이기 위해
- 클래스 간의 의존도가 높으면 유지보수와 확장이 어려워짐 → 인터페이스를 활용하여 결합도를 낮추자!
- 구체적인 구현 클래스가 아닌 작은 단위의 여러 인터페이스를 활용하면 코드가 더욱 유연해짐.
협업 관점에서의 장점
- 개발 기간 단축: 인터페이스만 작성해 두면, 각 구현 클래스에서 개발을 병렬적으로 진행 가능.
- 표준화 가능: 여러 개발자가 작업해도 일관된 구조로 유지할 수 있음.
- 독립적인 프로그래밍 가능: 인터페이스가 선언부를 담당하고, 구현부는 별도로 작성할 수 있음.
3. 인터페이스 예제
인터페이스 정의
public interface Payment
{
void Pay();
}
인터페이스 구현 클래스
public class Card : Payment
{
public void Pay()
{
Console.WriteLine("카드 결제 완료");
}
}
public class Cash : Payment
{
public void Pay()
{
Console.WriteLine("현금 결제 완료");
}
}
public class QR : Payment
{
public void Pay()
{
Console.WriteLine("QR 결제 완료");
}
}
잘못된 설계 (결합도가 높은 경우)
public class Store
{
Card card;
Cash cash;
QR qr;
}
- Store 클래스가 구체적인 결제 방식(Card, Cash, QR)에 직접 의존하고 있어 확장성이 떨어짐.
- 새로운 결제 방식이 추가될 경우 Store 클래스를 수정해야 함.
올바른 설계 (인터페이스를 활용한 결합도 낮추기)
public class Store
{
Payment payment;
public Store(Payment payment)
{
this.payment = payment;
}
public void ProcessPayment()
{
payment.Pay();
}
}
- Store 클래스는 Payment 인터페이스만 알면 되므로, 구체적인 결제 방식에 의존하지 않음.
- 새로운 결제 방식이 추가되어도 Store 코드를 수정할 필요 없이 Payment 인터페이스만 구현하면 됨.
사용 예시
Store store1 = new Store(new Card());
store1.ProcessPayment(); // 카드 결제 완료
Store store2 = new Store(new Cash());
store2.ProcessPayment(); // 현금 결제 완료
4. 마무리
- 인터페이스를 활용하면 코드의 결합도를 낮추고 유지보수를 쉽게 할 수 있음.
- 구현을 강제함으로써 일관성을 유지할 수 있으며, 다형성을 활용하여 유연한 설계가 가능함.
- 협업 시 인터페이스를 활용하면 표준화된 방식으로 개발 가능, 독립적인 프로그래밍이 용이해짐.
에러사항
'🎮 Unity_7 TIL WIL' 카테고리의 다른 글
[TIL Day 51] 3D 팀 프로젝트 시작 (0) | 2025.03.13 |
---|---|
[TIL Day43] Unity 3D 강의 ~ing (0) | 2025.03.05 |
[TIL Day42] 유니티 3D 공부시작! (0) | 2025.03.04 |
[TIL Day38] 팀 프로젝트 마무리 (0) | 2025.02.28 |
[TIL Day34] 팀 프로젝트 - 플레이어 구현 (0) | 2025.02.24 |