'Unity' 카테고리의 다른 글
Streaming of 'mpeg' on this platform is not supported (0) | 2020.11.11 |
---|---|
유니티 아틀라스 이미지 깨질때 (0) | 2020.11.09 |
이벤트 트리거 (0) | 2020.10.29 |
Streaming of 'mpeg' on this platform is not supported (0) | 2020.11.11 |
---|---|
유니티 아틀라스 이미지 깨질때 (0) | 2020.11.09 |
이벤트 트리거 (0) | 2020.10.29 |
투명 렌더텍스처 (0) | 2020.11.10 |
---|---|
이벤트 트리거 (0) | 2020.10.29 |
유니티 내비게이션 navigation (0) | 2020.10.25 |
거의 내 부스 상품을 만들기 위해서 만든 코드들이다
몇개는 개인작 하다가 만든정도
자주 쓰는 간단한 코드들만 적어놨다
두 값이 다른지 검사
if(!all(vec1 - vec2))
//위아래동일(all은 -1도 true로 반환하기 때문)
//(vec1 != vec2)
if(length(vec1 - vec2)<0.01) //가끔씩 미세한 변화로 인해 인식 안될때 사용
if(!((vec1.x==vec2.x)&&(vec1.y==vec2.y)&&(vec1.z==vec2.z)))
에미션
color.rgb = lerp(color.rgb,1 , _EmitionColor.rgb);
uv가 0~1을 벗어났는지 검사
v1
if (!all(uv.xy==saturate(uv.xy)))
{
col.a = 0;
}
v2
col.a*=all(uv==saturate(uv));
벡터 검사
흘러가는 쉐이더 (흐르는)
Shader "Unlit/Backgrond"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_Speed("Speed", Float) = 1
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _Speed;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
i.uv.x = (i.uv.x + _Time.y* _Speed) % 1;
i.uv.y = (i.uv.y + _Time.y* _Speed) % 1;
if (i.uv.x < 0)
{
i.uv.x += 1;
}
if (i.uv.y < 0)
{
i.uv.y += 1;
}
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
define
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#define _Board 0
#define _Black 1
#define _White 2
쉐이더에서 화면상의 좌표를 가져올때
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = ComputeGrabScreenPos(o.vertex);
}
uv에 담겨있음
이렇게 주면 스크린색상은 이렇게 나온다
col.r = i.grab_uv.x;
col.b = i.grab_uv.y;
col.g = 0;
SubShader
{
GrabPass {"_GrabTexture" }
Pass
{
sampler2D _GrabTexture;
fixed4 frag(v2f i) : SV_Target
{
fixed4 colGrab = tex2D(_GrabTexture, i.uv.xy);
}
}
}
그랩텍스처
모바일에선 프레임이 확떨어지니 주의
A31기준으로 60->50으로 떨어졌다
쉐이더 내부함수 공유
Shader "Unlit/DualPassUnlitShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
return col;
}
fixed4 frag2(v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
return col;
}
ENDCG
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag2
ENDCG
}
}
}
그림자생성코드 (vert frag용)
이 pass는 독립적이여야 한다(기존코드와 분리되어야 함)
Pass
{
Tags {"LightMode" = "ShadowCaster"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_shadowcaster
#include "UnityCG.cginc"
struct v2f {
V2F_SHADOW_CASTER;
};
v2f vert(appdata_base v)
{
v2f o;
TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
return o;
}
float4 frag(v2f i) : SV_Target
{
SHADOW_CASTER_FRAGMENT(i)
}
ENDCG
}
근데 위에거 안 들어가도 그림자 생기는 잣갓은 경우가 있음
FallBack 들어가서 그렇다.
역으로 응용하면 쉐도우 캐스터 안 쓰고도 그림자 뽑아내는데 쓸수도
FallBack "Diffuse"
그림자생성코드 (serf용)
addshadow는 필수이고
target 3.0은 필수라고는 하는데 테스트는 안해봄
#pragma target 3.0
#pragma surface surf Standard addshadow fullforwardshadows
Blend연산 기본
보통 SubShader의 Tags아래에 들어간다
Blend SrcAlpha OneMinusSrcAlpha // Traditional transparency
Blend One OneMinusSrcAlpha // Premultiplied transparency
Blend One One // Additive
Blend OneMinusDstColor One // Soft Additive
Blend DstColor Zero // Multiplicative
Blend DstColor SrcColor // 2x Multiplicative
스프라이트 쉐이더, UI에도 사용함
Shader "UI/SpriteSample"
{
Properties
{
[PerRendererData] _MainTex("Texture", 2D) = "white" {}
_StencilComp("Stencil Comparison", Float) = 8
_Stencil("Stencil ID", Float) = 0
_StencilOp("Stencil Operation", Float) = 0
_StencilWriteMask("Stencil Write Mask", Float) = 255
_StencilReadMask("Stencil Read Mask", Float) = 255
_ColorMask("Color Mask", Float) = 15
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"PreviewType" = "Plane"
"CanUseSpriteAtlas" = "True"
}
LOD 100
Cull Off
Lighting Off
ZWrite Off
//ZTest[unity_GUIZTestMode]
Blend One OneMinusSrcAlpha
Stencil
{
Ref[_Stencil]
Comp[_StencilComp]
Pass[_StencilOp]
ReadMask[_StencilReadMask]
WriteMask[_StencilWriteMask]
}
ColorMask[_ColorMask]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
fixed4 color : COLOR;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.color = v.color;
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
col.rgb *= col.a * i.color.a;
col.rgb *= i.color.rgb * i.color.a;
/*
위 두줄 잘 안되면 이거 사용
col.a *= i.color.a;
col.rgb *= col.a;
*/
// apply fog
//UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
컬링모드
Properties {
[KeywordEnum(None,Front,Back)] _CullingMode ("Culling Mode", Float) = 2
}
SubShader {
Cull [_CullingMode]
}
항상 보이는 UI
Shader "ahzkwid/UI/AhzkwidUISimple" {
Properties{
_MainTex("MainTex", 2D) = "white" {}
_Color("Main Color", Color) = (1,1,1,0)
[KeywordEnum(None,Front,Back)] _CullingMode("Culling Mode", Float) = 2
}
SubShader{
Tags {
"RenderType" = "Opaque"
"Queue" = "Geometry+3000"
}
Cull[_CullingMode]
ZWrite off
ZTest Always
blend srcalpha oneminussrcalpha
Pass{
SetTexture[_MainTex]
{
ConstantColor[_Color]
//Combine texture
Combine texture* primary DOUBLE, texture* constant
}
}
}
}
컷아웃버전
Shader "ahzkwid/UI/AhzkwidCutOut" {
Properties{
_MainTex("MainTex", 2D) = "white" {}
_Color("Main Color", Color) = (1,1,1,0)
_Cutoff("Cutout offset", Range(0, 1)) = 0.5
[KeywordEnum(None,Front,Back)] _CullingMode("Culling Mode", Float) = 2
[KeywordEnum(Opaque,CutOut,TransParent)] _RenderingMode("Rendering Mode", Float) = 2
}
SubShader{
Tags {
"RenderType" = "Opaque"
"Queue" = "Geometry+3000"
}
Tags { "Queue" = "AlphaTest" "RenderType" = "TransparentCutout" "IgnoreProjector" = "True" } //이거가 있어야 스텐실이 적용되더라
Cull[_CullingMode]
ZWrite off
ZTest Always
blend srcalpha oneminussrcalpha
Pass{
AlphaTest Greater [_Cutoff]
SetTexture[_MainTex]
{
ConstantColor[_Color]
//Combine texture
Combine texture* constant
}
}
}
}
컷아웃 UI (ugui)
Shader "ahzkwid/UI/AhzkwidUICutOut" {
Properties{
[PerRendererData] _MainTex("Texture", 2D) = "white" {}
_StencilComp("Stencil Comparison", Float) = 8
_Stencil("Stencil ID", Float) = 0
_StencilOp("Stencil Operation", Float) = 0
_StencilWriteMask("Stencil Write Mask", Float) = 255
_StencilReadMask("Stencil Read Mask", Float) = 255
_ColorMask("Color Mask", Float) = 15
_Cutoff("Cutout offset", Range(0, 1)) = 0.5
[KeywordEnum(None,Front,Back)] _CullingMode("Culling Mode", Float) = 2
[KeywordEnum(Opaque,CutOut,TransParent)] _RenderingMode("Rendering Mode", Float) = 2
}
SubShader{
Stencil
{
Ref[_Stencil]
Comp[_StencilComp]
Pass[_StencilOp]
ReadMask[_StencilReadMask]
WriteMask[_StencilWriteMask]
}
ColorMask[_ColorMask]
Tags
{
"PreviewType" = "Plane"
"CanUseSpriteAtlas" = "True"
}
Tags { "Queue" = "AlphaTest" "RenderType" = "TransparentCutout" "IgnoreProjector" = "True" } //이거가 있어야 스텐실이 적용되더라
Cull[_CullingMode]
ZWrite off
ZTest Always
blend srcalpha oneminussrcalpha
Pass{
AlphaTest Greater [_Cutoff]
SetTexture[_MainTex]
{
Combine texture* constant
}
}
}
}
vert frag를 컷아웃버전으로 만들땐 아래를 추가한다
Tags { "Queue" = "AlphaTest" "RenderType" = "TransparentCutout" "IgnoreProjector" = "True" }
AlphaToMask On
다기능버전
Shader "ahzkwid/UI/AhzkwidUI" {
Properties{
_MainTex("MainTex", 2D) = "white" {}
_Color("Main Color", Color) = (1,1,1,0)
_Cutoff("Cutout offset", Range(0, 1)) = 0.5
[KeywordEnum(None,Front,Back)] _CullingMode("Culling Mode", Float) = 2
[KeywordEnum(Opaque,CutOut,TransParent)] _RenderingMode("Rendering Mode", Float) = 2
}
SubShader{
Tags {
"RenderType" = "Opaque"
"Queue" = "Geometry+3000"
}
Cull[_CullingMode]
ZWrite off
ZTest Always
blend srcalpha oneminussrcalpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
fixed4 color : COLOR;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
fixed4 _TintColor;
float4 _Color;
float _Cutoff;
float _RenderingMode;
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.color = v.color;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
col.rgb *= _Color.rgb * i.color.rgb * _Color.a * i.color.a;
col.a *= _Color.a * i.color.a;
if (_RenderingMode == 0)
{
col.a = 1;
}
if (_RenderingMode == 1)
{
if (col.a >= _Cutoff)
{
col.a = 1;
}
else
{
col.a = 0;
}
}
return col;
}
ENDCG
}
}
}
//서피스쉐이더
테셀레이션 샘플
Shader "Tessellation Sample" {
Properties {
_Tess ("Tessellation", Range(1,32)) = 4
_MainTex ("Base (RGB)", 2D) = "white" {}
_DispTex ("Disp Texture", 2D) = "gray" {}
_NormalMap ("Normalmap", 2D) = "bump" {}
_Displacement ("Displacement", Range(0, 1.0)) = 0.3
_Color ("Color", color) = (1,1,1,0)
_SpecColor ("Spec color", color) = (0.5,0.5,0.5,0.5)
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Standard addshadow fullforwardshadows tessellate:tessFixed
#pragma target 5.0
float _Tess;
float4 tessFixed()
{
return _Tess;
}
struct Input {
float2 uv_MainTex;
};
sampler2D _MainTex;
fixed4 _Color;
void surf (Input IN, inout SurfaceOutputStandard o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
}
ENDCG
}
}
텍스처 1픽셀 이동값과 텍스처 사이즈
sampler2D _MainTex;
float4 _MainTex_TexelSize;
_MainTex_TexelSize.x = 1/width //따라서 1픽셀 가로
_MainTex_TexelSize.y = 1/height //따라서 1픽셀 세로
_MainTex_TexelSize.z = width
_MainTex_TexelSize.w = height
RGB2HSV
이거 만들었을때가 쉐이더 뉴비일때라 코드가 좀 지저분하다
23년에 코드에 문제있는거 발견하고 재수정함
float3 rgb2hsv ( float3 c )
{
c=saturate(c);
float3 HSV={0,1,1};
float _min = c.r;
float _med = c.g;
float _max = c.b;
float _t = 0;
if(_min>_med)
{
_t=_min;
_min=_med;
_med=_t;
}
if(_min>_max)
{
_t=_min;
_min=_max;
_max=_t;
}
if(_med>_max)
{
_t=_med;
_med=_max;
_max=_t;
}
HSV.b=_max;
float Delta = _max - _min;
if(_max>0)
{
HSV.g = Delta/_max;
}
if(Delta>0)
{
if ( _max == c.r )
{
HSV.r = (c.g-c.b)/Delta;
}
else if ( _max == c.g )
{
HSV.r = 2.0 + (c.b-c.r)/Delta;
}
else
{
HSV.r = 4.0 + (c.r-c.g)/Delta;
}
if (HSV.r < 0)
{
HSV.r += 6.0;
}
}
HSV.r /= 6.0;
return HSV;
}
VR에서 화면분할할때
fixed4 frag (v2f i) : SV_Target
{
#if UNITY_SINGLE_PASS_STEREO
i.uv.x/=2;
if(unity_StereoEyeIndex>0)
{
i.uv.x+=0.5;
}
#endif
흘러가는 쉐이더
i.uv.x = (i.uv.x + _Time.y* _Speed) % 1;
i.uv.y = (i.uv.y + _Time.y* _Speed) % 1;
fixed4 col = tex2D(_MainTex, i.uv);
아웃라인
half4 color = tex2D(_MainTex, IN.texcoord);
float outlineColAlphaMax = 0;
for (float x = -_OutLineWidth; x < _OutLineWidth; x += _MainTex_TexelSize.x)
{
for (float y = -_OutLineWidth; y < _OutLineWidth; y += _MainTex_TexelSize.y)
{
if (x*x+y*y < _OutLineWidth * _OutLineWidth)
{
half4 colTarget = tex2D(_MainTex, IN.texcoord + float2(x, y));
float colAlpha = max(0,colTarget.a - color.a);
outlineColAlphaMax = max(colAlpha, outlineColAlphaMax);
}
}
}
color.rgb = _OutLineColor;
color.a = outlineColAlphaMax;
디스토션 테스트
옛날에 짠거라 uv 포지션 다시 잡아줘야 하는데 언젠가 할듯
Shader "Ahzkwid/Distortion"
{
Properties
{
[KeywordEnum(Default,Overlay)] _RenderMode("Render Mode", Float) = 0
_MainTex("UI Texture", 2D) = "normal" {}
[KeywordEnum(Off,Front,Back)] _CullingMode("Cull Mode", Float) = 0
_Strength("Strength", range(0,1)) = 1.0
}
SubShader
{
Tags {
"RenderType" = "TransparentCutout"
"Queue" = "Transparent+2000"}
AlphaToMask On
ZWrite off
LOD 100
Cull[_CullingMode]
GrabPass {"_GrabTexture" }
Pass
{
blend srcalpha oneminussrcalpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
#pragma target 4.0
#pragma shader_feature PP_ON
#pragma shader_feature LR_ON
#include "UnityCG.cginc"
sampler2D _GrabTexture;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
float4 distance : TEXCOORD2;
float4 grab_uv : TEXCOORD3;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _Strength;
float _RenderMode;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
//o.distance.x = o.vertex.w;
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
//o.uv = o.vertex;
//o.grab_uv = ComputeGrabScreenPos(o.vertex);
{
//수동계산
o.grab_uv = o.vertex;
//o.grab_uv.xy /= o.vertex.w;
//o.grab_uv.x = (o.grab_uv.x + 1) / 2;
//o.grab_uv.y = 1 - (o.grab_uv.y + 1) / 2;
}
/*
if (_RenderMode > 0)
{
o.uv = float4(TRANSFORM_TEX(v.uv, _MainTex),1,1);
o.vertex.xy = o.uv;
o.vertex.xy -= 0.5;
o.vertex.xy *= 2;
o.vertex.y = -o.vertex.y;
o.vertex.zw = 1;
}
*/
#if UNITY_SINGLE_PASS_STEREO
o.grabUv.x /= 2;
if (unity_StereoEyeIndex > 0)
{
o.grabUv.x += 0.5;
}
#endif
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 colMain = tex2D(_MainTex, i.uv.xy);
float2 grabUv = i.grab_uv.xy;
if (_RenderMode > 0)
{
}
else
{
//수동계산
grabUv.xy /= i.vertex.w;
grabUv.x = (grabUv.x + 1) / 2;
grabUv.y = 1 - (grabUv.y + 1) / 2;
}
float3 offset;
//offset.rg = 0.5;
offset.rg = 128.0/255.0;
offset.b = 1;
grabUv.x += (colMain.r- offset.r) * _Strength;
grabUv.y += (colMain.g - offset.g) * _Strength;
//grabUv.y += 0.1;
fixed4 colGrab = tex2D(_GrabTexture, grabUv.xy);
fixed4 col = colGrab;
UNITY_APPLY_FOG(i.fogCoord, colMain);
return col;
}
ENDCG
}
}
}
쉐이더용 LenPos
int2 LenPos(int _angle, int _len)
{
int2 _pos = int2(0,0);
switch (_angle)
{
case 0:
_pos.x = _len;
_pos.y = 0;
break;
case 45:
_pos.x = _len;
_pos.y = _len;
break;
case 90:
_pos.x = 0;
_pos.y = _len;
break;
case 135:
_pos.x = -_len;
_pos.y = +_len;
break;
case 180:
_pos.x = -_len;
_pos.y = 0;
break;
case 225:
_pos.x = -_len;
_pos.y = -_len;
break;
case 270:
_pos.x = 0;
_pos.y = -_len;
break;
case 315:
_pos.x = _len;
_pos.y = -_len;
break;
}
return _pos;
}
스크린 사이즈
_ScreenParams.x //width
_ScreenParams.y //height
각도계산
float2 center = 0.5;
float2 pos = i.uv.xy-center;
float2 dir =((atan2(pos.x,-pos.y)*2/3.14)/4+0.75)%1;
UI(UGUI)의 color가져오기
존나 자주 쓰는데 맨날 까먹음
그래서 그냥 얘만 따로 적어놨다
struct appdata
{
fixed4 color : COLOR;
};
struct v2f
{
fixed4 color : COLOR;
};
v2f vert (appdata v)
{
v2f o;
o.color = v.color;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return i.color.rgb;
}
UI(UGUI)쉐이더의 필수항목
SubShader
{
ZWrite Off //없으면 자글자글하게 나온다
}
유니티 쉐이더 인스펙터 (0) | 2021.02.21 |
---|---|
스텐실 (0) | 2021.01.20 |
Material Button GameStage Gray doesn't have _Stencil property (0) | 2020.06.29 |
떼었을때 작동하는 온클릭을 눌렀을때 작동하는 버튼으로 바꿔줌
할당후에 온클릭은 지워주면 된다
유니티 아틀라스 이미지 깨질때 (0) | 2020.11.09 |
---|---|
유니티 내비게이션 navigation (0) | 2020.10.25 |
TTS (0) | 2020.10.19 |
스탠다드 에셋 방식
먼저 스탠다드 에셋을 다운받는다
3D모델의 애니메이터가 있는 최상단에 ThirdPersonAnimatorController를 넣는다
AI캐릭터 컨트롤을 넣고 이동하고자 하는 지점의 트랜스폼을 넣는다
Third Person Character의 Ground Check Distance값을 0.2로 수정한다.
왜냐하면 기본값은 Ground Check Distance가 너무 작아서 지면판정이 안되기 때문이다
Window-> AI/Navigation을 누른다
베이크 하면 완료된다
커스텀 방식
AIControl 코드
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class AIControl : MonoBehaviour
{
public Transform target;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
var agent = GetComponent<NavMeshAgent>();
if ((target != null)&& (agent != null))
{
agent.SetDestination(target.position);
}
}
}
저렇게 배치하고 AIControl을 넣는다
void DownloadTTS(string folderPath, string text, string fileName)
{
if (System.IO.Directory.Exists(folderPath) == false)
{
Debug.Log($"System.IO.Directory.CreateDirectory(folderPath), folderPath: {folderPath}");
System.IO.Directory.CreateDirectory(folderPath);
}
var filePath = $"{folderPath}/{fileName}.mp3";
if (CheckFile(filePath) == false)
{
StartCoroutine(DownloadFile("http://" + $@"translate.google.com/translate_tts?ie=UTF-8&textlen=32&client=tw-ob&q={text.Substring(0, Mathf.Min(200, text.Length))}&tl=en-gb", filePath));
}
}
Web에서 긁어오는 타입
200자 제한
일본어는 ja다
원샷타입
IEnumerator TextToSpeech(string text)
{
Debug.Log($"TextToSpeech({text})");
if (string.IsNullOrWhiteSpace(text))
{
Debug.Log($"빈문자열이라 정지");
yield break;
}
var co = LoadAudioClipMP3($@"http://translate.google.com/translate_tts?ie=UTF-8&textlen=32&client=tw-ob&q={text.Substring(0, Mathf.Min(200, text.Length))}&tl=en-gb");
StartCoroutine(co);
yield return new WaitUntil(() => co?.Current as AudioClip != null);
var audio = (AudioClip)co.Current;
var obj = new GameObject("WebTTS-" + text);
var audioSource = obj.AddComponent<AudioSource>();
audioSource.PlayOneShot(audio);
Debug.Log($"오디오 길이 {audio.length}초");
Destroy(obj, audio.length + 1); //오디오 시간에 1초를 추가(여유분)
yield return null;
}
static IEnumerator LoadAudioClipMP3(string downloadLink)
{
Debug.Log($"LoadAudioClipMP3({downloadLink})");
UnityWebRequest unityWebRequest = UnityWebRequestMultimedia.GetAudioClip(downloadLink, AudioType.MPEG);
var operation = unityWebRequest.SendWebRequest();
yield return new WaitUntil(() => operation.isDone);
if (unityWebRequest.isNetworkError)
{
Debug.LogError(unityWebRequest.error);
}
else
{
Debug.Log("LoadAudioClipSuccess");
}
var clip = DownloadHandlerAudioClip.GetContent(unityWebRequest);
clip.name = downloadLink;
yield return clip;
}
위에서 딕셔너리 추가버전
Dictionary<string, AudioClip> ttsDict = new Dictionary<string, AudioClip>();
AudioSource lastTTS;
IEnumerator TextToSpeech(string text)
{
Debug.Log($"TextToSpeech({text})");
if (string.IsNullOrWhiteSpace(text))
{
Debug.Log($"빈문자열이라 정지");
yield break;
}
AudioClip audio;
if (ttsDict.ContainsKey(text))
{
Debug.Log($"딕셔너리에서 가져옴({text})");
audio = ttsDict[text];
}
else
{
var co = LoadAudioClipMP3($@"http://translate.google.com/translate_tts?ie=UTF-8&textlen=32&client=tw-ob&q={text.Substring(0, Mathf.Min(200, text.Length))}&tl=ja");
StartCoroutine(co);
yield return new WaitUntil(() => co?.Current as AudioClip != null);
audio = (AudioClip)co.Current;
ttsDict.Add(text, audio);
}
var obj = new GameObject("WebTTS-" + text);
var audioSource = obj.AddComponent<AudioSource>();
if (lastTTS!=null)
{
Destroy(lastTTS);
}
lastTTS = audioSource;
audioSource.PlayOneShot(audio);
//audioSource.pitch = 1.2f;
Debug.Log($"오디오 길이 {audio.length}초");
Destroy(obj, audio.length + 1); //오디오 시간에 1초를 추가(여유분)
yield return null;
}
static IEnumerator LoadAudioClipMP3(string downloadLink)
{
Debug.Log($"LoadAudioClipMP3({downloadLink})");
UnityWebRequest unityWebRequest = UnityWebRequestMultimedia.GetAudioClip(downloadLink, AudioType.MPEG);
var operation = unityWebRequest.SendWebRequest();
yield return new WaitUntil(() => operation.isDone);
if (unityWebRequest.isNetworkError)
{
Debug.LogError(unityWebRequest.error);
}
else
{
Debug.Log("LoadAudioClipSuccess");
}
var clip = DownloadHandlerAudioClip.GetContent(unityWebRequest);
clip.name = downloadLink;
yield return clip;
}
유니티 내비게이션 navigation (0) | 2020.10.25 |
---|---|
유니티 Mask (0) | 2020.09.24 |
유니티 IDE(비주얼스튜디오) 바꾸기 (0) | 2020.08.19 |
gui색을 노란색으로 바꿈
GUILayout도 적용됨
GUI.backgroundColor = Color.yellow;
{
GUILayout.Box(nameof(gameclass.name), GUILayout.Width(50), GUILayout.Height(50));
}
GUI.backgroundColor = Color.white;
가로전환
GUILayout.BeginHorizontal();
{
}
GUILayout.EndHorizontal();
스크롤뷰(슬라이더)
Vector2 scrollPosition=Vector2.zero;
void OnGUI()
{
//scrollPosition=GUILayout.BeginScrollView(scrollPosition, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
scrollPosition=GUILayout.BeginScrollView(scrollPosition);
{
}
GUILayout.EndScrollView();
}
스크롤뷰(슬라이더) v2 (미완성)
Vector2 scrollPosition=Vector2.zero;
void OnGUI()
{
scrollPosition = GUI.BeginScrollView(new Rect(0, 0, position.width, position.height), scrollPosition, new Rect(0, 0, width:500, height:800));
{
}
GUI.EndScrollView();
}
마우스 대면 바뀌는 주석
if (Event.current.type == EventType.Repaint && GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition))
GUILayout.Label("Mouse over!");
else
GUILayout.Label("Mouse somewhere else");
버튼
if(GUILayout.Button("버튼"))
{
}
왼쪽으로 밀린 박스
var Texture2D = new Texture2D(1, 1);//삭제가 안되어 메모리릭을 유발하므로 전역에 생성해 두어야함
{
BoxBG.SetPixels(0,0,1,1, new Color[]{ Color.gray});
BoxBG.Apply();
var guiStyle = new GUIStyle();
guiStyle.alignment = TextAnchor.UpperLeft;
guiStyle.richText = true;
guiStyle.normal.background = BoxBG;
GUILayout.Box("내용",guiStyle);
}
인스펙터 변동사항이 있는지 검사한다
겸 드롭다운 샘플
EditorGUI.BeginChangeCheck();
{
index = EditorGUILayout.Popup("Index", index, new string[] { "1", "2" });
}
if (EditorGUI.EndChangeCheck())
{
Debug.Log("index값이 변경됨");
}
들여쓰기
EditorGUILayout계열만 적용됨
GUILayout은 안됨
EditorGUI.indentLevel++;
{
}
EditorGUI.indentLevel--;
스크립트오브젝트저장
//더티플래그
EditorUtility.SetDirty(scriptableObject);
var filePath = AssetDatabase.GetAssetPath(scriptableObject);
Debug.Log($"scriptableObject 저장됨, filePath: {filePath}");
//AssetDatabase.SaveAssets(); //이건 딱히 안 넣어도 되는듯
애니메이션 상태 저장
ImportAsset이 붙은 이유는 이래야 저장되더라
아마 위도 동일할듯 싶은데 나중에 해봐야지
여기서 사용함
UnityEditor.AssetDatabase.SaveAssetIfDirty(animationClip);
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(animationClip));
패스 에디터
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
[CustomEditor(typeof(PayloadRace))]
public class PayloadRaceEditor : Editor
{
private Vector3 position = Vector3.zero;
void OnSceneGUI()
{
var payloadRace = (PayloadRace)target;
var tracksParent = payloadRace.tracksParent;
if (tracksParent)
{
var childs = new List<Transform>();
for (int i = 0; i < tracksParent.childCount; i++)
{
childs.Add(tracksParent.GetChild(i));
}
foreach (var child in childs)
{
if (Vector3.Distance(payloadRace.transform.position, child.position) < 1)
{
//너무 가까우면 최상위 조작이 불가하므로
continue;
}
var newPosition = UnityEditor.Handles.PositionHandle(child.position, child.rotation);
if (newPosition != child.position)
{
UnityEditor.Undo.RecordObject(child, "Move Transform");
child.position = newPosition;
}
}
}
}
}
#endif
public class PayloadRace : MonoBehaviour
{
public int team = 0;
public GameObject payload;
public Transform tracksParent;
#if UNITY_EDITOR_WIN
void OnDrawGizmos()
{
var color = Color.red;
if (team == 0)
{
color = Color.blue;
}
Gizmos.color = color;
{
Gizmos.DrawWireSphere(transform.position,5);
}
Gizmos.color = Color.white;
if (tracksParent)
{
var childs = new List<Transform>();
for (int i = 0; i < tracksParent.childCount; i++)
{
childs.Add(tracksParent.GetChild(i));
}
foreach (var child in childs)
{
Gizmos.DrawSphere(child.position,0.1f);
if (Vector3.Distance(transform.position, child.position)<1)
{
continue;
}
}
for (int i = 0; i < childs.Count-1; i++)
{
Gizmos.DrawLine(childs[i].position, childs[i + 1].position);
}
}
}
#endif
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
그래디언트효과 (0) | 2020.10.20 |
---|---|
failed to connect to localhost port 80: Connection (0) | 2020.09.01 |
c# MD5 (0) | 2020.08.25 |