ADD : 웹 리타겟팅 기능 추가 및 연습실 크기 키우기 바닥 그림자 기능 추가 시스템 컨트롤러에서 클라이언트 없으면 자동 추가

This commit is contained in:
user 2026-01-23 22:15:09 +09:00
parent 951ccedb06
commit 8daba5b832
67 changed files with 3768 additions and 74 deletions

View File

@ -17,8 +17,10 @@ namespace UnityEditor.Rendering.Universal.ShaderGUI
//=======================================================================
private LitSplatGUI.LitProperties litSplatProperties;
private LitScreenSpaceOutlineGUI.LitProperties litScreenSpaceOutlineProperties;
private LitCharSelfShadowGUI.LitProperties litCharSelfShadowProperties;
private SavedBool m_SplatInputsFolder;
private SavedBool m_ScreenSpaceOutlineInputsFolder;
private SavedBool m_CharSelfShadowInputsFolder;
//=======================================================================
// NiloToon added (to support URP 12):
@ -31,6 +33,7 @@ namespace UnityEditor.Rendering.Universal.ShaderGUI
//=======================================================================
materialScopesList.RegisterHeaderScope(LitSplatGUI.Styles.splatInputs, Expandable.Details, _ => LitSplatGUI.DoSplatArea(litSplatProperties, materialEditor));
materialScopesList.RegisterHeaderScope(LitScreenSpaceOutlineGUI.Styles.outlineInputs, Expandable.Details, _ => LitScreenSpaceOutlineGUI.DoScreenSpaceOutlineArea(litScreenSpaceOutlineProperties, materialEditor));
materialScopesList.RegisterHeaderScope(LitCharSelfShadowGUI.Styles.charSelfShadowInputs, Expandable.Details, _ => LitCharSelfShadowGUI.DoCharSelfShadowArea(litCharSelfShadowProperties, materialEditor));
//=======================================================================
}
//=======================================================================
@ -46,6 +49,7 @@ namespace UnityEditor.Rendering.Universal.ShaderGUI
//=======================================================================
litSplatProperties = new LitSplatGUI.LitProperties(properties);
litScreenSpaceOutlineProperties = new LitScreenSpaceOutlineGUI.LitProperties(properties);
litCharSelfShadowProperties = new LitCharSelfShadowGUI.LitProperties(properties);
//=======================================================================
}
@ -70,6 +74,7 @@ namespace UnityEditor.Rendering.Universal.ShaderGUI
//=======================================================================
LitSplatGUI.SetMaterialKeywords(material);
LitScreenSpaceOutlineGUI.SetMaterialKeywords(material);
LitCharSelfShadowGUI.SetMaterialKeywords(material);
//=======================================================================
}
@ -533,6 +538,73 @@ namespace UnityEditor.Rendering.Universal.ShaderGUI
*/
}
}
internal class LitCharSelfShadowGUI
{
public static class Styles
{
public static readonly GUIContent charSelfShadowInputs = new GUIContent("NiloToon Character Self Shadow",
"These settings let you receive shadow from NiloToon characters.");
public static readonly GUIContent receiveCharShadow = new GUIContent("Receive Char Shadow",
"Enable to receive shadow cast by NiloToon characters. Requires NiloToon Renderer Feature's Character Self Shadow to be enabled.");
public static readonly GUIContent charShadowStrength = new GUIContent("Shadow Strength",
"Controls the intensity of the received character shadow.");
}
public struct LitProperties
{
public MaterialProperty receiveNiloToonCharShadow;
public MaterialProperty niloToonCharShadowStrength;
public LitProperties(MaterialProperty[] properties)
{
receiveNiloToonCharShadow = BaseShaderGUI.FindProperty("_ReceiveNiloToonCharShadow", properties, false);
niloToonCharShadowStrength = BaseShaderGUI.FindProperty("_NiloToonCharShadowStrength", properties, false);
}
}
public static void DoCharSelfShadowArea(LitProperties properties, MaterialEditor materialEditor)
{
// Toggle for receiving character shadow
if (properties.receiveNiloToonCharShadow != null)
{
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = properties.receiveNiloToonCharShadow.hasMixedValue;
var value = EditorGUILayout.Toggle(Styles.receiveCharShadow, properties.receiveNiloToonCharShadow.floatValue > 0.5f);
if (EditorGUI.EndChangeCheck())
properties.receiveNiloToonCharShadow.floatValue = value ? 1.0f : 0.0f;
EditorGUI.showMixedValue = false;
}
// Shadow strength slider (only show when receive shadow is enabled)
if (properties.niloToonCharShadowStrength != null && properties.receiveNiloToonCharShadow != null)
{
if (properties.receiveNiloToonCharShadow.floatValue > 0.5f)
{
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = properties.niloToonCharShadowStrength.hasMixedValue;
var strengthValue = EditorGUILayout.Slider(Styles.charShadowStrength, properties.niloToonCharShadowStrength.floatValue, 0f, 1f);
if (EditorGUI.EndChangeCheck())
properties.niloToonCharShadowStrength.floatValue = strengthValue;
EditorGUI.showMixedValue = false;
EditorGUI.indentLevel--;
}
}
// Info box
EditorGUILayout.HelpBox("Requires NiloToon Renderer Feature's 'Character Self Shadow' to be enabled.", MessageType.Info);
}
public static void SetMaterialKeywords(Material material)
{
if (material.HasProperty("_ReceiveNiloToonCharShadow"))
{
CoreUtils.SetKeyword(material, "_RECEIVE_NILOTOON_CHAR_SHADOW", material.GetFloat("_ReceiveNiloToonCharShadow") > 0.5f);
}
}
}
//=====================================================================================================================================
// direct copy from URP10.5.1's LitDetailGUI.cs (no edit)

View File

@ -114,6 +114,12 @@ Shader "Universal Render Pipeline/NiloToon/NiloToon_Environment"
_ScreenSpaceOutlineIntensity("_ScreenSpaceOutlineIntensity", Range(0,1)) = 1
[HDR]_ScreenSpaceOutlineColor("_ScreenSpaceOutlineColor", Color) = (1,1,1,1)
_ScreenSpaceOutlineWidth("_ScreenSpaceOutlineWidth", Float) = 1
////////////////////////////////////////////////////////////////////
// NiloToon Character Self Shadow (receive shadow from NiloToon characters)
////////////////////////////////////////////////////////////////////
[Toggle(_RECEIVE_NILOTOON_CHAR_SHADOW)] _ReceiveNiloToonCharShadow("Receive NiloToon Char Shadow", Float) = 0
_NiloToonCharShadowStrength(" Shadow Strength", Range(0, 1)) = 1.0
//==========================================================================
// Blending state
@ -282,6 +288,8 @@ Shader "Universal Render Pipeline/NiloToon/NiloToon_Environment"
#pragma shader_feature_local _SPLATMAP
#pragma multi_compile_fragment _ _NILOTOON_GLOBAL_ENABLE_SCREENSPACE_OUTLINE
//#pragma multi_compile_fragment _ _NILOTOON_GLOBAL_ENABLE_SCREENSPACE_OUTLINE_V2 //WIP, temp disabled
#pragma shader_feature_local_fragment _RECEIVE_NILOTOON_CHAR_SHADOW
#pragma multi_compile_fragment _ _NILOTOON_RECEIVE_SELF_SHADOW
//==========================================================================================================
//[NiloToon] remove:

View File

