Chapter 3 ~ 6
데코레이터 패턴 : 좀 별로인듯. 객체를 파고파고 들어가야하는게 마음에 들지 않는다. 구현도 어렵고 사용도 어렵고... 어쩔 수 없이 써야할 때 쓰는 패턴인듯.
팩토리 패턴 : 간단한 팩토리 패턴은 그냥 캡슐화한다는거고, 팩토리 메소드 패턴은 거기에 상속으로 경우 나눈다는거. 추상 클래스 패턴은 거기에 또 composition 추가.
의존성 역전 : 종류별로 다 쪼개지 말고 부모 클래스로 묶어라. 부모 클래스에 의존하게 되는걸 의존성 역전이라고 표현한듯. 이름이 별로 마음에 들진 않는다. 결국 여러 개에 의존하던 걸 부모 클래스 하나에 의존하게 되니까 '원래'의 의존성 방향은 그대로고 역전된 방향으로의 의존성이 추가되는 건데 역전이라고만 하면 직관적이지도 않고 헷갈리는듯.
싱글톤 패턴 : 전역 변수 및 static 메서드를 인스턴스화하여 좀 더 유연하게 만든다.
커맨드 패턴 : 특정 경우마다 if문으로 나누는게 아니라 execute() 메서드를 가진 명령 인스턴스를 만든 뒤 그 명령을 처리하는 인스턴스에 보낸다. 인스턴스 대신 함수 객체로 composition할 수도 있다.
using UnityEngine;
public class PlayerInput : MonoBehaviour
{
[SerializeField] PlayerStat playerStat;
[SerializeField] float slideSpeed;
[SerializeField] float lowLimit;
private Rigidbody2D rb;
private bool isClicking = false;
private Vector2 lastFramePos;
private Vector2 slideVecSum;
private int enemyLayer;
void Start()
{
rb = GetComponent<Rigidbody2D>();
enemyLayer = LayerMask.NameToLayer("Enemy");
}
void Update()
{
if (isClicking)
{
if (Input.GetMouseButtonUp(0)) isClicking = false;
Vector2 deltaPos = (Vector2)Input.mousePosition - lastFramePos;
slideVecSum += deltaPos;
float angle = Mathf.Abs(Vector2.SignedAngle(slideVecSum, deltaPos));
if (angle > 45) isClicking = false;
rb.AddForce(deltaPos * slideSpeed);
lastFramePos = (Vector2)Input.mousePosition;
}
else if (Input.GetMouseButtonDown(0))
{
isClicking = true;
slideVecSum = Vector2.zero;
lastFramePos = Input.mousePosition;
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
GameObject colObj = collision.gameObject;
if (colObj.layer == enemyLayer && collision.relativeVelocity.magnitude > playerStat.sliceSpeed)
{
colObj.GetComponent<Enemy>().Die();
rb.linearVelocity = -collision.relativeVelocity / 2;
}
else
rb.linearVelocity = Vector2.zero;
}
}

