Merge pull request 'feature/UpdateAvatar' (#405) from feature/UpdateAvatar into develop
Reviewed-on: https://git.pthub.vn/Unity/perfect-world-unity/pulls/405
This commit is contained in:
@@ -161,8 +161,8 @@ GameObject:
|
||||
m_Component:
|
||||
- component: {fileID: 2127540135059465312}
|
||||
- component: {fileID: 2085804573552353186}
|
||||
- component: {fileID: 5477947404616405472}
|
||||
- component: {fileID: 2090693574295861813}
|
||||
- component: {fileID: 2301294577913282359}
|
||||
m_Layer: 5
|
||||
m_Name: Avatar
|
||||
m_TagString: Untagged
|
||||
@@ -186,8 +186,8 @@ RectTransform:
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: -151.8, y: 7.8005}
|
||||
m_SizeDelta: {x: 85.3021, y: 124.4}
|
||||
m_AnchoredPosition: {x: -151.8, y: -19.49}
|
||||
m_SizeDelta: {x: 128, y: 180}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &2085804573552353186
|
||||
CanvasRenderer:
|
||||
@@ -197,36 +197,6 @@ CanvasRenderer:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 955704001844978227}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &5477947404616405472
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 955704001844978227}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 21300000, guid: 88530e3bf1ec5ea4d93e2a0d01a5d525, type: 3}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!114 &2090693574295861813
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -267,10 +237,37 @@ MonoBehaviour:
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 5477947404616405472}
|
||||
m_TargetGraphic: {fileID: 2301294577913282359}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!114 &2301294577913282359
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 955704001844978227}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Texture: {fileID: 8400000, guid: bba090692914cf841bc3173b85871a66, type: 2}
|
||||
m_UVRect:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
--- !u!1 &974102734944724072
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -1804,7 +1801,7 @@ RectTransform:
|
||||
m_GameObject: {fileID: 4823752405346273106}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1.3, y: 1.3, z: 1.3}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 2127540135059465312}
|
||||
@@ -1818,10 +1815,10 @@ RectTransform:
|
||||
- {fileID: 8118804085881780215}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 275.1, y: -110.3}
|
||||
m_SizeDelta: {x: 461, y: 133}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: -143, y: -20}
|
||||
m_SizeDelta: {x: 128, y: 180}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &3549955056024652669
|
||||
CanvasRenderer:
|
||||
|
||||
@@ -30,7 +30,8 @@ RectTransform:
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Children:
|
||||
- {fileID: 1510810868840459915}
|
||||
m_Father: {fileID: 7601428160728630082}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
@@ -175,6 +176,7 @@ MonoBehaviour:
|
||||
_nameText: {fileID: 8459104239633154731}
|
||||
_statText: {fileID: 7225922753763360209}
|
||||
healthImage: {fileID: 391766345810538963}
|
||||
_avatarImage: {fileID: 5732841064457103199}
|
||||
--- !u!1 &5230218528339883288
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -601,6 +603,78 @@ MonoBehaviour:
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!1 &8106823484631380573
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1510810868840459915}
|
||||
- component: {fileID: 8158437551720672858}
|
||||
- component: {fileID: 5732841064457103199}
|
||||
m_Layer: 5
|
||||
m_Name: AvatarImage
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1510810868840459915
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8106823484631380573}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 8841982213385894347}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: -19}
|
||||
m_SizeDelta: {x: 128, y: 180}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &8158437551720672858
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8106823484631380573}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &5732841064457103199
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8106823484631380573}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 0
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Texture: {fileID: 8400000, guid: 86b263f7c57f2b2408a59d5c3bafcfe1, type: 2}
|
||||
m_UVRect:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
--- !u!1 &8340737021475261245
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a295172ba5abc95449425dcf9c63a0ae
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,39 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!84 &8400000
|
||||
RenderTexture:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Avatar_EslePlayer
|
||||
m_ImageContentsHash:
|
||||
serializedVersion: 2
|
||||
Hash: 00000000000000000000000000000000
|
||||
m_IsAlphaChannelOptional: 0
|
||||
serializedVersion: 6
|
||||
m_Width: 90
|
||||
m_Height: 128
|
||||
m_AntiAliasing: 1
|
||||
m_MipCount: -1
|
||||
m_DepthStencilFormat: 90
|
||||
m_ColorFormat: 12
|
||||
m_MipMap: 0
|
||||
m_GenerateMips: 1
|
||||
m_SRGB: 0
|
||||
m_UseDynamicScale: 0
|
||||
m_UseDynamicScaleExplicit: 0
|
||||
m_BindMS: 0
|
||||
m_EnableCompatibleFormat: 1
|
||||
m_EnableRandomWrite: 0
|
||||
m_TextureSettings:
|
||||
serializedVersion: 2
|
||||
m_FilterMode: 0
|
||||
m_Aniso: 0
|
||||
m_MipBias: 0
|
||||
m_WrapU: 1
|
||||
m_WrapV: 1
|
||||
m_WrapW: 1
|
||||
m_Dimension: 2
|
||||
m_VolumeDepth: 1
|
||||
m_ShadowSamplingMode: 2
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86b263f7c57f2b2408a59d5c3bafcfe1
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 8400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,39 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!84 &8400000
|
||||
RenderTexture:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Avatar_HostPlayer
|
||||
m_ImageContentsHash:
|
||||
serializedVersion: 2
|
||||
Hash: 00000000000000000000000000000000
|
||||
m_IsAlphaChannelOptional: 0
|
||||
serializedVersion: 6
|
||||
m_Width: 90
|
||||
m_Height: 128
|
||||
m_AntiAliasing: 1
|
||||
m_MipCount: -1
|
||||
m_DepthStencilFormat: 90
|
||||
m_ColorFormat: 12
|
||||
m_MipMap: 0
|
||||
m_GenerateMips: 1
|
||||
m_SRGB: 0
|
||||
m_UseDynamicScale: 0
|
||||
m_UseDynamicScaleExplicit: 0
|
||||
m_BindMS: 0
|
||||
m_EnableCompatibleFormat: 1
|
||||
m_EnableRandomWrite: 0
|
||||
m_TextureSettings:
|
||||
serializedVersion: 2
|
||||
m_FilterMode: 0
|
||||
m_Aniso: 0
|
||||
m_MipBias: 0
|
||||
m_WrapU: 1
|
||||
m_WrapV: 1
|
||||
m_WrapW: 1
|
||||
m_Dimension: 2
|
||||
m_VolumeDepth: 1
|
||||
m_ShadowSamplingMode: 2
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bba090692914cf841bc3173b85871a66
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 8400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,194 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &92356230978766869
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3314397423840653037}
|
||||
- component: {fileID: 4978808551651698537}
|
||||
m_Layer: 0
|
||||
m_Name: ElsePlayerPortraitCapture
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &3314397423840653037
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 92356230978766869}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 926741264994506648}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &4978808551651698537
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 92356230978766869}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: aa7ed0ae48461f645932270bfda7ec70, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
portraitCamera: {fileID: 3566761532475057225}
|
||||
outputTexture: {fileID: 8400000, guid: 86b263f7c57f2b2408a59d5c3bafcfe1, type: 2}
|
||||
portraitLayer: 9
|
||||
stagePosition: {x: 9999, y: 0, z: 0}
|
||||
cameraDistance: 2
|
||||
faceUpLift: 0.04
|
||||
lookSmoothSpeed: 20
|
||||
headFaceAxis: 0
|
||||
flipFaceAxis: 0
|
||||
fieldOfView: 35
|
||||
--- !u!1 &6925809458492533610
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 926741264994506648}
|
||||
- component: {fileID: 3566761532475057225}
|
||||
- component: {fileID: 3644885308902631293}
|
||||
- component: {fileID: 5217538199177562225}
|
||||
m_Layer: 0
|
||||
m_Name: Camera
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &926741264994506648
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6925809458492533610}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 3314397423840653037}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!20 &3566761532475057225
|
||||
Camera:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6925809458492533610}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 2
|
||||
m_ClearFlags: 4
|
||||
m_BackGroundColor: {r: 1, g: 1, b: 1, a: 0}
|
||||
m_projectionMatrixMode: 1
|
||||
m_GateFitMode: 2
|
||||
m_FOVAxisMode: 0
|
||||
m_Iso: 200
|
||||
m_ShutterSpeed: 0.005
|
||||
m_Aperture: 16
|
||||
m_FocusDistance: 10
|
||||
m_FocalLength: 50
|
||||
m_BladeCount: 5
|
||||
m_Curvature: {x: 2, y: 11}
|
||||
m_BarrelClipping: 0.25
|
||||
m_Anamorphism: 0
|
||||
m_SensorSize: {x: 36, y: 24}
|
||||
m_LensShift: {x: 0, y: 0}
|
||||
m_NormalizedViewPortRect:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
near clip plane: 0.3
|
||||
far clip plane: 10
|
||||
field of view: 60
|
||||
orthographic: 1
|
||||
orthographic size: 0.2
|
||||
m_Depth: 0
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 511
|
||||
m_RenderingPath: -1
|
||||
m_TargetTexture: {fileID: 8400000, guid: 86b263f7c57f2b2408a59d5c3bafcfe1, type: 2}
|
||||
m_TargetDisplay: 0
|
||||
m_TargetEye: 3
|
||||
m_HDR: 1
|
||||
m_AllowMSAA: 1
|
||||
m_AllowDynamicResolution: 0
|
||||
m_ForceIntoRT: 0
|
||||
m_OcclusionCulling: 1
|
||||
m_StereoConvergence: 10
|
||||
m_StereoSeparation: 0.022
|
||||
--- !u!81 &3644885308902631293
|
||||
AudioListener:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6925809458492533610}
|
||||
m_Enabled: 1
|
||||
--- !u!114 &5217538199177562225
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6925809458492533610}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_RenderShadows: 0
|
||||
m_RequiresDepthTextureOption: 2
|
||||
m_RequiresOpaqueTextureOption: 2
|
||||
m_CameraType: 0
|
||||
m_Cameras: []
|
||||
m_RendererIndex: -1
|
||||
m_VolumeLayerMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 1
|
||||
m_VolumeTrigger: {fileID: 0}
|
||||
m_VolumeFrameworkUpdateModeOption: 2
|
||||
m_RenderPostProcessing: 0
|
||||
m_Antialiasing: 0
|
||||
m_AntialiasingQuality: 2
|
||||
m_StopNaN: 0
|
||||
m_Dithering: 0
|
||||
m_ClearDepth: 1
|
||||
m_AllowXRRendering: 1
|
||||
m_AllowHDROutput: 1
|
||||
m_UseScreenCoordOverride: 0
|
||||
m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_RequiresDepthTexture: 0
|
||||
m_RequiresColorTexture: 0
|
||||
m_Version: 2
|
||||
m_TaaSettings:
|
||||
m_Quality: 3
|
||||
m_FrameInfluence: 0.1
|
||||
m_JitterScale: 1
|
||||
m_MipBias: 0
|
||||
m_VarianceClampScale: 0.9
|
||||
m_ContrastAdaptiveSharpening: 0
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ceb796bc537f4b24bbe022ed90af174a
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,193 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &5307011407514547582
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 969654748246802177}
|
||||
- component: {fileID: 5984941419743339992}
|
||||
- component: {fileID: 6319271102976364310}
|
||||
- component: {fileID: 8188555422466428940}
|
||||
m_Layer: 0
|
||||
m_Name: Camera
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &969654748246802177
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5307011407514547582}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 2751797771262260024}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!20 &5984941419743339992
|
||||
Camera:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5307011407514547582}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 2
|
||||
m_ClearFlags: 4
|
||||
m_BackGroundColor: {r: 1, g: 1, b: 1, a: 0}
|
||||
m_projectionMatrixMode: 1
|
||||
m_GateFitMode: 2
|
||||
m_FOVAxisMode: 0
|
||||
m_Iso: 200
|
||||
m_ShutterSpeed: 0.005
|
||||
m_Aperture: 16
|
||||
m_FocusDistance: 10
|
||||
m_FocalLength: 50
|
||||
m_BladeCount: 5
|
||||
m_Curvature: {x: 2, y: 11}
|
||||
m_BarrelClipping: 0.25
|
||||
m_Anamorphism: 0
|
||||
m_SensorSize: {x: 36, y: 24}
|
||||
m_LensShift: {x: 0, y: 0}
|
||||
m_NormalizedViewPortRect:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
near clip plane: 0.3
|
||||
far clip plane: 10
|
||||
field of view: 60
|
||||
orthographic: 1
|
||||
orthographic size: 0.2
|
||||
m_Depth: 0
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 511
|
||||
m_RenderingPath: -1
|
||||
m_TargetTexture: {fileID: 8400000, guid: bba090692914cf841bc3173b85871a66, type: 2}
|
||||
m_TargetDisplay: 0
|
||||
m_TargetEye: 3
|
||||
m_HDR: 1
|
||||
m_AllowMSAA: 1
|
||||
m_AllowDynamicResolution: 0
|
||||
m_ForceIntoRT: 0
|
||||
m_OcclusionCulling: 1
|
||||
m_StereoConvergence: 10
|
||||
m_StereoSeparation: 0.022
|
||||
--- !u!81 &6319271102976364310
|
||||
AudioListener:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5307011407514547582}
|
||||
m_Enabled: 1
|
||||
--- !u!114 &8188555422466428940
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5307011407514547582}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_RenderShadows: 0
|
||||
m_RequiresDepthTextureOption: 2
|
||||
m_RequiresOpaqueTextureOption: 2
|
||||
m_CameraType: 0
|
||||
m_Cameras: []
|
||||
m_RendererIndex: -1
|
||||
m_VolumeLayerMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 1
|
||||
m_VolumeTrigger: {fileID: 0}
|
||||
m_VolumeFrameworkUpdateModeOption: 2
|
||||
m_RenderPostProcessing: 0
|
||||
m_Antialiasing: 0
|
||||
m_AntialiasingQuality: 2
|
||||
m_StopNaN: 0
|
||||
m_Dithering: 0
|
||||
m_ClearDepth: 1
|
||||
m_AllowXRRendering: 1
|
||||
m_AllowHDROutput: 1
|
||||
m_UseScreenCoordOverride: 0
|
||||
m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_RequiresDepthTexture: 0
|
||||
m_RequiresColorTexture: 0
|
||||
m_Version: 2
|
||||
m_TaaSettings:
|
||||
m_Quality: 3
|
||||
m_FrameInfluence: 0.1
|
||||
m_JitterScale: 1
|
||||
m_MipBias: 0
|
||||
m_VarianceClampScale: 0.9
|
||||
m_ContrastAdaptiveSharpening: 0
|
||||
--- !u!1 &7927669976924756812
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2751797771262260024}
|
||||
- component: {fileID: 210989495011050937}
|
||||
m_Layer: 0
|
||||
m_Name: HostPlayerPortraitCapture
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &2751797771262260024
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7927669976924756812}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 969654748246802177}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &210989495011050937
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7927669976924756812}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 93accee0d329e0f45a7be8b74cf0cb99, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
portraitCamera: {fileID: 5984941419743339992}
|
||||
outputTexture: {fileID: 8400000, guid: bba090692914cf841bc3173b85871a66, type: 2}
|
||||
portraitLayer: 9
|
||||
headFaceAxis: 0
|
||||
flipFaceAxis: 0
|
||||
cameraDistance: 1.2
|
||||
faceUpLift: 0.04
|
||||
lookSmoothSpeed: 20
|
||||
fieldOfView: 35
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 633f0bb5015e02a4588799a30e68fb62
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:fdca6f6915cfc055b350581a53fbc4d2e19ab522da9eb954295d71d45d8aed58
|
||||
size 303299
|
||||
oid sha256:2dfe17492882fb88b93875b027ade9cef638e3bdadaf3a7ccbbcf48dd7ec6b67
|
||||
size 308617
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using BrewMonster.Scripts.Managers;
|
||||
using CSNetwork.Protocols.RPCData;
|
||||
@@ -13,6 +14,13 @@ namespace BrewMonster.Scripts
|
||||
public List<GameObject> playerModels = new();
|
||||
public List<int> playerModelIds = new();
|
||||
|
||||
/// <summary>
|
||||
/// Fired (with the roleId) the first time a model becomes active after loading completes.
|
||||
/// Subscribe from HostPlayerPortraitCapture so it can attach the portrait camera at the
|
||||
/// right moment even when the async load finishes after AttachToPlayerModelPreview is called.
|
||||
/// </summary>
|
||||
public event Action<int> OnModelReady;
|
||||
|
||||
private int _loadVersion;
|
||||
|
||||
private bool _hasRequestedPlayerModelId;
|
||||
@@ -104,20 +112,28 @@ namespace BrewMonster.Scripts
|
||||
|
||||
/// <summary>
|
||||
/// Applies the visibility of player models based on the requested player model id.
|
||||
/// Fires <see cref="OnModelReady"/> the first time a model transitions to active so that
|
||||
/// portrait capture systems can attach at the correct moment after async loading.
|
||||
/// </summary>
|
||||
private void ApplyRequestedModelVisibility()
|
||||
{
|
||||
if(!_hasRequestedPlayerModelId)
|
||||
if (!_hasRequestedPlayerModelId)
|
||||
return;
|
||||
|
||||
int n = Mathf.Min(playerModels.Count, playerModelIds.Count);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
GameObject go = playerModels[i];
|
||||
if(go == null)
|
||||
if (go == null)
|
||||
continue;
|
||||
|
||||
go.SetActive(playerModelIds[i] == _requestedPlayerModelId);
|
||||
bool shouldBeActive = playerModelIds[i] == _requestedPlayerModelId;
|
||||
bool wasActive = go.activeSelf;
|
||||
go.SetActive(shouldBeActive);
|
||||
|
||||
// Fire once when this model first becomes visible
|
||||
if (shouldBeActive && !wasActive)
|
||||
OnModelReady?.Invoke(playerModelIds[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
using BrewMonster.Scripts.Managers;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
/// <summary>
|
||||
/// Renders an EC_ElsePlayer portrait into a RenderTexture for the target HUD (HUDNPC).
|
||||
///
|
||||
/// Instead of following the live player transform every frame (which causes jitter when
|
||||
/// the target moves/jumps), this system clones the visual model into an isolated
|
||||
/// "portrait stage" at a fixed world position. The portrait camera only ever looks at
|
||||
/// the static clone, so the output is perfectly stable.
|
||||
///
|
||||
/// Public API (unchanged — CECUIManager needs no edits):
|
||||
/// SetTarget(Transform playerRoot) — clone model, start rendering
|
||||
/// ClearTarget() — destroy clone, stop rendering
|
||||
/// OutputTexture — wire to RawImage.texture
|
||||
/// </summary>
|
||||
public class ElsePlayerPortraitCapture : MonoSingleton<ElsePlayerPortraitCapture>
|
||||
{
|
||||
[Header("Portrait Camera")]
|
||||
[SerializeField] private Camera portraitCamera;
|
||||
|
||||
[Header("Render Output")]
|
||||
[SerializeField] private RenderTexture outputTexture;
|
||||
|
||||
[Header("Portrait Stage")]
|
||||
[Tooltip("Layer index for the Portrait layer (Project Settings > Tags and Layers).")]
|
||||
[SerializeField] private int portraitLayer = 9;
|
||||
|
||||
[Tooltip("Fixed world position of the clone. Keep far from gameplay to avoid overlap.")]
|
||||
[SerializeField] private Vector3 stagePosition = new Vector3(9999f, 0f, 0f);
|
||||
|
||||
[Header("Framing")]
|
||||
[Tooltip("Distance the camera sits in front of the face (meters). ~0.5–1.0 for tight portrait.")]
|
||||
[SerializeField] private float cameraDistance = 0.7f;
|
||||
|
||||
[Tooltip("Extra upward offset applied to the look-at focus point (moves portrait up toward eyes).")]
|
||||
[SerializeField] private float faceUpLift = 0.04f;
|
||||
|
||||
[Tooltip("How fast the camera rotation interpolates toward the face each frame (higher = snappier).")]
|
||||
[SerializeField][Range(1f, 50f)] private float lookSmoothSpeed = 20f;
|
||||
|
||||
[Header("Head Bone Face Direction")]
|
||||
[Tooltip("Which local axis of Bip01 Head points OUT of the face (toward the camera).")]
|
||||
[SerializeField] private FaceAxis headFaceAxis = FaceAxis.Forward;
|
||||
|
||||
[Tooltip("Flip the chosen face axis (e.g. if Forward gives back-of-head, enable this).")]
|
||||
[SerializeField] private bool flipFaceAxis;
|
||||
|
||||
[SerializeField][Range(10f, 60f)] private float fieldOfView = 35f;
|
||||
|
||||
// ── runtime state ────────────────────────────────────────────────────────────
|
||||
private GameObject _portraitClone;
|
||||
private Transform _headBone;
|
||||
|
||||
public RenderTexture OutputTexture => outputTexture;
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// Lifecycle
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
EnsureCamera();
|
||||
EnsureRenderTexture();
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
ClearTarget();
|
||||
if (outputTexture != null && outputTexture.IsCreated())
|
||||
outputTexture.Release();
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// Public API
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// Clones the visual model of <paramref name="playerRoot"/> into the portrait stage
|
||||
/// and starts rendering. Safe to call multiple times — old clone is destroyed first.
|
||||
/// </summary>
|
||||
public void SetTarget(Transform playerRoot)
|
||||
{
|
||||
ClearTarget();
|
||||
if (playerRoot == null) return;
|
||||
|
||||
Transform modelRoot = PortraitCaptureUtils.FindVisualModelRoot(playerRoot);
|
||||
if (modelRoot == null)
|
||||
{
|
||||
BMLogger.LogWarning("[ElsePlayerPortraitCapture] Visual model root not found — portrait skipped.");
|
||||
return;
|
||||
}
|
||||
|
||||
_portraitClone = Object.Instantiate(modelRoot.gameObject);
|
||||
_portraitClone.GetComponentInChildren<Animator>().enabled = false;
|
||||
_portraitClone.name = "[Portrait] ElsePlayer";
|
||||
_portraitClone.transform.position = stagePosition;
|
||||
_portraitClone.transform.rotation = Quaternion.identity;
|
||||
|
||||
// Strip physics / game-logic components; keep Animator for idle animation
|
||||
PortraitCaptureUtils.CleanupCloneComponents(_portraitClone);
|
||||
|
||||
// Hide from main camera — portrait camera sees only this layer
|
||||
PortraitCaptureUtils.SetLayerRecursive(_portraitClone, portraitLayer);
|
||||
|
||||
_headBone = PortraitCaptureUtils.FindHeadBone(_portraitClone.transform);
|
||||
|
||||
AttachCameraToHeadBone();
|
||||
SetCameraEnabled(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the portrait clone and disables the camera.
|
||||
/// Call from OnTargetHUDClear / TryHideUINPC.
|
||||
/// </summary>
|
||||
public void ClearTarget()
|
||||
{
|
||||
if (_portraitClone != null)
|
||||
{
|
||||
Object.Destroy(_portraitClone);
|
||||
_portraitClone = null;
|
||||
}
|
||||
DetachCamera();
|
||||
_headBone = null;
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (portraitCamera == null || !portraitCamera.enabled) return;
|
||||
if (_headBone == null) return;
|
||||
|
||||
Vector3 faceCenter = _headBone.position + Vector3.up * faceUpLift;
|
||||
Vector3 toFace = faceCenter - portraitCamera.transform.position;
|
||||
if (toFace.sqrMagnitude < 0.0001f) return;
|
||||
|
||||
Quaternion targetRot = Quaternion.LookRotation(toFace);
|
||||
portraitCamera.transform.rotation = Quaternion.Slerp(
|
||||
portraitCamera.transform.rotation,
|
||||
targetRot,
|
||||
Time.deltaTime * lookSmoothSpeed);
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// Internal
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
private void AttachCameraToHeadBone()
|
||||
{
|
||||
if (portraitCamera == null) return;
|
||||
|
||||
Transform anchor = _headBone != null ? _headBone : _portraitClone.transform;
|
||||
Vector3 faceDir = GetFaceDirectionWorld(anchor);
|
||||
Vector3 headPos = anchor.position;
|
||||
Vector3 faceCenter = headPos + Vector3.up * faceUpLift;
|
||||
Vector3 camWorldPos = headPos + faceDir * cameraDistance;
|
||||
|
||||
portraitCamera.transform.SetParent(anchor, worldPositionStays: false);
|
||||
portraitCamera.transform.position = camWorldPos;
|
||||
portraitCamera.transform.LookAt(faceCenter);
|
||||
}
|
||||
|
||||
private Vector3 GetFaceDirectionWorld(Transform bone)
|
||||
{
|
||||
Vector3 dir = headFaceAxis switch
|
||||
{
|
||||
FaceAxis.Forward => bone.forward,
|
||||
FaceAxis.Back => -bone.forward,
|
||||
FaceAxis.Up => bone.up,
|
||||
FaceAxis.Down => -bone.up,
|
||||
FaceAxis.Right => bone.right,
|
||||
FaceAxis.Left => -bone.right,
|
||||
_ => bone.forward
|
||||
};
|
||||
|
||||
return flipFaceAxis ? -dir : dir;
|
||||
}
|
||||
|
||||
private void DetachCamera()
|
||||
{
|
||||
if (portraitCamera != null)
|
||||
{
|
||||
portraitCamera.transform.SetParent(transform, worldPositionStays: false);
|
||||
SetCameraEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetCameraEnabled(bool enabled)
|
||||
{
|
||||
if (portraitCamera != null)
|
||||
portraitCamera.enabled = enabled;
|
||||
}
|
||||
|
||||
private void EnsureCamera()
|
||||
{
|
||||
if (portraitCamera != null)
|
||||
{
|
||||
portraitCamera.cullingMask = 1 << portraitLayer;
|
||||
portraitCamera.fieldOfView = fieldOfView;
|
||||
portraitCamera.enabled = false;
|
||||
return;
|
||||
}
|
||||
portraitCamera = PortraitCaptureUtils.CreatePortraitCamera(
|
||||
transform, "PortraitCamera_ElsePlayer", portraitLayer, fieldOfView);
|
||||
}
|
||||
|
||||
private void EnsureRenderTexture()
|
||||
{
|
||||
if (outputTexture != null)
|
||||
{
|
||||
if (portraitCamera != null) portraitCamera.targetTexture = outputTexture;
|
||||
return;
|
||||
}
|
||||
outputTexture = PortraitCaptureUtils.CreatePortraitRT("ElsePlayerPortraitRT", portraitCamera);
|
||||
}
|
||||
|
||||
public enum FaceAxis { Forward, Back, Up, Down, Right, Left }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa7ed0ae48461f645932270bfda7ec70
|
||||
@@ -13,6 +13,7 @@ namespace BrewMonster
|
||||
[SerializeField] private TextMeshProUGUI _nameText;
|
||||
[SerializeField] private TextMeshProUGUI _statText;
|
||||
[SerializeField] private Image healthImage;
|
||||
[SerializeField] private RawImage _avatarImage;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
@@ -53,5 +54,18 @@ namespace BrewMonster
|
||||
{
|
||||
healthImage.fillAmount = health;
|
||||
}
|
||||
|
||||
public void SetAvatar(Texture tex)
|
||||
{
|
||||
if (_avatarImage == null) return;
|
||||
_avatarImage.texture = tex;
|
||||
_avatarImage.gameObject.SetActive(tex != null);
|
||||
}
|
||||
|
||||
public void ShowAvatar(bool show)
|
||||
{
|
||||
if (_avatarImage != null)
|
||||
_avatarImage.gameObject.SetActive(show);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,353 @@
|
||||
using BrewMonster.Scripts;
|
||||
using BrewMonster.Scripts.Managers;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
/// <summary>
|
||||
/// Renders the host player's portrait into a RenderTexture for the HUD.
|
||||
///
|
||||
/// Integrates with <see cref="PlayerModelPreview"/>:
|
||||
/// • If the model is already loaded when AttachToPlayerModelPreview is called → attach immediately.
|
||||
/// • If the model is still loading (async) → subscribe to PlayerModelPreview.OnModelReady and
|
||||
/// attach automatically as soon as the model becomes active.
|
||||
///
|
||||
/// Camera is parented directly to the "Bip01 Head" bone so it rides every head
|
||||
/// movement from idle animation without any world-space tracking code.
|
||||
/// Every LateUpdate the camera rotation is Slerp-interpolated toward the face.
|
||||
///
|
||||
/// Public API:
|
||||
/// AttachToPlayerModelPreview(int roleId) — primary; handles async loading
|
||||
/// SetHostPlayer(Transform root) — fallback; any player root directly
|
||||
/// Refresh(int roleId) — call after equipment reload
|
||||
/// ClearPortrait() — detach camera, stop rendering
|
||||
/// OutputTexture — wire to RawImage.texture on HUD
|
||||
/// </summary>
|
||||
public class HostPlayerPortraitCapture : MonoSingleton<HostPlayerPortraitCapture>
|
||||
{
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// Inspector
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
[Header("Portrait Camera")]
|
||||
[SerializeField] private Camera portraitCamera;
|
||||
|
||||
[Header("Render Output")]
|
||||
[SerializeField] private RenderTexture outputTexture;
|
||||
|
||||
[Header("Portrait Layer")]
|
||||
[Tooltip("Layer index rendered ONLY by the portrait camera (Project Settings > Tags and Layers).")]
|
||||
[SerializeField] private int portraitLayer = 29;
|
||||
|
||||
[Header("Head Bone Face Direction")]
|
||||
[Tooltip("Which local axis of Bip01 Head points OUT of the face (toward the camera).\n" +
|
||||
"In most Biped rigs exported from 3ds Max/Unity: Forward (+Z).\n" +
|
||||
"Switch to Back (-Z) or Up (+Y) if portrait faces wrong way.")]
|
||||
[SerializeField] private FaceAxis headFaceAxis = FaceAxis.Forward;
|
||||
|
||||
[Tooltip("Flip the chosen face axis (e.g. if Forward gives back-of-head, enable this).")]
|
||||
[SerializeField] private bool flipFaceAxis;
|
||||
|
||||
[Header("Framing")]
|
||||
[Tooltip("Distance the camera sits in front of the face (meters). ~0.5–1.0 for tight portrait.")]
|
||||
[SerializeField] private float cameraDistance = 0.7f;
|
||||
|
||||
[Tooltip("Extra upward offset applied to the look-at focus point (moves portrait up toward eyes).")]
|
||||
[SerializeField] private float faceUpLift = 0.04f;
|
||||
|
||||
[Tooltip("How fast the camera rotation interpolates toward the face each frame (higher = snappier).")]
|
||||
[SerializeField][Range(1f, 50f)] private float lookSmoothSpeed = 20f;
|
||||
|
||||
[SerializeField][Range(10f, 60f)] private float fieldOfView = 40f;
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// Runtime state
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
private Transform _modelTransform;
|
||||
private Transform _headBone;
|
||||
|
||||
// Stored while waiting for async model load; -1 means no pending request
|
||||
private int _pendingRoleId = -1;
|
||||
|
||||
public RenderTexture OutputTexture => outputTexture;
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// Lifecycle
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
EnsureCamera();
|
||||
EnsureRenderTexture();
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
UnsubscribeModelReady();
|
||||
ClearPortrait();
|
||||
if (outputTexture != null && outputTexture.IsCreated())
|
||||
outputTexture.Release();
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// Public API
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// Attaches the portrait camera to the model matching <paramref name="roleId"/> inside
|
||||
/// <see cref="PlayerModelPreview"/>.
|
||||
///
|
||||
/// Two paths:
|
||||
/// 1. Model already loaded and active → attach immediately.
|
||||
/// 2. Model still loading (async) → subscribe to <see cref="PlayerModelPreview.OnModelReady"/>
|
||||
/// and attach automatically when the event fires for this roleId.
|
||||
/// </summary>
|
||||
public void AttachToPlayerModelPreview(int roleId)
|
||||
{
|
||||
UnsubscribeModelReady();
|
||||
DetachCamera();
|
||||
|
||||
if (PlayerModelPreview.Instance == null)
|
||||
{
|
||||
BMLogger.LogWarning("[HostPlayerPortraitCapture] PlayerModelPreview.Instance is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Path 1: model already in the list and active → attach now
|
||||
if (TryAttachFromPreview(roleId))
|
||||
return;
|
||||
|
||||
// Path 2: model not ready yet — wait for OnModelReady event
|
||||
_pendingRoleId = roleId;
|
||||
PlayerModelPreview.Instance.OnModelReady += OnPreviewModelReady;
|
||||
BMLogger.Log($"[HostPlayerPortraitCapture] Model for roleId={roleId} not ready, waiting for load...");
|
||||
}
|
||||
|
||||
/// <summary>Fallback: attach directly to any player hierarchy root.</summary>
|
||||
public void SetHostPlayer(Transform hostPlayerRoot)
|
||||
{
|
||||
DetachCamera();
|
||||
if (hostPlayerRoot == null) return;
|
||||
_modelTransform = hostPlayerRoot;
|
||||
SetupPortrait();
|
||||
}
|
||||
|
||||
/// <summary>Re-attach after equipment reload rebuilds the PlayerModelPreview model.</summary>
|
||||
public void Refresh(int roleId) => AttachToPlayerModelPreview(roleId);
|
||||
|
||||
/// <summary>Detach camera and stop rendering. Call on logout / scene unload.</summary>
|
||||
public void ClearPortrait()
|
||||
{
|
||||
UnsubscribeModelReady();
|
||||
DetachCamera();
|
||||
_modelTransform = null;
|
||||
_headBone = null;
|
||||
_pendingRoleId = -1;
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// LateUpdate — smooth Slerp toward face every frame
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (portraitCamera == null || !portraitCamera.enabled) return;
|
||||
if (_headBone == null) return;
|
||||
|
||||
// Focus point: centre of face, nudged upward by faceUpLift
|
||||
Vector3 faceCenter = _headBone.position + Vector3.up * faceUpLift;
|
||||
|
||||
// Direction from camera to face centre
|
||||
Vector3 toFace = faceCenter - portraitCamera.transform.position;
|
||||
if (toFace.sqrMagnitude < 0.0001f) return;
|
||||
|
||||
// Slerp rotation smoothly toward the look-at orientation
|
||||
Quaternion targetRot = Quaternion.LookRotation(toFace);
|
||||
portraitCamera.transform.rotation = Quaternion.Slerp(
|
||||
portraitCamera.transform.rotation,
|
||||
targetRot,
|
||||
Time.deltaTime * lookSmoothSpeed);
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// PlayerModelPreview integration helpers
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// Called by <see cref="PlayerModelPreview.OnModelReady"/> when a model becomes active.
|
||||
/// Attaches only if the roleId matches the pending request.
|
||||
/// </summary>
|
||||
private void OnPreviewModelReady(int readyRoleId)
|
||||
{
|
||||
if (readyRoleId != _pendingRoleId) return;
|
||||
|
||||
UnsubscribeModelReady();
|
||||
TryAttachFromPreview(readyRoleId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find and attach to the model for <paramref name="roleId"/> in PlayerModelPreview.
|
||||
/// Returns true if the model was found (active or not) and attachment succeeded.
|
||||
/// </summary>
|
||||
private bool TryAttachFromPreview(int roleId)
|
||||
{
|
||||
var preview = PlayerModelPreview.Instance;
|
||||
if (preview == null) return false;
|
||||
|
||||
var models = preview.playerModels;
|
||||
var ids = preview.playerModelIds;
|
||||
|
||||
int count = Mathf.Min(models.Count, ids.Count);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (ids[i] != roleId || models[i] == null) continue;
|
||||
|
||||
// Ensure the model is active so the camera can render it
|
||||
if (!models[i].activeSelf)
|
||||
models[i].SetActive(true);
|
||||
|
||||
_modelTransform = models[i].transform;
|
||||
SetupPortrait();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void UnsubscribeModelReady()
|
||||
{
|
||||
if (PlayerModelPreview.Instance != null)
|
||||
PlayerModelPreview.Instance.OnModelReady -= OnPreviewModelReady;
|
||||
_pendingRoleId = -1;
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// Internal
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
private void SetupPortrait()
|
||||
{
|
||||
if (_modelTransform == null) return;
|
||||
|
||||
// Move model to portrait layer so the dedicated camera can render it
|
||||
PortraitCaptureUtils.SetLayerRecursive(_modelTransform.gameObject, portraitLayer);
|
||||
|
||||
// Find head bone — primary target for camera attachment
|
||||
_headBone = PortraitCaptureUtils.FindChildByName(_modelTransform, "Bip01 Head")
|
||||
?? PortraitCaptureUtils.FindChildByName(_modelTransform, "Bip001 Head")
|
||||
?? PortraitCaptureUtils.FindHeadBone(_modelTransform);
|
||||
|
||||
if (_headBone == null)
|
||||
BMLogger.LogWarning("[HostPlayerPortraitCapture] Head bone not found — portrait skipped.");
|
||||
|
||||
AttachCameraToHeadBone();
|
||||
SetCameraEnabled(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parents the portrait camera to "Bip01 Head" and sets its initial position
|
||||
/// directly in front of the face.
|
||||
///
|
||||
/// Coordinate math:
|
||||
/// faceDir = local axis of headBone that points OUT of the face (Inspector: headFaceAxis)
|
||||
/// camWorldPos = headBone.position + faceDir * cameraDistance
|
||||
///
|
||||
/// After SetParent, Unity converts this world position into a localPosition relative
|
||||
/// to the head bone automatically. From that point on the camera rides the bone —
|
||||
/// no per-frame world-space override is needed. Only LookAt is refreshed in LateUpdate.
|
||||
/// </summary>
|
||||
private void AttachCameraToHeadBone()
|
||||
{
|
||||
if (portraitCamera == null) return;
|
||||
|
||||
Transform anchor = _headBone ?? _modelTransform;
|
||||
|
||||
// Face direction in world space — derived from head bone's own local axes
|
||||
Vector3 faceDir = GetFaceDirectionWorld(anchor);
|
||||
|
||||
Vector3 headPos = anchor.position;
|
||||
Vector3 faceCenter = headPos + Vector3.up * faceUpLift;
|
||||
|
||||
// Camera sits cameraDistance units in FRONT of the face (outside, looking back in)
|
||||
Vector3 camWorldPos = headPos + faceDir * cameraDistance;
|
||||
|
||||
// Parent to head bone first with worldPositionStays:false (resets local to zero),
|
||||
// then assign world position — Unity stores the correct localPosition internally
|
||||
portraitCamera.transform.SetParent(anchor, worldPositionStays: false);
|
||||
portraitCamera.transform.position = camWorldPos;
|
||||
|
||||
// Initial look-at so first frame is already correct before LateUpdate fires
|
||||
portraitCamera.transform.LookAt(faceCenter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the world-space direction that points OUT OF the character's face,
|
||||
/// derived from the head bone's local coordinate axes according to <see cref="headFaceAxis"/>.
|
||||
///
|
||||
/// Biped rig convention (3ds Max → Unity export):
|
||||
/// In most Perfect World rigs, the head bone's +Z (forward) points toward the face.
|
||||
/// If the portrait comes out upside-down or backwards, toggle <see cref="headFaceAxis"/>
|
||||
/// and/or <see cref="flipFaceAxis"/> in the Inspector without changing code.
|
||||
/// </summary>
|
||||
private Vector3 GetFaceDirectionWorld(Transform bone)
|
||||
{
|
||||
Vector3 dir = headFaceAxis switch
|
||||
{
|
||||
FaceAxis.Forward => bone.forward,
|
||||
FaceAxis.Back => -bone.forward,
|
||||
FaceAxis.Up => bone.up,
|
||||
FaceAxis.Down => -bone.up,
|
||||
FaceAxis.Right => bone.right,
|
||||
FaceAxis.Left => -bone.right,
|
||||
_ => bone.forward
|
||||
};
|
||||
return flipFaceAxis ? -dir : dir;
|
||||
}
|
||||
|
||||
private void DetachCamera()
|
||||
{
|
||||
if (portraitCamera != null)
|
||||
{
|
||||
portraitCamera.transform.SetParent(transform, worldPositionStays: false);
|
||||
SetCameraEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetCameraEnabled(bool enabled)
|
||||
{
|
||||
if (portraitCamera != null)
|
||||
portraitCamera.enabled = enabled;
|
||||
}
|
||||
|
||||
private void EnsureCamera()
|
||||
{
|
||||
if (portraitCamera != null)
|
||||
{
|
||||
portraitCamera.cullingMask = 1 << portraitLayer;
|
||||
portraitCamera.fieldOfView = fieldOfView;
|
||||
portraitCamera.enabled = false;
|
||||
return;
|
||||
}
|
||||
portraitCamera = PortraitCaptureUtils.CreatePortraitCamera(
|
||||
transform, "PortraitCamera_HostPlayer", portraitLayer, fieldOfView);
|
||||
}
|
||||
|
||||
private void EnsureRenderTexture()
|
||||
{
|
||||
if (outputTexture != null)
|
||||
{
|
||||
if (portraitCamera != null) portraitCamera.targetTexture = outputTexture;
|
||||
return;
|
||||
}
|
||||
outputTexture = PortraitCaptureUtils.CreatePortraitRT("HostPlayerPortraitRT", portraitCamera);
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// Helpers
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
public enum FaceAxis { Forward, Back, Up, Down, Right, Left }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93accee0d329e0f45a7be8b74cf0cb99
|
||||
@@ -0,0 +1,139 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
/// <summary>
|
||||
/// Shared static helpers used by ElsePlayerPortraitCapture and HostPlayerPortraitCapture.
|
||||
/// </summary>
|
||||
public static class PortraitCaptureUtils
|
||||
{
|
||||
private static readonly string[] HeadBoneNames =
|
||||
{
|
||||
"Bip01 Head", "Bip001 Head", "head", "Head", "Bone_Head", "HEAD"
|
||||
};
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// Model / bone search
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// Returns the root transform of the visual model inside <paramref name="playerRoot"/>.
|
||||
/// Tries to find the first child that owns a SkinnedMeshRenderer; falls back to the
|
||||
/// root itself if a SkinnedMeshRenderer is found anywhere in the hierarchy.
|
||||
/// </summary>
|
||||
public static Transform FindVisualModelRoot(Transform playerRoot)
|
||||
{
|
||||
if (playerRoot == null) return null;
|
||||
|
||||
// Walk immediate children first — model root is usually a direct child
|
||||
for (int i = 0; i < playerRoot.childCount; i++)
|
||||
{
|
||||
var child = playerRoot.GetChild(i);
|
||||
if (child.GetComponentInChildren<SkinnedMeshRenderer>() != null)
|
||||
return child;
|
||||
}
|
||||
|
||||
// Fallback: if the root itself contains a SMR, use it
|
||||
if (playerRoot.GetComponentInChildren<SkinnedMeshRenderer>() != null)
|
||||
return playerRoot;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches <paramref name="modelRoot"/>'s hierarchy for a head bone by common name patterns.
|
||||
/// </summary>
|
||||
public static Transform FindHeadBone(Transform modelRoot)
|
||||
{
|
||||
if (modelRoot == null) return null;
|
||||
foreach (var boneName in HeadBoneNames)
|
||||
{
|
||||
var bone = FindChildByName(modelRoot, boneName);
|
||||
if (bone != null) return bone;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>Recursive depth-first search for a child transform by exact name.</summary>
|
||||
public static Transform FindChildByName(Transform root, string name)
|
||||
{
|
||||
if (root.name == name) return root;
|
||||
for (int i = 0; i < root.childCount; i++)
|
||||
{
|
||||
var result = FindChildByName(root.GetChild(i), name);
|
||||
if (result != null) return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// Clone setup
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// Strips non-visual components from a cloned GameObject so it becomes a lightweight
|
||||
/// render-only puppet. Keeps Animator so idle animations continue to play.
|
||||
/// </summary>
|
||||
public static void CleanupCloneComponents(GameObject go)
|
||||
{
|
||||
foreach (var col in go.GetComponentsInChildren<Collider>(true))
|
||||
Object.Destroy(col);
|
||||
|
||||
foreach (var rb in go.GetComponentsInChildren<Rigidbody>(true))
|
||||
Object.Destroy(rb);
|
||||
|
||||
foreach (var mb in go.GetComponentsInChildren<MonoBehaviour>(true))
|
||||
{
|
||||
if (mb is Animator) continue;
|
||||
Object.Destroy(mb);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Recursively sets the layer of <paramref name="go"/> and all its children.</summary>
|
||||
public static void SetLayerRecursive(GameObject go, int layer)
|
||||
{
|
||||
go.layer = layer;
|
||||
foreach (Transform child in go.transform)
|
||||
SetLayerRecursive(child.gameObject, layer);
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// Camera / RenderTexture factories
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Camera child GameObject under <paramref name="parent"/> whose culling mask
|
||||
/// covers only <paramref name="portraitLayer"/>. Camera starts disabled.
|
||||
/// </summary>
|
||||
public static Camera CreatePortraitCamera(Transform parent, string goName, int portraitLayer, float fov)
|
||||
{
|
||||
var camGO = new GameObject(goName);
|
||||
camGO.transform.SetParent(parent, false);
|
||||
|
||||
var cam = camGO.AddComponent<Camera>();
|
||||
cam.cullingMask = 1 << portraitLayer;
|
||||
cam.clearFlags = CameraClearFlags.SolidColor;
|
||||
cam.backgroundColor = Color.clear;
|
||||
cam.fieldOfView = fov;
|
||||
cam.nearClipPlane = 0.1f;
|
||||
cam.farClipPlane = 200f;
|
||||
cam.enabled = false;
|
||||
return cam;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a 256×256 ARGB32 RenderTexture and wires it to <paramref name="cam"/> if provided.
|
||||
/// </summary>
|
||||
public static RenderTexture CreatePortraitRT(string rtName, Camera cam)
|
||||
{
|
||||
var rt = new RenderTexture(256, 256, 16, RenderTextureFormat.ARGB32)
|
||||
{
|
||||
name = rtName,
|
||||
antiAliasing = 1
|
||||
};
|
||||
rt.Create();
|
||||
if (cam != null) cam.targetTexture = rt;
|
||||
return rt;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d2d46da24e62da45a4abea222294fd2
|
||||
@@ -1,4 +1,5 @@
|
||||
using BrewMonster;
|
||||
using BrewMonster.Managers;
|
||||
using BrewMonster.Network;
|
||||
using BrewMonster.UI;
|
||||
using System;
|
||||
@@ -8,6 +9,7 @@ using BrewMonster.Scripts.Chat.EmotionData;
|
||||
using BrewMonster.Scripts.Managers;
|
||||
using BrewMonster.Scripts.Task.UI;
|
||||
using BrewMonster.Scripts.UI;
|
||||
using CSNetwork.GPDataType;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
@@ -172,10 +174,29 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
float fill = obj.MaxHealth > 0 ? (float)obj.CurrentHealth / (float)obj.MaxHealth : 1f;
|
||||
npsUI.SetHealthImage(fill);
|
||||
currentTargetNPCID = obj.IDNPC;
|
||||
|
||||
// Render ElsePlayer portrait avatar — mirrors C++ PlayerRenderPortrait / SetRenderCallback
|
||||
if (GPDataTypeHelper.ISPLAYERID(obj.IDNPC))
|
||||
{
|
||||
var elsePlayer = EC_ManMessageMono.Instance?.GetECManPlayer?
|
||||
.GetPlayer(obj.IDNPC) as EC_ElsePlayer;
|
||||
if (elsePlayer != null)
|
||||
{
|
||||
ElsePlayerPortraitCapture.Instance?.SetTarget(elsePlayer.transform);
|
||||
npsUI.SetAvatar(ElsePlayerPortraitCapture.Instance?.OutputTexture);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// NPC thường hoặc không tìm thấy ElsePlayer — ẩn avatar
|
||||
ElsePlayerPortraitCapture.Instance?.ClearTarget();
|
||||
npsUI.ShowAvatar(false);
|
||||
}
|
||||
|
||||
private void OnTargetHUDClear(CECHostPlayer.TargetHUDClearEvent _)
|
||||
{
|
||||
ElsePlayerPortraitCapture.Instance?.ClearTarget();
|
||||
npsUI.ShowAvatar(false);
|
||||
npsUI.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
@@ -187,6 +208,8 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
private void TryHideUINPC(NPCDiedEvent obj)
|
||||
{
|
||||
if (obj.NPCID != currentTargetNPCID) return;
|
||||
ElsePlayerPortraitCapture.Instance?.ClearTarget();
|
||||
npsUI.ShowAvatar(false);
|
||||
npsUI.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -187,6 +187,7 @@ namespace BrewMonster.UI
|
||||
if (PlayerModelPreview.Instance.playerModelIds != null && PlayerModelPreview.Instance.playerModelIds.Contains(roleId))
|
||||
{
|
||||
PlayerModelPreview.Instance.ShowPlayerModel(roleId);
|
||||
HostPlayerPortraitCapture.Instance?.AttachToPlayerModelPreview(roleId);
|
||||
_btnEnterGame.interactable = true;
|
||||
_showModelReadyCoroutine = null;
|
||||
yield break; // Model is ready, show it and stop this coroutine
|
||||
|
||||
Reference in New Issue
Block a user