| 특징 | Plane | Quad |
|---|---|---|
| 구성 | 10x10으로 분할된 그리드 | 단순한 1개의 사각형(2개의 삼각형) |
| 폴리곤 수 | 200개의 삼각형 | 2개의 삼각형 |
| 기본 크기 | 10x10 Unity Units | 1x1 Unity Units |
| 사용 용도 | 복잡한 표면 변형, 지형, 물결 효과 | 간단한 표면, UI, 텍스처 표출 |
| 성능 | 비교적 무거움 | 가벼움 |
base는 부모 클래스의 생성자나 메서드를 호출할 때 사용됩니다.
base(weapon)은 부모 생성자 호출, base.Attack()은 부모 메서드 호출입니다.
Triplaner는 UV 좌표 없이 균일한 텍스쳐를 입힐 수 있는 좌표를 만든다.
UV를 펼 시간이 없거나, 동적으로 지형이 변경되는 상황에 사용할 수 있다.

위(Y축)에서 내려다봤을 때 문제없는, 일반적인 UV.
U는 Z축이 되고, V는 X축이 된다.

오른쪽(X축)에서 봤을 때 문제 없는 UV.
U는 Z축이 되고, V는 Y축이 된다.

각 축에 대해 뽑아낸 normal vector를, 각 축에 대한 UV를 입력한 텍스쳐와 곱하고
(Absolute를 해주는 이유는, 반대편에서도 보이게 하기 위함)

전부 더해주면 모든 축의 시선에 대해 UV가 제대로 입혀진다.
물론 내장된 Triplaner 노드도 있긴 하지만,
직접 만들면 옆면에 한해 다른 텍스쳐를 입히기, 일정 각도 이상이 되면 옆면에 다른 텍스쳐 입히기 등 다양한 응용을 할 수 있다.
뎁스 페이드

Troubleshooting
- scene depth와 물체의 depth값의 차이가 책과 다름.
- 예제 파일을 확인해보니 Blending Mode가 Additive였고, Quad가 아닌 Plane이었음. (Plane이 Quad보다 10배 커서 깊이값이 달랐다)
물의 특징



주변과 어느 정도 어울리는 반사로 만들어주기 위해, 주변 환경을 캡처하여 정반사 소스로 만드는 리플렉션 프로브를 사용한다.

모든 물체, 특히 비금속 물체는 시야 기준으로 기울어질수록 반사가 심해진다. 물도 마찬가지다.
프레넬로 이를 구현할 수 있다.

제자리에서 찰랑거리는 물은 각기 다른 방향으로 움직이는 normal 텍스쳐를 blend하면 간단하게 구현할 수 있다.

y 위치를 x축 위치에 대응되는 sine값으로 치환하면 이런 모양이 나온다.

파장의 길이와 높이 수치를 조절하고, sine에 대입할 x축 위치에 시간을 더해서 흘러가게 만든다.

코드는 변경에는 닫혀 있고 확장에는 열려 있어야 한다.
무조건 OCP를 적용하면 시간 낭비가 될 수 있고, 추상화를 하다보면 코드가 복잡해지기 때문에, 가장 가변적인 부분만 OCP를 적용하는게 좋다.
데코레이터 패턴
데코레이터는 원 객체를 감싸고 또 감싸는 식으로 작동.
데코레이터 객체에서 특정 기능 구현하는 방식은 자기가 할거 한 후에 변수에 담고 있는 (감싼) 객체의 같은 메소드에 값을 넘겨주는 것.
데코레이터의 단점
public astract class Beverage {
string description = "제목 없음";
public string GetDescription() {
return description;
}
public abstract double cost();
|
모든 객체를 위한 슈퍼 클래스 예시.
책에서 설정해놓은 상황은 레거시 코드가 추상 클래스여서 굳이 기존 코드를 바꾸는 건 피해야 하니까 추상 클래스로 만든거라고 하고,
원래는 인터페이스로 구현한다고 함. 인터페이스로 구현하면 GetDescription()도 컴포넌트의 슈퍼 클래스에서 선언하면 되는듯.
public abstract class CondimentDecorator : Beverage {
protected Beverage beverage;
public abstract string GetDesription();
}
데코레이터를 나타내는 추상 클래스 예시.
beverage를 담을 변수를 구현한다.
Component: 기본 기능을 정의하는 인터페이스
ConcreteComponent: Component 인터페이스를 구현하며, 기본 기능을 제공하는 클래스
Decorator: Component 인터페이스를 구현하며, 추가 기능을 제공하기 위해 다른 Component 객체를 감싸는 클래스
ConcreteDecorator: Decorator 클래스를 상속받아 추가적인 기능을 실제로 구현하는 클래스
// Component
interface IWeapon {
string Attack();
}
// ConcreteComponent
class BasicWeapon : IWeapon {
public virtual string Attack() {
return "공격한다";
}
}
// Decorator
abstract class WeaponDecorator : IWeapon {
protected IWeapon decoratedWeapon;
public WeaponDecorator(IWeapon weapon) {
this.decoratedWeapon = weapon;
}
public virtual string Attack() {
return decoratedWeapon.Attack();
}
}
// ConcreteDecorator
class FireWeaponDecorator : WeaponDecorator {
public FireWeaponDecorator(IWeapon weapon) : base(weapon) {}
public override string Attack() {
return base.Attack() + ", 불꽃 속성 공격을 추가한다";
}
}
// 사용 예
IWeapon weapon = new BasicWeapon();
weapon = new FireWeaponDecorator(weapon);
Console.WriteLine(weapon.Attack());