@ -26,6 +26,8 @@
#define _NILOTOON_GLOBAL_ENABLE_SCREENSPACE_OUTLINE 1
#define _NILOTOON_GLOBAL_ENABLE_SCREENSPACE_OUTLINE_V2 1
#define _SPLATMAP 1
#define _RECEIVE_NILOTOON_CHAR_SHADOW 1
#define _NILOTOON_RECEIVE_SELF_SHADOW 1
#endif
#include "../../ShaderLibrary/NiloUtilityHLSL/NiloAllUtilIncludes.hlsl"
@ -251,8 +253,88 @@ float _GlobalScreenSpaceOutlineV2NormalAngleCosThetaThresholdForEnvi;
// global camera uniforms
float _CurrentCameraFOV;
// NiloToon Character Self Shadow uniforms and texture
#if defined(_RECEIVE_NILOTOON_CHAR_SHADOW) && defined(_NILOTOON_RECEIVE_SELF_SHADOW)
TEXTURE2D(_NiloToonCharSelfShadowMapRT);
SAMPLER_CMP(sampler_NiloToonCharSelfShadowMapRT_LinearClampCompare);
SAMPLER(sampler_NiloToonCharSelfShadowMapRT_Linear_Clamp); // for raw depth sampling
float4x4 _NiloToonSelfShadowWorldToClip;
float4 _NiloToonSelfShadowParam; // (1/w, 1/h, w, h)
float3 _NiloToonSelfShadowLightDirection;
float _GlobalReceiveNiloToonSelfShadowMap;
float _NiloToonSelfShadowRange;
float _NiloToonSelfShadowUseNdotLFix;
float _NiloToonCharShadowStrength; // per-material shadow strength
#endif
// include files, include as late as possible to get all defines
#include "NiloToonEnvironment_ExtendFunctionsForUserCustomLogic.hlsl"
// NiloToon Character Self Shadow sampling function
#if defined(_RECEIVE_NILOTOON_CHAR_SHADOW) && defined(_NILOTOON_RECEIVE_SELF_SHADOW)
half SampleNiloToonCharSelfShadow(float3 positionWS, float3 normalWS, float linearEyeDepth)
{
// Transform world position to shadow map clip space
float4 positionSelfShadowCS = mul(_NiloToonSelfShadowWorldToClip, float4(positionWS, 1));
float3 positionSelfShadowNDC = positionSelfShadowCS.xyz;
// Convert NDC.xy[-1,1] to UV[0,1]
float2 shadowMapUV = positionSelfShadowNDC.xy * 0.5 + 0.5;
// Calculate compare value for shadow test
float ndcZCompareValue = positionSelfShadowNDC.z;
// If OpenGL, convert NDC.z[-1,1] to [0,1], because shadowmap uses [0,1] range
// If DirectX, it's already [0,1]
ndcZCompareValue = UNITY_NEAR_CLIP_VALUE < 0 ? ndcZCompareValue * 0.5 + 0.5 : ndcZCompareValue;
// If DirectX, flip shadowMapUV.y (y = 1-y)
// If OpenGL, do nothing
#if UNITY_UV_STARTS_AT_TOP
shadowMapUV.y = 1 - shadowMapUV.y;
#endif
// Check if outside shadow map UV bounds - no shadow outside
if(shadowMapUV.x < 0 || shadowMapUV.x > 1 || shadowMapUV.y < 0 || shadowMapUV.y > 1)
{
return 1; // no shadow
}
// Sample raw depth from shadow map to check if this is an empty area (no character)
// Empty areas have depth = 0 (cleared value), which would incorrectly cause shadow
float shadowMapRawDepth = SAMPLE_TEXTURE2D_LOD(_NiloToonCharSelfShadowMapRT,
sampler_NiloToonCharSelfShadowMapRT_Linear_Clamp,
shadowMapUV, 0).r;
// If shadowmap depth is near 0 (empty area - no character rendered there), no shadow
// In reverse-Z, 0 = far plane (empty/cleared), values closer to 1 = actual geometry
if(shadowMapRawDepth < 0.0001)
{
return 1; // no shadow - empty area in shadow map
}
// Pack UV and compare value for SAMPLE_TEXTURE2D_SHADOW
float4 selfShadowmapUV = float4(shadowMapUV, ndcZCompareValue, 0);
// Sample shadow map with depth comparison (hardware 1-tap bilinear filter)
half shadow = SAMPLE_TEXTURE2D_SHADOW(_NiloToonCharSelfShadowMapRT,
sampler_NiloToonCharSelfShadowMapRT_LinearClampCompare,
selfShadowmapUV.xyz);
// Fadeout shadow if reaching the end of shadow distance
float fadeTotalDistance = 1.0;
shadow = lerp(shadow, 1, saturate((1.0 / fadeTotalDistance) * (linearEyeDepth - (_NiloToonSelfShadowRange - fadeTotalDistance))));
// Use N dot L fix to hide shadow acne on surfaces facing away from light
if(_NiloToonSelfShadowUseNdotLFix > 0.5)
{
shadow *= smoothstep(0.1, 0.2, saturate(dot(normalWS, _NiloToonSelfShadowLightDirection)));
}
return shadow;
}
#endif
//==========================================================================================================================================================
///////////////////////////////////////////////////////////////////////////////
@ -521,6 +603,16 @@ void LitPassFragment(
Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, shadowMask);
// NiloToon Character Self Shadow
#if defined(_RECEIVE_NILOTOON_CHAR_SHADOW) && defined(_NILOTOON_RECEIVE_SELF_SHADOW)
{
float linearEyeDepth = abs(mul(UNITY_MATRIX_V, float4(input.positionWS, 1)).z);
half charSelfShadow = SampleNiloToonCharSelfShadow(input.positionWS, inputData.normalWS, linearEyeDepth);
charSelfShadow = lerp(1, charSelfShadow, _NiloToonCharShadowStrength * _GlobalReceiveNiloToonSelfShadowMap);
color.rgb *= charSelfShadow;
}
#endif
// shadow border tint color
float isShadowEdge = 1-abs(mainLight.shadowAttenuation-0.5)*2;
color.rgb = lerp(color.rgb,color.rgb * _NiloToonGlobalEnviShadowBorderTintColor.rgb, isShadowEdge * _NiloToonGlobalEnviShadowBorderTintColor.a);

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 53a33bd699913a642832d9cefe527f21
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Resources/KindRetargeting/retargeting_script.txt (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 500a6ad5f33a60347b30b0ca73a3e650
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Resources/KindRetargeting/retargeting_style.txt (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: f26ead3daa5f7de479c0c8547b3a792d
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Resources/KindRetargeting/retargeting_template.txt (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 227ed0897c5a66b47b6431f0c95fa98a
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Resources/KindRetargeting/웹 리타겟팅.txt (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b9d33120f9b2266498b51080310c89e6
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -8,7 +8,7 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Door__Door_C_jpg
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_Shader: {fileID: 4800000, guid: 50e19b7c9fbe3324e978246ad9789e96, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
@ -19,8 +19,7 @@ Material:
m_CustomRenderQueue: -1
stringTagMap:
RenderType: Opaque
disabledShaderPasses:
- MOTIONVECTORS
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@ -33,6 +32,10 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ClearCoatMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -69,6 +72,58 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -88,7 +143,9 @@ Material:
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BlendOp: 0
- _BumpScale: 1
- _ClearCoat: 0
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
@ -106,9 +163,29 @@ Material:
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _ScreenSpaceOutlineIntensity: 1
- _ScreenSpaceOutlineWidth: 1
- _Smoothness: 0
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SplatAlbedoMapATiling: 1
- _SplatAlbedoMapBTiling: 1
- _SplatAlbedoMapGTiling: 1
- _SplatAlbedoMapRTiling: 1
- _SplatHeightMultiplierA: 1
- _SplatHeightMultiplierB: 1
- _SplatHeightMultiplierG: 1
- _SplatHeightMultiplierR: 1
- _SplatMapFeatureOnOff: 0
- _SplatMaskBlendingSoftness: 0.5
- _SplatNormalMapIntensityA: 1
- _SplatNormalMapIntensityB: 1
- _SplatNormalMapIntensityG: 1
- _SplatNormalMapIntensityR: 1
- _SplatSmoothnessMultiplierA: 1
- _SplatSmoothnessMultiplierB: 1
- _SplatSmoothnessMultiplierG: 1
- _SplatSmoothnessMultiplierR: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
@ -119,7 +196,12 @@ Material:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _ScreenSpaceOutlineColor: {r: 1, g: 1, b: 1, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
- _SplatAlbedoMapATintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapBTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapGTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapRTintColor: {r: 1, g: 1, b: 1, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &1862183031488364992

View File

@ -8,7 +8,7 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Glass
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_Shader: {fileID: 4800000, guid: 50e19b7c9fbe3324e978246ad9789e96, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
@ -22,9 +22,8 @@ Material:
stringTagMap:
RenderType: Transparent
disabledShaderPasses:
- MOTIONVECTORS
- DepthOnly
- SHADOWCASTER
- DepthOnly
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@ -37,6 +36,10 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ClearCoatMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -73,6 +76,58 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -92,7 +147,9 @@ Material:
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BlendOp: 0
- _BumpScale: 1
- _ClearCoat: 0
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
@ -110,9 +167,29 @@ Material:
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _ScreenSpaceOutlineIntensity: 1
- _ScreenSpaceOutlineWidth: 1
- _Smoothness: 1
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SplatAlbedoMapATiling: 1
- _SplatAlbedoMapBTiling: 1
- _SplatAlbedoMapGTiling: 1
- _SplatAlbedoMapRTiling: 1
- _SplatHeightMultiplierA: 1
- _SplatHeightMultiplierB: 1
- _SplatHeightMultiplierG: 1
- _SplatHeightMultiplierR: 1
- _SplatMapFeatureOnOff: 0
- _SplatMaskBlendingSoftness: 0.5
- _SplatNormalMapIntensityA: 1
- _SplatNormalMapIntensityB: 1
- _SplatNormalMapIntensityG: 1
- _SplatNormalMapIntensityR: 1
- _SplatSmoothnessMultiplierA: 1
- _SplatSmoothnessMultiplierB: 1
- _SplatSmoothnessMultiplierG: 1
- _SplatSmoothnessMultiplierR: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 1
@ -123,7 +200,12 @@ Material:
- _BaseColor: {r: 1, g: 1, b: 1, a: 0.12941177}
- _Color: {r: 1, g: 1, b: 1, a: 0.12941177}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _ScreenSpaceOutlineColor: {r: 1, g: 1, b: 1, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
- _SplatAlbedoMapATintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapBTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapGTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapRTintColor: {r: 1, g: 1, b: 1, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &5761234848443323032

View File

@ -8,7 +8,7 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Glossy__Reflexion_jpg
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_Shader: {fileID: 4800000, guid: 50e19b7c9fbe3324e978246ad9789e96, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
@ -19,8 +19,7 @@ Material:
m_CustomRenderQueue: -1
stringTagMap:
RenderType: Opaque
disabledShaderPasses:
- MOTIONVECTORS
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@ -33,6 +32,10 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ClearCoatMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -69,6 +72,58 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -88,7 +143,9 @@ Material:
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BlendOp: 0
- _BumpScale: 1
- _ClearCoat: 0
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
@ -106,9 +163,29 @@ Material:
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _ScreenSpaceOutlineIntensity: 1
- _ScreenSpaceOutlineWidth: 1
- _Smoothness: 0
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SplatAlbedoMapATiling: 1
- _SplatAlbedoMapBTiling: 1
- _SplatAlbedoMapGTiling: 1
- _SplatAlbedoMapRTiling: 1
- _SplatHeightMultiplierA: 1
- _SplatHeightMultiplierB: 1
- _SplatHeightMultiplierG: 1
- _SplatHeightMultiplierR: 1
- _SplatMapFeatureOnOff: 0
- _SplatMaskBlendingSoftness: 0.5
- _SplatNormalMapIntensityA: 1
- _SplatNormalMapIntensityB: 1
- _SplatNormalMapIntensityG: 1
- _SplatNormalMapIntensityR: 1
- _SplatSmoothnessMultiplierA: 1
- _SplatSmoothnessMultiplierB: 1
- _SplatSmoothnessMultiplierG: 1
- _SplatSmoothnessMultiplierR: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
@ -119,7 +196,12 @@ Material:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _ScreenSpaceOutlineColor: {r: 1, g: 1, b: 1, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
- _SplatAlbedoMapATintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapBTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapGTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapRTintColor: {r: 1, g: 1, b: 1, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &7470487251160043050

View File

@ -21,7 +21,7 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Glossy__Reflexion_jpg_0
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_Shader: {fileID: 4800000, guid: 50e19b7c9fbe3324e978246ad9789e96, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
@ -32,8 +32,7 @@ Material:
m_CustomRenderQueue: -1
stringTagMap:
RenderType: Opaque
disabledShaderPasses:
- MOTIONVECTORS
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@ -46,6 +45,10 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ClearCoatMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -82,6 +85,58 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -101,7 +156,9 @@ Material:
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BlendOp: 0
- _BumpScale: 1
- _ClearCoat: 0
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
@ -119,9 +176,29 @@ Material:
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _ScreenSpaceOutlineIntensity: 1
- _ScreenSpaceOutlineWidth: 1
- _Smoothness: 0
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SplatAlbedoMapATiling: 1
- _SplatAlbedoMapBTiling: 1
- _SplatAlbedoMapGTiling: 1
- _SplatAlbedoMapRTiling: 1
- _SplatHeightMultiplierA: 1
- _SplatHeightMultiplierB: 1
- _SplatHeightMultiplierG: 1
- _SplatHeightMultiplierR: 1
- _SplatMapFeatureOnOff: 0
- _SplatMaskBlendingSoftness: 0.5
- _SplatNormalMapIntensityA: 1
- _SplatNormalMapIntensityB: 1
- _SplatNormalMapIntensityG: 1
- _SplatNormalMapIntensityR: 1
- _SplatSmoothnessMultiplierA: 1
- _SplatSmoothnessMultiplierB: 1
- _SplatSmoothnessMultiplierG: 1
- _SplatSmoothnessMultiplierR: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
@ -132,6 +209,11 @@ Material:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _ScreenSpaceOutlineColor: {r: 1, g: 1, b: 1, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
- _SplatAlbedoMapATintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapBTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapGTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapRTintColor: {r: 1, g: 1, b: 1, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

@ -8,7 +8,7 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Glossy__Reflexion_jpg_1
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_Shader: {fileID: 4800000, guid: 50e19b7c9fbe3324e978246ad9789e96, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
@ -19,8 +19,7 @@ Material:
m_CustomRenderQueue: -1
stringTagMap:
RenderType: Opaque
disabledShaderPasses:
- MOTIONVECTORS
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@ -33,6 +32,10 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ClearCoatMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -69,6 +72,58 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -88,7 +143,9 @@ Material:
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BlendOp: 0
- _BumpScale: 1
- _ClearCoat: 0
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
@ -106,9 +163,29 @@ Material:
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _ScreenSpaceOutlineIntensity: 1
- _ScreenSpaceOutlineWidth: 1
- _Smoothness: 0
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SplatAlbedoMapATiling: 1
- _SplatAlbedoMapBTiling: 1
- _SplatAlbedoMapGTiling: 1
- _SplatAlbedoMapRTiling: 1
- _SplatHeightMultiplierA: 1
- _SplatHeightMultiplierB: 1
- _SplatHeightMultiplierG: 1
- _SplatHeightMultiplierR: 1
- _SplatMapFeatureOnOff: 0
- _SplatMaskBlendingSoftness: 0.5
- _SplatNormalMapIntensityA: 1
- _SplatNormalMapIntensityB: 1
- _SplatNormalMapIntensityG: 1
- _SplatNormalMapIntensityR: 1
- _SplatSmoothnessMultiplierA: 1
- _SplatSmoothnessMultiplierB: 1
- _SplatSmoothnessMultiplierG: 1
- _SplatSmoothnessMultiplierR: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
@ -119,7 +196,12 @@ Material:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _ScreenSpaceOutlineColor: {r: 1, g: 1, b: 1, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
- _SplatAlbedoMapATintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapBTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapGTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapRTintColor: {r: 1, g: 1, b: 1, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &7269642324176022440

View File

@ -21,11 +21,12 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Material.001
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_Shader: {fileID: 4800000, guid: 50e19b7c9fbe3324e978246ad9789e96, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _NORMALMAP
- _RECEIVE_NILOTOON_CHAR_SHADOW
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
@ -33,8 +34,7 @@ Material:
m_CustomRenderQueue: -1
stringTagMap:
RenderType: Opaque
disabledShaderPasses:
- MOTIONVECTORS
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@ -47,6 +47,10 @@ Material:
m_Texture: {fileID: 2800000, guid: 98d719629dbafc44aa8c71a15aa70ece, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ClearCoatMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -83,6 +87,58 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -102,7 +158,9 @@ Material:
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BlendOp: 0
- _BumpScale: 1
- _ClearCoat: 0
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
@ -116,13 +174,35 @@ Material:
- _Glossiness: 0
- _GlossyReflections: 0
- _Metallic: 0.036
- _NiloToonCharShadowStrength: 0.436
- _OcclusionStrength: 1
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveNiloToonCharShadow: 1
- _ReceiveShadows: 1
- _ScreenSpaceOutlineIntensity: 1
- _ScreenSpaceOutlineWidth: 1
- _Smoothness: 0.916
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SplatAlbedoMapATiling: 1
- _SplatAlbedoMapBTiling: 1
- _SplatAlbedoMapGTiling: 1
- _SplatAlbedoMapRTiling: 1
- _SplatHeightMultiplierA: 1
- _SplatHeightMultiplierB: 1
- _SplatHeightMultiplierG: 1
- _SplatHeightMultiplierR: 1
- _SplatMapFeatureOnOff: 0
- _SplatMaskBlendingSoftness: 0.5
- _SplatNormalMapIntensityA: 1
- _SplatNormalMapIntensityB: 1
- _SplatNormalMapIntensityG: 1
- _SplatNormalMapIntensityR: 1
- _SplatSmoothnessMultiplierA: 1
- _SplatSmoothnessMultiplierB: 1
- _SplatSmoothnessMultiplierG: 1
- _SplatSmoothnessMultiplierR: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
@ -133,6 +213,11 @@ Material:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _ScreenSpaceOutlineColor: {r: 1, g: 1, b: 1, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
- _SplatAlbedoMapATintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapBTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapGTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapRTintColor: {r: 1, g: 1, b: 1, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

@ -8,7 +8,7 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Material.002
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_Shader: {fileID: 4800000, guid: 50e19b7c9fbe3324e978246ad9789e96, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
@ -19,8 +19,7 @@ Material:
m_CustomRenderQueue: -1
stringTagMap:
RenderType: Opaque
disabledShaderPasses:
- MOTIONVECTORS
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@ -33,6 +32,10 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ClearCoatMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -69,6 +72,58 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -88,7 +143,9 @@ Material:
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BlendOp: 0
- _BumpScale: 1
- _ClearCoat: 0
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
@ -106,9 +163,29 @@ Material:
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _ScreenSpaceOutlineIntensity: 1
- _ScreenSpaceOutlineWidth: 1
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SplatAlbedoMapATiling: 1
- _SplatAlbedoMapBTiling: 1
- _SplatAlbedoMapGTiling: 1
- _SplatAlbedoMapRTiling: 1
- _SplatHeightMultiplierA: 1
- _SplatHeightMultiplierB: 1
- _SplatHeightMultiplierG: 1
- _SplatHeightMultiplierR: 1
- _SplatMapFeatureOnOff: 0
- _SplatMaskBlendingSoftness: 0.5
- _SplatNormalMapIntensityA: 1
- _SplatNormalMapIntensityB: 1
- _SplatNormalMapIntensityG: 1
- _SplatNormalMapIntensityR: 1
- _SplatSmoothnessMultiplierA: 1
- _SplatSmoothnessMultiplierB: 1
- _SplatSmoothnessMultiplierG: 1
- _SplatSmoothnessMultiplierR: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
@ -119,7 +196,12 @@ Material:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _ScreenSpaceOutlineColor: {r: 1, g: 1, b: 1, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
- _SplatAlbedoMapATintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapBTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapGTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapRTintColor: {r: 1, g: 1, b: 1, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &2158766202383902538

View File

@ -21,7 +21,7 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Material.003
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_Shader: {fileID: 4800000, guid: 50e19b7c9fbe3324e978246ad9789e96, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
@ -32,8 +32,7 @@ Material:
m_CustomRenderQueue: -1
stringTagMap:
RenderType: Opaque
disabledShaderPasses:
- MOTIONVECTORS
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@ -46,6 +45,10 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ClearCoatMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -82,6 +85,58 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -101,7 +156,9 @@ Material:
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BlendOp: 0
- _BumpScale: 1
- _ClearCoat: 0
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
@ -115,13 +172,35 @@ Material:
- _Glossiness: 0
- _GlossyReflections: 0
- _Metallic: 0
- _NiloToonCharShadowStrength: 1
- _OcclusionStrength: 1
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveNiloToonCharShadow: 0
- _ReceiveShadows: 1
- _ScreenSpaceOutlineIntensity: 1
- _ScreenSpaceOutlineWidth: 1
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SplatAlbedoMapATiling: 1
- _SplatAlbedoMapBTiling: 1
- _SplatAlbedoMapGTiling: 1
- _SplatAlbedoMapRTiling: 1
- _SplatHeightMultiplierA: 1
- _SplatHeightMultiplierB: 1
- _SplatHeightMultiplierG: 1
- _SplatHeightMultiplierR: 1
- _SplatMapFeatureOnOff: 0
- _SplatMaskBlendingSoftness: 0.5
- _SplatNormalMapIntensityA: 1
- _SplatNormalMapIntensityB: 1
- _SplatNormalMapIntensityG: 1
- _SplatNormalMapIntensityR: 1
- _SplatSmoothnessMultiplierA: 1
- _SplatSmoothnessMultiplierB: 1
- _SplatSmoothnessMultiplierG: 1
- _SplatSmoothnessMultiplierR: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
@ -132,6 +211,11 @@ Material:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _ScreenSpaceOutlineColor: {r: 1, g: 1, b: 1, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
- _SplatAlbedoMapATintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapBTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapGTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapRTintColor: {r: 1, g: 1, b: 1, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

@ -21,7 +21,7 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: T_hanging_lights_1001
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_Shader: {fileID: 4800000, guid: 50e19b7c9fbe3324e978246ad9789e96, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
@ -34,8 +34,7 @@ Material:
m_CustomRenderQueue: -1
stringTagMap:
RenderType: Opaque
disabledShaderPasses:
- MOTIONVECTORS
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@ -48,6 +47,10 @@ Material:
m_Texture: {fileID: 2800000, guid: efb424378ae795b408086e2f6814fcbb, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ClearCoatMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -84,6 +87,58 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -103,7 +158,9 @@ Material:
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BlendOp: 0
- _BumpScale: 1
- _ClearCoat: 0
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
@ -121,9 +178,29 @@ Material:
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _ScreenSpaceOutlineIntensity: 1
- _ScreenSpaceOutlineWidth: 1
- _Smoothness: 0.735
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SplatAlbedoMapATiling: 1
- _SplatAlbedoMapBTiling: 1
- _SplatAlbedoMapGTiling: 1
- _SplatAlbedoMapRTiling: 1
- _SplatHeightMultiplierA: 1
- _SplatHeightMultiplierB: 1
- _SplatHeightMultiplierG: 1
- _SplatHeightMultiplierR: 1
- _SplatMapFeatureOnOff: 0
- _SplatMaskBlendingSoftness: 0.5
- _SplatNormalMapIntensityA: 1
- _SplatNormalMapIntensityB: 1
- _SplatNormalMapIntensityG: 1
- _SplatNormalMapIntensityR: 1
- _SplatSmoothnessMultiplierA: 1
- _SplatSmoothnessMultiplierB: 1
- _SplatSmoothnessMultiplierG: 1
- _SplatSmoothnessMultiplierR: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
@ -134,6 +211,11 @@ Material:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 2, g: 2, b: 2, a: 1}
- _ScreenSpaceOutlineColor: {r: 1, g: 1, b: 1, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
- _SplatAlbedoMapATintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapBTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapGTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapRTintColor: {r: 1, g: 1, b: 1, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

@ -8,7 +8,7 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: defaultMat_0
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_Shader: {fileID: 4800000, guid: 50e19b7c9fbe3324e978246ad9789e96, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
@ -19,8 +19,7 @@ Material:
m_CustomRenderQueue: -1
stringTagMap:
RenderType: Opaque
disabledShaderPasses:
- MOTIONVECTORS
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@ -33,6 +32,10 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ClearCoatMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -69,6 +72,58 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -88,7 +143,9 @@ Material:
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BlendOp: 0
- _BumpScale: 1
- _ClearCoat: 0
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
@ -106,9 +163,29 @@ Material:
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _ScreenSpaceOutlineIntensity: 1
- _ScreenSpaceOutlineWidth: 1
- _Smoothness: 1
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SplatAlbedoMapATiling: 1
- _SplatAlbedoMapBTiling: 1
- _SplatAlbedoMapGTiling: 1
- _SplatAlbedoMapRTiling: 1
- _SplatHeightMultiplierA: 1
- _SplatHeightMultiplierB: 1
- _SplatHeightMultiplierG: 1
- _SplatHeightMultiplierR: 1
- _SplatMapFeatureOnOff: 0
- _SplatMaskBlendingSoftness: 0.5
- _SplatNormalMapIntensityA: 1
- _SplatNormalMapIntensityB: 1
- _SplatNormalMapIntensityG: 1
- _SplatNormalMapIntensityR: 1
- _SplatSmoothnessMultiplierA: 1
- _SplatSmoothnessMultiplierB: 1
- _SplatSmoothnessMultiplierG: 1
- _SplatSmoothnessMultiplierR: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
@ -119,7 +196,12 @@ Material:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _ScreenSpaceOutlineColor: {r: 1, g: 1, b: 1, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
- _SplatAlbedoMapATintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapBTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapGTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapRTintColor: {r: 1, g: 1, b: 1, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &3317871890002257173

View File

@ -21,7 +21,7 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: embossed-plaster
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_Shader: {fileID: 4800000, guid: 50e19b7c9fbe3324e978246ad9789e96, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
@ -33,8 +33,7 @@ Material:
m_CustomRenderQueue: -1
stringTagMap:
RenderType: Opaque
disabledShaderPasses:
- MOTIONVECTORS
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
@ -47,6 +46,10 @@ Material:
m_Texture: {fileID: 2800000, guid: f6ff171e183018147b53c52d61cc5319, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ClearCoatMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -83,6 +86,58 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatAlbedoMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatNormalMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapA:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapB:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapG:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SplatPackedDataMapR:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@ -102,7 +157,9 @@ Material:
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BlendOp: 0
- _BumpScale: 1
- _ClearCoat: 0
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
@ -120,9 +177,29 @@ Material:
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _ScreenSpaceOutlineIntensity: 1
- _ScreenSpaceOutlineWidth: 1
- _Smoothness: 0.843
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SplatAlbedoMapATiling: 1
- _SplatAlbedoMapBTiling: 1
- _SplatAlbedoMapGTiling: 1
- _SplatAlbedoMapRTiling: 1
- _SplatHeightMultiplierA: 1
- _SplatHeightMultiplierB: 1
- _SplatHeightMultiplierG: 1
- _SplatHeightMultiplierR: 1
- _SplatMapFeatureOnOff: 0
- _SplatMaskBlendingSoftness: 0.5
- _SplatNormalMapIntensityA: 1
- _SplatNormalMapIntensityB: 1
- _SplatNormalMapIntensityG: 1
- _SplatNormalMapIntensityR: 1
- _SplatSmoothnessMultiplierA: 1
- _SplatSmoothnessMultiplierB: 1
- _SplatSmoothnessMultiplierG: 1
- _SplatSmoothnessMultiplierR: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
@ -133,6 +210,11 @@ Material:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _ScreenSpaceOutlineColor: {r: 1, g: 1, b: 1, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
- _SplatAlbedoMapATintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapBTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapGTintColor: {r: 1, g: 1, b: 1, a: 1}
- _SplatAlbedoMapRTintColor: {r: 1, g: 1, b: 1, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

@ -0,0 +1,117 @@
fileFormatVersion: 2
guid: 66686f1b558d9424f9264a116e0f3f8a
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 1
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 3
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 12
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 2
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,117 @@
fileFormatVersion: 2
guid: 76510edb63367774cbb6604bf1af9e8e
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 1
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 3
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 0
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 6
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 2
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,117 @@
fileFormatVersion: 2
guid: 66b19b6e2a88a2740a03850e901c1f84
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 1
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 3
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 12
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 2
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,117 @@
fileFormatVersion: 2
guid: 0edb763249ebda742bbe6bd5e606afec
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 1
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 3
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 0
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 6
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 2
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,117 @@
fileFormatVersion: 2
guid: e6199872890fe8f47a509897a435a289
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 1
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 3
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 12
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 2
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,117 @@
fileFormatVersion: 2
guid: 7655ae17f8945294f8a7b30fbae09ffe
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 1
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 3
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 0
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 6
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 2
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -118,11 +118,20 @@ namespace KindRetargeting
private float initialHipsHeight; // 초기 힙 높이
// T-포즈에서의 머리 정면 방향 (캘리브레이션용)
[HideInInspector] public Vector3 tPoseHeadForward = Vector3.forward;
[HideInInspector] public Vector3 tPoseHeadUp = Vector3.up;
[Header("아바타 크기 조정")]
[SerializeField, Range(0.1f, 3f)] private float avatarScale = 1f;
private float previousScale = 1f;
private List<Transform> scalableObjects = new List<Transform>();
[Header("머리 크기 조정")]
[SerializeField, Range(0.1f, 3f)] private float headScale = 1f;
private Transform headBone;
private Vector3 originalHeadScale = Vector3.one;
// 필드 추가
private Dictionary<Transform, Vector3> originalScales = new Dictionary<Transform, Vector3>();
private Dictionary<Transform, Vector3> originalPositions = new Dictionary<Transform, Vector3>();
@ -180,6 +189,8 @@ namespace KindRetargeting
public float headRotationOffsetX;
public float headRotationOffsetY;
public float headRotationOffsetZ;
// 머리 크기
public float headScale;
}
[System.Serializable]
@ -355,6 +366,9 @@ namespace KindRetargeting
SetTPose(sourceAnimator);
SetTPose(targetAnimator);
// T-포즈에서의 머리 정면 방향 캐싱 (캘리브레이션용)
CacheTPoseHeadDirection();
// HumanPoseHandler 초기화
InitializeHumanPoseHandlers();
@ -385,6 +399,21 @@ namespace KindRetargeting
previousScale = avatarScale;
ApplyScale();
// 머리 본 초기화
if (targetAnimator != null)
{
headBone = targetAnimator.GetBoneTransform(HumanBodyBones.Head);
if (headBone != null)
{
originalHeadScale = headBone.localScale;
Debug.Log($"[CustomRetargetingScript] 머리 본 초기화 완료: {headBone.name}, 원본 스케일: {originalHeadScale}");
}
else
{
Debug.LogWarning("[CustomRetargetingScript] 머리 본을 찾을 수 없습니다!");
}
}
}
/// <summary>
@ -697,6 +726,7 @@ namespace KindRetargeting
headRotationOffsetX = headRotationOffsetX,
headRotationOffsetY = headRotationOffsetY,
headRotationOffsetZ = headRotationOffsetZ,
headScale = headScale,
};
string json = JsonUtility.ToJson(settings, true);
@ -757,6 +787,7 @@ namespace KindRetargeting
initialHipsHeight = settings.initialHipsHeight;
avatarScale = settings.avatarScale;
previousScale = avatarScale;
headScale = settings.headScale;
// Mingle 캘리브레이션 데이터 로드
if (settings.fingerOpenRotationsCache != null && settings.fingerOpenRotationsCache.Count > 0)
@ -1375,11 +1406,37 @@ namespace KindRetargeting
}
/// <summary>
/// LateUpdate에서 머리 회전 오프셋 적용합니다 (IK 이후 실행).
/// LateUpdate에서 머리 회전 오프셋과 머리 크기를 적용합니다 (IK 이후 실행).
/// </summary>
void LateUpdate()
{
ApplyHeadRotationOffset();
ApplyHeadScale();
}
/// <summary>
/// 머리 크기를 적용합니다.
/// 애니메이션이 매 프레임 스케일을 리셋할 수 있으므로 매 프레임 적용합니다.
/// </summary>
private void ApplyHeadScale()
{
if (headBone == null)
{
// headBone이 없으면 다시 찾기 시도
if (targetAnimator != null)
{
headBone = targetAnimator.GetBoneTransform(HumanBodyBones.Head);
if (headBone != null)
{
originalHeadScale = headBone.localScale;
Debug.Log($"[HeadScale] 머리 본 재초기화: {headBone.name}");
}
}
if (headBone == null) return;
}
// 매 프레임 스케일 적용 (애니메이션이 리셋할 수 있음)
headBone.localScale = originalHeadScale * headScale;
}
/// <summary>
@ -1403,6 +1460,91 @@ namespace KindRetargeting
Quaternion offsetRotation = Quaternion.Euler(headRotationOffsetX, headRotationOffsetY, headRotationOffsetZ);
headBone.localRotation *= offsetRotation;
}
/// <summary>
/// T-포즈 상태에서 머리의 정면 방향을 캐싱합니다.
/// 이 값은 정면 캘리브레이션에서 기준점으로 사용됩니다.
/// </summary>
private void CacheTPoseHeadDirection()
{
if (targetAnimator == null) return;
Transform headBone = targetAnimator.GetBoneTransform(HumanBodyBones.Head);
if (headBone == null) return;
// T-포즈 상태에서의 머리 월드 방향 저장
tPoseHeadForward = headBone.forward;
tPoseHeadUp = headBone.up;
Debug.Log($"[{gameObject.name}] T-포즈 머리 방향 캐싱 완료 - Forward: {tPoseHeadForward}, Up: {tPoseHeadUp}");
}
/// <summary>
/// 정면 캘리브레이션을 실행합니다. (웹 리모컨에서 호출)
/// </summary>
public void CalibrateHeadToForward()
{
if (targetAnimator == null) return;
Transform targetHead = targetAnimator.GetBoneTransform(HumanBodyBones.Head);
if (targetHead == null) return;
if (tPoseHeadForward.sqrMagnitude < 0.001f)
{
Debug.LogWarning("T-포즈 머리 방향이 캐싱되지 않았습니다.");
return;
}
// 1. 기존 오프셋 제거하여 원본 로컬 회전 계산
Quaternion currentLocalRot = targetHead.localRotation;
Quaternion prevOffset = Quaternion.Euler(headRotationOffsetX, headRotationOffsetY, headRotationOffsetZ);
Quaternion baseLocalRot = currentLocalRot * Quaternion.Inverse(prevOffset);
// 2. 부모 월드 회전
Transform headParent = targetHead.parent;
Quaternion parentWorldRot = headParent != null ? headParent.rotation : Quaternion.identity;
// 3. 오프셋 제거된 원본 상태의 월드 회전
Quaternion baseWorldRot = parentWorldRot * baseLocalRot;
// 4. 오프셋 제거된 원본 상태에서의 머리 forward/up 방향 계산
Vector3 currentHeadForward = baseWorldRot * Vector3.forward;
Vector3 currentHeadUp = baseWorldRot * Vector3.up;
// 5. 현재 머리 forward → T-포즈 forward로의 회전 계산
Quaternion forwardCorrection = Quaternion.FromToRotation(currentHeadForward, tPoseHeadForward);
// 6. forward 보정 후 up 방향도 맞춰야 함
Vector3 correctedUp = forwardCorrection * currentHeadUp;
float rollAngle = Vector3.SignedAngle(correctedUp, tPoseHeadUp, tPoseHeadForward);
Quaternion rollCorrection = Quaternion.AngleAxis(rollAngle, tPoseHeadForward);
// 7. 전체 월드 보정 회전
Quaternion worldCorrection = rollCorrection * forwardCorrection;
// 8. 보정된 월드 회전
Quaternion correctedWorldRot = worldCorrection * baseWorldRot;
// 9. 보정된 로컬 회전
Quaternion correctedLocalRot = Quaternion.Inverse(parentWorldRot) * correctedWorldRot;
// 10. 오프셋 계산
Quaternion offsetQuat = Quaternion.Inverse(baseLocalRot) * correctedLocalRot;
// 11. 오일러로 변환
Vector3 euler = offsetQuat.eulerAngles;
if (euler.x > 180f) euler.x -= 360f;
if (euler.y > 180f) euler.y -= 360f;
if (euler.z > 180f) euler.z -= 360f;
// 12. 적용
headRotationOffsetX = Mathf.Clamp(euler.x, -180f, 180f);
headRotationOffsetY = Mathf.Clamp(euler.y, -180f, 180f);
headRotationOffsetZ = Mathf.Clamp(euler.z, -180f, 180f);
Debug.Log($"[{gameObject.name}] 정면 캘리브레이션 완료 - Offset X: {euler.x:F1}°, Y: {euler.y:F1}°, Z: {euler.z:F1}°");
}
/// <summary>
/// 머슬 데이터를 사용하여 손가락 포즈를 복제합니다.
/// SetHumanPose가 모든 본에 영향을 미치므로, 손가락을 제외한 모든 본의 Transform을 저장하고 복원합니다.
@ -2183,6 +2325,46 @@ namespace KindRetargeting
{
return avatarScale;
}
// 외부에서 머리 크기를 설정할 수 있는 public 메서드
public void SetHeadScale(float scale)
{
headScale = Mathf.Clamp(scale, 0.1f, 3f);
ApplyHeadScaleImmediate();
}
// 현재 머리 크기를 가져오는 메서드
public float GetHeadScale()
{
return headScale;
}
// 머리 크기 리셋
public void ResetHeadScale()
{
headScale = 1f;
ApplyHeadScaleImmediate();
}
// 머리 크기 즉시 적용 (headBone이 없으면 찾아서 적용)
private void ApplyHeadScaleImmediate()
{
// headBone이 없으면 찾기
if (headBone == null && targetAnimator != null)
{
headBone = targetAnimator.GetBoneTransform(HumanBodyBones.Head);
if (headBone != null)
{
originalHeadScale = headBone.localScale;
Debug.Log($"[HeadScale] 머리 본 찾음: {headBone.name}, 원본 스케일: {originalHeadScale}");
}
}
if (headBone != null)
{
headBone.localScale = originalHeadScale * headScale;
}
}
}
}

View File

@ -1119,6 +1119,9 @@ public class RetargetingControlWindow : EditorWindow
var avatarScaleProp = serializedObject.FindProperty("avatarScale");
EditorGUILayout.PropertyField(avatarScaleProp, new GUIContent("아바타 크기"));
var headScaleProp = serializedObject.FindProperty("headScale");
EditorGUILayout.PropertyField(headScaleProp, new GUIContent("머리 크기"));
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
@ -1141,8 +1144,10 @@ public class RetargetingControlWindow : EditorWindow
EditorGUILayout.Slider(headRotationZProp, -180f, 180f,
new GUIContent("Z (Pitch) - 상하 회전", "머리를 상하로 회전합니다"));
// 초기화 버튼
// 초기화 버튼과 정면 캘리브레이션 버튼을 가로로 배치
EditorGUILayout.Space(5);
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("회전 초기화", GUILayout.Height(25)))
{
headRotationXProp.floatValue = 0f;
@ -1152,6 +1157,21 @@ public class RetargetingControlWindow : EditorWindow
EditorUtility.SetDirty(serializedObject.targetObject);
}
// 정면 캘리브레이션 버튼
GUI.enabled = Application.isPlaying;
if (GUILayout.Button("정면 캘리브레이션", GUILayout.Height(25)))
{
CalibrateHeadToForward(serializedObject, headRotationXProp, headRotationYProp, headRotationZProp);
}
GUI.enabled = true;
EditorGUILayout.EndHorizontal();
if (!Application.isPlaying)
{
EditorGUILayout.HelpBox("정면 캘리브레이션은 플레이 모드에서만 사용 가능합니다.", MessageType.Info);
}
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
@ -1343,6 +1363,104 @@ public class RetargetingControlWindow : EditorWindow
EditorGUILayout.LabelField("부착된 프랍 없음");
}
}
/// <summary>
/// T-포즈에서 캐싱한 머리 정면 방향과 현재 머리 방향을 비교하여 오프셋을 계산합니다.
/// 사용법: 모캡 배우가 정면을 바라볼 때 버튼을 누르세요.
/// </summary>
private void CalibrateHeadToForward(SerializedObject serializedObject,
SerializedProperty headRotationXProp,
SerializedProperty headRotationYProp,
SerializedProperty headRotationZProp)
{
CustomRetargetingScript script = serializedObject.targetObject as CustomRetargetingScript;
if (script == null)
{
Debug.LogWarning("CustomRetargetingScript가 없습니다.");
return;
}
Animator targetAnimator = script.GetComponent<Animator>();
if (targetAnimator == null)
{
Debug.LogWarning("타겟 Animator가 없습니다.");
return;
}
Transform targetHead = targetAnimator.GetBoneTransform(HumanBodyBones.Head);
if (targetHead == null)
{
Debug.LogWarning("타겟 아바타의 Head 본을 찾을 수 없습니다.");
return;
}
// T-포즈 머리 방향이 캐싱되어 있는지 확인
Vector3 tPoseForward = script.tPoseHeadForward;
Vector3 tPoseUp = script.tPoseHeadUp;
if (tPoseForward.sqrMagnitude < 0.001f)
{
Debug.LogWarning("T-포즈 머리 방향이 캐싱되지 않았습니다. 게임을 재시작해주세요.");
return;
}
// 1. 기존 오프셋 제거하여 원본 로컬 회전 계산
float prevX = headRotationXProp.floatValue;
float prevY = headRotationYProp.floatValue;
float prevZ = headRotationZProp.floatValue;
Quaternion currentLocalRot = targetHead.localRotation;
Quaternion prevOffset = Quaternion.Euler(prevX, prevY, prevZ);
Quaternion baseLocalRot = currentLocalRot * Quaternion.Inverse(prevOffset);
// 2. 부모 월드 회전
Transform headParent = targetHead.parent;
Quaternion parentWorldRot = headParent != null ? headParent.rotation : Quaternion.identity;
// 3. 오프셋 제거된 원본 상태의 월드 회전
Quaternion baseWorldRot = parentWorldRot * baseLocalRot;
// 4. 오프셋 제거된 원본 상태에서의 머리 forward/up 방향 계산
Vector3 currentHeadForward = baseWorldRot * Vector3.forward;
Vector3 currentHeadUp = baseWorldRot * Vector3.up;
// 5. 현재 머리 forward → T-포즈 forward로의 회전 계산
Quaternion forwardCorrection = Quaternion.FromToRotation(currentHeadForward, tPoseForward);
// 6. forward 보정 후 up 방향도 맞춰야 함
Vector3 correctedUp = forwardCorrection * currentHeadUp;
// T-포즈 up과의 차이 (roll)
float rollAngle = Vector3.SignedAngle(correctedUp, tPoseUp, tPoseForward);
Quaternion rollCorrection = Quaternion.AngleAxis(rollAngle, tPoseForward);
// 7. 전체 월드 보정 회전
Quaternion worldCorrection = rollCorrection * forwardCorrection;
// 8. 보정된 월드 회전
Quaternion correctedWorldRot = worldCorrection * baseWorldRot;
// 9. 보정된 로컬 회전
Quaternion correctedLocalRot = Quaternion.Inverse(parentWorldRot) * correctedWorldRot;
// 10. 오프셋 계산: baseLocalRot * offset = correctedLocalRot
Quaternion offsetQuat = Quaternion.Inverse(baseLocalRot) * correctedLocalRot;
// 11. 오일러로 변환
Vector3 euler = offsetQuat.eulerAngles;
if (euler.x > 180f) euler.x -= 360f;
if (euler.y > 180f) euler.y -= 360f;
if (euler.z > 180f) euler.z -= 360f;
// 12. 적용
headRotationXProp.floatValue = Mathf.Clamp(euler.x, -180f, 180f);
headRotationYProp.floatValue = Mathf.Clamp(euler.y, -180f, 180f);
headRotationZProp.floatValue = Mathf.Clamp(euler.z, -180f, 180f);
serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(serializedObject.targetObject);
Debug.Log($"정면 캘리브레이션 완료 - T-Pose Forward: {tPoseForward}, Current Forward: {currentHeadForward}\n" +
$" → Offset X: {euler.x:F1}°, Y: {euler.y:F1}°, Z: {euler.z:F1}°");
}
}
[System.Serializable]

View File

@ -0,0 +1,184 @@
using UnityEngine;
using UnityEditor;
using KindRetargeting.Remote;
namespace KindRetargeting.Editor
{
[CustomEditor(typeof(RetargetingRemoteController))]
public class RetargetingRemoteControllerEditor : UnityEditor.Editor
{
private SerializedProperty httpPortProp;
private SerializedProperty wsPortProp;
private SerializedProperty autoStartProp;
private SerializedProperty registeredCharactersProp;
private void OnEnable()
{
httpPortProp = serializedObject.FindProperty("httpPort");
wsPortProp = serializedObject.FindProperty("wsPort");
autoStartProp = serializedObject.FindProperty("autoStart");
registeredCharactersProp = serializedObject.FindProperty("registeredCharacters");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
RetargetingRemoteController controller = (RetargetingRemoteController)target;
// 헤더
EditorGUILayout.Space(5);
EditorGUILayout.LabelField("리타게팅 웹 리모컨", EditorStyles.boldLabel);
EditorGUILayout.Space(5);
// 상태 표시
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("상태:", GUILayout.Width(40));
if (Application.isPlaying)
{
if (controller.IsRunning)
{
GUI.color = Color.green;
EditorGUILayout.LabelField("실행 중", EditorStyles.boldLabel);
GUI.color = Color.white;
}
else
{
GUI.color = Color.yellow;
EditorGUILayout.LabelField("중지됨", EditorStyles.boldLabel);
GUI.color = Color.white;
}
}
else
{
GUI.color = Color.gray;
EditorGUILayout.LabelField("대기 중 (플레이 모드 필요)", EditorStyles.boldLabel);
GUI.color = Color.white;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
EditorGUILayout.Space(10);
// 서버 설정
EditorGUILayout.LabelField("서버 설정", EditorStyles.boldLabel);
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
EditorGUILayout.PropertyField(httpPortProp, new GUIContent("HTTP 포트"));
EditorGUILayout.PropertyField(wsPortProp, new GUIContent("WebSocket 포트"));
EditorGUILayout.PropertyField(autoStartProp, new GUIContent("자동 시작"));
EditorGUILayout.EndVertical();
EditorGUILayout.Space(10);
// 접속 URL
if (Application.isPlaying && controller.IsRunning)
{
EditorGUILayout.LabelField("접속 URL", EditorStyles.boldLabel);
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
string localUrl = $"http://localhost:{httpPortProp.intValue}";
EditorGUILayout.BeginHorizontal();
EditorGUILayout.TextField("로컬", localUrl);
if (GUILayout.Button("복사", GUILayout.Width(40)))
{
EditorGUIUtility.systemCopyBuffer = localUrl;
}
EditorGUILayout.EndHorizontal();
string localIP = GetLocalIPAddress();
if (!string.IsNullOrEmpty(localIP))
{
string networkUrl = $"http://{localIP}:{httpPortProp.intValue}";
EditorGUILayout.BeginHorizontal();
EditorGUILayout.TextField("네트워크", networkUrl);
if (GUILayout.Button("복사", GUILayout.Width(40)))
{
EditorGUIUtility.systemCopyBuffer = networkUrl;
}
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndVertical();
}
EditorGUILayout.Space(10);
// 캐릭터 등록
EditorGUILayout.LabelField("등록된 캐릭터", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(registeredCharactersProp, GUIContent.none);
// 자동 등록 버튼
EditorGUILayout.Space(5);
if (GUILayout.Button("씬에서 캐릭터 자동 찾기"))
{
AutoFindCharacters();
}
EditorGUILayout.Space(10);
// 서버 제어 버튼 (플레이 모드에서만)
if (Application.isPlaying)
{
EditorGUILayout.LabelField("서버 제어", EditorStyles.boldLabel);
EditorGUILayout.BeginHorizontal();
if (controller.IsRunning)
{
if (GUILayout.Button("서버 중지", GUILayout.Height(30)))
{
controller.StopServer();
}
}
else
{
if (GUILayout.Button("서버 시작", GUILayout.Height(30)))
{
controller.StartServer();
}
}
EditorGUILayout.EndHorizontal();
}
serializedObject.ApplyModifiedProperties();
}
private void AutoFindCharacters()
{
var characters = FindObjectsByType<CustomRetargetingScript>(FindObjectsSortMode.None);
registeredCharactersProp.ClearArray();
foreach (var character in characters)
{
int index = registeredCharactersProp.arraySize;
registeredCharactersProp.InsertArrayElementAtIndex(index);
registeredCharactersProp.GetArrayElementAtIndex(index).objectReferenceValue = character;
}
serializedObject.ApplyModifiedProperties();
Debug.Log($"[RetargetingRemote] {characters.Length}개의 캐릭터를 찾았습니다.");
}
private string GetLocalIPAddress()
{
try
{
var host = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
}
catch { }
return "";
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: eccd6d5782992bd45913dd1589224b88

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0bcd317210d39fe4f8105a09742be66a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,246 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Threading;
using UnityEngine;
namespace KindRetargeting.Remote
{
/// <summary>
/// HTTP 서버 - 웹 리모컨 UI 페이지를 제공합니다.
/// Resources 폴더에서 CSS, HTML 템플릿, JavaScript를 로드합니다.
/// </summary>
public class RetargetingHTTPServer
{
private HttpListener listener;
private Thread listenerThread;
private bool isRunning = false;
private int httpPort;
private int wsPort;
private string cachedCSS = "";
private string cachedTemplate = "";
private string cachedJS = "";
private List<string> boundAddresses = new List<string>();
public bool IsRunning => isRunning;
public IReadOnlyList<string> BoundAddresses => boundAddresses;
public RetargetingHTTPServer(int httpPort, int wsPort)
{
this.httpPort = httpPort;
this.wsPort = wsPort;
}
public void Start()
{
if (isRunning) return;
LoadResources();
try
{
listener = new HttpListener();
boundAddresses.Clear();
// 로컬 접속 지원
listener.Prefixes.Add($"http://localhost:{httpPort}/");
boundAddresses.Add($"http://localhost:{httpPort}");
listener.Prefixes.Add($"http://127.0.0.1:{httpPort}/");
boundAddresses.Add($"http://127.0.0.1:{httpPort}");
// 외부 접속도 시도
try
{
listener.Prefixes.Add($"http://+:{httpPort}/");
string localIP = GetLocalIPAddress();
if (!string.IsNullOrEmpty(localIP))
{
boundAddresses.Add($"http://{localIP}:{httpPort}");
}
}
catch (Exception)
{
Debug.LogWarning("[RetargetingHTTP] 외부 접속 바인딩 실패. localhost만 사용 가능합니다.");
}
listener.Start();
isRunning = true;
listenerThread = new Thread(HandleRequests);
listenerThread.IsBackground = true;
listenerThread.Start();
Debug.Log("[RetargetingHTTP] HTTP 서버 시작됨");
foreach (var addr in boundAddresses)
{
Debug.Log($"[RetargetingHTTP] 접속: {addr}");
}
}
catch (Exception ex)
{
Debug.LogError($"[RetargetingHTTP] 서버 시작 실패: {ex.Message}");
}
}
public void Stop()
{
if (!isRunning) return;
isRunning = false;
try
{
listener?.Stop();
listener?.Close();
}
catch (Exception) { }
Debug.Log("[RetargetingHTTP] HTTP 서버 중지됨");
}
private void LoadResources()
{
TextAsset cssAsset = Resources.Load<TextAsset>("KindRetargeting/retargeting_style");
TextAsset templateAsset = Resources.Load<TextAsset>("KindRetargeting/retargeting_template");
TextAsset jsAsset = Resources.Load<TextAsset>("KindRetargeting/retargeting_script");
cachedCSS = cssAsset != null ? cssAsset.text : GetFallbackCSS();
cachedTemplate = templateAsset != null ? templateAsset.text : GetFallbackTemplate();
cachedJS = jsAsset != null ? jsAsset.text : GetFallbackJS();
if (cssAsset == null || templateAsset == null || jsAsset == null)
{
Debug.LogWarning("[RetargetingHTTP] 일부 리소스를 로드할 수 없습니다. Fallback 사용 중.");
}
}
private void HandleRequests()
{
while (isRunning)
{
try
{
HttpListenerContext context = listener.GetContext();
ProcessRequest(context);
}
catch (HttpListenerException)
{
// 서버 종료 시 발생
}
catch (Exception ex)
{
if (isRunning)
{
Debug.LogError($"[RetargetingHTTP] 요청 처리 오류: {ex.Message}");
}
}
}
}
private void ProcessRequest(HttpListenerContext context)
{
try
{
string path = context.Request.Url.AbsolutePath;
string responseContent;
string contentType;
if (path == "/" || path == "/index.html")
{
responseContent = GenerateHTML();
contentType = "text/html; charset=utf-8";
}
else if (path == "/style.css")
{
responseContent = cachedCSS;
contentType = "text/css; charset=utf-8";
}
else if (path == "/script.js")
{
responseContent = cachedJS.Replace("{{WS_PORT}}", wsPort.ToString());
contentType = "application/javascript; charset=utf-8";
}
else
{
context.Response.StatusCode = 404;
responseContent = "Not Found";
contentType = "text/plain";
}
byte[] buffer = Encoding.UTF8.GetBytes(responseContent);
context.Response.ContentType = contentType;
context.Response.ContentLength64 = buffer.Length;
context.Response.AddHeader("Cache-Control", "no-cache");
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
context.Response.Close();
}
catch (Exception ex)
{
Debug.LogError($"[RetargetingHTTP] 응답 처리 오류: {ex.Message}");
}
}
private string GenerateHTML()
{
string html = cachedTemplate;
html = html.Replace("{{CSS}}", cachedCSS);
html = html.Replace("{{JS}}", cachedJS.Replace("{{WS_PORT}}", wsPort.ToString()));
return html;
}
private string GetLocalIPAddress()
{
try
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
}
catch (Exception) { }
return "";
}
private string GetFallbackCSS()
{
return @"
body { font-family: sans-serif; background: #1a1a2e; color: #fff; padding: 20px; }
.error { color: #ff6b6b; padding: 20px; text-align: center; }
";
}
private string GetFallbackTemplate()
{
return @"
<!DOCTYPE html>
<html>
<head>
<meta charset=""UTF-8"">
<title> </title>
<style>{{CSS}}</style>
</head>
<body>
<div class=""error"">
.<br>
Assets/Resources/KindRetargeting/ .
</div>
</body>
</html>";
}
private string GetFallbackJS()
{
return "console.error('JavaScript resource not found');";
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: aefa700f1b9823544bf33043b01244b2

View File

@ -0,0 +1,670 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace KindRetargeting.Remote
{
/// <summary>
/// 리타게팅 원격 제어 컨트롤러
/// HTTP 서버와 WebSocket 서버를 관리하고 메시지를 처리합니다.
/// </summary>
public class RetargetingRemoteController : MonoBehaviour
{
[Header("서버 설정")]
[SerializeField] private int httpPort = 8080;
[SerializeField] private int wsPort = 8081;
[SerializeField] private bool autoStart = true;
[Header("캐릭터 등록")]
[SerializeField] private List<CustomRetargetingScript> registeredCharacters = new List<CustomRetargetingScript>();
private RetargetingHTTPServer httpServer;
private RetargetingWebSocketServer wsServer;
private Queue<Action> mainThreadActions = new Queue<Action>();
public bool IsRunning => httpServer?.IsRunning == true && wsServer?.IsRunning == true;
public int HttpPort { get => httpPort; set => httpPort = value; }
public int WsPort { get => wsPort; set => wsPort = value; }
public bool AutoStart { get => autoStart; set => autoStart = value; }
// 손 포즈 프리셋 목록
private static readonly string[] handPosePresets = new string[]
{
"가위", "바위", "보", "브이", "검지", "초기화"
};
private void Start()
{
if (autoStart)
{
StartServer();
}
}
private void OnDestroy()
{
StopServer();
}
private void Update()
{
// 메인 스레드 액션 처리
lock (mainThreadActions)
{
while (mainThreadActions.Count > 0)
{
var action = mainThreadActions.Dequeue();
try
{
action?.Invoke();
}
catch (Exception ex)
{
Debug.LogError($"[RetargetingRemote] 메인 스레드 액션 오류: {ex.Message}");
}
}
}
}
public void StartServer()
{
if (IsRunning) return;
httpServer = new RetargetingHTTPServer(httpPort, wsPort);
wsServer = new RetargetingWebSocketServer(wsPort);
wsServer.OnMessageReceived += OnWebSocketMessage;
httpServer.Start();
wsServer.Start();
Debug.Log($"[RetargetingRemote] 서버 시작됨 - HTTP: {httpPort}, WS: {wsPort}");
}
public void StopServer()
{
wsServer?.Stop();
httpServer?.Stop();
if (wsServer != null)
{
wsServer.OnMessageReceived -= OnWebSocketMessage;
}
Debug.Log("[RetargetingRemote] 서버 중지됨");
}
private void OnWebSocketMessage(string message)
{
EnqueueMainThread(() => ProcessMessage(message));
}
private void EnqueueMainThread(Action action)
{
lock (mainThreadActions)
{
mainThreadActions.Enqueue(action);
}
}
private void ProcessMessage(string message)
{
try
{
var json = JObject.Parse(message);
string action = json["action"]?.ToString();
switch (action)
{
case "refresh":
SendCharacterList();
SendHandPosePresets();
break;
case "getCharacterData":
{
string charId = json["characterId"]?.ToString();
SendCharacterData(charId);
}
break;
case "updateValueRealtime":
{
string charId = json["characterId"]?.ToString();
string property = json["property"]?.ToString();
float value = json["value"]?.Value<float>() ?? 0f;
UpdateValue(charId, property, value);
}
break;
case "setHandPosePreset":
{
string charId = json["characterId"]?.ToString();
string property = json["property"]?.ToString();
string presetName = json["stringValue"]?.ToString();
ApplyHandPosePreset(charId, property, presetName);
}
break;
case "calibrateIPose":
{
string charId = json["characterId"]?.ToString();
CalibrateIPose(charId);
}
break;
case "resetCalibration":
{
string charId = json["characterId"]?.ToString();
ResetCalibration(charId);
}
break;
case "calibrateMingleOpen":
{
string charId = json["characterId"]?.ToString();
CalibrateMingleOpen(charId);
}
break;
case "calibrateMingleClose":
{
string charId = json["characterId"]?.ToString();
CalibrateMingleClose(charId);
}
break;
case "calibrateHeadForward":
{
string charId = json["characterId"]?.ToString();
CalibrateHeadForward(charId);
}
break;
default:
Debug.LogWarning($"[RetargetingRemote] 알 수 없는 액션: {action}");
break;
}
}
catch (Exception ex)
{
Debug.LogError($"[RetargetingRemote] 메시지 처리 오류: {ex.Message}");
}
}
private void SendCharacterList()
{
var charIds = new List<string>();
foreach (var script in registeredCharacters)
{
if (script != null)
{
charIds.Add(script.gameObject.name);
}
}
var response = new
{
type = "characterList",
characters = charIds
};
wsServer?.Broadcast(JsonConvert.SerializeObject(response));
}
private void SendHandPosePresets()
{
var response = new
{
type = "handPosePresets",
presets = handPosePresets
};
wsServer?.Broadcast(JsonConvert.SerializeObject(response));
}
private void SendCharacterData(string characterId)
{
var script = FindCharacter(characterId);
if (script == null)
{
SendStatus(false, $"캐릭터를 찾을 수 없습니다: {characterId}");
return;
}
var limbWeight = script.GetComponent<LimbWeightController>();
var handPose = script.GetComponent<FingerShapedController>();
var data = new Dictionary<string, object>
{
// 힙 위치 보정 (로컬)
{ "hipsVertical", GetPrivateField<float>(script, "hipsOffsetY") },
{ "hipsForward", GetPrivateField<float>(script, "hipsOffsetZ") },
{ "hipsHorizontal", GetPrivateField<float>(script, "hipsOffsetX") },
// 무릎 위치 조정
{ "kneeFrontBackWeight", GetPrivateField<float>(script, "kneeFrontBackWeight") },
{ "kneeInOutWeight", GetPrivateField<float>(script, "kneeInOutWeight") },
// 발 IK 위치 조정
{ "feetForwardBackward", GetPrivateField<float>(script, "footFrontBackOffset") },
{ "feetNarrow", GetPrivateField<float>(script, "footInOutOffset") },
// 바닥 높이
{ "floorHeight", script.floorHeight },
// 아바타 크기
{ "avatarScale", GetPrivateField<float>(script, "avatarScale") },
// 머리 크기
{ "headScale", script.GetHeadScale() },
// 머리 회전 오프셋
{ "headRotationOffsetX", script.headRotationOffsetX },
{ "headRotationOffsetY", script.headRotationOffsetY },
{ "headRotationOffsetZ", script.headRotationOffsetZ },
// 손가락 복제 모드
{ "fingerCopyMode", (int)GetPrivateField<EnumsList.FingerCopyMode>(script, "fingerCopyMode") },
// 모션 설정
{ "useMotionFilter", GetPrivateField<bool>(script, "useMotionFilter") },
{ "filterBufferSize", GetPrivateField<int>(script, "filterBufferSize") },
{ "useBodyRoughMotion", GetPrivateField<bool>(script, "useBodyRoughMotion") },
{ "bodyRoughness", GetPrivateField<float>(script, "bodyRoughness") },
// 캘리브레이션 상태
{ "hasCalibrationData", script.HasCachedSettings() }
};
// LimbWeightController 데이터
if (limbWeight != null)
{
data["limbMinDistance"] = limbWeight.minDistance;
data["limbMaxDistance"] = limbWeight.maxDistance;
data["weightSmoothSpeed"] = limbWeight.weightSmoothSpeed;
data["hipsMinDistance"] = limbWeight.hipsMinDistance;
data["hipsMaxDistance"] = limbWeight.hipsMaxDistance;
data["groundHipsMinHeight"] = limbWeight.groundHipsMinHeight;
data["groundHipsMaxHeight"] = limbWeight.groundHipsMaxHeight;
data["footHeightMinThreshold"] = limbWeight.footHeightMinThreshold;
data["footHeightMaxThreshold"] = limbWeight.footHeightMaxThreshold;
data["chairSeatHeightOffset"] = limbWeight.chairSeatHeightOffset;
}
// FingerShapedController 데이터
if (handPose != null)
{
data["handPoseEnabled"] = handPose.enabled;
data["leftHandEnabled"] = handPose.leftHandEnabled;
data["rightHandEnabled"] = handPose.rightHandEnabled;
}
else
{
data["handPoseEnabled"] = false;
data["leftHandEnabled"] = false;
data["rightHandEnabled"] = false;
}
var response = new
{
type = "characterData",
characterId = characterId,
data = data
};
wsServer?.Broadcast(JsonConvert.SerializeObject(response));
}
private void UpdateValue(string characterId, string property, float value)
{
var script = FindCharacter(characterId);
if (script == null) return;
var limbWeight = script.GetComponent<LimbWeightController>();
var handPose = script.GetComponent<FingerShapedController>();
switch (property)
{
// 힙 위치 보정
case "hipsVertical":
SetPrivateField(script, "hipsOffsetY", value);
break;
case "hipsForward":
SetPrivateField(script, "hipsOffsetZ", value);
break;
case "hipsHorizontal":
SetPrivateField(script, "hipsOffsetX", value);
break;
// 무릎 위치 조정
case "kneeFrontBackWeight":
SetPrivateField(script, "kneeFrontBackWeight", value);
break;
case "kneeInOutWeight":
SetPrivateField(script, "kneeInOutWeight", value);
break;
// 발 IK 위치 조정
case "feetForwardBackward":
SetPrivateField(script, "footFrontBackOffset", value);
break;
case "feetNarrow":
SetPrivateField(script, "footInOutOffset", value);
break;
// 바닥 높이
case "floorHeight":
script.floorHeight = value;
break;
// 아바타 크기
case "avatarScale":
SetPrivateField(script, "avatarScale", value);
break;
// 머리 크기
case "headScale":
script.SetHeadScale(value);
break;
// 머리 회전 오프셋
case "headRotationOffsetX":
script.headRotationOffsetX = value;
break;
case "headRotationOffsetY":
script.headRotationOffsetY = value;
break;
case "headRotationOffsetZ":
script.headRotationOffsetZ = value;
break;
// 손가락 복제 모드
case "fingerCopyMode":
SetPrivateField(script, "fingerCopyMode", (EnumsList.FingerCopyMode)(int)value);
break;
// 모션 설정
case "useMotionFilter":
SetPrivateField(script, "useMotionFilter", value > 0.5f);
break;
case "filterBufferSize":
SetPrivateField(script, "filterBufferSize", (int)value);
break;
case "useBodyRoughMotion":
SetPrivateField(script, "useBodyRoughMotion", value > 0.5f);
break;
case "bodyRoughness":
SetPrivateField(script, "bodyRoughness", value);
break;
// LimbWeightController 속성
case "limbMinDistance":
if (limbWeight != null) limbWeight.minDistance = value;
break;
case "limbMaxDistance":
if (limbWeight != null) limbWeight.maxDistance = value;
break;
case "weightSmoothSpeed":
if (limbWeight != null) limbWeight.weightSmoothSpeed = value;
break;
case "hipsMinDistance":
if (limbWeight != null) limbWeight.hipsMinDistance = value;
break;
case "hipsMaxDistance":
if (limbWeight != null) limbWeight.hipsMaxDistance = value;
break;
case "groundHipsMinHeight":
if (limbWeight != null) limbWeight.groundHipsMinHeight = value;
break;
case "groundHipsMaxHeight":
if (limbWeight != null) limbWeight.groundHipsMaxHeight = value;
break;
case "footHeightMinThreshold":
if (limbWeight != null) limbWeight.footHeightMinThreshold = value;
break;
case "footHeightMaxThreshold":
if (limbWeight != null) limbWeight.footHeightMaxThreshold = value;
break;
case "chairSeatHeightOffset":
if (limbWeight != null) limbWeight.chairSeatHeightOffset = value;
break;
// FingerShapedController 속성
case "handPoseEnabled":
if (handPose != null)
handPose.enabled = value > 0.5f;
break;
case "leftHandEnabled":
if (handPose != null)
{
handPose.leftHandEnabled = value > 0.5f;
if (handPose.leftHandEnabled)
handPose.enabled = true;
}
break;
case "rightHandEnabled":
if (handPose != null)
{
handPose.rightHandEnabled = value > 0.5f;
if (handPose.rightHandEnabled)
handPose.enabled = true;
}
break;
default:
Debug.LogWarning($"[RetargetingRemote] 알 수 없는 속성: {property}");
break;
}
}
private void ApplyHandPosePreset(string characterId, string property, string presetName)
{
var script = FindCharacter(characterId);
if (script == null) return;
var handPose = script.GetComponent<FingerShapedController>();
if (handPose == null) return;
// 스크립트 자동 활성화
handPose.enabled = true;
// 해당 손 활성화
if (property == "leftHandPreset")
handPose.leftHandEnabled = true;
else if (property == "rightHandPreset")
handPose.rightHandEnabled = true;
// 프리셋 적용
float thumb = 0, index = 0, middle = 0, ring = 0, pinky = 0, spread = 0;
switch (presetName)
{
case "가위":
thumb = 1f; index = 1f; middle = -1f; ring = -1f; pinky = -1f; spread = 0.3f;
break;
case "바위":
thumb = -1f; index = -1f; middle = -1f; ring = -1f; pinky = -1f; spread = 0f;
break;
case "보":
thumb = 1f; index = 1f; middle = 1f; ring = 1f; pinky = 1f; spread = 1f;
break;
case "브이":
thumb = -1f; index = 1f; middle = 1f; ring = -1f; pinky = -1f; spread = 1f;
break;
case "검지":
thumb = -1f; index = 1f; middle = -1f; ring = -1f; pinky = -1f; spread = 0f;
break;
case "초기화":
thumb = 0.8f; index = 0.8f; middle = 0.8f; ring = 0.8f; pinky = 0.8f; spread = 0.8f;
break;
}
if (property == "leftHandPreset" && handPose.leftHandEnabled)
{
handPose.leftThumbCurl = thumb;
handPose.leftIndexCurl = index;
handPose.leftMiddleCurl = middle;
handPose.leftRingCurl = ring;
handPose.leftPinkyCurl = pinky;
handPose.leftSpreadFingers = spread;
}
else if (property == "rightHandPreset" && handPose.rightHandEnabled)
{
handPose.rightThumbCurl = thumb;
handPose.rightIndexCurl = index;
handPose.rightMiddleCurl = middle;
handPose.rightRingCurl = ring;
handPose.rightPinkyCurl = pinky;
handPose.rightSpreadFingers = spread;
}
SendStatus(true, $"{presetName} 프리셋 적용됨");
}
private void CalibrateIPose(string characterId)
{
var script = FindCharacter(characterId);
if (script == null) return;
script.I_PoseCalibration();
script.SaveSettings(); // 캘리브레이션 후 설정 저장
SendCharacterData(characterId);
SendStatus(true, "I-포즈 캘리브레이션 완료");
}
private void ResetCalibration(string characterId)
{
var script = FindCharacter(characterId);
if (script == null) return;
script.ResetPoseAndCache();
SendCharacterData(characterId);
SendStatus(true, "캘리브레이션 초기화됨");
}
private void CalibrateMingleOpen(string characterId)
{
var script = FindCharacter(characterId);
if (script == null) return;
script.CalibrateMingleOpen();
script.SaveSettings();
SendCharacterData(characterId);
SendStatus(true, "Mingle 펼침 캘리브레이션 완료");
}
private void CalibrateMingleClose(string characterId)
{
var script = FindCharacter(characterId);
if (script == null) return;
script.CalibrateMingleClose();
script.SaveSettings();
SendCharacterData(characterId);
SendStatus(true, "Mingle 모음 캘리브레이션 완료");
}
private void CalibrateHeadForward(string characterId)
{
var script = FindCharacter(characterId);
if (script == null) return;
script.CalibrateHeadToForward();
script.SaveSettings();
SendCharacterData(characterId);
SendStatus(true, "정면 캘리브레이션 완료");
}
private CustomRetargetingScript FindCharacter(string characterId)
{
foreach (var script in registeredCharacters)
{
if (script != null && script.gameObject.name == characterId)
{
return script;
}
}
return null;
}
private void SendStatus(bool success, string message)
{
var response = new
{
type = "status",
success = success,
message = message
};
wsServer?.Broadcast(JsonConvert.SerializeObject(response));
}
#region Reflection Helpers
private T GetPrivateField<T>(object obj, string fieldName)
{
try
{
var field = obj.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
if (field != null)
{
return (T)field.GetValue(obj);
}
}
catch (Exception) { }
return default(T);
}
private void SetPrivateField<T>(object obj, string fieldName, T value)
{
try
{
var field = obj.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
if (field != null)
{
field.SetValue(obj, value);
}
}
catch (Exception ex)
{
Debug.LogError($"[RetargetingRemote] 필드 설정 오류 ({fieldName}): {ex.Message}");
}
}
#endregion
#region Public API
/// <summary>
/// 캐릭터 등록
/// </summary>
public void RegisterCharacter(CustomRetargetingScript character)
{
if (!registeredCharacters.Contains(character))
{
registeredCharacters.Add(character);
}
}
/// <summary>
/// 캐릭터 등록 해제
/// </summary>
public void UnregisterCharacter(CustomRetargetingScript character)
{
registeredCharacters.Remove(character);
}
#endregion
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 6318df208b6a254409cc1af28be31e28

View File

@ -0,0 +1,107 @@
using System;
using WebSocketSharp;
using WebSocketSharp.Server;
using UnityEngine;
namespace KindRetargeting.Remote
{
/// <summary>
/// WebSocket 서버 - 실시간 양방향 통신을 담당합니다.
/// </summary>
public class RetargetingWebSocketServer
{
private WebSocketServer wss;
private int port;
private bool isRunning = false;
public bool IsRunning => isRunning;
public int Port => port;
public event Action<string> OnMessageReceived;
public RetargetingWebSocketServer(int port)
{
this.port = port;
}
public void Start()
{
if (isRunning) return;
try
{
wss = new WebSocketServer(port);
wss.AddWebSocketService<RetargetingBehavior>("/retargeting", behavior =>
{
behavior.OnMessageReceivedCallback = (msg) => OnMessageReceived?.Invoke(msg);
});
wss.Start();
isRunning = true;
Debug.Log($"[RetargetingWS] WebSocket 서버 시작됨 (포트: {port})");
}
catch (Exception ex)
{
Debug.LogError($"[RetargetingWS] 서버 시작 실패: {ex.Message}");
}
}
public void Stop()
{
if (!isRunning) return;
try
{
wss?.Stop();
}
catch (Exception) { }
isRunning = false;
Debug.Log("[RetargetingWS] WebSocket 서버 중지됨");
}
public void Broadcast(string message)
{
if (!isRunning || wss == null) return;
try
{
wss.WebSocketServices["/retargeting"].Sessions.Broadcast(message);
}
catch (Exception ex)
{
Debug.LogError($"[RetargetingWS] 브로드캐스트 실패: {ex.Message}");
}
}
/// <summary>
/// WebSocket 동작 핸들러
/// </summary>
private class RetargetingBehavior : WebSocketBehavior
{
public Action<string> OnMessageReceivedCallback;
protected override void OnOpen()
{
// 연결 시 로그 제거 (문서 요청에 따름)
}
protected override void OnClose(CloseEventArgs e)
{
// 연결 종료 시 로그 제거
}
protected override void OnMessage(MessageEventArgs e)
{
// 로그 제거 (문서 요청에 따름)
OnMessageReceivedCallback?.Invoke(e.Data);
}
protected override void OnError(ErrorEventArgs e)
{
Debug.LogError($"[RetargetingWS] 오류: {e.Message}");
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 103c4e3f462b1c44bb2bee945fa2cbe7

View File

@ -1,4 +1,5 @@
using UnityEngine;
using KindRetargeting;
[DefaultExecutionOrder(16001)]
public class SimplePoseTransfer : MonoBehaviour
@ -7,6 +8,10 @@ public class SimplePoseTransfer : MonoBehaviour
public Animator sourceBone;
public Animator[] targetBones;
[Header("Scale Transfer")]
[Tooltip("소스의 머리 스케일을 타겟에도 적용")]
public bool transferHeadScale = true;
// 캐싱된 Transform들
private Transform[] cachedSourceBones;
private Transform[,] cachedTargetBones;
@ -14,6 +19,10 @@ public class SimplePoseTransfer : MonoBehaviour
// 각 targetBone의 초기 회전 차이를 저장
private Quaternion[,] boneRotationDifferences;
// 머리 스케일 관련
private CustomRetargetingScript sourceRetargetingScript;
private Vector3[] originalTargetHeadScales;
private void Start()
{
Init();
@ -35,10 +44,35 @@ public class SimplePoseTransfer : MonoBehaviour
InitializeTargetBones();
CacheAllBoneTransforms();
CacheHeadScales();
Debug.Log($"SimplePoseTransfer initialized with {targetBones.Length} targets");
}
private void CacheHeadScales()
{
// 소스에서 CustomRetargetingScript 찾기
sourceRetargetingScript = sourceBone.GetComponent<CustomRetargetingScript>();
// 타겟들의 원본 머리 스케일 저장
originalTargetHeadScales = new Vector3[targetBones.Length];
for (int i = 0; i < targetBones.Length; i++)
{
if (targetBones[i] != null)
{
Transform headBone = targetBones[i].GetBoneTransform(HumanBodyBones.Head);
if (headBone != null)
{
originalTargetHeadScales[i] = headBone.localScale;
}
else
{
originalTargetHeadScales[i] = Vector3.one;
}
}
}
}
private void InitializeTargetBones()
{
boneRotationDifferences = new Quaternion[targetBones.Length, 55];
@ -109,7 +143,7 @@ public class SimplePoseTransfer : MonoBehaviour
private void TransferPoseToTarget(int targetIndex)
{
Animator targetBone = targetBones[targetIndex];
// 루트 회전 동기화
targetBone.transform.rotation = sourceBone.transform.rotation;
@ -129,6 +163,30 @@ public class SimplePoseTransfer : MonoBehaviour
{
targetBoneTransform.position = sourceBoneTransform.position;
}
// 머리 스케일 적용 (HumanBodyBones.Head = 10)
if (transferHeadScale && i == 10)
{
ApplyHeadScale(targetIndex, targetBoneTransform);
}
}
}
}
private void ApplyHeadScale(int targetIndex, Transform targetHeadBone)
{
if (sourceRetargetingScript != null)
{
float headScale = sourceRetargetingScript.GetHeadScale();
targetHeadBone.localScale = originalTargetHeadScales[targetIndex] * headScale;
}
else
{
// CustomRetargetingScript가 없으면 소스 머리 스케일 직접 복사
Transform sourceHead = cachedSourceBones[10]; // HumanBodyBones.Head
if (sourceHead != null)
{
targetHeadBone.localScale = sourceHead.localScale;
}
}
}

View File

@ -4,6 +4,8 @@ using System.Linq;
using System.IO;
using System;
using Entum;
using KindRetargeting;
using KindRetargeting.Remote;
#if MAGICACLOTH2
using MagicaCloth2;
#endif
@ -17,6 +19,12 @@ public class SystemController : MonoBehaviour
[Header("OptiTrack 참조")]
public OptitrackStreamingClient optitrackClient;
[Tooltip("OptiTrack 클라이언트가 없을 때 자동으로 프리펩에서 생성할지 여부")]
public bool autoSpawnOptitrackClient = true;
[Tooltip("OptiTrack 클라이언트 프리펩 경로 (Resources 폴더 기준이 아닌 경우 직접 할당 필요)")]
public GameObject optitrackClientPrefab;
[Header("모션 녹화 설정")]
[Tooltip("모션 녹화 시 OptiTrack Motive도 함께 녹화할지 여부")]
public bool recordOptiTrackWithMotion = true;
@ -61,6 +69,19 @@ public class SystemController : MonoBehaviour
[Range(0f, 3f)]
public float alphaBlurRadius = 1.0f;
[Header("리타게팅 웹 리모컨")]
[Tooltip("리타게팅 웹 리모컨 컨트롤러 (없으면 자동 생성)")]
public RetargetingRemoteController retargetingRemote;
[Tooltip("리타게팅 웹 리모컨 HTTP 포트")]
public int retargetingHttpPort = 8080;
[Tooltip("리타게팅 웹 리모컨 WebSocket 포트")]
public int retargetingWsPort = 8081;
[Tooltip("시작 시 리타게팅 웹 리모컨 자동 시작")]
public bool autoStartRetargetingRemote = true;
[Header("디버그")]
public bool enableDebugLog = true;
@ -84,11 +105,8 @@ public class SystemController : MonoBehaviour
private void Start()
{
// OptiTrack 클라이언트 자동 찾기
if (optitrackClient == null)
{
optitrackClient = FindObjectOfType<OptitrackStreamingClient>();
}
// OptiTrack 클라이언트 자동 찾기 및 생성
InitializeOptitrackClient();
// Motion Recorder 자동 찾기
if (autoFindRecorders)
@ -129,7 +147,11 @@ public class SystemController : MonoBehaviour
Log($"Screenshots 폴더 생성됨: {screenshotSavePath}");
}
// 리타게팅 웹 리모컨 초기화
InitializeRetargetingRemote();
Log("SystemController 초기화 완료");
Log($"OptiTrack 클라이언트: {(optitrackClient != null ? "" : "")}");
Log($"Motion Recorder 개수: {motionRecorders.Count}");
Log($"Facial Motion 클라이언트 개수: {facialMotionClients.Count}");
Log($"Screenshot 카메라: {(screenshotCamera != null ? "" : "")}");
@ -145,6 +167,99 @@ public class SystemController : MonoBehaviour
Log($"Motion Recorder {motionRecorders.Count}개 발견");
}
#region OptiTrack
/// <summary>
/// OptiTrack 클라이언트 초기화 (씬에서 찾거나 프리펩에서 생성)
/// </summary>
private void InitializeOptitrackClient()
{
// 이미 할당되어 있으면 사용
if (optitrackClient != null)
{
Log("OptiTrack 클라이언트가 이미 할당되어 있습니다.");
return;
}
// 씬에서 찾기
optitrackClient = FindObjectOfType<OptitrackStreamingClient>();
if (optitrackClient != null)
{
Log("씬에서 OptiTrack 클라이언트를 찾았습니다.");
return;
}
// 씬에 없고 자동 생성 옵션이 켜져 있으면 프리펩에서 생성
if (autoSpawnOptitrackClient)
{
SpawnOptitrackClientFromPrefab();
}
else
{
Log("OptiTrack 클라이언트가 없습니다. 자동 생성 옵션이 꺼져 있습니다.");
}
}
/// <summary>
/// OptiTrack 클라이언트 프리펩을 씬에 생성합니다
/// </summary>
public void SpawnOptitrackClientFromPrefab()
{
// 이미 씬에 있는지 확인
var existingClient = FindObjectOfType<OptitrackStreamingClient>();
if (existingClient != null)
{
optitrackClient = existingClient;
Log("씬에 이미 OptiTrack 클라이언트가 있습니다.");
return;
}
GameObject clientInstance = null;
// 직접 할당된 프리펩이 있으면 사용
if (optitrackClientPrefab != null)
{
clientInstance = Instantiate(optitrackClientPrefab);
clientInstance.name = "Client - OptiTrack";
Log("할당된 프리펩에서 OptiTrack 클라이언트 생성됨");
}
else
{
#if UNITY_EDITOR
// 에디터에서는 AssetDatabase를 통해 프리펩 로드
string prefabPath = "Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Client - OptiTrack.prefab";
var prefab = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
if (prefab != null)
{
clientInstance = Instantiate(prefab);
clientInstance.name = "Client - OptiTrack";
Log($"프리펩에서 OptiTrack 클라이언트 생성됨: {prefabPath}");
}
else
{
LogError($"OptiTrack 클라이언트 프리펩을 찾을 수 없습니다: {prefabPath}");
return;
}
#else
LogError("OptiTrack 클라이언트 프리펩이 할당되지 않았습니다. Inspector에서 프리펩을 할당해주세요.");
return;
#endif
}
if (clientInstance != null)
{
optitrackClient = clientInstance.GetComponent<OptitrackStreamingClient>();
if (optitrackClient == null)
{
LogError("생성된 프리펩에 OptitrackStreamingClient 컴포넌트가 없습니다!");
Destroy(clientInstance);
}
}
}
#endregion
#region OptiTrack
/// <summary>
@ -755,6 +870,135 @@ public class SystemController : MonoBehaviour
#endregion
#region
/// <summary>
/// 리타게팅 웹 리모컨 초기화
/// </summary>
private void InitializeRetargetingRemote()
{
// 이미 할당되어 있으면 사용
if (retargetingRemote == null)
{
// 씬에서 찾기
retargetingRemote = FindObjectOfType<RetargetingRemoteController>();
}
// 없으면 자동 생성
if (retargetingRemote == null && autoStartRetargetingRemote)
{
GameObject remoteObj = new GameObject("RetargetingRemoteController");
retargetingRemote = remoteObj.AddComponent<RetargetingRemoteController>();
retargetingRemote.AutoStart = false; // SystemController가 관리
Log("리타게팅 웹 리모컨 컨트롤러 자동 생성됨");
}
// 포트 설정 적용
if (retargetingRemote != null)
{
retargetingRemote.HttpPort = retargetingHttpPort;
retargetingRemote.WsPort = retargetingWsPort;
}
// 캐릭터 자동 등록
if (retargetingRemote != null)
{
AutoRegisterRetargetingCharacters();
if (autoStartRetargetingRemote && !retargetingRemote.IsRunning)
{
retargetingRemote.StartServer();
Log($"리타게팅 웹 리모컨 시작됨 - http://localhost:{retargetingHttpPort}");
}
}
}
/// <summary>
/// 씬의 모든 CustomRetargetingScript를 자동으로 등록합니다
/// </summary>
public void AutoRegisterRetargetingCharacters()
{
if (retargetingRemote == null)
{
LogError("리타게팅 웹 리모컨 컨트롤러가 없습니다!");
return;
}
var characters = FindObjectsByType<CustomRetargetingScript>(FindObjectsSortMode.None);
foreach (var character in characters)
{
retargetingRemote.RegisterCharacter(character);
}
Log($"리타게팅 캐릭터 {characters.Length}개 등록됨");
}
/// <summary>
/// 리타게팅 웹 리모컨 시작
/// </summary>
public void StartRetargetingRemote()
{
if (retargetingRemote == null)
{
InitializeRetargetingRemote();
}
if (retargetingRemote != null && !retargetingRemote.IsRunning)
{
retargetingRemote.StartServer();
Log($"리타게팅 웹 리모컨 시작됨 - http://localhost:{retargetingHttpPort}");
}
}
/// <summary>
/// 리타게팅 웹 리모컨 중지
/// </summary>
public void StopRetargetingRemote()
{
if (retargetingRemote != null && retargetingRemote.IsRunning)
{
retargetingRemote.StopServer();
Log("리타게팅 웹 리모컨 중지됨");
}
}
/// <summary>
/// 리타게팅 웹 리모컨 토글 (시작/중지)
/// </summary>
public void ToggleRetargetingRemote()
{
if (retargetingRemote == null || !retargetingRemote.IsRunning)
{
StartRetargetingRemote();
}
else
{
StopRetargetingRemote();
}
}
/// <summary>
/// 리타게팅 웹 리모컨 실행 중인지 여부 반환
/// </summary>
public bool IsRetargetingRemoteRunning()
{
return retargetingRemote != null && retargetingRemote.IsRunning;
}
/// <summary>
/// 리타게팅 웹 리모컨 URL 반환
/// </summary>
public string GetRetargetingRemoteUrl()
{
if (retargetingRemote != null && retargetingRemote.IsRunning)
{
return $"http://localhost:{retargetingHttpPort}";
}
return "";
}
#endregion
/// <summary>
/// 명령어 실행 - WebSocket에서 받은 명령을 처리
/// </summary>
@ -782,6 +1026,11 @@ public class SystemController : MonoBehaviour
ReconnectOptitrack();
break;
// OptiTrack 클라이언트 생성
case "spawn_optitrack_client":
SpawnOptitrackClientFromPrefab();
break;
// Facial Motion 재접속
case "reconnect_facial_motion":
ReconnectFacialMotion();
@ -831,6 +1080,23 @@ public class SystemController : MonoBehaviour
ResetAllMagicaClothKeepPose();
break;
// 리타게팅 웹 리모컨
case "start_retargeting_remote":
StartRetargetingRemote();
break;
case "stop_retargeting_remote":
StopRetargetingRemote();
break;
case "toggle_retargeting_remote":
ToggleRetargetingRemote();
break;
case "refresh_retargeting_characters":
AutoRegisterRetargetingCharacters();
break;
default:
LogError($"알 수 없는 명령어: {command}");
break;