
SubShader
{
Pass
{
Tags {"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "UnityLightingCommon.cginc"
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
fixed4 diff : COLOR0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
// 램버트 모델로 빛 세기 계산
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
half3 worldNormal = UnityObjectToWorldNormal(v.normal); // 노말을 월드 좌표계로 변환
half nl = max(0, dot(worldNormal, _WorldSpaceLightPos0.xyz)); // 광원 방향과 노말의 내적
o.diff = nl * _LightColor0; // 광원 색상과 내적값을 곱하여 diffuse 색상 계산
return o;
}
// 텍스쳐랑 빛 세기 곱하기
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
col *= i.diff;
return col;
}
ENDCG
}
}

램버트에 패스 추가
Pass
{
Tags {"LightMode"="ShadowCaster"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_shadowcaster
#include "UnityCG.cginc"
struct appdata {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};
struct v2f {
V2F_SHADOW_CASTER;
};
v2f vert(appdata v)
{
v2f o;
TRANSFER_SHADOW_CASTER_NORMALOFFSET(o); // 그림자 데이터 생성
return o;
}
float4 frag(v2f i) : SV_Target
{
SHADOW_CASTER_FRAGMENT(i); // 그림자 받았다면 색상 변환
}
ENDCG
}
함수 호출로 유니티가 그림자 대신 계산해줌

Pass
{
Tags {"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// directional light와 실시간 그림자만 고려하겠다는 뜻
#pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlighmap novertexlight
#include "UnityCG.cginc"
#include "UnityLightingCommon.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
fixed4 diff : COLOR0;
// vertex에서 post로 바꾼 이유 : TRANSFER_SHADOW()가 vertex가 아닌 pos를 찾기 때문
float4 pos : SV_POSITION;
SHADOW_COORDS(1) // 그림자 좌표들을 계산
};
sampler2D _MainTex;
float4 _MainTex_ST;
// 램버트 모델로 빛 세기 계산
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
half3 worldNormal = UnityObjectToWorldNormal(v.normal);
half nl = max(0, dot(worldNormal, _WorldSpaceLightPos0.xyz));
o.diff = nl * _LightColor0;
TRANSFER_SHADOW(o); // 그림자를 월드 좌표계에서 frag를 위한 좌표계로 변환
return o;
}
// 텍스쳐랑 빛 세기 곱하기
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
fixed shadow = SHADOW_ATTENUATION(i); // 그림자 세기 계산
col *= i.diff * shadow;
return col;
}
ENDCG
}
클릭하던 와중에 방향을 크게 틀거나 이리저리 움직여도 힘이 가해져서 어색한 문제
클릭 프레임과 그 다음 프레임의 차이를 기준으로 하려고 했는데 인식을 잘 못함
버퍼를 둬서 프레임 방향벡터 모은 후에 그걸로 기준 벡터 적용하려고 했는데 로직이 너무 어지러워짐
상태 패턴 쓰려고 했더니 상태가 공통으로 쓰는 변수가 너무 많아서 계속 매니저에 함수나 변수 추가해야할 것 같아서 뭔가 이상함 상태 패턴의 이점이 격감되는 것 같음
gpt는 Context 데이터 구조를 만드는 걸 추천 (공통 부분 코드를 나눌 수 있다는 것 외에 나아지는 거 없다)
차라리 판정 로직 계획을 수정하여 '지금까지 그었던 벡터들 총합'을 저장해놓고 비교하는게 더 간단할듯. 패턴 다 제거.
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;
player.GetComponent<Rigidbody2D>().AddForce(deltaPos * power);
lastFramePos = (Vector2)Input.mousePosition;
}
else if (Input.GetMouseButtonDown(0) && IsPlayer())
{
isClicking = true;
slideVecSum = Vector2.zero;
lastFramePos = Input.mousePosition;
}
}
