Merge branch 'develop' into feature/gfx-action
This commit is contained in:
@@ -5279,6 +5279,7 @@ RectTransform:
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 7020286574697807252}
|
||||
- {fileID: 2986444586062603990}
|
||||
- {fileID: 7009781864899289290}
|
||||
- {fileID: 306866035769036868}
|
||||
- {fileID: 7749074831901819156}
|
||||
@@ -6730,6 +6731,11 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
inputField: {fileID: 9217902013627304316}
|
||||
chatSystem: {fileID: 0}
|
||||
typingPreview:
|
||||
typingPreviewRoot: {fileID: 0}
|
||||
typingPreviewText: {fileID: 0}
|
||||
typingPreviewRect: {fileID: 0}
|
||||
previewVerticalOffset: 8
|
||||
_spriteMap: {fileID: 0}
|
||||
channelButtons: []
|
||||
recentWhisperDropdown: {fileID: 0}
|
||||
@@ -9300,6 +9306,7 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
skillNameText: {fileID: 0}
|
||||
imageProgress: {fileID: 0}
|
||||
btnCancel: {fileID: 0}
|
||||
AUIImagePictureList:
|
||||
- {fileID: 2554621538146193444}
|
||||
- {fileID: 453489490841355523}
|
||||
@@ -11486,6 +11493,7 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
skillNameText: {fileID: 0}
|
||||
imageProgress: {fileID: 0}
|
||||
btnCancel: {fileID: 0}
|
||||
uiSkillButton: {fileID: 1484158212461992110}
|
||||
uiAssignSkillButton: {fileID: 3134606437297610210}
|
||||
skillUI: {fileID: 5226149676194325592}
|
||||
@@ -11504,6 +11512,7 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
skillNameText: {fileID: 0}
|
||||
imageProgress: {fileID: 0}
|
||||
btnCancel: {fileID: 0}
|
||||
--- !u!114 &3162833025978482600
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -11530,6 +11539,7 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
skillNameText: {fileID: 0}
|
||||
imageProgress: {fileID: 0}
|
||||
btnCancel: {fileID: 0}
|
||||
m_comboSkillImages: []
|
||||
m_fixedImgPics: []
|
||||
m_fixedTxts: []
|
||||
@@ -11554,6 +11564,142 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 01a97b889c107814eb3c4957c683c0b4, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &7074520118473636777
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 241237157041429321}
|
||||
- component: {fileID: 270969581052521031}
|
||||
- component: {fileID: 4350240862534366165}
|
||||
m_Layer: 5
|
||||
m_Name: Text (TMP)
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &241237157041429321
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7074520118473636777}
|
||||
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: 2986444586062603990}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &270969581052521031
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7074520118473636777}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &4350240862534366165
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7074520118473636777}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, 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_text: Pets Bag
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||
m_fontSharedMaterials: []
|
||||
m_fontMaterial: {fileID: 0}
|
||||
m_fontMaterials: []
|
||||
m_fontColor32:
|
||||
serializedVersion: 2
|
||||
rgba: 4281479730
|
||||
m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_enableVertexGradient: 0
|
||||
m_colorMode: 3
|
||||
m_fontColorGradient:
|
||||
topLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
topRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_fontColorGradientPreset: {fileID: 0}
|
||||
m_spriteAsset: {fileID: 0}
|
||||
m_tintAllSprites: 0
|
||||
m_StyleSheet: {fileID: 0}
|
||||
m_TextStyleHashCode: -1183493901
|
||||
m_overrideHtmlColors: 0
|
||||
m_faceColor:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontSize: 24
|
||||
m_fontSizeBase: 24
|
||||
m_fontWeight: 400
|
||||
m_enableAutoSizing: 0
|
||||
m_fontSizeMin: 18
|
||||
m_fontSizeMax: 72
|
||||
m_fontStyle: 1
|
||||
m_HorizontalAlignment: 2
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 0
|
||||
m_ActiveFontFeatures: 6e72656b
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
m_horizontalMapping: 0
|
||||
m_verticalMapping: 0
|
||||
m_uvLineOffset: 0
|
||||
m_geometrySortingOrder: 0
|
||||
m_IsTextObjectScaleStatic: 0
|
||||
m_VertexBufferAutoSizeReduction: 0
|
||||
m_useMaxVisibleDescender: 1
|
||||
m_pageToDisplay: 1
|
||||
m_margin: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_isUsingLegacyAnimationComponent: 0
|
||||
m_isVolumetricText: 0
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!1 &7085407906379676811
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -12179,6 +12325,127 @@ MonoBehaviour:
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!1 &7225530504037035146
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2986444586062603990}
|
||||
- component: {fileID: 6978431260668590831}
|
||||
- component: {fileID: 4263386157695161978}
|
||||
- component: {fileID: 2284650751748751962}
|
||||
m_Layer: 5
|
||||
m_Name: PetBagsBtn
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &2986444586062603990
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7225530504037035146}
|
||||
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: 241237157041429321}
|
||||
m_Father: {fileID: 7304194108989414091}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0, y: 1}
|
||||
--- !u!222 &6978431260668590831
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7225530504037035146}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &4263386157695161978
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7225530504037035146}
|
||||
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: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 1
|
||||
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 &2284650751748751962
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7225530504037035146}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_WrapAround: 0
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_SelectedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 4263386157695161978}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &7311465216184143602
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -12258,6 +12525,7 @@ MonoBehaviour:
|
||||
_btnTaskTrace: {fileID: 3253955040536933532}
|
||||
_taskTraceParent: {fileID: 2578159539417438268}
|
||||
_btnTeamList: {fileID: 540188344648694736}
|
||||
_btnPetBags: {fileID: 2284650751748751962}
|
||||
--- !u!1 &7352847439676120744
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -13974,6 +14242,7 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
skillNameText: {fileID: 0}
|
||||
imageProgress: {fileID: 0}
|
||||
btnCancel: {fileID: 0}
|
||||
AUIImagePictureList:
|
||||
- {fileID: 445184971459596056}
|
||||
- {fileID: 3804662600613272361}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using BrewMonster.Scripts.Managers;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -50,9 +51,14 @@ namespace BrewMonster
|
||||
|
||||
[SerializeField][Range(10f, 60f)] private float fieldOfView = 35f;
|
||||
|
||||
[Header("Materials")]
|
||||
[Tooltip("Clone each renderer material on the portrait clone and switch copies to URP/Unlit.")]
|
||||
[SerializeField] private bool usePortraitUnlitMaterials = true;
|
||||
|
||||
// ── runtime state ────────────────────────────────────────────────────────────
|
||||
private GameObject _portraitClone;
|
||||
private Transform _headBone;
|
||||
private readonly List<Material> _portraitMaterialInstances = new();
|
||||
|
||||
public RenderTexture OutputTexture => outputTexture;
|
||||
|
||||
@@ -106,6 +112,14 @@ namespace BrewMonster
|
||||
// Hide from main camera — portrait camera sees only this layer
|
||||
PortraitCaptureUtils.SetLayerRecursive(_portraitClone, portraitLayer);
|
||||
|
||||
if (usePortraitUnlitMaterials)
|
||||
{
|
||||
PortraitCaptureUtils.ApplyClonedUrpUnlitMaterials(
|
||||
_portraitClone,
|
||||
_portraitMaterialInstances,
|
||||
static msg => BMLogger.LogWarning(msg));
|
||||
}
|
||||
|
||||
_headBone = PortraitCaptureUtils.FindHeadBone(_portraitClone.transform);
|
||||
|
||||
AttachCameraToHeadBone();
|
||||
@@ -123,6 +137,12 @@ namespace BrewMonster
|
||||
Object.Destroy(_portraitClone);
|
||||
_portraitClone = null;
|
||||
}
|
||||
for (int i = 0; i < _portraitMaterialInstances.Count; i++)
|
||||
{
|
||||
if (_portraitMaterialInstances[i] != null)
|
||||
Object.Destroy(_portraitMaterialInstances[i]);
|
||||
}
|
||||
_portraitMaterialInstances.Clear();
|
||||
DetachCamera();
|
||||
_headBone = null;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace BrewMonster
|
||||
[SerializeField]private Toggle _btnTaskTrace;
|
||||
[SerializeField]private Transform _taskTraceParent;
|
||||
[SerializeField]private Button _btnTeamList;
|
||||
[SerializeField]private Button _btnPetBags;
|
||||
|
||||
public const int AUIPROGRESS_MAX = 100;
|
||||
private DlgWinPrgs2 _dlgWinPrgs;
|
||||
@@ -32,6 +33,7 @@ namespace BrewMonster
|
||||
_btnTeam.onValueChanged.AddListener(OnTeamClicked);
|
||||
_btnTaskTrace.onValueChanged.AddListener(OnTaskTraceClicked);
|
||||
_btnTeamList.onClick.AddListener(OnTeamListClicked);
|
||||
_btnPetBags.onClick.AddListener(OnCallPetBagsClicked);
|
||||
EventBus.Unsubscribe<UIEvent>(OnUIEvent);
|
||||
EventBus.Subscribe<UIEvent>(OnUIEvent);
|
||||
}
|
||||
@@ -44,6 +46,7 @@ namespace BrewMonster
|
||||
_btnTeam.onValueChanged.RemoveListener(OnTeamClicked);
|
||||
_btnTaskTrace.onValueChanged.RemoveListener(OnTaskTraceClicked);
|
||||
_btnTeamList.onClick.RemoveListener(OnTeamListClicked);
|
||||
_btnPetBags.onClick.RemoveListener(OnCallPetBagsClicked);
|
||||
EventBus.Unsubscribe<UIEvent>(OnUIEvent);
|
||||
}
|
||||
|
||||
@@ -145,9 +148,14 @@ namespace BrewMonster
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCallPetBagsClicked()
|
||||
{
|
||||
EC_Game.GetGameRun().GetUIManager().GetInGameUIMan().PopupPetListDialog();
|
||||
}
|
||||
|
||||
#region Progress Bar
|
||||
|
||||
public void RefreshStatusBar()
|
||||
public void RefreshStatusBar()
|
||||
{
|
||||
bool bActive = true;
|
||||
// if( GetGameUIMan()->GetActiveDialog() &&
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using BrewMonster.Scripts;
|
||||
using BrewMonster.Scripts.Managers;
|
||||
using UnityEngine;
|
||||
@@ -60,6 +61,10 @@ namespace BrewMonster
|
||||
|
||||
[SerializeField][Range(10f, 60f)] private float fieldOfView = 40f;
|
||||
|
||||
[Header("Materials")]
|
||||
[Tooltip("Clone each renderer material and switch copies to URP/Unlit for stable portrait lighting.")]
|
||||
[SerializeField] private bool usePortraitUnlitMaterials = true;
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// Runtime state
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
@@ -67,9 +72,18 @@ namespace BrewMonster
|
||||
private Transform _modelTransform;
|
||||
private Transform _headBone;
|
||||
|
||||
private readonly List<Material> _portraitMaterialInstances = new();
|
||||
private readonly List<RendererSharedMaterialsSnapshot> _previewMaterialRestore = new();
|
||||
|
||||
// Stored while waiting for async model load; -1 means no pending request
|
||||
private int _pendingRoleId = -1;
|
||||
|
||||
private struct RendererSharedMaterialsSnapshot
|
||||
{
|
||||
public Renderer Renderer;
|
||||
public Material[] SharedMaterials;
|
||||
}
|
||||
|
||||
public RenderTexture OutputTexture => outputTexture;
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
@@ -107,6 +121,7 @@ namespace BrewMonster
|
||||
public void AttachToPlayerModelPreview(int roleId)
|
||||
{
|
||||
UnsubscribeModelReady();
|
||||
RestorePreviewMaterials();
|
||||
DetachCamera();
|
||||
|
||||
if (PlayerModelPreview.Instance == null)
|
||||
@@ -128,6 +143,7 @@ namespace BrewMonster
|
||||
/// <summary>Fallback: attach directly to any player hierarchy root.</summary>
|
||||
public void SetHostPlayer(Transform hostPlayerRoot)
|
||||
{
|
||||
RestorePreviewMaterials();
|
||||
DetachCamera();
|
||||
if (hostPlayerRoot == null) return;
|
||||
_modelTransform = hostPlayerRoot;
|
||||
@@ -141,6 +157,7 @@ namespace BrewMonster
|
||||
public void ClearPortrait()
|
||||
{
|
||||
UnsubscribeModelReady();
|
||||
RestorePreviewMaterials();
|
||||
DetachCamera();
|
||||
_modelTransform = null;
|
||||
_headBone = null;
|
||||
@@ -231,6 +248,15 @@ namespace BrewMonster
|
||||
{
|
||||
if (_modelTransform == null) return;
|
||||
|
||||
if (usePortraitUnlitMaterials)
|
||||
{
|
||||
CaptureRendererMaterialsForRestore(_modelTransform.gameObject);
|
||||
PortraitCaptureUtils.ApplyClonedUrpUnlitMaterials(
|
||||
_modelTransform.gameObject,
|
||||
_portraitMaterialInstances,
|
||||
static msg => BMLogger.LogWarning(msg));
|
||||
}
|
||||
|
||||
// Move model to portrait layer so the dedicated camera can render it
|
||||
PortraitCaptureUtils.SetLayerRecursive(_modelTransform.gameObject, portraitLayer);
|
||||
|
||||
@@ -246,6 +272,46 @@ namespace BrewMonster
|
||||
SetCameraEnabled(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restores <see cref="PlayerModelPreview"/> renderers to their original shared materials
|
||||
/// and destroys portrait-only material instances.
|
||||
/// </summary>
|
||||
private void RestorePreviewMaterials()
|
||||
{
|
||||
for (int i = 0; i < _previewMaterialRestore.Count; i++)
|
||||
{
|
||||
var snap = _previewMaterialRestore[i];
|
||||
if (snap.Renderer != null && snap.SharedMaterials != null)
|
||||
snap.Renderer.sharedMaterials = snap.SharedMaterials;
|
||||
}
|
||||
_previewMaterialRestore.Clear();
|
||||
|
||||
for (int i = 0; i < _portraitMaterialInstances.Count; i++)
|
||||
{
|
||||
if (_portraitMaterialInstances[i] != null)
|
||||
Object.Destroy(_portraitMaterialInstances[i]);
|
||||
}
|
||||
_portraitMaterialInstances.Clear();
|
||||
}
|
||||
|
||||
private void CaptureRendererMaterialsForRestore(GameObject root)
|
||||
{
|
||||
if (root == null) return;
|
||||
|
||||
var renderers = root.GetComponentsInChildren<Renderer>(true);
|
||||
for (int i = 0; i < renderers.Length; i++)
|
||||
{
|
||||
var r = renderers[i];
|
||||
var shared = r.sharedMaterials;
|
||||
if (shared == null || shared.Length == 0) continue;
|
||||
|
||||
var copy = new Material[shared.Length];
|
||||
System.Array.Copy(shared, copy, shared.Length);
|
||||
_previewMaterialRestore.Add(
|
||||
new RendererSharedMaterialsSnapshot { Renderer = r, SharedMaterials = copy });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parents the portrait camera to "Bip01 Head" and sets its initial position
|
||||
/// directly in front of the face.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster
|
||||
@@ -7,6 +8,19 @@ namespace BrewMonster
|
||||
/// </summary>
|
||||
public static class PortraitCaptureUtils
|
||||
{
|
||||
private static readonly string[] UrpUnlitShaderNames =
|
||||
{
|
||||
"Universal Render Pipeline/Unlit",
|
||||
};
|
||||
|
||||
private static readonly int BaseMapId = Shader.PropertyToID("_BaseMap");
|
||||
private static readonly int BaseColorId = Shader.PropertyToID("_BaseColor");
|
||||
private static readonly int BaseMapStId = Shader.PropertyToID("_BaseMap_ST");
|
||||
private static readonly int MainTexId = Shader.PropertyToID("_MainTex");
|
||||
private static readonly int MainTexStId = Shader.PropertyToID("_MainTex_ST");
|
||||
private static readonly int ColorId = Shader.PropertyToID("_Color");
|
||||
private static readonly int CutoffId = Shader.PropertyToID("_Cutoff");
|
||||
|
||||
private static readonly string[] HeadBoneNames =
|
||||
{
|
||||
"Bip01 Head", "Bip001 Head", "head", "Head", "Bone_Head", "HEAD"
|
||||
@@ -97,6 +111,117 @@ namespace BrewMonster
|
||||
SetLayerRecursive(child.gameObject, layer);
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// Portrait materials (clone + URP Unlit)
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the built-in URP Unlit shader by name. Returns null if the project
|
||||
/// does not include URP or the shader is stripped from the build.
|
||||
/// </summary>
|
||||
public static Shader FindUrpUnlitShader()
|
||||
{
|
||||
for (int i = 0; i < UrpUnlitShaderNames.Length; i++)
|
||||
{
|
||||
var s = Shader.Find(UrpUnlitShaderNames[i]);
|
||||
if (s != null)
|
||||
return s;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For every <see cref="Renderer"/> under <paramref name="root"/>, replaces each slot
|
||||
/// with <c>new Material(original)</c> (so shared assets are never mutated), then assigns
|
||||
/// <see cref="FindUrpUnlitShader"/> and copies main texture / tint where possible.
|
||||
/// All created instances are appended to <paramref name="createdInstances"/> for later
|
||||
/// <c>Destroy</c> (ElsePlayer clone) or for bookkeeping alongside restore (host preview).
|
||||
/// </summary>
|
||||
public static void ApplyClonedUrpUnlitMaterials(
|
||||
GameObject root,
|
||||
List<Material> createdInstances,
|
||||
System.Action<string> logWarning = null)
|
||||
{
|
||||
if (root == null || createdInstances == null) return;
|
||||
|
||||
Shader unlit = FindUrpUnlitShader();
|
||||
if (unlit == null)
|
||||
{
|
||||
logWarning?.Invoke(
|
||||
"[PortraitCaptureUtils] URP Unlit shader not found — portrait keeps cloned materials with original shaders.");
|
||||
}
|
||||
|
||||
var renderers = root.GetComponentsInChildren<Renderer>(true);
|
||||
for (int r = 0; r < renderers.Length; r++)
|
||||
{
|
||||
var renderer = renderers[r];
|
||||
var shared = renderer.sharedMaterials;
|
||||
if (shared == null || shared.Length == 0) continue;
|
||||
|
||||
var newMats = new Material[shared.Length];
|
||||
for (int i = 0; i < shared.Length; i++)
|
||||
{
|
||||
var src = shared[i];
|
||||
if (src == null)
|
||||
{
|
||||
newMats[i] = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
var clone = new Material(src);
|
||||
createdInstances.Add(clone);
|
||||
|
||||
if (unlit != null)
|
||||
ConvertMaterialToUrpUnlit(clone, src, unlit);
|
||||
|
||||
newMats[i] = clone;
|
||||
}
|
||||
|
||||
renderer.sharedMaterials = newMats;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads common albedo/texture slots from <paramref name="source"/> and reapplies them
|
||||
/// on <paramref name="target"/> after switching to URP Unlit.
|
||||
/// </summary>
|
||||
public static void ConvertMaterialToUrpUnlit(Material target, Material source, Shader urpUnlit)
|
||||
{
|
||||
if (target == null || source == null || urpUnlit == null) return;
|
||||
|
||||
Texture mainTex = null;
|
||||
if (source.HasProperty(BaseMapId))
|
||||
mainTex = source.GetTexture(BaseMapId);
|
||||
else if (source.HasProperty(MainTexId))
|
||||
mainTex = source.GetTexture(MainTexId);
|
||||
|
||||
Vector4 baseSt = new Vector4(1f, 1f, 0f, 0f);
|
||||
if (source.HasProperty(BaseMapStId))
|
||||
baseSt = source.GetVector(BaseMapStId);
|
||||
else if (source.HasProperty(MainTexStId))
|
||||
baseSt = source.GetVector(MainTexStId);
|
||||
|
||||
Color baseColor = Color.white;
|
||||
if (source.HasProperty(BaseColorId))
|
||||
baseColor = source.GetColor(BaseColorId);
|
||||
else if (source.HasProperty(ColorId))
|
||||
baseColor = source.GetColor(ColorId);
|
||||
|
||||
target.shader = urpUnlit;
|
||||
|
||||
if (mainTex != null && target.HasProperty(BaseMapId))
|
||||
target.SetTexture(BaseMapId, mainTex);
|
||||
|
||||
if (target.HasProperty(BaseMapStId))
|
||||
target.SetVector(BaseMapStId, baseSt);
|
||||
|
||||
if (target.HasProperty(BaseColorId))
|
||||
target.SetColor(BaseColorId, baseColor);
|
||||
|
||||
if (source.HasProperty(CutoffId) && target.HasProperty(CutoffId))
|
||||
target.SetFloat(CutoffId, source.GetFloat(CutoffId));
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// Camera / RenderTexture factories
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -14,7 +14,7 @@ TagManager:
|
||||
- Terrain
|
||||
- Brush
|
||||
- Water
|
||||
-
|
||||
- Portrait
|
||||
-
|
||||
-
|
||||
-
|
||||
|
||||
Reference in New Issue
Block a user