加入很多新内容,这波一块交了
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17f3455809bcc5e4b8cb2398e1ca92a4
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 225102
|
||||
packageName: Simple Cartoon UI
|
||||
packageVersion: 1.1
|
||||
assetPath: Assets/Cartoon UI/Icons/Gift Grey.png
|
||||
uploadId: 825882
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
@@ -128,10 +135,3 @@ TextureImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 225102
|
||||
packageName: Simple Cartoon UI
|
||||
packageVersion: 1.1
|
||||
assetPath: Assets/Cartoon UI/Icons/Gift Grey.png
|
||||
uploadId: 825882
|
||||
|
||||
@@ -346,6 +346,7 @@ MonoBehaviour:
|
||||
- {fileID: -665122592112833258}
|
||||
- {fileID: -5415734101822189328}
|
||||
- {fileID: 8032282833275709512}
|
||||
- {fileID: 564577042516712540}
|
||||
--- !u!114 &446725181531353334
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 3
|
||||
@@ -380,6 +381,40 @@ MonoBehaviour:
|
||||
highlightsEnd:
|
||||
m_OverrideState: 1
|
||||
m_Value: 1
|
||||
--- !u!114 &564577042516712540
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fcaf02ee66ed11d4d9c67508e0130935, type: 3}
|
||||
m_Name: GlobalDistortionVolume
|
||||
m_EditorClassIdentifier:
|
||||
active: 1
|
||||
intensity:
|
||||
m_OverrideState: 1
|
||||
m_Value: 0
|
||||
noiseStrength:
|
||||
m_OverrideState: 1
|
||||
m_Value: 0.16
|
||||
radialStrength:
|
||||
m_OverrideState: 1
|
||||
m_Value: 0.35
|
||||
noiseScale:
|
||||
m_OverrideState: 1
|
||||
m_Value: 12
|
||||
center:
|
||||
m_OverrideState: 1
|
||||
m_Value: {x: 0.5, y: 0.5}
|
||||
edgeFade:
|
||||
m_OverrideState: 1
|
||||
m_Value: 1.25
|
||||
affectSceneView:
|
||||
m_OverrideState: 1
|
||||
m_Value: 0
|
||||
--- !u!114 &757156498526246967
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 3
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8cad1f4047312243880d8f3e90872b7
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,4 +1,4 @@
|
||||
%YAML 1.1
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
@@ -12,18 +12,19 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 27e379f45b1bb88449756219caee2f89, type: 3}
|
||||
m_Name: playerData_uniqueData
|
||||
m_EditorClassIdentifier:
|
||||
player_currentEXP: 0
|
||||
player_coins: 9999999
|
||||
player_material: 0
|
||||
commonExpBottle78001: 0
|
||||
mediumExpBottle78002: 0
|
||||
superiorExpBottle78003: 0
|
||||
supremeExpBottle78004: 0
|
||||
extraordinaryExpBottle78005: 0
|
||||
player_currentEXP: 802
|
||||
player_coins: 999988
|
||||
player_material: 486
|
||||
player_currentLevel: 0
|
||||
commonExpBottle78001: 1
|
||||
mediumExpBottle78002: 2
|
||||
superiorExpBottle78003: 1
|
||||
supremeExpBottle78004: 1
|
||||
extraordinaryExpBottle78005: 3
|
||||
celestialExpBottle78006: 0
|
||||
uRankingScore: 0
|
||||
dushMaterial78021: 0
|
||||
dushMaterial78022: 0
|
||||
uRankingScore: 0.6457693
|
||||
dushMaterial78021: 1
|
||||
dushMaterial78022: 1
|
||||
dushMaterial78023: 0
|
||||
dushMaterial78024: 0
|
||||
firstLaunchDate: 2026-03-16
|
||||
|
||||
@@ -39,4 +39,4 @@ MonoBehaviour:
|
||||
- currencyType: 0
|
||||
amount: 3
|
||||
unlockRequirements: []
|
||||
purchasedCount: 1453
|
||||
purchasedCount: 1454
|
||||
|
||||
@@ -39,4 +39,4 @@ MonoBehaviour:
|
||||
- currencyType: 0
|
||||
amount: 4
|
||||
unlockRequirements: []
|
||||
purchasedCount: 2316
|
||||
purchasedCount: 2318
|
||||
|
||||
@@ -39,4 +39,4 @@ MonoBehaviour:
|
||||
- currencyType: 0
|
||||
amount: 5
|
||||
unlockRequirements: []
|
||||
purchasedCount: 400
|
||||
purchasedCount: 401
|
||||
|
||||
@@ -39,4 +39,4 @@ MonoBehaviour:
|
||||
- currencyType: 0
|
||||
amount: 6
|
||||
unlockRequirements: []
|
||||
purchasedCount: 402
|
||||
purchasedCount: 403
|
||||
|
||||
@@ -39,4 +39,4 @@ MonoBehaviour:
|
||||
- currencyType: 0
|
||||
amount: 7
|
||||
unlockRequirements: []
|
||||
purchasedCount: 300
|
||||
purchasedCount: 303
|
||||
|
||||
@@ -39,4 +39,4 @@ MonoBehaviour:
|
||||
- currencyType: 0
|
||||
amount: 1
|
||||
unlockRequirements: []
|
||||
purchasedCount: 1308
|
||||
purchasedCount: 1309
|
||||
|
||||
@@ -39,4 +39,4 @@ MonoBehaviour:
|
||||
- currencyType: 0
|
||||
amount: 2
|
||||
unlockRequirements: []
|
||||
purchasedCount: 1300
|
||||
purchasedCount: 1301
|
||||
|
||||
@@ -39,4 +39,4 @@ MonoBehaviour:
|
||||
- currencyType: 0
|
||||
amount: 1
|
||||
unlockRequirements: []
|
||||
purchasedCount: 2
|
||||
purchasedCount: 3
|
||||
|
||||
@@ -39,4 +39,4 @@ MonoBehaviour:
|
||||
- currencyType: 1
|
||||
amount: 40
|
||||
unlockRequirements: []
|
||||
purchasedCount: 0
|
||||
purchasedCount: 1
|
||||
|
||||
@@ -39,4 +39,4 @@ MonoBehaviour:
|
||||
- currencyType: 1
|
||||
amount: 60
|
||||
unlockRequirements: []
|
||||
purchasedCount: 0
|
||||
purchasedCount: 1
|
||||
|
||||
@@ -23,7 +23,7 @@ MonoBehaviour:
|
||||
isOnShelf: 1
|
||||
canbepurchased: 1
|
||||
isHot: 0
|
||||
user_has_read: 0
|
||||
user_has_read: 1
|
||||
itemType: 3
|
||||
associatedAllyHero: {fileID: 0}
|
||||
associatedSong: {fileID: 0}
|
||||
|
||||
@@ -39,4 +39,4 @@ MonoBehaviour:
|
||||
- currencyType: 1
|
||||
amount: 1000
|
||||
unlockRequirements: []
|
||||
purchasedCount: 0
|
||||
purchasedCount: 1
|
||||
|
||||
@@ -16,42 +16,78 @@ MonoBehaviour:
|
||||
level: 20
|
||||
tierNameConfig: {fileID: 11400000, guid: dd40d174875037e439647e54cf81eab1, type: 2}
|
||||
maxHp:
|
||||
basicGain: 0.086
|
||||
cultivationInterval: 0.005
|
||||
basicGain: 0.1
|
||||
cultivationInterval: 0.045
|
||||
attack:
|
||||
basicGain: 0
|
||||
cultivationInterval: 0.005
|
||||
basicGain: 0.1
|
||||
cultivationInterval: 0.045
|
||||
maxMana:
|
||||
basicGain: 0
|
||||
cultivationInterval: 0.005
|
||||
basicGain: 0.1
|
||||
cultivationInterval: 0.045
|
||||
damageResistance:
|
||||
basicGain: 0
|
||||
cultivationInterval: 0.005
|
||||
basicGain: 0.1
|
||||
cultivationInterval: 0.045
|
||||
scoreEfficiency:
|
||||
basicGain: 0.082
|
||||
cultivationInterval: 0.005
|
||||
basicGain: 0.1
|
||||
cultivationInterval: 0.045
|
||||
specialEffects:
|
||||
- effectType: 4
|
||||
value: 0.03
|
||||
- effectType: 0
|
||||
value: 999999
|
||||
- effectType: 1
|
||||
value: 999999
|
||||
- effectType: 2
|
||||
value: 999999
|
||||
- effectType: 3
|
||||
value: 0.02
|
||||
value: 0.9
|
||||
- effectType: 4
|
||||
value: 0.9
|
||||
- effectType: 5
|
||||
value: 999999
|
||||
- effectType: 6
|
||||
value: 999999
|
||||
- effectType: 7
|
||||
value: -9
|
||||
- effectType: 8
|
||||
value: 0
|
||||
value: -9
|
||||
enableTypeSameEffects: 0
|
||||
typeSameEffects:
|
||||
- effectType: 0
|
||||
value: 0.05
|
||||
value: 1
|
||||
- effectType: 4
|
||||
value: 0.05
|
||||
value: 1
|
||||
- effectType: 2
|
||||
value: 1
|
||||
- effectType: 3
|
||||
value: 1
|
||||
- effectType: 4
|
||||
value: 1
|
||||
- effectType: 5
|
||||
value: 1
|
||||
- effectType: 6
|
||||
value: 1
|
||||
illusionEffects:
|
||||
- effectType: 0
|
||||
value: 60
|
||||
- effectType: 3
|
||||
value: 0.03
|
||||
- effectType: 4
|
||||
value: 0.05
|
||||
value: 999999
|
||||
- effectType: 1
|
||||
value: 999999
|
||||
- effectType: 2
|
||||
value: 999999
|
||||
maxLevelEffects:
|
||||
- effectType: 0
|
||||
value: 0.01
|
||||
value: 999999
|
||||
- effectType: 1
|
||||
value: 999999
|
||||
- effectType: 2
|
||||
value: 999999
|
||||
- effectType: 3
|
||||
value: 0.9
|
||||
- effectType: 4
|
||||
value: 0.9
|
||||
- effectType: 5
|
||||
value: 999999
|
||||
- effectType: 6
|
||||
value: 999999
|
||||
- effectType: 7
|
||||
value: -999999
|
||||
sa_skillID: 30011005
|
||||
ia_skillID: 30011006
|
||||
|
||||
@@ -1451,7 +1451,7 @@ GameObject:
|
||||
m_Component:
|
||||
- component: {fileID: 159785774}
|
||||
- component: {fileID: 159785776}
|
||||
- component: {fileID: 159785775}
|
||||
- component: {fileID: 159785777}
|
||||
m_Layer: 5
|
||||
m_Name: selected_song
|
||||
m_TagString: Untagged
|
||||
@@ -1475,10 +1475,18 @@ 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: 842, y: 266.1}
|
||||
m_AnchoredPosition: {x: 848.8, y: 266.1}
|
||||
m_SizeDelta: {x: 200, y: 50}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &159785775
|
||||
--- !u!222 &159785776
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 159785773}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &159785777
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
@@ -1487,7 +1495,7 @@ MonoBehaviour:
|
||||
m_GameObject: {fileID: 159785773}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
|
||||
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
@@ -1498,85 +1506,20 @@ MonoBehaviour:
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_text: SELECTED SONG
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: c95ab61f13e39254e8e3cbf4059d88c5, type: 2}
|
||||
m_sharedMaterial: {fileID: 4492750392876140565, guid: c95ab61f13e39254e8e3cbf4059d88c5, type: 2}
|
||||
m_fontSharedMaterials: []
|
||||
m_fontMaterial: {fileID: 0}
|
||||
m_fontMaterials: []
|
||||
m_fontColor32:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontColor: {r: 1, g: 1, b: 1, 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: 18
|
||||
m_fontSizeBase: 18
|
||||
m_fontWeight: 400
|
||||
m_enableAutoSizing: 0
|
||||
m_fontSizeMin: 18
|
||||
m_fontSizeMax: 72
|
||||
m_fontStyle: 1
|
||||
m_HorizontalAlignment: 4
|
||||
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: 1
|
||||
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: -304.58203, 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!222 &159785776
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 159785773}
|
||||
m_CullTransparentMesh: 1
|
||||
m_FontData:
|
||||
m_Font: {fileID: 12800000, guid: 8b8373b0af11dca46b89be60dbe469f8, type: 3}
|
||||
m_FontSize: 14
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 5
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: S E L E C T E D S O N G
|
||||
--- !u!1 &167571322
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -20112,7 +20055,7 @@ 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: 800.98553, y: 297.84952}
|
||||
m_AnchoredPosition: {x: 795.1, y: 297.84952}
|
||||
m_SizeDelta: {x: 318.019, y: 50}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &2004358155
|
||||
|
||||
+696
-61
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &-3594275912957905754
|
||||
--- !u!114 &-4028999061945789234
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
@@ -9,22 +9,31 @@ MonoBehaviour:
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: ccf1aba9553839d41ae37dd52e9ebcce, type: 3}
|
||||
m_Name: MotionBlur
|
||||
m_Script: {fileID: 11500000, guid: 54a30677f5d2e4548881a79f4c3e3972, type: 3}
|
||||
m_Name: GlobalGlitchVolume
|
||||
m_EditorClassIdentifier:
|
||||
active: 0
|
||||
mode:
|
||||
m_OverrideState: 1
|
||||
m_Value: 1
|
||||
quality:
|
||||
m_OverrideState: 1
|
||||
m_Value: 1
|
||||
active: 1
|
||||
intensity:
|
||||
m_OverrideState: 1
|
||||
m_Value: 0.476
|
||||
clamp:
|
||||
m_Value: 0
|
||||
blockStrength:
|
||||
m_OverrideState: 1
|
||||
m_Value: 0.118
|
||||
m_Value: 0.297
|
||||
colorSplit:
|
||||
m_OverrideState: 1
|
||||
m_Value: 0.0128
|
||||
jitterAmount:
|
||||
m_OverrideState: 1
|
||||
m_Value: 1
|
||||
stripFrequency:
|
||||
m_OverrideState: 1
|
||||
m_Value: 213
|
||||
scanlineStrength:
|
||||
m_OverrideState: 1
|
||||
m_Value: 0.527
|
||||
affectSceneView:
|
||||
m_OverrideState: 1
|
||||
m_Value: 0
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -38,4 +47,118 @@ MonoBehaviour:
|
||||
m_Name: gpGV
|
||||
m_EditorClassIdentifier:
|
||||
components:
|
||||
- {fileID: -3594275912957905754}
|
||||
- {fileID: 2046802184354103511}
|
||||
- {fileID: 2590790448571127267}
|
||||
- {fileID: -4028999061945789234}
|
||||
- {fileID: 1487594879138804974}
|
||||
- {fileID: 9136543105356401684}
|
||||
- {fileID: 0}
|
||||
--- !u!114 &1487594879138804974
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 29fa0085f50d5e54f8144f766051a691, type: 3}
|
||||
m_Name: FilmGrain
|
||||
m_EditorClassIdentifier:
|
||||
active: 1
|
||||
type:
|
||||
m_OverrideState: 1
|
||||
m_Value: 0
|
||||
intensity:
|
||||
m_OverrideState: 1
|
||||
m_Value: 0.547
|
||||
response:
|
||||
m_OverrideState: 1
|
||||
m_Value: 0
|
||||
texture:
|
||||
m_OverrideState: 1
|
||||
m_Value: {fileID: 0}
|
||||
--- !u!114 &2046802184354103511
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fcaf02ee66ed11d4d9c67508e0130935, type: 3}
|
||||
m_Name: GlobalDistortionVolume
|
||||
m_EditorClassIdentifier:
|
||||
active: 1
|
||||
intensity:
|
||||
m_OverrideState: 1
|
||||
m_Value: 0
|
||||
noiseStrength:
|
||||
m_OverrideState: 1
|
||||
m_Value: 1
|
||||
radialStrength:
|
||||
m_OverrideState: 1
|
||||
m_Value: 2
|
||||
noiseScale:
|
||||
m_OverrideState: 1
|
||||
m_Value: 14.5
|
||||
center:
|
||||
m_OverrideState: 1
|
||||
m_Value: {x: -11.47, y: 0.5}
|
||||
edgeFade:
|
||||
m_OverrideState: 1
|
||||
m_Value: 3
|
||||
affectSceneView:
|
||||
m_OverrideState: 1
|
||||
m_Value: 0
|
||||
--- !u!114 &2590790448571127267
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c5e1dc532bcb41949b58bc4f2abfbb7e, type: 3}
|
||||
m_Name: LensDistortion
|
||||
m_EditorClassIdentifier:
|
||||
active: 1
|
||||
intensity:
|
||||
m_OverrideState: 0
|
||||
m_Value: 0
|
||||
xMultiplier:
|
||||
m_OverrideState: 0
|
||||
m_Value: 0.532
|
||||
yMultiplier:
|
||||
m_OverrideState: 0
|
||||
m_Value: 1
|
||||
center:
|
||||
m_OverrideState: 0
|
||||
m_Value: {x: 0.5, y: 0.5}
|
||||
scale:
|
||||
m_OverrideState: 0
|
||||
m_Value: 0.98
|
||||
--- !u!114 &9136543105356401684
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 2b5b0fcb28cb9254bbcd2a498e0fe228, type: 3}
|
||||
m_Name: GlobalAfterimageVolume
|
||||
m_EditorClassIdentifier:
|
||||
active: 1
|
||||
opacity:
|
||||
m_OverrideState: 1
|
||||
m_Value: 0
|
||||
scale:
|
||||
m_OverrideState: 1
|
||||
m_Value: 1.05
|
||||
affectSceneView:
|
||||
m_OverrideState: 1
|
||||
m_Value: 0
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &-7968524894476178354
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: d71f5b59ebb9a7640b177e16adf3d6c7, type: 3}
|
||||
m_Name: Global Distortion Renderer Feature
|
||||
m_EditorClassIdentifier:
|
||||
m_Active: 1
|
||||
renderPassEvent: 600
|
||||
--- !u!114 &-82031990492403773
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 84ae0996c2f9f6c43a0d5b735af7f121, type: 3}
|
||||
m_Name: Global Glitch Renderer Feature
|
||||
m_EditorClassIdentifier:
|
||||
m_Active: 1
|
||||
renderPassEvent: 600
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -24,8 +52,12 @@ MonoBehaviour:
|
||||
probeSamplingDebugMesh: {fileID: 0}
|
||||
probeSamplingDebugTexture: {fileID: 0}
|
||||
probeVolumeBlendStatesCS: {fileID: 0}
|
||||
m_RendererFeatures: []
|
||||
m_RendererFeatureMap:
|
||||
m_RendererFeatures:
|
||||
- {fileID: -7968524894476178354}
|
||||
- {fileID: -82031990492403773}
|
||||
- {fileID: 8810499459484542277}
|
||||
- {fileID: 4089674193680255197}
|
||||
m_RendererFeatureMap: 4eece3d8d31c6a91c3677bda5690dcfe45e55810942e457addc864d90271c138
|
||||
m_UseNativeRenderPass: 0
|
||||
m_LayerMask:
|
||||
serializedVersion: 2
|
||||
@@ -56,3 +88,31 @@ MonoBehaviour:
|
||||
m_PostProcessData: {fileID: 11400000, guid: 41439944d30ece34e96484bdb6645b55, type: 2}
|
||||
m_DefaultMaterialType: 0
|
||||
m_DefaultCustomMaterial: {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2}
|
||||
--- !u!114 &4089674193680255197
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: e30db065f184af241b78ce51edc50d96, type: 3}
|
||||
m_Name: Global Monochrome Renderer Feature
|
||||
m_EditorClassIdentifier:
|
||||
m_Active: 1
|
||||
renderPassEvent: 600
|
||||
--- !u!114 &8810499459484542277
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: a28c239b9c2736e489a75bd286167cb9, type: 3}
|
||||
m_Name: Global Afterimage Renderer Feature
|
||||
m_EditorClassIdentifier:
|
||||
m_Active: 1
|
||||
renderPassEvent: 600
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4cfb6d280c0131d45b93db3841bd7acf
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,42 @@
|
||||
Shader "Hidden/Bansonic/GlobalAfterimage"
|
||||
{
|
||||
SubShader
|
||||
{
|
||||
Tags { "RenderPipeline" = "UniversalPipeline" }
|
||||
ZWrite Off
|
||||
Cull Off
|
||||
ZTest Always
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "GlobalAfterimage"
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex Vert
|
||||
#pragma fragment Frag
|
||||
#pragma target 4.5
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
|
||||
|
||||
float _AfterimageOpacity;
|
||||
float _AfterimageScale;
|
||||
TEXTURE2D(_SnapshotTex);
|
||||
SAMPLER(sampler_SnapshotTex);
|
||||
|
||||
half4 Frag(Varyings input) : SV_Target
|
||||
{
|
||||
float2 uv = input.texcoord;
|
||||
half4 baseColor = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv);
|
||||
|
||||
float safeScale = max(_AfterimageScale, 1.0);
|
||||
float2 scaledUv = (uv - 0.5) / safeScale + 0.5;
|
||||
float inside = step(0.0, scaledUv.x) * step(0.0, scaledUv.y) * step(scaledUv.x, 1.0) * step(scaledUv.y, 1.0);
|
||||
half4 snapshot = SAMPLE_TEXTURE2D(_SnapshotTex, sampler_SnapshotTex, saturate(scaledUv));
|
||||
float alpha = saturate(_AfterimageOpacity) * inside;
|
||||
return lerp(baseColor, snapshot, alpha);
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 08e184084ff672d4f8e6b649d27dc10d
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,52 @@
|
||||
Shader "Hidden/Bansonic/GlobalDistortion"
|
||||
{
|
||||
SubShader
|
||||
{
|
||||
Tags { "RenderPipeline" = "UniversalPipeline" }
|
||||
ZWrite Off
|
||||
Cull Off
|
||||
ZTest Always
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "GlobalDistortion"
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex Vert
|
||||
#pragma fragment Frag
|
||||
#pragma target 4.5
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
|
||||
|
||||
float _DistortionIntensity;
|
||||
float _NoiseStrength;
|
||||
float _RadialStrength;
|
||||
float _NoiseScale;
|
||||
float2 _DistortionCenter;
|
||||
float _EdgeFade;
|
||||
|
||||
half4 Frag(Varyings input) : SV_Target
|
||||
{
|
||||
float2 uv = input.texcoord;
|
||||
float2 centered = uv - _DistortionCenter;
|
||||
float distanceFromCenter = length(centered);
|
||||
float2 direction = distanceFromCenter > 0.0001 ? centered / distanceFromCenter : float2(0.0, 0.0);
|
||||
float normalizedDistance = saturate(distanceFromCenter * 1.41421356);
|
||||
float edgeMask = saturate(1.0 - pow(normalizedDistance, _EdgeFade));
|
||||
|
||||
float t = _Time.y;
|
||||
float noiseA = sin((uv.x + t * 0.73) * _NoiseScale) * cos((uv.y - t * 1.13) * (_NoiseScale * 0.87));
|
||||
float noiseB = cos((uv.x * 1.31 - t * 0.41) * (_NoiseScale * 0.63)) * sin((uv.y * 1.11 + t * 0.52) * (_NoiseScale * 1.21));
|
||||
|
||||
float2 radialOffset = direction * edgeMask * (_RadialStrength * 0.03) * _DistortionIntensity;
|
||||
float2 noiseOffset = float2(noiseA, noiseB) * (_NoiseStrength * 0.015) * _DistortionIntensity;
|
||||
float2 sampleUv = uv + radialOffset + noiseOffset;
|
||||
sampleUv = clamp(sampleUv, 0.0, 1.0);
|
||||
|
||||
return SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, sampleUv);
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc80b7dbbe782854c9f0c6ae053bfc70
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,71 @@
|
||||
Shader "Hidden/Bansonic/GlobalGlitch"
|
||||
{
|
||||
SubShader
|
||||
{
|
||||
Tags { "RenderPipeline" = "UniversalPipeline" }
|
||||
ZWrite Off
|
||||
Cull Off
|
||||
ZTest Always
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "GlobalGlitch"
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex Vert
|
||||
#pragma fragment Frag
|
||||
#pragma target 4.5
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
|
||||
|
||||
float _GlitchIntensity;
|
||||
float _BlockStrength;
|
||||
float _ColorSplit;
|
||||
float _JitterAmount;
|
||||
float _StripFrequency;
|
||||
float _ScanlineStrength;
|
||||
|
||||
float Hash(float2 p)
|
||||
{
|
||||
p = frac(p * float2(123.34, 345.45));
|
||||
p += dot(p, p + 34.345);
|
||||
return frac(p.x * p.y);
|
||||
}
|
||||
|
||||
half4 Frag(Varyings input) : SV_Target
|
||||
{
|
||||
float2 uv = input.texcoord;
|
||||
float timeSlice = floor(_Time.y * 24.0);
|
||||
float stripIndex = floor(uv.y * _StripFrequency);
|
||||
float stripNoise = Hash(float2(stripIndex, timeSlice));
|
||||
float blockMask = step(0.58, stripNoise);
|
||||
|
||||
float blockShift = (stripNoise - 0.5) * _BlockStrength * 0.12 * _GlitchIntensity * blockMask;
|
||||
float lineJitter = sin((uv.y + _Time.y * 14.0) * 420.0) * _JitterAmount * 0.003 * _GlitchIntensity;
|
||||
float combinedShift = blockShift + lineJitter;
|
||||
|
||||
float2 baseUv = uv;
|
||||
baseUv.x = clamp(baseUv.x + combinedShift, 0.0, 1.0);
|
||||
|
||||
float colorSplit = _ColorSplit * _GlitchIntensity;
|
||||
float2 redUv = float2(clamp(baseUv.x + colorSplit, 0.0, 1.0), baseUv.y);
|
||||
float2 greenUv = baseUv;
|
||||
float2 blueUv = float2(clamp(baseUv.x - colorSplit, 0.0, 1.0), baseUv.y);
|
||||
|
||||
half red = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, redUv).r;
|
||||
half green = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, greenUv).g;
|
||||
half blue = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, blueUv).b;
|
||||
|
||||
half4 color = half4(red, green, blue, 1.0);
|
||||
|
||||
float scan = sin(uv.y * _ScreenParams.y * 1.15 + _Time.y * 12.0) * 0.5 + 0.5;
|
||||
float scanMask = lerp(1.0, 1.0 - scan * 0.35, _ScanlineStrength * _GlitchIntensity);
|
||||
color.rgb *= scanMask;
|
||||
|
||||
return color;
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32a0932fed2df844c8796df10247873b
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
Shader "Hidden/Bansonic/GlobalMonochrome"
|
||||
{
|
||||
SubShader
|
||||
{
|
||||
Tags { "RenderPipeline" = "UniversalPipeline" }
|
||||
ZWrite Off
|
||||
Cull Off
|
||||
ZTest Always
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "GlobalMonochrome"
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex Vert
|
||||
#pragma fragment Frag
|
||||
#pragma target 4.5
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
|
||||
|
||||
float _MonochromeIntensity;
|
||||
|
||||
half4 Frag(Varyings input) : SV_Target
|
||||
{
|
||||
float2 uv = input.texcoord;
|
||||
half4 color = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv);
|
||||
half luminance = dot(color.rgb, half3(0.299h, 0.587h, 0.114h));
|
||||
half3 grayscale = luminance.xxx;
|
||||
color.rgb = lerp(color.rgb, grayscale, saturate(_MonochromeIntensity));
|
||||
return color;
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: adee8c544438ff3498bececba27c3c76
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -29,8 +29,8 @@ Transform:
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0.1, y: 6.49, z: 0.1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_LocalScale: {x: 0.5, y: 0.5, z: 0.5}
|
||||
m_ConstrainProportionsScale: 1
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
"length": 0.0,
|
||||
"barNumber": 3,
|
||||
"yPos": -268.5,
|
||||
"noteFunction": "",
|
||||
"noteFunction": "CameraWaveFX",
|
||||
"noteid": "7ae79d1c-43ff-4115-b804-486befebef2c",
|
||||
"newLocation": {
|
||||
"bar": 3,
|
||||
@@ -128,7 +128,7 @@
|
||||
"length": 0.0,
|
||||
"barNumber": 5,
|
||||
"yPos": -268.5,
|
||||
"noteFunction": "",
|
||||
"noteFunction": "CameraScaleEvent",
|
||||
"noteid": "ca34a006-3d0a-46da-b853-900d9fd32929",
|
||||
"newLocation": {
|
||||
"bar": 5,
|
||||
@@ -145,7 +145,7 @@
|
||||
"length": 0.0,
|
||||
"barNumber": 5,
|
||||
"yPos": 201.375,
|
||||
"noteFunction": "",
|
||||
"noteFunction": "CameraShakeEvent",
|
||||
"noteid": "1ed274b6-3065-46df-b8ba-229a8ca90d81",
|
||||
"newLocation": {
|
||||
"bar": 5,
|
||||
@@ -162,7 +162,7 @@
|
||||
"length": 0.0,
|
||||
"barNumber": 7,
|
||||
"yPos": -268.5,
|
||||
"noteFunction": "",
|
||||
"noteFunction": "FlashBlinkEvent",
|
||||
"noteid": "a62ce93e-8977-4ef7-874e-d2aafa2e0b46",
|
||||
"newLocation": {
|
||||
"bar": 7,
|
||||
@@ -179,7 +179,7 @@
|
||||
"length": 0.0,
|
||||
"barNumber": 7,
|
||||
"yPos": 201.375,
|
||||
"noteFunction": "",
|
||||
"noteFunction": "CameraGlitchFX",
|
||||
"noteid": "7ab2727f-3234-4823-9053-9d803186728d",
|
||||
"newLocation": {
|
||||
"bar": 7,
|
||||
@@ -196,7 +196,7 @@
|
||||
"length": 0.6818181818181818,
|
||||
"barNumber": 9,
|
||||
"yPos": -268.5,
|
||||
"noteFunction": "",
|
||||
"noteFunction": "CameraGlitchFX",
|
||||
"noteid": "6ca6c017-f1a1-45ce-b222-38174fbacaed",
|
||||
"newLocation": {
|
||||
"bar": 9,
|
||||
@@ -213,7 +213,7 @@
|
||||
"length": 0.6818181818181818,
|
||||
"barNumber": 10,
|
||||
"yPos": -268.5,
|
||||
"noteFunction": "",
|
||||
"noteFunction": "ScreenshotScale",
|
||||
"noteid": "f3b85cc8-4287-4180-b831-97eef996c938",
|
||||
"newLocation": {
|
||||
"bar": 10,
|
||||
@@ -230,7 +230,7 @@
|
||||
"length": 0.0,
|
||||
"barNumber": 10,
|
||||
"yPos": 0.0,
|
||||
"noteFunction": "",
|
||||
"noteFunction": "CameraMonochromeFX",
|
||||
"noteid": "b4a846b0-e857-450e-99b9-a092c9f33be8",
|
||||
"newLocation": {
|
||||
"bar": 10,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
%YAML 1.1
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
@@ -92,7 +92,7 @@ MonoBehaviour:
|
||||
- tierName: "\u6F84\u660E\u5883"
|
||||
equipmentSprite: {fileID: 21300000, guid: 814f39e3a1e204c4586f75b514a06601, type: 3}
|
||||
tierDescription:
|
||||
- tierName: "\u5FC3\u517B\u5F52\u4E00"
|
||||
- tierName: "\u5FC3\u517B\u5F52\u4E00\u5492"
|
||||
equipmentSprite: {fileID: 21300000, guid: 4ce68bd00ecc6f64baefd01ce27f33f9, type: 3}
|
||||
tierDescription:
|
||||
- tierName: "\u68A6\u9192\xB7\u65E0\u5C18\u771F\u5883"
|
||||
|
||||
@@ -139,19 +139,27 @@ public class chooseSkillPrefab : MonoBehaviour, IPointerEnterHandler, IPointerEx
|
||||
detailPinnedByButton = pinnedByButton;
|
||||
detailOpenedFrame = Time.frameCount;
|
||||
|
||||
Transform parent = transform.root != null ? transform.root : transform;
|
||||
Transform parent = ResolveDetailParent();
|
||||
spawnedDetail = Instantiate(sskilldetialPrefab, parent);
|
||||
spawnedDetail.transform.SetAsLastSibling();
|
||||
|
||||
RectTransform selfRect = transform as RectTransform;
|
||||
RectTransform detailRect = spawnedDetail.transform as RectTransform;
|
||||
RectTransform parentRect = parent as RectTransform;
|
||||
if (selfRect != null && detailRect != null && parentRect != null)
|
||||
{
|
||||
Canvas canvas = parent.GetComponentInParent<Canvas>();
|
||||
Camera eventCamera = null;
|
||||
if (canvas != null && canvas.renderMode != RenderMode.ScreenSpaceOverlay)
|
||||
{
|
||||
eventCamera = canvas.worldCamera;
|
||||
}
|
||||
|
||||
Vector3 worldPoint = selfRect.TransformPoint(new Vector3(selfRect.rect.xMax, selfRect.rect.center.y, 0f));
|
||||
RectTransformUtility.ScreenPointToLocalPointInRectangle(
|
||||
parentRect,
|
||||
RectTransformUtility.WorldToScreenPoint(null, worldPoint),
|
||||
null,
|
||||
RectTransformUtility.WorldToScreenPoint(eventCamera, worldPoint),
|
||||
eventCamera,
|
||||
out Vector2 localPoint);
|
||||
detailRect.anchoredPosition = localPoint + detailPrefabOffset;
|
||||
}
|
||||
@@ -163,6 +171,22 @@ public class chooseSkillPrefab : MonoBehaviour, IPointerEnterHandler, IPointerEx
|
||||
}
|
||||
}
|
||||
|
||||
private Transform ResolveDetailParent()
|
||||
{
|
||||
Canvas canvas = GetComponentInParent<Canvas>();
|
||||
if (canvas != null && canvas.rootCanvas != null)
|
||||
{
|
||||
return canvas.rootCanvas.transform;
|
||||
}
|
||||
|
||||
if (transform.root != null)
|
||||
{
|
||||
return transform.root;
|
||||
}
|
||||
|
||||
return transform;
|
||||
}
|
||||
|
||||
private bool IsPointerInside(Vector2 screenPoint)
|
||||
{
|
||||
if (IsScreenPointInside(transform as RectTransform, screenPoint))
|
||||
|
||||
@@ -195,6 +195,11 @@ public class equipSmelt : MonoBehaviour
|
||||
SavePersistentState();
|
||||
}
|
||||
|
||||
public void RefreshPlayerSkillAdjustedUi()
|
||||
{
|
||||
RefreshAllUi();
|
||||
}
|
||||
|
||||
public void SetDragPreviewVisible(bool visible)
|
||||
{
|
||||
if (dragObj == null)
|
||||
@@ -382,6 +387,7 @@ public class equipSmelt : MonoBehaviour
|
||||
return;
|
||||
}
|
||||
|
||||
int grantedFragments = Mathf.Max(0, pendingDirectFragmentsState);
|
||||
if (pendingDirectFragmentsState > 0)
|
||||
{
|
||||
PlayerEconomyLedger.EnsureInstance().AddMaterial(pendingDirectFragmentsState);
|
||||
@@ -398,6 +404,11 @@ public class equipSmelt : MonoBehaviour
|
||||
SavePersistentState();
|
||||
RefreshAllSmeltPools();
|
||||
RefreshAllEquipBags();
|
||||
|
||||
if (grantedFragments > 0)
|
||||
{
|
||||
gItemGet.display(gItemGet.Create("记忆碎片", ResolveMemoryFragmentSprite(), grantedFragments, ItemRarity.Uncommon));
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleGetRewardClicked()
|
||||
@@ -530,10 +541,30 @@ public class equipSmelt : MonoBehaviour
|
||||
ReinstateRewardEquipment(generated);
|
||||
storedSmeltEnergyState = Mathf.Max(0, storedSmeltEnergyState - requiredAmount);
|
||||
SavePersistentState();
|
||||
gItemGet.display(gItemGet.FromEquipment(generated, 1));
|
||||
RefreshAllUi();
|
||||
RefreshAllEquipBags();
|
||||
}
|
||||
|
||||
private static Sprite ResolveMemoryFragmentSprite()
|
||||
{
|
||||
equipSmelt[] instances = FindObjectsByType<equipSmelt>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
||||
if (instances == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < instances.Length; i++)
|
||||
{
|
||||
if (instances[i] != null && instances[i].memoryFragment != null)
|
||||
{
|
||||
return instances[i].memoryFragment;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void HandleRewardSelectorClosed()
|
||||
{
|
||||
activeCtasInstance = null;
|
||||
@@ -959,12 +990,14 @@ public class equipSmelt : MonoBehaviour
|
||||
|
||||
private int GetQuickFinishCost()
|
||||
{
|
||||
return ssrso != null ? Mathf.Max(0, ssrso.quickFinishCost) : 0;
|
||||
int baseCost = ssrso != null ? Mathf.Max(0, ssrso.quickFinishCost) : 0;
|
||||
return PlayerSkillService.ModifySmeltCoinCost(baseCost);
|
||||
}
|
||||
|
||||
private int GetStartSmeltCost()
|
||||
{
|
||||
return ssrso != null ? Mathf.Max(0, ssrso.startSmeltCost) : 0;
|
||||
int baseCost = ssrso != null ? Mathf.Max(0, ssrso.startSmeltCost) : 0;
|
||||
return PlayerSkillService.ModifySmeltCoinCost(baseCost);
|
||||
}
|
||||
|
||||
private smeltStageRewardSO.SmeltStageRewardRequirement GetSelectedRewardRequirement()
|
||||
|
||||
@@ -120,6 +120,10 @@ public class equipmentRandomTestButton : MonoBehaviour
|
||||
GenerateSpecialEffects(generated);
|
||||
GenerateIllusionEffects(generated);
|
||||
lastGeneratedEquipment = PersistGeneratedEquipment(generated);
|
||||
if (lastGeneratedEquipment != null)
|
||||
{
|
||||
gItemGet.display(gItemGet.FromEquipment(lastGeneratedEquipment, 1));
|
||||
}
|
||||
BuildSummary(generated);
|
||||
RefreshEquipmentList();
|
||||
MarkHostDirty();
|
||||
|
||||
@@ -41,4 +41,25 @@ public class esDesPrefab : MonoBehaviour
|
||||
skill_story.gameObject.SetActive(!string.IsNullOrWhiteSpace(storyText));
|
||||
}
|
||||
}
|
||||
|
||||
public void Bind(string displayName, Sprite icon, string description, string story)
|
||||
{
|
||||
if (skillProfile != null)
|
||||
{
|
||||
skillProfile.sprite = icon;
|
||||
skillProfile.enabled = icon != null;
|
||||
}
|
||||
|
||||
if (skillName != null)
|
||||
skillName.text = displayName ?? string.Empty;
|
||||
|
||||
if (skillDescription != null)
|
||||
skillDescription.text = description ?? string.Empty;
|
||||
|
||||
if (skill_story != null)
|
||||
{
|
||||
skill_story.text = story ?? string.Empty;
|
||||
skill_story.gameObject.SetActive(!string.IsNullOrWhiteSpace(skill_story.text));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ RectTransform:
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 124.06795, y: -57}
|
||||
m_AnchoredPosition: {x: 124.06795, y: -80}
|
||||
m_SizeDelta: {x: 208.1359, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &2049021961984502307
|
||||
@@ -68,7 +68,7 @@ MonoBehaviour:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 12800000, guid: bd4be44636ad6c24a9b117a7108a75e9, type: 3}
|
||||
m_FontSize: 10
|
||||
m_FontSize: 14
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 1
|
||||
@@ -211,7 +211,7 @@ MonoBehaviour:
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0, g: 0, b: 0, a: 0.88235295}
|
||||
m_Color: {r: 0, g: 0, b: 0, a: 0.9411765}
|
||||
m_RaycastTarget: 0
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 0
|
||||
@@ -244,7 +244,7 @@ MonoBehaviour:
|
||||
m_Left: 20
|
||||
m_Right: 0
|
||||
m_Top: 57
|
||||
m_Bottom: 10
|
||||
m_Bottom: 16
|
||||
m_ChildAlignment: 0
|
||||
m_Spacing: 0
|
||||
m_ChildForceExpandWidth: 1
|
||||
@@ -379,7 +379,7 @@ RectTransform:
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 124.06795, y: -57}
|
||||
m_AnchoredPosition: {x: 124.06795, y: -93}
|
||||
m_SizeDelta: {x: 208.1359, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &2792857840598114499
|
||||
@@ -473,7 +473,7 @@ RectTransform:
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 124.06795, y: -57}
|
||||
m_AnchoredPosition: {x: 124.06795, y: -65}
|
||||
m_SizeDelta: {x: 208.1359, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &1487207466561665800
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bansonic
|
||||
{
|
||||
public static class gItemGet
|
||||
{
|
||||
private const string PrefabResourcePath = "itemGet";
|
||||
private static readonly Color FallbackColor = Color.white;
|
||||
|
||||
private static GameObject currentInstance;
|
||||
private static itemGetPrefab currentController;
|
||||
private static ItemRarityColorConfigSO cachedRarityConfig;
|
||||
|
||||
public struct ItemEntry
|
||||
{
|
||||
public Sprite icon;
|
||||
public string displayName;
|
||||
public int amount;
|
||||
public ItemRarity rarity;
|
||||
public bool useCustomColor;
|
||||
public Color customColor;
|
||||
}
|
||||
|
||||
public static void display(params ItemEntry[] items)
|
||||
{
|
||||
display((IEnumerable<ItemEntry>)items);
|
||||
}
|
||||
|
||||
public static void display(IEnumerable<ItemEntry> items)
|
||||
{
|
||||
EnsureInstance();
|
||||
if (currentController == null)
|
||||
{
|
||||
Debug.LogWarning("[gItemGet] itemGet prefab missing itemGetPrefab component.");
|
||||
return;
|
||||
}
|
||||
|
||||
currentController.ClearItems();
|
||||
|
||||
if (items == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (ItemEntry entry in items)
|
||||
{
|
||||
get_item_prefab item = currentController.AddItem();
|
||||
if (item == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Color qualityColor = entry.useCustomColor
|
||||
? entry.customColor
|
||||
: ResolveRarityColor(entry.rarity);
|
||||
|
||||
item.Bind(entry.icon, entry.displayName, entry.amount, qualityColor);
|
||||
}
|
||||
}
|
||||
|
||||
public static ItemEntry Create(string displayName, Sprite icon, int amount = 1, ItemRarity rarity = ItemRarity.None)
|
||||
{
|
||||
return new ItemEntry
|
||||
{
|
||||
displayName = displayName,
|
||||
icon = icon,
|
||||
amount = Mathf.Max(1, amount),
|
||||
rarity = rarity,
|
||||
useCustomColor = false,
|
||||
customColor = default
|
||||
};
|
||||
}
|
||||
|
||||
public static ItemEntry Create(string displayName, Sprite icon, int amount, Color qualityColor)
|
||||
{
|
||||
return new ItemEntry
|
||||
{
|
||||
displayName = displayName,
|
||||
icon = icon,
|
||||
amount = Mathf.Max(1, amount),
|
||||
rarity = ItemRarity.None,
|
||||
useCustomColor = true,
|
||||
customColor = qualityColor
|
||||
};
|
||||
}
|
||||
|
||||
public static ItemEntry FromStoreItem(storeItemSO item, int amount = 1)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
return Create("未知物品", null, amount, ItemRarity.None);
|
||||
}
|
||||
|
||||
return Create(item.itemName, item.itemIcon, amount, item.itemRarity);
|
||||
}
|
||||
|
||||
public static ItemEntry FromExpBottle(expBottlesSO item, int amount = 1)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
return Create("未知经验瓶", null, amount, ItemRarity.None);
|
||||
}
|
||||
|
||||
return Create(item.expBottleName, item.expBottleSprite, amount, item.itemRarity);
|
||||
}
|
||||
|
||||
public static ItemEntry FromGrowthMaterial(growthMaterialSO item, int amount = 1)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
return Create("未知培养材料", null, amount, ItemRarity.None);
|
||||
}
|
||||
|
||||
return Create(item.growthMaterialName, item.growthMaterialSprite, amount, item.itemRarity);
|
||||
}
|
||||
|
||||
public static ItemEntry FromEquipmentConsumable(equipmentConsumableSO item, int amount = 1)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
return Create("未知装备材料", null, amount, ItemRarity.None);
|
||||
}
|
||||
|
||||
return Create(item.consumableName, item.consumableSprite, amount, item.itemRarity);
|
||||
}
|
||||
|
||||
public static ItemEntry FromEquipment(equipmentSO equipment, int amount = 1)
|
||||
{
|
||||
if (equipment == null)
|
||||
{
|
||||
return Create("未知记忆", null, amount, ItemRarity.None);
|
||||
}
|
||||
|
||||
return Create(
|
||||
equipment.GetDisplayTierName(),
|
||||
equipment.GetCurrentEquipmentSprite(),
|
||||
amount,
|
||||
ResolveEquipmentColor(equipment));
|
||||
}
|
||||
|
||||
private static void EnsureInstance()
|
||||
{
|
||||
if (currentInstance != null && currentController != null)
|
||||
{
|
||||
if (!currentInstance.activeInHierarchy)
|
||||
{
|
||||
currentInstance.SetActive(true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject prefab = Resources.Load<GameObject>(PrefabResourcePath);
|
||||
if (prefab == null)
|
||||
{
|
||||
Debug.LogWarning("[gItemGet] Failed to load Resources/itemGet.prefab");
|
||||
return;
|
||||
}
|
||||
|
||||
Transform parent = ResolveParent();
|
||||
currentInstance = parent != null
|
||||
? Object.Instantiate(prefab, parent, false)
|
||||
: Object.Instantiate(prefab);
|
||||
|
||||
currentInstance.name = prefab.name;
|
||||
currentController = currentInstance.GetComponent<itemGetPrefab>();
|
||||
}
|
||||
|
||||
private static Transform ResolveParent()
|
||||
{
|
||||
Canvas[] canvases = Object.FindObjectsByType<Canvas>(FindObjectsInactive.Exclude, FindObjectsSortMode.None);
|
||||
Canvas best = null;
|
||||
|
||||
for (int i = 0; i < canvases.Length; i++)
|
||||
{
|
||||
Canvas canvas = canvases[i];
|
||||
if (canvas == null || !canvas.gameObject.activeInHierarchy || !canvas.isRootCanvas)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (best == null || canvas.sortingOrder >= best.sortingOrder)
|
||||
{
|
||||
best = canvas;
|
||||
}
|
||||
}
|
||||
|
||||
return best != null ? best.transform : null;
|
||||
}
|
||||
|
||||
private static Color ResolveRarityColor(ItemRarity rarity)
|
||||
{
|
||||
if (cachedRarityConfig == null)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
cachedRarityConfig = UnityEditor.AssetDatabase.LoadAssetAtPath<ItemRarityColorConfigSO>(
|
||||
"Assets/playerBagSystem/ItemRarityColorConfig.asset");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (cachedRarityConfig != null)
|
||||
{
|
||||
return cachedRarityConfig.GetColor(rarity, FallbackColor);
|
||||
}
|
||||
|
||||
switch (rarity)
|
||||
{
|
||||
case ItemRarity.Common:
|
||||
return new Color32(95, 155, 107, 255);
|
||||
case ItemRarity.Uncommon:
|
||||
return new Color32(74, 134, 184, 255);
|
||||
case ItemRarity.Rare:
|
||||
return new Color32(106, 76, 156, 255);
|
||||
case ItemRarity.Epic:
|
||||
return new Color32(184, 134, 69, 255);
|
||||
case ItemRarity.Legendary:
|
||||
return new Color32(184, 76, 76, 255);
|
||||
case ItemRarity.Mythic:
|
||||
return new Color32(217, 108, 158, 255);
|
||||
case ItemRarity.Supreme:
|
||||
return new Color32(255, 103, 164, 255);
|
||||
default:
|
||||
return FallbackColor;
|
||||
}
|
||||
}
|
||||
|
||||
private static Color ResolveEquipmentColor(equipmentSO equipment)
|
||||
{
|
||||
if (equipment == null)
|
||||
{
|
||||
return FallbackColor;
|
||||
}
|
||||
|
||||
int index = equipment.GetVisualQualityColorIndex();
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
return new Color32(95, 155, 107, 255);
|
||||
case 2:
|
||||
return new Color32(74, 134, 184, 255);
|
||||
case 3:
|
||||
return new Color32(106, 76, 156, 255);
|
||||
case 4:
|
||||
return new Color32(184, 134, 69, 255);
|
||||
case 5:
|
||||
return new Color32(184, 76, 76, 255);
|
||||
default:
|
||||
return new Color32(255, 103, 164, 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82dd3d62659b6a64e88a02d137a400ac
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1ebfa8f32810ce4ea4f2576d8dadf66
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,43 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
|
||||
public class get_item_prefab : MonoBehaviour
|
||||
{
|
||||
public Image item_btm;
|
||||
public Image itemProfile;
|
||||
public TextMeshProUGUI itemAmount;
|
||||
public Text itemName;
|
||||
|
||||
public void Bind(Sprite icon, string displayName, int amount, Color qualityColor)
|
||||
{
|
||||
if (item_btm != null)
|
||||
{
|
||||
item_btm.color = qualityColor;
|
||||
}
|
||||
|
||||
if (itemProfile != null)
|
||||
{
|
||||
itemProfile.sprite = icon;
|
||||
itemProfile.enabled = icon != null;
|
||||
itemProfile.color = icon != null ? Color.white : new Color(1f, 1f, 1f, 0f);
|
||||
}
|
||||
|
||||
if (itemName != null)
|
||||
{
|
||||
itemName.text = displayName ?? string.Empty;
|
||||
}
|
||||
|
||||
if (itemAmount != null)
|
||||
{
|
||||
if (amount <= 1)
|
||||
{
|
||||
itemAmount.text = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
itemAmount.text = amount.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e7f5efecd257f70488d56bf0a767230c
|
||||
@@ -0,0 +1,423 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &18974122146848510
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3319628771906024608}
|
||||
- component: {fileID: 4359877026299959118}
|
||||
- component: {fileID: 7767232844961157683}
|
||||
m_Layer: 5
|
||||
m_Name: btmQuality
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &3319628771906024608
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 18974122146848510}
|
||||
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: 4325416963031440304}
|
||||
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: 0}
|
||||
m_SizeDelta: {x: 130, y: 130}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &4359877026299959118
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 18974122146848510}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &7767232844961157683
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 18974122146848510}
|
||||
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: 0}
|
||||
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!1 &339661534610086690
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 518968684966382619}
|
||||
- component: {fileID: 4988922451899572295}
|
||||
- component: {fileID: 514154942639368217}
|
||||
m_Layer: 5
|
||||
m_Name: itemProfile
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &518968684966382619
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 339661534610086690}
|
||||
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: 4325416963031440304}
|
||||
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: 0}
|
||||
m_SizeDelta: {x: 120, y: 120}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &4988922451899572295
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 339661534610086690}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &514154942639368217
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 339661534610086690}
|
||||
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: 1a62adf36834dd04181a6dd61344f8b8, 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!1 &913995668709144583
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4325416963031440304}
|
||||
- component: {fileID: 7456664981039242979}
|
||||
m_Layer: 5
|
||||
m_Name: get_item_prefab
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &4325416963031440304
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 913995668709144583}
|
||||
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: 3319628771906024608}
|
||||
- {fileID: 518968684966382619}
|
||||
- {fileID: 2293333086341986953}
|
||||
- {fileID: 6074961186985790639}
|
||||
m_Father: {fileID: 0}
|
||||
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: 0}
|
||||
m_SizeDelta: {x: 130, y: 130}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &7456664981039242979
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 913995668709144583}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: e7f5efecd257f70488d56bf0a767230c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
item_btm: {fileID: 7767232844961157683}
|
||||
itemProfile: {fileID: 514154942639368217}
|
||||
itemAmount: {fileID: 508704441844867492}
|
||||
itemName: {fileID: 2482204293705619698}
|
||||
--- !u!1 &2281945804967682548
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2293333086341986953}
|
||||
- component: {fileID: 6679092906817300735}
|
||||
- component: {fileID: 508704441844867492}
|
||||
m_Layer: 5
|
||||
m_Name: amt
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &2293333086341986953
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2281945804967682548}
|
||||
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: 4325416963031440304}
|
||||
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: -17.9, y: -40}
|
||||
m_SizeDelta: {x: 148.671, y: 50}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &6679092906817300735
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2281945804967682548}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &508704441844867492
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2281945804967682548}
|
||||
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: 2147483647
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: 452fa97492cae71479cf143f29930751, type: 2}
|
||||
m_sharedMaterial: {fileID: -346136068272202111, guid: 452fa97492cae71479cf143f29930751, type: 2}
|
||||
m_fontSharedMaterials: []
|
||||
m_fontMaterial: {fileID: 0}
|
||||
m_fontMaterials: []
|
||||
m_fontColor32:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontColor: {r: 1, g: 1, b: 1, 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: 0
|
||||
m_HorizontalAlignment: 4
|
||||
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 &4937134612620184442
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 6074961186985790639}
|
||||
- component: {fileID: 3728309417902643327}
|
||||
- component: {fileID: 2482204293705619698}
|
||||
m_Layer: 5
|
||||
m_Name: name
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &6074961186985790639
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4937134612620184442}
|
||||
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: 4325416963031440304}
|
||||
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: -86.05}
|
||||
m_SizeDelta: {x: 140, y: 30}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &3728309417902643327
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4937134612620184442}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &2482204293705619698
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4937134612620184442}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, 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_FontData:
|
||||
m_Font: {fileID: 12800000, guid: dfa10de3e2846524089b5073175cd151, type: 3}
|
||||
m_FontSize: 14
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 1
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 20
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: "\u4ED9\u54C1\u5076\u50CF\u590D\u6F14\u5355\u5143"
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: acdf60e42009ece499bb3c9187c7a120
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,70 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class itemGetPrefab : MonoBehaviour
|
||||
{
|
||||
[Header("item prefab")]
|
||||
public GameObject itemPrefab;
|
||||
public Transform displayParent;
|
||||
|
||||
[Header("btn")]
|
||||
public Button close;
|
||||
|
||||
private readonly List<GameObject> spawnedItems = new List<GameObject>();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (close != null)
|
||||
{
|
||||
close.onClick.RemoveListener(CloseSelf);
|
||||
close.onClick.AddListener(CloseSelf);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (close != null)
|
||||
{
|
||||
close.onClick.RemoveListener(CloseSelf);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearItems()
|
||||
{
|
||||
for (int i = 0; i < spawnedItems.Count; i++)
|
||||
{
|
||||
if (spawnedItems[i] != null)
|
||||
{
|
||||
Destroy(spawnedItems[i]);
|
||||
}
|
||||
}
|
||||
|
||||
spawnedItems.Clear();
|
||||
|
||||
if (displayParent != null)
|
||||
{
|
||||
for (int i = displayParent.childCount - 1; i >= 0; i--)
|
||||
{
|
||||
Destroy(displayParent.GetChild(i).gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public get_item_prefab AddItem()
|
||||
{
|
||||
if (itemPrefab == null || displayParent == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
GameObject instance = Instantiate(itemPrefab, displayParent);
|
||||
spawnedItems.Add(instance);
|
||||
return instance.GetComponent<get_item_prefab>();
|
||||
}
|
||||
|
||||
public void CloseSelf()
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39b86a94e0f9b43418207c0c1a25c044
|
||||
@@ -3043,7 +3043,7 @@ MonoBehaviour:
|
||||
m_PressedTrigger: Pressed
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_Interactable: 0
|
||||
m_TargetGraphic: {fileID: 4599931531580898861}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
@@ -5868,7 +5868,7 @@ MonoBehaviour:
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: "\u8FD8\u5DEE2\u573A\u6BD4\u8D5B\u53EF\u63D0\u53D6\u5956\u52B1/\u878D\u5408\u5B8C\u6BD5\uFF0C\u53EF\u9886\u53D6\u5956\u52B1"
|
||||
m_Text:
|
||||
--- !u!1 &1496425020052927388
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -8141,7 +8141,7 @@ MonoBehaviour:
|
||||
m_PressedTrigger: Pressed
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_Interactable: 0
|
||||
m_TargetGraphic: {fileID: 8317396197396341973}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
@@ -10526,7 +10526,7 @@ MonoBehaviour:
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: 2000 / 2000
|
||||
m_Text: 0/3000
|
||||
--- !u!1 &3049892735558273088
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -10857,7 +10857,7 @@ MonoBehaviour:
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: 2
|
||||
m_Text: 0
|
||||
--- !u!1 &3213626675873551214
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -11214,7 +11214,7 @@ MonoBehaviour:
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: "\u878D\u5408\u8FDB\u5EA6"
|
||||
m_Text: "\u878D\u5408\u8FDB\u5EA60/1"
|
||||
--- !u!1 &3313849891983255375
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -13152,7 +13152,7 @@ MonoBehaviour:
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 0.5
|
||||
m_FillAmount: 0
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
@@ -13310,7 +13310,7 @@ MonoBehaviour:
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: reason.why
|
||||
m_Text: "\u9700\u8981\u6295\u5165\u8BB0\u5FC6"
|
||||
--- !u!1 &3966248874610226284
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -15311,7 +15311,7 @@ MonoBehaviour:
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Option A
|
||||
m_Text: "<color=#FF0000>40 \u968F\u673A\u8BB0\u5FC6</color>"
|
||||
--- !u!1 &4635021010433457706
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -16644,7 +16644,7 @@ MonoBehaviour:
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: "1000\u7B97\u529B\u5FEB\u901F\u5B8C\u6210"
|
||||
m_Text: 0
|
||||
--- !u!1 &5018197546540534172
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -19386,11 +19386,17 @@ MonoBehaviour:
|
||||
m_Value: 0
|
||||
m_Options:
|
||||
m_Options:
|
||||
- m_Text: Option A
|
||||
- m_Text: "<color=#FF0000>40 \u968F\u673A\u8BB0\u5FC6</color>"
|
||||
m_Image: {fileID: 0}
|
||||
- m_Text: Option B
|
||||
- m_Text: "<color=#FF0000>60 \u81EA\u9009\u8BB0\u5FC6</color>"
|
||||
m_Image: {fileID: 0}
|
||||
- m_Text: Option C
|
||||
- m_Text: "<color=#FF0000>200 \u81EA\u9009\u9AD8\u5929\u8D4B\u8BB0\u5FC6</color>"
|
||||
m_Image: {fileID: 0}
|
||||
- m_Text: "<color=#FF0000>500 \u81EA\u9009\u73CD\u85CF\u8BB0\u5FC6</color>"
|
||||
m_Image: {fileID: 0}
|
||||
- m_Text: "<color=#FF0000>1000 \u81EA\u9009\u81F3\u81FB\u8BB0\u5FC6</color>"
|
||||
m_Image: {fileID: 0}
|
||||
- m_Text: "<color=#FF0000>1500 \u81EA\u9009\u523B\u9AA8\u94ED\u5FC3\u8BB0\u5FC6</color>"
|
||||
m_Image: {fileID: 0}
|
||||
m_OnValueChanged:
|
||||
m_PersistentCalls:
|
||||
@@ -24893,7 +24899,7 @@ GameObject:
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
m_IsActive: 0
|
||||
--- !u!224 &8851354205082234328
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -25110,7 +25116,7 @@ MonoBehaviour:
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: 2048
|
||||
m_Text: 0
|
||||
--- !u!1 &8192863506754736897
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -25493,7 +25499,7 @@ MonoBehaviour:
|
||||
m_PressedTrigger: Pressed
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_Interactable: 0
|
||||
m_TargetGraphic: {fileID: 4344585137749710138}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
@@ -26969,7 +26975,7 @@ MonoBehaviour:
|
||||
m_MinValue: 0
|
||||
m_MaxValue: 1
|
||||
m_WholeNumbers: 0
|
||||
m_Value: 0.5
|
||||
m_Value: 0
|
||||
m_OnValueChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
@@ -28050,7 +28056,7 @@ MonoBehaviour:
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: 2048
|
||||
m_Text: 0
|
||||
--- !u!1 &9107132343803959900
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -164,6 +164,7 @@ GameObject:
|
||||
m_Component:
|
||||
- component: {fileID: 6155334586977510247}
|
||||
- component: {fileID: 4151510886845045432}
|
||||
- component: {fileID: 7562484254110654814}
|
||||
m_Layer: 5
|
||||
m_Name: uAchievementPrefab
|
||||
m_TagString: Untagged
|
||||
@@ -208,6 +209,18 @@ MonoBehaviour:
|
||||
aName: {fileID: 6612220277252403227}
|
||||
aGetDate: {fileID: 8035948722274830026}
|
||||
aDescription: {fileID: 1893507208843142754}
|
||||
--- !u!114 &7562484254110654814
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3853073308254161695}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 76ce63b908338a84c8a3aa071b90c46b, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &4178773801772122773
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
@@ -10,4 +10,54 @@ public class uLevel : MonoBehaviour
|
||||
public Text uL_post;
|
||||
|
||||
public Button view_levelDetail;
|
||||
public Button close_levelDetail;
|
||||
|
||||
[Header("uLevelPanel")]
|
||||
public GameObject uLevelPanel;
|
||||
|
||||
public uLevel_skills uls;
|
||||
|
||||
[Header("so")]
|
||||
public Player_SO pso;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (pso == null)
|
||||
pso = Resources.Load<Player_SO>("playerdata/playerData_uniqueData");
|
||||
|
||||
if (uLevelPanel != null)
|
||||
uLevelPanel.SetActive(false);
|
||||
|
||||
if (uls != null && pso != null)
|
||||
uls.SetPlayerSo(pso);
|
||||
|
||||
if (view_levelDetail != null)
|
||||
{
|
||||
view_levelDetail.onClick.RemoveListener(OpenLevelDetailPanel);
|
||||
view_levelDetail.onClick.AddListener(OpenLevelDetailPanel);
|
||||
}
|
||||
|
||||
if (close_levelDetail != null)
|
||||
{
|
||||
close_levelDetail.onClick.RemoveListener(CloseLevelDetailPanel);
|
||||
close_levelDetail.onClick.AddListener(CloseLevelDetailPanel);
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenLevelDetailPanel()
|
||||
{
|
||||
if (uLevelPanel == null)
|
||||
return;
|
||||
|
||||
if (uls != null && pso != null)
|
||||
uls.SetPlayerSo(pso);
|
||||
|
||||
uLevelPanel.SetActive(true);
|
||||
}
|
||||
|
||||
private void CloseLevelDetailPanel()
|
||||
{
|
||||
if (uLevelPanel != null)
|
||||
uLevelPanel.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ public class uBehaviourRaderController : MonoBehaviour
|
||||
public URadarChartController radarChartController;
|
||||
public UGUIChartBridge chartBridge;
|
||||
public RankConfig rankConfig;
|
||||
public bool hideWhenOverlayVisible = false;
|
||||
|
||||
[Header("Async")]
|
||||
public bool reloadOnEnable = true;
|
||||
@@ -175,10 +176,20 @@ public class uBehaviourRaderController : MonoBehaviour
|
||||
|
||||
child.gameObject.SetActive(child == target);
|
||||
}
|
||||
|
||||
if (!uRaderObj.activeSelf)
|
||||
{
|
||||
uRaderObj.SetActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void BindOverlayVisibility()
|
||||
{
|
||||
if (!hideWhenOverlayVisible)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (overlaySubscribed)
|
||||
{
|
||||
return;
|
||||
@@ -218,7 +229,7 @@ public class uBehaviourRaderController : MonoBehaviour
|
||||
return;
|
||||
}
|
||||
|
||||
uRaderObj.SetActive(!overlayVisible);
|
||||
uRaderObj.SetActive(!hideWhenOverlayVisible || !overlayVisible);
|
||||
}
|
||||
|
||||
private void ApplySummary(BehaviourRadarSummary summary)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96251f1ca650d554f886d2e2ea7bde5b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,296 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &2099462153568767799
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 665396819362690529}
|
||||
- component: {fileID: 3192217589302937993}
|
||||
- component: {fileID: 5556623676502886536}
|
||||
m_Layer: 5
|
||||
m_Name: levelID
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &665396819362690529
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2099462153568767799}
|
||||
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: 9152270112823009895}
|
||||
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: -107.33, y: 0}
|
||||
m_SizeDelta: {x: 25.792, y: 30}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &3192217589302937993
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2099462153568767799}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &5556623676502886536
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2099462153568767799}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, 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_FontData:
|
||||
m_Font: {fileID: 12800000, guid: 8b8373b0af11dca46b89be60dbe469f8, type: 3}
|
||||
m_FontSize: 20
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 2
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: 10
|
||||
--- !u!1 &2343926165364488871
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 9152270112823009895}
|
||||
- component: {fileID: 4801688296739999581}
|
||||
- component: {fileID: 4501378674247754304}
|
||||
m_Layer: 5
|
||||
m_Name: btm
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &9152270112823009895
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2343926165364488871}
|
||||
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: 2290428063649654242}
|
||||
- {fileID: 665396819362690529}
|
||||
m_Father: {fileID: 2460305581810160109}
|
||||
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: 0}
|
||||
m_SizeDelta: {x: 250, y: 30}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &4801688296739999581
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2343926165364488871}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &4501378674247754304
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2343926165364488871}
|
||||
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: -52179173452712981, guid: be120bf969ae2c84fa997ecca6dd28e6, type: 3}
|
||||
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: 2
|
||||
--- !u!1 &3339470438795980614
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2290428063649654242}
|
||||
- component: {fileID: 4129409205783608839}
|
||||
- component: {fileID: 534678815217464394}
|
||||
m_Layer: 5
|
||||
m_Name: skillName
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &2290428063649654242
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3339470438795980614}
|
||||
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: 9152270112823009895}
|
||||
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: 1.4, y: 0}
|
||||
m_SizeDelta: {x: 187.733, y: 30}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &4129409205783608839
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3339470438795980614}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &534678815217464394
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3339470438795980614}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, 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_FontData:
|
||||
m_Font: {fileID: 12800000, guid: dfa10de3e2846524089b5073175cd151, type: 3}
|
||||
m_FontSize: 20
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 2
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 3
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: "\u5076\u50CF\u5927\u5E08\uFF1A\u8D5B\u540E\u611F\u609F"
|
||||
--- !u!1 &4419549278339915466
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2460305581810160109}
|
||||
- component: {fileID: 7517620086478948793}
|
||||
m_Layer: 5
|
||||
m_Name: levelRewardPrefab
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &2460305581810160109
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4419549278339915466}
|
||||
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: 9152270112823009895}
|
||||
m_Father: {fileID: 0}
|
||||
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: 0}
|
||||
m_SizeDelta: {x: 450, y: 30}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &7517620086478948793
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4419549278339915466}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 427d68583c7d9ab4588888b68dc7a8d2, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
enableSprite: {fileID: -52179173452712981, guid: be120bf969ae2c84fa997ecca6dd28e6, type: 3}
|
||||
availableSprite: {fileID: 2561534620446350566, guid: 23a48ca1e983a4c47971fcf7eab26b89, type: 3}
|
||||
lockedSprite: {fileID: -1936355827857895663, guid: fa360ec6245a3dd43bfbae1ac1093a6e, type: 3}
|
||||
unknownSprite: {fileID: 21300000, guid: 931f6455943555649a61ed7f1c76cbf6, type: 3}
|
||||
preSelectSprite: {fileID: 7919194353434859991, guid: b35fcaa46fa9f3e49b71c103f69df698, type: 3}
|
||||
levelName: {fileID: 5556623676502886536}
|
||||
statusImg: {fileID: 4501378674247754304}
|
||||
thisSkillName: {fileID: 534678815217464394}
|
||||
descriptionPrefab: {fileID: 2219571326304505587, guid: bde76837f913f3943836d4f83292618b, type: 3}
|
||||
descriptionOffsetX: 150
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26d681beab8631442ac57714a80f1f37
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,184 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
using System.Collections;
|
||||
|
||||
public class lrPrefab : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler
|
||||
{
|
||||
[Header("sprite")]
|
||||
public Sprite enableSprite;
|
||||
public Sprite availableSprite;
|
||||
public Sprite lockedSprite;
|
||||
public Sprite unknownSprite;
|
||||
public Sprite preSelectSprite;
|
||||
|
||||
[Header("uis")]
|
||||
public Text levelName;
|
||||
public Image statusImg;
|
||||
public Text thisSkillName;
|
||||
|
||||
[Header("desOBJ")]
|
||||
public GameObject descriptionPrefab;
|
||||
public float descriptionOffsetX = 80f;
|
||||
|
||||
private uLevel_skills owner;
|
||||
private userLevel_skills_SO ownerSo;
|
||||
private userLevel_skills_SO.UserLevelSkillEntry boundEntry;
|
||||
private int boundIndex = -1;
|
||||
private bool isUnlocked = false;
|
||||
private Coroutine hoverCoroutine;
|
||||
private GameObject spawnedDescription;
|
||||
|
||||
public void Bind(uLevel_skills ownerController, userLevel_skills_SO sourceSo, int index, userLevel_skills_SO.UserLevelSkillEntry entry, bool unlocked)
|
||||
{
|
||||
owner = ownerController;
|
||||
ownerSo = sourceSo;
|
||||
boundIndex = index;
|
||||
boundEntry = entry;
|
||||
isUnlocked = unlocked;
|
||||
|
||||
if (levelName != null)
|
||||
levelName.text = entry != null ? entry.userLevel.ToString() : string.Empty;
|
||||
|
||||
RefreshVisualState();
|
||||
}
|
||||
|
||||
public void RefreshVisualState()
|
||||
{
|
||||
if (owner != null && boundEntry != null)
|
||||
isUnlocked = owner.IsSkillUnlocked(boundEntry);
|
||||
|
||||
if (boundEntry == null)
|
||||
return;
|
||||
|
||||
bool revealLockedSkills = PlayerSkillService.IsSkillEnabled(7);
|
||||
bool shouldHideLockedSkillInfo = !isUnlocked && !revealLockedSkills;
|
||||
|
||||
if (thisSkillName != null)
|
||||
{
|
||||
thisSkillName.text = shouldHideLockedSkillInfo
|
||||
? "?????"
|
||||
: (boundEntry.skillName ?? string.Empty);
|
||||
}
|
||||
|
||||
if (statusImg == null)
|
||||
return;
|
||||
|
||||
if (owner != null && owner.IsSkillPreselected(boundIndex))
|
||||
statusImg.sprite = preSelectSprite != null ? preSelectSprite : availableSprite;
|
||||
else if (boundEntry.isEnabled)
|
||||
statusImg.sprite = enableSprite;
|
||||
else if (isUnlocked)
|
||||
statusImg.sprite = availableSprite;
|
||||
else if (shouldHideLockedSkillInfo)
|
||||
statusImg.sprite = unknownSprite != null ? unknownSprite : lockedSprite;
|
||||
else
|
||||
statusImg.sprite = lockedSprite;
|
||||
}
|
||||
|
||||
public void OnPointerEnter(PointerEventData eventData)
|
||||
{
|
||||
if (boundEntry == null || descriptionPrefab == null)
|
||||
return;
|
||||
|
||||
if (!isUnlocked && !PlayerSkillService.IsSkillEnabled(7))
|
||||
return;
|
||||
|
||||
if (hoverCoroutine != null)
|
||||
StopCoroutine(hoverCoroutine);
|
||||
|
||||
hoverCoroutine = StartCoroutine(ShowDescriptionAfterDelay());
|
||||
}
|
||||
|
||||
public void OnPointerExit(PointerEventData eventData)
|
||||
{
|
||||
if (hoverCoroutine != null)
|
||||
{
|
||||
StopCoroutine(hoverCoroutine);
|
||||
hoverCoroutine = null;
|
||||
}
|
||||
|
||||
HideDescription();
|
||||
}
|
||||
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
if (owner == null || boundIndex < 0)
|
||||
return;
|
||||
|
||||
owner.ToggleSkill(boundIndex);
|
||||
}
|
||||
|
||||
private IEnumerator ShowDescriptionAfterDelay()
|
||||
{
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
hoverCoroutine = null;
|
||||
ShowDescription();
|
||||
}
|
||||
|
||||
private void ShowDescription()
|
||||
{
|
||||
if (spawnedDescription != null || descriptionPrefab == null || boundEntry == null)
|
||||
return;
|
||||
|
||||
RectTransform root = ResolveDescriptionRoot();
|
||||
if (root == null)
|
||||
return;
|
||||
|
||||
spawnedDescription = Instantiate(descriptionPrefab, root);
|
||||
spawnedDescription.SetActive(true);
|
||||
spawnedDescription.transform.SetAsLastSibling();
|
||||
|
||||
esDesPrefab detail = spawnedDescription.GetComponent<esDesPrefab>();
|
||||
if (detail != null)
|
||||
detail.Bind(boundEntry.skillName, boundEntry.skillIcon, boundEntry.skillDescription, boundEntry.skillSummary);
|
||||
|
||||
RectTransform spawnedRect = spawnedDescription.GetComponent<RectTransform>();
|
||||
if (spawnedRect == null)
|
||||
return;
|
||||
|
||||
Canvas canvas = root.GetComponentInParent<Canvas>();
|
||||
Camera eventCamera = null;
|
||||
if (canvas != null && canvas.renderMode != RenderMode.ScreenSpaceOverlay)
|
||||
eventCamera = canvas.worldCamera;
|
||||
|
||||
Vector2 localPoint;
|
||||
RectTransformUtility.ScreenPointToLocalPointInRectangle(root, Input.mousePosition, eventCamera, out localPoint);
|
||||
localPoint.x += descriptionOffsetX;
|
||||
spawnedRect.anchoredPosition = localPoint;
|
||||
}
|
||||
|
||||
private RectTransform ResolveDescriptionRoot()
|
||||
{
|
||||
Canvas canvas = GetComponentInParent<Canvas>();
|
||||
if (canvas == null)
|
||||
return null;
|
||||
|
||||
Canvas rootCanvas = canvas.rootCanvas != null ? canvas.rootCanvas : canvas;
|
||||
return rootCanvas.transform as RectTransform;
|
||||
}
|
||||
|
||||
private void HideDescription()
|
||||
{
|
||||
if (spawnedDescription == null)
|
||||
return;
|
||||
|
||||
if (Application.isPlaying)
|
||||
Destroy(spawnedDescription);
|
||||
else
|
||||
DestroyImmediate(spawnedDescription);
|
||||
|
||||
spawnedDescription = null;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (hoverCoroutine != null)
|
||||
{
|
||||
StopCoroutine(hoverCoroutine);
|
||||
hoverCoroutine = null;
|
||||
}
|
||||
|
||||
HideDescription();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 427d68583c7d9ab4588888b68dc7a8d2
|
||||
@@ -0,0 +1,415 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class uLevel_skills : MonoBehaviour
|
||||
{
|
||||
public userLevel_skills_SO ulsSO;
|
||||
public Player_SO pso;
|
||||
|
||||
[Header("objs")]
|
||||
public GameObject uSkillBarPrefab;
|
||||
public Transform uSkillBarParent;
|
||||
|
||||
[Header("current selected skill details")]
|
||||
public Image btm_skillImage;
|
||||
public Image skillIcon_Profile;
|
||||
public Text skill_thisSkillName;
|
||||
public Text skill_thisSkillSummary;
|
||||
|
||||
[Header("change")]
|
||||
public Slider need_progress;
|
||||
public Text need_text;
|
||||
public Text need_howmuchCoins;
|
||||
public Button yesChangeButton;
|
||||
public Button noCancelButton;
|
||||
|
||||
private readonly System.Collections.Generic.List<lrPrefab> spawnedBars = new System.Collections.Generic.List<lrPrefab>();
|
||||
private bool hasStarted = false;
|
||||
private int pendingSkillIndex = -1;
|
||||
private Color defaultNeedCoinsColor = Color.white;
|
||||
private const int SkillSwitchCooldownMatches = 3;
|
||||
private const int SkillSwitchMinimumCost = 200;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
hasStarted = true;
|
||||
CacheUiDefaults();
|
||||
RegisterButtons();
|
||||
PlayerSkillService.RegisterSkillAsset(ulsSO);
|
||||
RefreshSkillBars();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
CacheUiDefaults();
|
||||
RegisterButtons();
|
||||
PlayerSkillService.RegisterSkillAsset(ulsSO);
|
||||
if (hasStarted)
|
||||
{
|
||||
RefreshSkillBars();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
UnregisterButtons();
|
||||
}
|
||||
|
||||
public void SetPlayerSo(Player_SO playerSo)
|
||||
{
|
||||
pso = playerSo;
|
||||
}
|
||||
|
||||
public void RefreshSkillBars()
|
||||
{
|
||||
EnsurePlayerSo();
|
||||
|
||||
if (uSkillBarParent == null || uSkillBarPrefab == null || ulsSO == null)
|
||||
return;
|
||||
|
||||
NormalizeSelectionState();
|
||||
ClearExistingBars();
|
||||
spawnedBars.Clear();
|
||||
|
||||
for (int i = 0; i < ulsSO.skills.Count; i++)
|
||||
{
|
||||
var entry = ulsSO.skills[i];
|
||||
if (entry == null)
|
||||
continue;
|
||||
|
||||
GameObject instance = Instantiate(uSkillBarPrefab, uSkillBarParent);
|
||||
instance.SetActive(true);
|
||||
|
||||
lrPrefab bar = instance.GetComponent<lrPrefab>();
|
||||
if (bar == null)
|
||||
continue;
|
||||
|
||||
bar.Bind(this, ulsSO, i, entry, IsSkillUnlocked(entry));
|
||||
spawnedBars.Add(bar);
|
||||
}
|
||||
|
||||
RefreshDetailPanel();
|
||||
RefreshChangeUi();
|
||||
}
|
||||
|
||||
public void ToggleSkill(int index)
|
||||
{
|
||||
if (ulsSO == null || index < 0 || index >= ulsSO.skills.Count)
|
||||
return;
|
||||
|
||||
var entry = ulsSO.skills[index];
|
||||
if (entry == null || !IsSkillUnlocked(entry))
|
||||
return;
|
||||
|
||||
int currentEnabledIndex = GetEnabledSkillIndex();
|
||||
if (index == currentEnabledIndex)
|
||||
{
|
||||
pendingSkillIndex = -1;
|
||||
RefreshDetailPanel();
|
||||
RefreshChangeUi();
|
||||
RefreshStatusesOnly();
|
||||
return;
|
||||
}
|
||||
|
||||
pendingSkillIndex = pendingSkillIndex == index ? -1 : index;
|
||||
RefreshDetailPanel();
|
||||
RefreshChangeUi();
|
||||
RefreshStatusesOnly();
|
||||
}
|
||||
|
||||
public bool IsSkillPreselected(int index)
|
||||
{
|
||||
return pendingSkillIndex >= 0 && pendingSkillIndex == index;
|
||||
}
|
||||
|
||||
public bool IsSkillUnlocked(userLevel_skills_SO.UserLevelSkillEntry entry)
|
||||
{
|
||||
EnsurePlayerSo();
|
||||
|
||||
if (entry == null)
|
||||
return false;
|
||||
|
||||
int currentExp = pso != null ? Mathf.Max(0, pso.player_currentEXP) : 0;
|
||||
return currentExp >= Mathf.Max(0, entry.thisLevelNeedExps);
|
||||
}
|
||||
|
||||
private void RefreshStatusesOnly()
|
||||
{
|
||||
for (int i = 0; i < spawnedBars.Count; i++)
|
||||
{
|
||||
if (spawnedBars[i] == null)
|
||||
continue;
|
||||
|
||||
spawnedBars[i].RefreshVisualState();
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshDetailPanel()
|
||||
{
|
||||
if (ulsSO == null || ulsSO.skills == null || ulsSO.skills.Count == 0)
|
||||
{
|
||||
SetDetailPanel(null);
|
||||
return;
|
||||
}
|
||||
|
||||
int detailIndex = pendingSkillIndex >= 0 ? pendingSkillIndex : GetEnabledSkillIndex();
|
||||
if (detailIndex < 0 || detailIndex >= ulsSO.skills.Count)
|
||||
{
|
||||
SetDetailPanel(null);
|
||||
return;
|
||||
}
|
||||
|
||||
SetDetailPanel(ulsSO.skills[detailIndex]);
|
||||
}
|
||||
|
||||
private void SetDetailPanel(userLevel_skills_SO.UserLevelSkillEntry entry)
|
||||
{
|
||||
if (btm_skillImage != null)
|
||||
{
|
||||
btm_skillImage.sprite = entry != null ? entry.skillIcon : null;
|
||||
}
|
||||
|
||||
if (skillIcon_Profile != null)
|
||||
{
|
||||
skillIcon_Profile.sprite = entry != null ? entry.skillIcon : null;
|
||||
}
|
||||
|
||||
if (skill_thisSkillName != null)
|
||||
{
|
||||
skill_thisSkillName.text = entry != null ? (entry.skillName ?? string.Empty) : string.Empty;
|
||||
}
|
||||
|
||||
if (skill_thisSkillSummary != null)
|
||||
{
|
||||
skill_thisSkillSummary.text = entry != null ? (entry.skillDescription ?? string.Empty) : string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshChangeUi()
|
||||
{
|
||||
int cooldownRemaining = PlayerSkillService.GetSkillSwitchCooldownRemainingMatches();
|
||||
int currentEnabledIndex = GetEnabledSkillIndex();
|
||||
bool hasPendingSelection = pendingSkillIndex >= 0 && pendingSkillIndex != currentEnabledIndex;
|
||||
|
||||
if (need_text != null)
|
||||
{
|
||||
need_text.text = cooldownRemaining > 0
|
||||
? $"还需要{cooldownRemaining}场比赛"
|
||||
: "可以切换技能";
|
||||
}
|
||||
|
||||
if (need_progress != null)
|
||||
{
|
||||
need_progress.minValue = 0f;
|
||||
need_progress.maxValue = 1f;
|
||||
need_progress.value = cooldownRemaining > 0
|
||||
? Mathf.Clamp01((float)(SkillSwitchCooldownMatches - cooldownRemaining) / SkillSwitchCooldownMatches)
|
||||
: 1f;
|
||||
}
|
||||
|
||||
int switchCost = GetSkillSwitchCost();
|
||||
bool hasEnoughCoins = HasEnoughCoinsForSwitch(switchCost);
|
||||
|
||||
if (need_howmuchCoins != null)
|
||||
{
|
||||
need_howmuchCoins.text = switchCost.ToString();
|
||||
need_howmuchCoins.color = hasEnoughCoins ? defaultNeedCoinsColor : Color.red;
|
||||
}
|
||||
|
||||
if (yesChangeButton != null)
|
||||
{
|
||||
yesChangeButton.interactable = hasPendingSelection && cooldownRemaining <= 0 && hasEnoughCoins;
|
||||
}
|
||||
|
||||
if (noCancelButton != null)
|
||||
{
|
||||
noCancelButton.interactable = pendingSkillIndex >= 0;
|
||||
}
|
||||
}
|
||||
|
||||
private int GetSkillSwitchCost()
|
||||
{
|
||||
int currentCoins = Application.isPlaying
|
||||
? PlayerEconomyLedger.EnsureInstance().GetCoins()
|
||||
: (pso != null ? Mathf.Max(0, pso.Coins) : 0);
|
||||
int percentCost = Mathf.CeilToInt(currentCoins * 0.01f);
|
||||
return Mathf.Max(SkillSwitchMinimumCost, percentCost);
|
||||
}
|
||||
|
||||
private bool HasEnoughCoinsForSwitch(int amount)
|
||||
{
|
||||
if (amount <= 0)
|
||||
return true;
|
||||
|
||||
return Application.isPlaying
|
||||
? PlayerEconomyLedger.EnsureInstance().HasEnoughCoins(amount)
|
||||
: (pso != null && pso.Coins >= amount);
|
||||
}
|
||||
|
||||
private void HandleConfirmSwitchClicked()
|
||||
{
|
||||
int currentEnabledIndex = GetEnabledSkillIndex();
|
||||
if (pendingSkillIndex < 0 || pendingSkillIndex == currentEnabledIndex || ulsSO == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (PlayerSkillService.GetSkillSwitchCooldownRemainingMatches() > 0)
|
||||
{
|
||||
RefreshChangeUi();
|
||||
return;
|
||||
}
|
||||
|
||||
int switchCost = GetSkillSwitchCost();
|
||||
bool spent = Application.isPlaying
|
||||
? PlayerEconomyLedger.EnsureInstance().TrySpendCoins(switchCost)
|
||||
: (pso != null && pso.TrySpendCoins(switchCost));
|
||||
if (!spent)
|
||||
{
|
||||
RefreshChangeUi();
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerSkillService.ConfirmSkillSelection(ulsSO, pendingSkillIndex);
|
||||
pendingSkillIndex = -1;
|
||||
MarkSkillsDirty();
|
||||
RefreshStatusesOnly();
|
||||
RefreshDetailPanel();
|
||||
RefreshChangeUi();
|
||||
}
|
||||
|
||||
private void HandleCancelPreselectClicked()
|
||||
{
|
||||
pendingSkillIndex = -1;
|
||||
RefreshStatusesOnly();
|
||||
RefreshDetailPanel();
|
||||
RefreshChangeUi();
|
||||
}
|
||||
|
||||
private void ClearExistingBars()
|
||||
{
|
||||
for (int i = uSkillBarParent.childCount - 1; i >= 0; i--)
|
||||
{
|
||||
Transform child = uSkillBarParent.GetChild(i);
|
||||
if (Application.isPlaying)
|
||||
Destroy(child.gameObject);
|
||||
else
|
||||
DestroyImmediate(child.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void MarkSkillsDirty()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying && ulsSO != null)
|
||||
UnityEditor.EditorUtility.SetDirty(ulsSO);
|
||||
#endif
|
||||
}
|
||||
|
||||
private void EnsurePlayerSo()
|
||||
{
|
||||
if (pso == null)
|
||||
pso = Resources.Load<Player_SO>("playerdata/playerData_uniqueData");
|
||||
}
|
||||
|
||||
private void CacheUiDefaults()
|
||||
{
|
||||
if (need_howmuchCoins != null)
|
||||
{
|
||||
defaultNeedCoinsColor = need_howmuchCoins.color;
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterButtons()
|
||||
{
|
||||
if (yesChangeButton != null)
|
||||
{
|
||||
yesChangeButton.onClick.RemoveListener(HandleConfirmSwitchClicked);
|
||||
yesChangeButton.onClick.AddListener(HandleConfirmSwitchClicked);
|
||||
}
|
||||
|
||||
if (noCancelButton != null)
|
||||
{
|
||||
noCancelButton.onClick.RemoveListener(HandleCancelPreselectClicked);
|
||||
noCancelButton.onClick.AddListener(HandleCancelPreselectClicked);
|
||||
}
|
||||
}
|
||||
|
||||
private void UnregisterButtons()
|
||||
{
|
||||
if (yesChangeButton != null)
|
||||
{
|
||||
yesChangeButton.onClick.RemoveListener(HandleConfirmSwitchClicked);
|
||||
}
|
||||
|
||||
if (noCancelButton != null)
|
||||
{
|
||||
noCancelButton.onClick.RemoveListener(HandleCancelPreselectClicked);
|
||||
}
|
||||
}
|
||||
|
||||
private int GetEnabledSkillIndex()
|
||||
{
|
||||
if (ulsSO == null || ulsSO.skills == null)
|
||||
return -1;
|
||||
|
||||
for (int i = 0; i < ulsSO.skills.Count; i++)
|
||||
{
|
||||
var entry = ulsSO.skills[i];
|
||||
if (entry != null && entry.isEnabled)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void NormalizeSelectionState()
|
||||
{
|
||||
if (ulsSO == null || ulsSO.skills == null || ulsSO.skills.Count == 0)
|
||||
return;
|
||||
|
||||
int selectedIndex = -1;
|
||||
for (int i = 0; i < ulsSO.skills.Count; i++)
|
||||
{
|
||||
var entry = ulsSO.skills[i];
|
||||
if (entry == null || !entry.isEnabled)
|
||||
continue;
|
||||
|
||||
if (selectedIndex < 0)
|
||||
{
|
||||
selectedIndex = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry.isEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedIndex < 0)
|
||||
{
|
||||
for (int i = 0; i < ulsSO.skills.Count; i++)
|
||||
{
|
||||
var entry = ulsSO.skills[i];
|
||||
if (entry == null)
|
||||
continue;
|
||||
|
||||
selectedIndex = i;
|
||||
entry.isEnabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < ulsSO.skills.Count; i++)
|
||||
{
|
||||
var entry = ulsSO.skills[i];
|
||||
if (entry == null)
|
||||
continue;
|
||||
|
||||
entry.isEnabled = (i == selectedIndex);
|
||||
}
|
||||
|
||||
MarkSkillsDirty();
|
||||
PlayerSkillService.RegisterSkillAsset(ulsSO);
|
||||
pendingSkillIndex = -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 522d48b038e44bd4289b57ea155ae0b9
|
||||
@@ -0,0 +1,92 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 19a25568f1e1a8b4093dce8a6753be0e, type: 3}
|
||||
m_Name: ulsSO
|
||||
m_EditorClassIdentifier:
|
||||
skills:
|
||||
- userLevel: 0
|
||||
skillName: "\u8D5B\u524D\u51C6\u5907"
|
||||
skillDescription: "\u4F60\u5DF2\u6765\u5230\u672C\u7D22\u5C3C\u514B\u4E16\u754C\u3002\u8D5B\u524D\u51C6\u5907\u65F6\uFF0C\u4F60\u53EF\u4EE5\u65E0\u9650\u5236\u5730\u8FDB\u5165\u65B0\u624B\u6559\u7A0B\u3002"
|
||||
skillSummary: "\u5378\u4E0B\u5B83\u65F6\u4F60\u5DF2\u4E0D\u518D\u662F\u65B0\u624B"
|
||||
isEnabled: 1
|
||||
skillIcon: {fileID: 0}
|
||||
thisLevelNeedExps: 0
|
||||
- userLevel: 1
|
||||
skillName: "\u8BB0\u5FC6\u8D2D\u4E70\u8BA1\u5212"
|
||||
skillDescription: "\u5141\u8BB8\u4F60\u4EE510\u91D1\u5E01\u8D2D\u4E701\u4E2A\u8BB0\u5FC6\u788E\u7247\u3002\u88C5\u5907\u6B64\u6280\u80FD\u65F6\u53EF\u4E8E\u5546\u5E97\u89E3\u9501\u4E00\u4E2A\u8D2D\u4E70\u9009\u9879\u3002"
|
||||
skillSummary: "\u4ECE\u8001\u5E08\u90A3\u91CC\u65B0\u5B66\u4E86\u4EC0\u4E48\uFF1F"
|
||||
isEnabled: 0
|
||||
skillIcon: {fileID: 0}
|
||||
thisLevelNeedExps: 200
|
||||
- userLevel: 2
|
||||
skillName: "\u8BB0\u5FC6\u5F52\u8FD8\u8BA1\u5212"
|
||||
skillDescription: "\u5141\u8BB8\u4F60\u5C061\u4E2A\u8BB0\u5FC6\u788E\u7247\u4EE54\u91D1\u5E01\u552E\u51FA\u3002\u88C5\u5907\u6B64\u6280\u80FD\u65F6\u53EF\u4E8E\u5546\u5E97\u89E3\u9501\u4E00\u4E2A\u8D2D\u4E70\u9009\u9879\u3002"
|
||||
skillSummary: "\u8001\u5E08\u6559\u7ED9\u4F60\u7684\u53C8\u8FD8\u56DE\u53BB\u4E86\u5417\uFF1F"
|
||||
isEnabled: 0
|
||||
skillIcon: {fileID: 0}
|
||||
thisLevelNeedExps: 300
|
||||
- userLevel: 3
|
||||
skillName: "\u6311\u6218\u8005\u6A21\u578B"
|
||||
skillDescription: "\u5141\u8BB8\u8BBE\u7F6E\u4E00\u4E2A\u81EA\u5B9A\u7684\u767E\u5206\u6BD4\u9ED1\u5E55\u6765\u906E\u4F4F\u8F68\u9053\u3002\u6700\u5C11\u906E\u632120%\uFF0C\u6700\u591A\u906E\u632190%\u3002\u6BCF\u906E\u63211%\uFF0C\u63D0\u4F9B1.5%\u7ED3\u7B97\u5956\u52B1\u52A0\u6210\u3002"
|
||||
skillSummary: "\u9AD8\u98CE\u9669\u9AD8\u56DE\u62A5\uFF0C\u597D\u5947\u5FC3\u5BB3\u6B7B\u732B\u3002"
|
||||
isEnabled: 0
|
||||
skillIcon: {fileID: 0}
|
||||
thisLevelNeedExps: 400
|
||||
- userLevel: 4
|
||||
skillName: "\u8D5B\u540E\u611F\u609F"
|
||||
skillDescription: "\u6BCF\u8FDB\u884C10\u573A\u6BD4\u8D5B\u53EF\u83B7\u5F97\u4E00\u4EF6\u968F\u673A\u7C7B\u578B\u968F\u673A\u5C5E\u6027\u7684\u8BB0\u5FC6\u3002\u5728\u66F4\u6362\u6280\u80FD\u65F6\u6E05\u96F6\u8BA1\u6570\u5668\u3002"
|
||||
skillSummary:
|
||||
isEnabled: 0
|
||||
skillIcon: {fileID: 0}
|
||||
thisLevelNeedExps: 500
|
||||
- userLevel: 5
|
||||
skillName: "\u6211\u7231\u53D1\u660E"
|
||||
skillDescription: "\u4F60\u7684\u8BB0\u5FC6\u878D\u5408\u548C\u52A0\u901F\u6240\u9700\u7684\u8D27\u5E01\u51CF\u534A\u3002"
|
||||
skillSummary:
|
||||
isEnabled: 0
|
||||
skillIcon: {fileID: 0}
|
||||
thisLevelNeedExps: 600
|
||||
- userLevel: 6
|
||||
skillName: "\u8FFD\u68A6\u4E4B\u8DEF"
|
||||
skillDescription: "\u7ED3\u7B97\u65F6\uFF0C\u83B7\u5F97\u5076\u50CF\u5206\u65701\u2030\u7684\u8BB0\u5FC6\u788E\u7247\u3002"
|
||||
skillSummary:
|
||||
isEnabled: 0
|
||||
skillIcon: {fileID: 0}
|
||||
thisLevelNeedExps: 700
|
||||
- userLevel: 7
|
||||
skillName: "\u6D1E\u5BDF"
|
||||
skillDescription: "\u4F60\u53EF\u4EE5\u770B\u5230\u89D2\u8272\u672A\u89E3\u9501\u7684\u6280\u80FD\u53CA\u5176\u4ECB\u7ECD\u3002"
|
||||
skillSummary: "\u4F60\u7684\u76EE\u5149\u6781\u5177\u6218\u7565\u524D\u77BB\u6027\u3002"
|
||||
isEnabled: 0
|
||||
skillIcon: {fileID: 0}
|
||||
thisLevelNeedExps: 800
|
||||
- userLevel: 8
|
||||
skillName: "95\u6298"
|
||||
skillDescription: "\u6D88\u8D39\u8BB0\u5FC6\u788E\u7247\u548Ccoins\u65F6\u767E\u5206\u6BD4\u8FD4\u8FD8\u3002\u4F60\u6BCF\u62E5\u6709\u4E00\u4E2A\u5076\u50CF\uFF0C\u589E\u52A0\u6D88\u8D39\u8FD4\u8FD8\u7684\u6BD4\u4F8B0.5%\u3002\u6700\u591A\u5408\u8BA1\u8FD4\u8FD85%\u3002"
|
||||
skillSummary:
|
||||
isEnabled: 0
|
||||
skillIcon: {fileID: 0}
|
||||
thisLevelNeedExps: 900
|
||||
- userLevel: 9
|
||||
skillName: "\u5229\u6DA6\u63D0\u53D6\u5668"
|
||||
skillDescription: "\u7ED3\u7B97\u65F6\uFF0C\u83B7\u5F97\u5076\u50CF\u5206\u65702\u2030\u7684\u91D1\u5E01\u3002"
|
||||
skillSummary: "\u6B7B\u4E0E\u7A0E"
|
||||
isEnabled: 0
|
||||
skillIcon: {fileID: 0}
|
||||
thisLevelNeedExps: 1100
|
||||
- userLevel: 10
|
||||
skillName: "\u9876\u5CF0\u76F8\u89C1"
|
||||
skillDescription: "\u6E38\u620F\u4E2D\u4F60\u7684\u89C6\u89D2\u9AD8\u5EA6\u63D0\u9AD810%\u3002"
|
||||
skillSummary: "\u611F\u6069\u6559\u7EC3\u3002"
|
||||
isEnabled: 0
|
||||
skillIcon: {fileID: 0}
|
||||
thisLevelNeedExps: 1500
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: acf1a85d46975694aba2cdc12b9b3dfb
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
[CreateAssetMenu(fileName = "userLevel_skills", menuName = "Player/UserLevel Skills SO")]
|
||||
public class userLevel_skills_SO : ScriptableObject
|
||||
{
|
||||
[System.Serializable]
|
||||
public class UserLevelSkillEntry
|
||||
{
|
||||
public int userLevel;
|
||||
public string skillName;
|
||||
[TextArea(3, 10)] public string skillDescription;
|
||||
public string skillSummary;
|
||||
public bool isEnabled;
|
||||
public Sprite skillIcon;
|
||||
public int thisLevelNeedExps;
|
||||
}
|
||||
|
||||
public List<UserLevelSkillEntry> skills = new List<UserLevelSkillEntry>();
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19a25568f1e1a8b4093dce8a6753be0e
|
||||
@@ -15,6 +15,7 @@ using TMPro;
|
||||
/// </summary>
|
||||
public class AllyCombatant : MonoBehaviour, ICombatant
|
||||
{
|
||||
private static AllyHero_SO[] cachedAllAllyHeroes;
|
||||
public int slotIndex = 0; // Documentation text normalized.
|
||||
|
||||
// runtime stats
|
||||
@@ -989,8 +990,8 @@ public class AllyCombatant : MonoBehaviour, ICombatant
|
||||
|
||||
if (id > 0)
|
||||
{
|
||||
var all = Resources.LoadAll<AllyHero_SO>("");
|
||||
foreach (var a in all)
|
||||
EnsureAllyHeroCache();
|
||||
foreach (var a in cachedAllAllyHeroes)
|
||||
{
|
||||
if (a != null && a.ally_heroID == id)
|
||||
{
|
||||
@@ -1049,6 +1050,12 @@ public class AllyCombatant : MonoBehaviour, ICombatant
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureAllyHeroCache()
|
||||
{
|
||||
if (cachedAllAllyHeroes != null) return;
|
||||
cachedAllAllyHeroes = Resources.LoadAll<AllyHero_SO>("") ?? Array.Empty<AllyHero_SO>();
|
||||
}
|
||||
|
||||
// Documentation text normalized.
|
||||
private static AllyHero_SO.AllyLevelInfo GetEffectiveLevelForExp(AllyHero_SO so, int exp)
|
||||
{
|
||||
|
||||
@@ -414,6 +414,8 @@ public class EnemyCombatant : MonoBehaviour, ICombatant
|
||||
}
|
||||
}
|
||||
|
||||
AwardBountyScoreToLivingAllies();
|
||||
|
||||
// Finally mark dead
|
||||
isDead = true;
|
||||
|
||||
@@ -510,6 +512,62 @@ public class EnemyCombatant : MonoBehaviour, ICombatant
|
||||
public bool IsDead => isDead;
|
||||
|
||||
// New: allow EffectSystem/SkillBuilder to adjust enemy max HP safely
|
||||
private void AwardBountyScoreToLivingAllies()
|
||||
{
|
||||
if (sourceData == null)
|
||||
return;
|
||||
|
||||
float difficultyLevel = ResolveCurrentDifficultyLevel();
|
||||
var stats = sourceData.GetStatsByDifficultyID(_currentDifficultyID);
|
||||
int calculatedMaxHp = Mathf.Max(0, stats.enemy_maxHP);
|
||||
float totalBounty = calculatedMaxHp * 0.05f * difficultyLevel + sourceData.enemyBountyBonus;
|
||||
if (totalBounty <= 0f)
|
||||
return;
|
||||
|
||||
AllyCombatant[] allies = UnityEngine.Object.FindObjectsByType<AllyCombatant>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
||||
List<AllyCombatant> livingAllies = new List<AllyCombatant>();
|
||||
for (int i = 0; i < allies.Length; i++)
|
||||
{
|
||||
AllyCombatant ally = allies[i];
|
||||
if (ally == null)
|
||||
continue;
|
||||
if (ally.IsDead || ally.maxHP <= 0 || !ally.gameObject.activeInHierarchy)
|
||||
continue;
|
||||
livingAllies.Add(ally);
|
||||
}
|
||||
|
||||
if (livingAllies.Count == 0)
|
||||
return;
|
||||
|
||||
int awardPerAlly = Mathf.CeilToInt(totalBounty / livingAllies.Count);
|
||||
if (awardPerAlly <= 0)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < livingAllies.Count; i++)
|
||||
{
|
||||
livingAllies[i].AddScoreDirect(awardPerAlly);
|
||||
}
|
||||
}
|
||||
|
||||
private float ResolveCurrentDifficultyLevel()
|
||||
{
|
||||
BeatmapManager beatmapManager = BeatmapManager.Instance;
|
||||
if (beatmapManager == null || beatmapManager.assignedSongData == null || beatmapManager.assignedSongData.chartFiles == null)
|
||||
return 1f;
|
||||
|
||||
List<ChartFileEntry> chartFiles = beatmapManager.assignedSongData.chartFiles;
|
||||
for (int i = 0; i < chartFiles.Count; i++)
|
||||
{
|
||||
ChartFileEntry entry = chartFiles[i];
|
||||
if (entry == null || entry.difficulty != _currentDifficultyID)
|
||||
continue;
|
||||
|
||||
return Mathf.Max(0f, entry.difficultyLEVEL);
|
||||
}
|
||||
|
||||
return 1f;
|
||||
}
|
||||
|
||||
public void SetMaxHP(int newMax, bool keepCurrentRatio = true)
|
||||
{
|
||||
if (newMax < 1) newMax = 1;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using Spine.Unity;
|
||||
|
||||
@@ -45,6 +45,9 @@ public class EnemyData_SO : ScriptableObject
|
||||
|
||||
[Header("Inspector")]
|
||||
public EnemyType enemyType = EnemyType.Simple;
|
||||
[Header("Reward")]
|
||||
[Tooltip("Flat bounty score bonus added on top of the HP-based bounty formula.")]
|
||||
public int enemyBountyBonus = 0;
|
||||
|
||||
public enum EnemyType
|
||||
{
|
||||
@@ -132,3 +135,4 @@ public class EnemyData_SO : ScriptableObject
|
||||
[Range(0f, 1f)]
|
||||
public float manaGainOnDamagePercent = 0.2f; // default 20%
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,10 @@ public sealed class PlayerEconomyLedger : MonoBehaviour
|
||||
PlayerEconomyPayload loadedPayload;
|
||||
loadedFromSave = PlayerEconomyStorage.TryLoad(out loadedPayload);
|
||||
payload = loadedPayload;
|
||||
if (payload == null)
|
||||
{
|
||||
payload = PlayerEconomyStorage.CreateDefaultPayload();
|
||||
}
|
||||
initialized = true;
|
||||
SaveNow();
|
||||
}
|
||||
@@ -165,6 +169,11 @@ public sealed class PlayerEconomyLedger : MonoBehaviour
|
||||
payload.coins -= amount;
|
||||
SaveNow();
|
||||
DailyTaskEventHub.ReportSpendCoins(amount);
|
||||
int refundAmount = PlayerSkillService.GetCoinRefundAmount(amount);
|
||||
if (refundAmount > 0)
|
||||
{
|
||||
AddCoins(refundAmount);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -183,6 +192,11 @@ public sealed class PlayerEconomyLedger : MonoBehaviour
|
||||
|
||||
payload.material -= amount;
|
||||
SaveNow();
|
||||
int refundAmount = PlayerSkillService.GetMaterialRefundAmount(amount);
|
||||
if (refundAmount > 0)
|
||||
{
|
||||
AddMaterial(refundAmount);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ public static class PlayerEconomyStorage
|
||||
{
|
||||
version = 1,
|
||||
lastUpdatedUtcTicks = DateTime.UtcNow.Ticks,
|
||||
coins = 0,
|
||||
coins = 999999,
|
||||
material = 0
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,652 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Bansonic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
[Serializable]
|
||||
public class PlayerSkillSaveData
|
||||
{
|
||||
public int selectedSkillIndex = -1;
|
||||
public int postMatchRewardCounter = 0;
|
||||
public int skillSwitchCooldownRemainingMatches = 0;
|
||||
}
|
||||
|
||||
public sealed class PlayerSkillService : MonoBehaviour
|
||||
{
|
||||
private const string SaveCategory = "player_skills";
|
||||
private const string SaveKey = "runtime";
|
||||
private const string SkillAssetEditorPath = "Assets/playerInfoDisplay/uls/ulsSO.asset";
|
||||
private const int MemoryBuySkillIndex = 1;
|
||||
private const int MemorySellSkillIndex = 2;
|
||||
private const int PostMatchEquipmentSkillIndex = 4;
|
||||
private const int SmeltDiscountSkillIndex = 5;
|
||||
private const int ScoreToMaterialSkillIndex = 6;
|
||||
private const int RevealLockedIdolSkillsSkillIndex = 7;
|
||||
private const int SpendRefundSkillIndex = 8;
|
||||
private const int ScoreToCoinsSkillIndex = 9;
|
||||
private const int CameraAngleSkillIndex = 10;
|
||||
private const int MemoryBuyStoreItemId = 799001;
|
||||
private const int MemorySellStoreItemId = 799002;
|
||||
private const int RandomMemoryStoreItemId = 78141;
|
||||
private const float SpendRefundPerOwnedHero = 0.005f;
|
||||
private const float MaxSpendRefundRate = 0.05f;
|
||||
|
||||
public static PlayerSkillService Instance { get; private set; }
|
||||
|
||||
private bool initialized;
|
||||
private PlayerSkillSaveData saveData;
|
||||
private userLevel_skills_SO registeredSkillAsset;
|
||||
private storeItemSO cachedRandomMemoryRewardItem;
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
private static void Bootstrap()
|
||||
{
|
||||
EnsureInstance();
|
||||
}
|
||||
|
||||
public static PlayerSkillService EnsureInstance()
|
||||
{
|
||||
if (Instance != null)
|
||||
{
|
||||
return Instance;
|
||||
}
|
||||
|
||||
GameObject host = new GameObject("__runtime_player_skill_bridge");
|
||||
host.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector;
|
||||
DontDestroyOnLoad(host);
|
||||
Instance = host.AddComponent<PlayerSkillService>();
|
||||
return Instance;
|
||||
}
|
||||
|
||||
public static void RegisterSkillAsset(userLevel_skills_SO skillAsset)
|
||||
{
|
||||
EnsureInstance().RegisterAssetInternal(skillAsset);
|
||||
}
|
||||
|
||||
public static bool IsSkillEnabled(int skillIndex)
|
||||
{
|
||||
return EnsureInstance().IsSkillEnabledInternal(skillIndex);
|
||||
}
|
||||
|
||||
public static int GetSelectedSkillIndex()
|
||||
{
|
||||
return EnsureInstance().GetSelectedSkillIndexInternal();
|
||||
}
|
||||
|
||||
public static int GetSkillSwitchCooldownRemainingMatches()
|
||||
{
|
||||
return EnsureInstance().GetSkillSwitchCooldownRemainingMatchesInternal();
|
||||
}
|
||||
|
||||
public static void ConfirmSkillSelection(userLevel_skills_SO skillAsset, int selectedIndex)
|
||||
{
|
||||
EnsureInstance().ConfirmSkillSelectionInternal(skillAsset, selectedIndex);
|
||||
}
|
||||
|
||||
public static int ModifySmeltCoinCost(int baseCost)
|
||||
{
|
||||
if (!IsSkillEnabled(SmeltDiscountSkillIndex))
|
||||
{
|
||||
return Mathf.Max(0, baseCost);
|
||||
}
|
||||
|
||||
return Mathf.CeilToInt(Mathf.Max(0, baseCost) * 0.5f);
|
||||
}
|
||||
|
||||
public static int GetCoinRefundAmount(int spentCoins)
|
||||
{
|
||||
return EnsureInstance().GetRefundAmount(spentCoins);
|
||||
}
|
||||
|
||||
public static int GetMaterialRefundAmount(int spentMaterial)
|
||||
{
|
||||
return EnsureInstance().GetRefundAmount(spentMaterial);
|
||||
}
|
||||
|
||||
public static void NotifySettlementCompleted(int idolScore)
|
||||
{
|
||||
EnsureInstance().HandleSettlementCompletedInternal(idolScore);
|
||||
}
|
||||
|
||||
public static void AppendDynamicStoreItems(List<storeItemSO> target, Sprite coinSprite, Sprite materialSprite)
|
||||
{
|
||||
EnsureInstance().AppendDynamicStoreItemsInternal(target, coinSprite, materialSprite);
|
||||
}
|
||||
|
||||
public static bool IsPlayerSkillStoreItem(storeItemSO item)
|
||||
{
|
||||
return item != null && (item.itemID == MemoryBuyStoreItemId || item.itemID == MemorySellStoreItemId);
|
||||
}
|
||||
|
||||
public static bool TryPurchasePlayerSkillStoreItem(storeItemSO item, int amount, out string failureMessage, out gItemGet.ItemEntry rewardEntry)
|
||||
{
|
||||
return EnsureInstance().TryPurchasePlayerSkillStoreItemInternal(item, amount, out failureMessage, out rewardEntry);
|
||||
}
|
||||
|
||||
public static void ClearPersistentState()
|
||||
{
|
||||
EnsureInstance().ClearPersistentStateInternal();
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
Instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
InitializeIfNeeded();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
SceneManager.sceneLoaded += HandleSceneLoaded;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
SceneManager.sceneLoaded -= HandleSceneLoaded;
|
||||
}
|
||||
|
||||
private void OnApplicationPause(bool pauseStatus)
|
||||
{
|
||||
if (pauseStatus)
|
||||
{
|
||||
SaveNow();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnApplicationQuit()
|
||||
{
|
||||
SaveNow();
|
||||
}
|
||||
|
||||
private void InitializeIfNeeded()
|
||||
{
|
||||
if (initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
if (!SecureSaveVault.TryLoadJson(SaveCategory, SaveKey, out saveData) || saveData == null)
|
||||
{
|
||||
saveData = new PlayerSkillSaveData();
|
||||
}
|
||||
|
||||
ResolveSkillAssetIfNeeded();
|
||||
SyncSelectionFromAsset();
|
||||
ApplySceneBindings();
|
||||
}
|
||||
|
||||
private void RegisterAssetInternal(userLevel_skills_SO skillAsset)
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
|
||||
if (skillAsset == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
registeredSkillAsset = skillAsset;
|
||||
SyncSelectionFromAsset();
|
||||
ApplySceneBindings();
|
||||
}
|
||||
|
||||
private bool IsSkillEnabledInternal(int skillIndex)
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
ResolveSkillAssetIfNeeded();
|
||||
SyncSelectionFromAsset();
|
||||
return saveData != null && saveData.selectedSkillIndex == skillIndex;
|
||||
}
|
||||
|
||||
private int GetSelectedSkillIndexInternal()
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
ResolveSkillAssetIfNeeded();
|
||||
SyncSelectionFromAsset();
|
||||
return saveData != null ? saveData.selectedSkillIndex : -1;
|
||||
}
|
||||
|
||||
private int GetSkillSwitchCooldownRemainingMatchesInternal()
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
return saveData != null ? Mathf.Max(0, saveData.skillSwitchCooldownRemainingMatches) : 0;
|
||||
}
|
||||
|
||||
private int GetRefundAmount(int spendAmount)
|
||||
{
|
||||
if (spendAmount <= 0 || !IsSkillEnabledInternal(SpendRefundSkillIndex))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
float refundRate = Mathf.Min(GetOwnedHeroCount() * SpendRefundPerOwnedHero, MaxSpendRefundRate);
|
||||
if (refundRate <= 0f)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Mathf.FloorToInt(spendAmount * refundRate);
|
||||
}
|
||||
|
||||
private void HandleSettlementCompletedInternal(int idolScore)
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
ResolveSkillAssetIfNeeded();
|
||||
SyncSelectionFromAsset();
|
||||
|
||||
if (saveData.skillSwitchCooldownRemainingMatches > 0)
|
||||
{
|
||||
saveData.skillSwitchCooldownRemainingMatches = Mathf.Max(0, saveData.skillSwitchCooldownRemainingMatches - 1);
|
||||
}
|
||||
|
||||
List<gItemGet.ItemEntry> grantedEntries = new List<gItemGet.ItemEntry>();
|
||||
|
||||
if (IsSkillEnabledInternal(PostMatchEquipmentSkillIndex))
|
||||
{
|
||||
saveData.postMatchRewardCounter = Mathf.Max(0, saveData.postMatchRewardCounter) + 1;
|
||||
if (saveData.postMatchRewardCounter >= 10)
|
||||
{
|
||||
saveData.postMatchRewardCounter = 0;
|
||||
equipmentSO generated = GrantRandomMemoryFromConfiguredSource();
|
||||
if (generated != null)
|
||||
{
|
||||
grantedEntries.Add(gItemGet.FromEquipment(generated, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (idolScore > 0 && IsSkillEnabledInternal(ScoreToMaterialSkillIndex))
|
||||
{
|
||||
int grantedMaterial = Mathf.FloorToInt(idolScore * 0.001f);
|
||||
if (grantedMaterial > 0)
|
||||
{
|
||||
PlayerEconomyLedger.EnsureInstance().AddMaterial(grantedMaterial);
|
||||
grantedEntries.Add(gItemGet.Create("\u8bb0\u5fc6\u788e\u7247", null, grantedMaterial, ItemRarity.Uncommon));
|
||||
}
|
||||
}
|
||||
|
||||
if (idolScore > 0 && IsSkillEnabledInternal(ScoreToCoinsSkillIndex))
|
||||
{
|
||||
int grantedCoins = Mathf.FloorToInt(idolScore * 0.002f);
|
||||
if (grantedCoins > 0)
|
||||
{
|
||||
PlayerEconomyLedger.EnsureInstance().AddCoins(grantedCoins);
|
||||
grantedEntries.Add(gItemGet.Create("\u91d1\u5e01", null, grantedCoins, new Color32(240, 196, 74, 255)));
|
||||
}
|
||||
}
|
||||
|
||||
SaveNow();
|
||||
|
||||
if (grantedEntries.Count > 0)
|
||||
{
|
||||
gItemGet.display(grantedEntries);
|
||||
}
|
||||
}
|
||||
|
||||
private void AppendDynamicStoreItemsInternal(List<storeItemSO> target, Sprite coinSprite, Sprite materialSprite)
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
ResolveSkillAssetIfNeeded();
|
||||
SyncSelectionFromAsset();
|
||||
|
||||
if (target == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsSkillEnabledInternal(MemoryBuySkillIndex))
|
||||
{
|
||||
target.Add(CreateMemoryBuyStoreItem(materialSprite));
|
||||
}
|
||||
|
||||
if (IsSkillEnabledInternal(MemorySellSkillIndex))
|
||||
{
|
||||
target.Add(CreateMemorySellStoreItem(coinSprite));
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryPurchasePlayerSkillStoreItemInternal(storeItemSO item, int amount, out string failureMessage, out gItemGet.ItemEntry rewardEntry)
|
||||
{
|
||||
failureMessage = string.Empty;
|
||||
rewardEntry = default;
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
failureMessage = "\u5546\u54c1\u6570\u636e\u4e22\u5931";
|
||||
return false;
|
||||
}
|
||||
|
||||
int purchaseAmount = Mathf.Max(1, amount);
|
||||
if (item.itemID == MemoryBuyStoreItemId)
|
||||
{
|
||||
int totalCost = purchaseAmount * 10;
|
||||
if (!PlayerEconomyLedger.EnsureInstance().TrySpendCoins(totalCost))
|
||||
{
|
||||
failureMessage = "\u8d27\u5e01\u4e0d\u8db3";
|
||||
return false;
|
||||
}
|
||||
|
||||
PlayerEconomyLedger.EnsureInstance().AddMaterial(purchaseAmount);
|
||||
rewardEntry = gItemGet.Create("\u8bb0\u5fc6\u788e\u7247", item.itemIcon, purchaseAmount, ItemRarity.Uncommon);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (item.itemID == MemorySellStoreItemId)
|
||||
{
|
||||
if (!PlayerEconomyLedger.EnsureInstance().TrySpendMaterial(purchaseAmount))
|
||||
{
|
||||
failureMessage = "\u8bb0\u5fc6\u788e\u7247\u4e0d\u8db3";
|
||||
return false;
|
||||
}
|
||||
|
||||
int grantedCoins = purchaseAmount * 4;
|
||||
PlayerEconomyLedger.EnsureInstance().AddCoins(grantedCoins);
|
||||
rewardEntry = gItemGet.Create("\u91d1\u5e01", item.itemIcon, grantedCoins, new Color32(240, 196, 74, 255));
|
||||
return true;
|
||||
}
|
||||
|
||||
failureMessage = "\u5f53\u524d\u672a\u914d\u7f6e\u53d1\u653e\u903b\u8f91";
|
||||
return false;
|
||||
}
|
||||
|
||||
private void ConfirmSkillSelectionInternal(userLevel_skills_SO skillAsset, int selectedIndex)
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
if (skillAsset == null || skillAsset.skills == null || selectedIndex < 0 || selectedIndex >= skillAsset.skills.Count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
registeredSkillAsset = skillAsset;
|
||||
|
||||
for (int i = 0; i < skillAsset.skills.Count; i++)
|
||||
{
|
||||
userLevel_skills_SO.UserLevelSkillEntry entry = skillAsset.skills[i];
|
||||
if (entry == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
entry.isEnabled = (i == selectedIndex);
|
||||
}
|
||||
|
||||
if (saveData.selectedSkillIndex != selectedIndex)
|
||||
{
|
||||
saveData.postMatchRewardCounter = 0;
|
||||
saveData.skillSwitchCooldownRemainingMatches = 3;
|
||||
}
|
||||
|
||||
saveData.selectedSkillIndex = selectedIndex;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
UnityEditor.EditorUtility.SetDirty(skillAsset);
|
||||
}
|
||||
#endif
|
||||
|
||||
SaveNow();
|
||||
ApplySceneBindings();
|
||||
}
|
||||
|
||||
private void ClearPersistentStateInternal()
|
||||
{
|
||||
saveData = new PlayerSkillSaveData();
|
||||
SecureSaveVault.Delete(SaveCategory, SaveKey);
|
||||
ApplySceneBindings();
|
||||
}
|
||||
|
||||
private void HandleSceneLoaded(Scene scene, LoadSceneMode mode)
|
||||
{
|
||||
ApplySceneBindings();
|
||||
}
|
||||
|
||||
private void ApplySceneBindings()
|
||||
{
|
||||
bool revealLockedSkills = IsSkillEnabledInternal(RevealLockedIdolSkillsSkillIndex);
|
||||
|
||||
idolSkillsHub[] hubs = Resources.FindObjectsOfTypeAll<idolSkillsHub>();
|
||||
for (int i = 0; i < hubs.Length; i++)
|
||||
{
|
||||
idolSkillsHub hub = hubs[i];
|
||||
if (hub == null || !IsSceneInstance(hub))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hub.display_ungotten != revealLockedSkills)
|
||||
{
|
||||
hub.display_ungotten = revealLockedSkills;
|
||||
if (hub.gameObject.activeInHierarchy)
|
||||
{
|
||||
hub.Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
storeSystem[] stores = Resources.FindObjectsOfTypeAll<storeSystem>();
|
||||
for (int i = 0; i < stores.Length; i++)
|
||||
{
|
||||
if (stores[i] != null && IsSceneInstance(stores[i]))
|
||||
{
|
||||
stores[i].RefreshPlayerSkillItems();
|
||||
}
|
||||
}
|
||||
|
||||
equipSmelt[] smelters = Resources.FindObjectsOfTypeAll<equipSmelt>();
|
||||
for (int i = 0; i < smelters.Length; i++)
|
||||
{
|
||||
if (smelters[i] != null && IsSceneInstance(smelters[i]))
|
||||
{
|
||||
smelters[i].RefreshPlayerSkillAdjustedUi();
|
||||
}
|
||||
}
|
||||
|
||||
effectEventController.RefreshPlayerSkillCameraOffset();
|
||||
}
|
||||
|
||||
private void ResolveSkillAssetIfNeeded()
|
||||
{
|
||||
if (registeredSkillAsset != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uLevel_skills[] skillPanels = Resources.FindObjectsOfTypeAll<uLevel_skills>();
|
||||
for (int i = 0; i < skillPanels.Length; i++)
|
||||
{
|
||||
if (skillPanels[i] != null && skillPanels[i].ulsSO != null)
|
||||
{
|
||||
registeredSkillAsset = skillPanels[i].ulsSO;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
userLevel_skills_SO[] loadedAssets = Resources.FindObjectsOfTypeAll<userLevel_skills_SO>();
|
||||
for (int i = 0; i < loadedAssets.Length; i++)
|
||||
{
|
||||
if (loadedAssets[i] != null)
|
||||
{
|
||||
registeredSkillAsset = loadedAssets[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
registeredSkillAsset = UnityEditor.AssetDatabase.LoadAssetAtPath<userLevel_skills_SO>(SkillAssetEditorPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
private void SyncSelectionFromAsset()
|
||||
{
|
||||
if (saveData == null || registeredSkillAsset == null || registeredSkillAsset.skills == null || registeredSkillAsset.skills.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int enabledIndex = -1;
|
||||
for (int i = 0; i < registeredSkillAsset.skills.Count; i++)
|
||||
{
|
||||
userLevel_skills_SO.UserLevelSkillEntry entry = registeredSkillAsset.skills[i];
|
||||
if (entry != null && entry.isEnabled)
|
||||
{
|
||||
enabledIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (enabledIndex == saveData.selectedSkillIndex)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (saveData.selectedSkillIndex >= 0)
|
||||
{
|
||||
saveData.postMatchRewardCounter = 0;
|
||||
}
|
||||
|
||||
saveData.selectedSkillIndex = enabledIndex;
|
||||
SaveNow();
|
||||
}
|
||||
|
||||
private storeItemSO CreateMemoryBuyStoreItem(Sprite materialSprite)
|
||||
{
|
||||
storeItemSO item = ScriptableObject.CreateInstance<storeItemSO>();
|
||||
item.hideFlags = HideFlags.DontSave;
|
||||
item.itemID = MemoryBuyStoreItemId;
|
||||
item.itemName = "1\u8bb0\u5fc6\u788e\u7247";
|
||||
item.itemIcon = materialSprite;
|
||||
item.itemRarity = ItemRarity.Uncommon;
|
||||
item.itemSinglePurchaseQty = 1;
|
||||
item.itemPurchaseQuota = -1;
|
||||
item.itemDescription = "\u82b1\u8d3910\u91d1\u5e01\u8d2d\u4e701\u4e2a\u8bb0\u5fc6\u788e\u7247\u3002";
|
||||
item.itemDetailedDescription = "\u73a9\u5bb6\u6280\u80fd\u201c\u8bb0\u5fc6\u8d2d\u4e70\u8ba1\u5212\u201d\u751f\u6548\u4e2d\u3002\u82b1\u8d3910\u91d1\u5e01\u8d2d\u4e701\u4e2a\u8bb0\u5fc6\u788e\u7247\u3002";
|
||||
item.isOnShelf = true;
|
||||
item.canbepurchased = true;
|
||||
item.itemType = storeItemSO.ItemType.consumable;
|
||||
item.costRequirements = new List<storeItemSO.CostRequirement>
|
||||
{
|
||||
new storeItemSO.CostRequirement
|
||||
{
|
||||
currencyType = storeItemSO.CurrencyType.coins,
|
||||
amount = 10
|
||||
}
|
||||
};
|
||||
item.unlockRequirements = new List<storeItemSO.UnlockRequirement>();
|
||||
return item;
|
||||
}
|
||||
|
||||
private storeItemSO CreateMemorySellStoreItem(Sprite coinSprite)
|
||||
{
|
||||
storeItemSO item = ScriptableObject.CreateInstance<storeItemSO>();
|
||||
item.hideFlags = HideFlags.DontSave;
|
||||
item.itemID = MemorySellStoreItemId;
|
||||
item.itemName = "4\u91d1\u5e01";
|
||||
item.itemIcon = coinSprite;
|
||||
item.itemRarity = ItemRarity.Common;
|
||||
item.itemSinglePurchaseQty = 1;
|
||||
item.itemPurchaseQuota = -1;
|
||||
item.itemDescription = "\u6d88\u80171\u4e2a\u8bb0\u5fc6\u788e\u7247\uff0c\u6362\u53d64\u91d1\u5e01\u3002";
|
||||
item.itemDetailedDescription = "\u73a9\u5bb6\u6280\u80fd\u201c\u8bb0\u5fc6\u5f52\u8fd8\u8ba1\u5212\u201d\u751f\u6548\u4e2d\u3002\u6d88\u80171\u4e2a\u8bb0\u5fc6\u788e\u7247\uff0c\u6362\u53d64\u91d1\u5e01\u3002";
|
||||
item.isOnShelf = true;
|
||||
item.canbepurchased = true;
|
||||
item.itemType = storeItemSO.ItemType.consumable;
|
||||
item.costRequirements = new List<storeItemSO.CostRequirement>
|
||||
{
|
||||
new storeItemSO.CostRequirement
|
||||
{
|
||||
currencyType = storeItemSO.CurrencyType.material,
|
||||
amount = 1
|
||||
}
|
||||
};
|
||||
item.unlockRequirements = new List<storeItemSO.UnlockRequirement>();
|
||||
return item;
|
||||
}
|
||||
|
||||
private equipmentSO GrantRandomMemoryFromConfiguredSource()
|
||||
{
|
||||
storeItemSO randomMemoryItem = ResolveRandomMemoryRewardItem();
|
||||
if (randomMemoryItem == null || randomMemoryItem.associatedSelectableEquipmentRewardSource == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
smeltStageRewardSO rewardSource = randomMemoryItem.associatedSelectableEquipmentRewardSource;
|
||||
int rewardIndex = Mathf.Max(0, randomMemoryItem.associatedSelectableEquipmentRewardIndex);
|
||||
if (rewardSource.rewardRequirements == null || rewardIndex >= rewardSource.rewardRequirements.Length)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return equipmentGenerator.GenerateFromSmeltReward(rewardSource, rewardSource.rewardRequirements[rewardIndex]);
|
||||
}
|
||||
|
||||
private storeItemSO ResolveRandomMemoryRewardItem()
|
||||
{
|
||||
if (cachedRandomMemoryRewardItem != null)
|
||||
{
|
||||
return cachedRandomMemoryRewardItem;
|
||||
}
|
||||
|
||||
storeItemSO[] items = Resources.LoadAll<storeItemSO>("so/storeSO");
|
||||
for (int i = 0; i < items.Length; i++)
|
||||
{
|
||||
if (items[i] != null && items[i].itemID == RandomMemoryStoreItemId)
|
||||
{
|
||||
cachedRandomMemoryRewardItem = items[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return cachedRandomMemoryRewardItem;
|
||||
}
|
||||
|
||||
private int GetOwnedHeroCount()
|
||||
{
|
||||
HashSet<int> heroIds = new HashSet<int>();
|
||||
AllyHero_SO[] heroes = Resources.LoadAll<AllyHero_SO>(string.Empty);
|
||||
if (heroes == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < heroes.Length; i++)
|
||||
{
|
||||
AllyHero_SO hero = heroes[i];
|
||||
if (hero != null && hero.isUnlocked)
|
||||
{
|
||||
heroIds.Add(hero.ally_heroID);
|
||||
}
|
||||
}
|
||||
|
||||
return heroIds.Count;
|
||||
}
|
||||
|
||||
private bool IsSceneInstance(Component component)
|
||||
{
|
||||
if (component == null || component.gameObject == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Scene scene = component.gameObject.scene;
|
||||
return scene.IsValid() && scene.isLoaded;
|
||||
}
|
||||
|
||||
private void SaveNow()
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SecureSaveVault.SaveJson(SaveCategory, SaveKey, saveData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3fc9125cbd0b7134ea8ac541779cb715
|
||||
@@ -38,6 +38,7 @@ public class dailyTaskManager : MonoBehaviour
|
||||
|
||||
private readonly List<GameObject> spawnedTaskItems = new List<GameObject>();
|
||||
private readonly Dictionary<int, Sprite> rewardSpriteByItemId = new Dictionary<int, Sprite>();
|
||||
private readonly Dictionary<int, storeItemSO> rewardStoreItemByItemId = new Dictionary<int, storeItemSO>();
|
||||
|
||||
private void Start()
|
||||
{
|
||||
@@ -157,6 +158,7 @@ public class dailyTaskManager : MonoBehaviour
|
||||
|
||||
private void OnSingleRewardClicked(string taskID)
|
||||
{
|
||||
var rewardEntry = BuildRewardEntryForTask(taskID);
|
||||
string failureMessage;
|
||||
if (!DailyTaskService.EnsureInstance().TryClaimReward(taskID, playerData, out failureMessage))
|
||||
{
|
||||
@@ -168,15 +170,57 @@ public class dailyTaskManager : MonoBehaviour
|
||||
return;
|
||||
}
|
||||
|
||||
if (rewardEntry.HasValue)
|
||||
{
|
||||
gItemGet.display(rewardEntry.Value);
|
||||
}
|
||||
|
||||
RefreshTaskUi();
|
||||
}
|
||||
|
||||
private void OnOneKeyRewardClicked()
|
||||
{
|
||||
string failureMessage;
|
||||
int claimedCount = DailyTaskService.EnsureInstance().ClaimAllAvailableRewards(playerData, out failureMessage);
|
||||
var taskService = DailyTaskService.EnsureInstance();
|
||||
var tasks = taskService.GetActiveTaskViews();
|
||||
var grantedEntries = new List<gItemGet.ItemEntry>();
|
||||
string failureMessage = string.Empty;
|
||||
int claimedCount = 0;
|
||||
|
||||
for (int i = 0; i < tasks.Count; i++)
|
||||
{
|
||||
var taskView = tasks[i];
|
||||
if (taskView == null || taskView.runtimeEntry == null || taskView.definition == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!taskView.runtimeEntry.isCompleted || taskView.runtimeEntry.isClaimed)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string claimError;
|
||||
if (!taskService.TryClaimReward(taskView.runtimeEntry.taskID, playerData, out claimError))
|
||||
{
|
||||
if (claimedCount <= 0 && string.IsNullOrEmpty(failureMessage))
|
||||
{
|
||||
failureMessage = claimError;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
claimedCount += 1;
|
||||
grantedEntries.Add(BuildRewardEntry(taskView.definition));
|
||||
}
|
||||
|
||||
if (claimedCount <= 0)
|
||||
{
|
||||
if (string.IsNullOrEmpty(failureMessage))
|
||||
{
|
||||
failureMessage = "暂无可领取奖励";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(failureMessage))
|
||||
{
|
||||
gNotice.warning.display(failureMessage);
|
||||
@@ -185,6 +229,11 @@ public class dailyTaskManager : MonoBehaviour
|
||||
return;
|
||||
}
|
||||
|
||||
if (grantedEntries.Count > 0)
|
||||
{
|
||||
gItemGet.display(grantedEntries);
|
||||
}
|
||||
|
||||
RefreshTaskUi();
|
||||
}
|
||||
|
||||
@@ -274,18 +323,24 @@ public class dailyTaskManager : MonoBehaviour
|
||||
private void CacheRewardSpritesFromStoreItems()
|
||||
{
|
||||
rewardSpriteByItemId.Clear();
|
||||
rewardStoreItemByItemId.Clear();
|
||||
|
||||
var rewardStoreItems = Resources.LoadAll<storeItemSO>("so/storeSO");
|
||||
for (int i = 0; i < rewardStoreItems.Length; i++)
|
||||
{
|
||||
var itemSO = rewardStoreItems[i];
|
||||
if (itemSO == null || itemSO.itemIcon == null)
|
||||
if (itemSO == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (itemSO.itemIcon != null)
|
||||
{
|
||||
rewardSpriteByItemId[itemSO.itemID] = itemSO.itemIcon;
|
||||
}
|
||||
|
||||
rewardStoreItemByItemId[itemSO.itemID] = itemSO;
|
||||
}
|
||||
}
|
||||
|
||||
private Sprite GetRewardSpriteByItemId(int itemId)
|
||||
@@ -299,6 +354,80 @@ public class dailyTaskManager : MonoBehaviour
|
||||
return rewardSpriteByItemId.TryGetValue(itemId, out sprite) ? sprite : null;
|
||||
}
|
||||
|
||||
private gItemGet.ItemEntry? BuildRewardEntryForTask(string taskID)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(taskID))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var tasks = DailyTaskService.EnsureInstance().GetActiveTaskViews();
|
||||
for (int i = 0; i < tasks.Count; i++)
|
||||
{
|
||||
var taskView = tasks[i];
|
||||
if (taskView == null || taskView.runtimeEntry == null || taskView.definition == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.Equals(taskView.runtimeEntry.taskID, taskID, System.StringComparison.Ordinal))
|
||||
{
|
||||
return BuildRewardEntry(taskView.definition);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private gItemGet.ItemEntry BuildRewardEntry(userTasksPool.TaskDefinition definition)
|
||||
{
|
||||
if (definition == null)
|
||||
{
|
||||
return gItemGet.Create("未知奖励", null, 1, ItemRarity.None);
|
||||
}
|
||||
|
||||
switch (definition.rewardType)
|
||||
{
|
||||
case userTasksPool.RewardType.coins:
|
||||
return gItemGet.Create("Coins", coinRewardSprite, Mathf.Max(1, definition.rewardAmount), ItemRarity.Common);
|
||||
|
||||
case userTasksPool.RewardType.expBottle:
|
||||
{
|
||||
int itemId = GetExpBottleRewardItemId(definition.rewardExpBottleKind);
|
||||
storeItemSO itemSO;
|
||||
if (rewardStoreItemByItemId.TryGetValue(itemId, out itemSO) && itemSO != null)
|
||||
{
|
||||
return gItemGet.FromStoreItem(itemSO, Mathf.Max(1, definition.rewardAmount));
|
||||
}
|
||||
|
||||
return gItemGet.Create(
|
||||
ExpBottleCatalog.GetDisplayName(definition.rewardExpBottleKind),
|
||||
GetRewardSpriteByItemId(itemId),
|
||||
Mathf.Max(1, definition.rewardAmount),
|
||||
ItemRarity.None);
|
||||
}
|
||||
|
||||
case userTasksPool.RewardType.dushMaterial:
|
||||
{
|
||||
int itemId = GetDushMaterialRewardItemId(definition.rewardDushMaterialKind);
|
||||
storeItemSO itemSO;
|
||||
if (rewardStoreItemByItemId.TryGetValue(itemId, out itemSO) && itemSO != null)
|
||||
{
|
||||
return gItemGet.FromStoreItem(itemSO, Mathf.Max(1, definition.rewardAmount));
|
||||
}
|
||||
|
||||
return gItemGet.Create(
|
||||
DushMaterialCatalog.GetDisplayName(definition.rewardDushMaterialKind),
|
||||
GetRewardSpriteByItemId(itemId),
|
||||
Mathf.Max(1, definition.rewardAmount),
|
||||
ItemRarity.None);
|
||||
}
|
||||
|
||||
default:
|
||||
return gItemGet.Create("未知奖励", null, Mathf.Max(1, definition.rewardAmount), ItemRarity.None);
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetExpBottleRewardItemId(ExpBottleKind kind)
|
||||
{
|
||||
switch (kind)
|
||||
|
||||
@@ -3,6 +3,11 @@ using System.Collections;
|
||||
|
||||
public class Animation_GenerateJudgementSituationPrefab : MonoBehaviour
|
||||
{
|
||||
private sealed class PooledJudgeTag : MonoBehaviour
|
||||
{
|
||||
public GameObject prefabSource;
|
||||
}
|
||||
|
||||
public static Animation_GenerateJudgementSituationPrefab Instance;
|
||||
|
||||
[Header("Inspector")]
|
||||
@@ -42,6 +47,9 @@ public class Animation_GenerateJudgementSituationPrefab : MonoBehaviour
|
||||
|
||||
// Track last scene to detect scene changes
|
||||
private int lastSceneIndex = -1;
|
||||
private Coroutine prewarmJudgeCoroutine;
|
||||
private readonly System.Collections.Generic.Dictionary<GameObject, System.Collections.Generic.Stack<GameObject>> judgePools
|
||||
= new System.Collections.Generic.Dictionary<GameObject, System.Collections.Generic.Stack<GameObject>>();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
@@ -147,7 +155,10 @@ public class Animation_GenerateJudgementSituationPrefab : MonoBehaviour
|
||||
|
||||
if (JudgeManager.IsDebugEnabled) Debug.Log($"[Animation_Generate] Spawning judge prefab: color={color}, result={judgeResult}, prefab={prefabToUse.name}");
|
||||
|
||||
GameObject instance = Instantiate(prefabToUse, spawnPoint);
|
||||
GameObject instance = GetPooledJudge(prefabToUse, spawnPoint);
|
||||
if (instance == null)
|
||||
return;
|
||||
|
||||
instance.transform.localPosition = Vector3.zero;
|
||||
|
||||
// Documentation text normalized.
|
||||
@@ -159,6 +170,52 @@ public class Animation_GenerateJudgementSituationPrefab : MonoBehaviour
|
||||
StartCoroutine(AnimateSprite(instance));
|
||||
}
|
||||
|
||||
public void PrewarmJudgePrefabs(int perPrefab = 1)
|
||||
{
|
||||
if (!Application.isPlaying)
|
||||
return;
|
||||
|
||||
if (prewarmJudgeCoroutine != null)
|
||||
{
|
||||
StopCoroutine(prewarmJudgeCoroutine);
|
||||
}
|
||||
|
||||
prewarmJudgeCoroutine = StartCoroutine(PrewarmJudgePrefabsRoutine(Mathf.Max(1, perPrefab)));
|
||||
}
|
||||
|
||||
public IEnumerator PrewarmJudgePrefabsRoutine(int perPrefab = 1)
|
||||
{
|
||||
GameObject[] prefabs =
|
||||
{
|
||||
perfect_judge_prefab,
|
||||
great_judge_prefab,
|
||||
good_judge_prefab,
|
||||
miss_judge_prefab
|
||||
};
|
||||
|
||||
int count = Mathf.Max(1, perPrefab);
|
||||
foreach (GameObject prefab in prefabs)
|
||||
{
|
||||
if (prefab == null)
|
||||
continue;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
GameObject instance = null;
|
||||
try
|
||||
{
|
||||
instance = CreatePooledJudge(prefab);
|
||||
ReturnJudgeToPool(instance);
|
||||
}
|
||||
catch { }
|
||||
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
prewarmJudgeCoroutine = null;
|
||||
}
|
||||
|
||||
private IEnumerator AnimateSprite(GameObject obj)
|
||||
{
|
||||
if (obj == null) yield break;
|
||||
@@ -232,7 +289,76 @@ public class Animation_GenerateJudgementSituationPrefab : MonoBehaviour
|
||||
|
||||
// Documentation text normalized.
|
||||
|
||||
if (obj != null) Destroy(obj);
|
||||
if (obj != null) ReturnJudgeToPool(obj);
|
||||
}
|
||||
|
||||
private GameObject GetPooledJudge(GameObject prefab, Transform parent)
|
||||
{
|
||||
if (prefab == null || parent == null)
|
||||
return null;
|
||||
|
||||
if (!judgePools.TryGetValue(prefab, out var pool))
|
||||
{
|
||||
pool = new System.Collections.Generic.Stack<GameObject>();
|
||||
judgePools[prefab] = pool;
|
||||
}
|
||||
|
||||
GameObject instance = null;
|
||||
while (pool.Count > 0 && instance == null)
|
||||
{
|
||||
instance = pool.Pop();
|
||||
}
|
||||
|
||||
if (instance == null)
|
||||
{
|
||||
instance = CreatePooledJudge(prefab);
|
||||
}
|
||||
|
||||
if (instance == null)
|
||||
return null;
|
||||
|
||||
instance.transform.SetParent(parent, false);
|
||||
instance.SetActive(true);
|
||||
return instance;
|
||||
}
|
||||
|
||||
private GameObject CreatePooledJudge(GameObject prefab)
|
||||
{
|
||||
if (prefab == null)
|
||||
return null;
|
||||
|
||||
GameObject instance = Instantiate(prefab, transform);
|
||||
var tag = instance.GetComponent<PooledJudgeTag>();
|
||||
if (tag == null)
|
||||
tag = instance.AddComponent<PooledJudgeTag>();
|
||||
tag.prefabSource = prefab;
|
||||
instance.SetActive(false);
|
||||
return instance;
|
||||
}
|
||||
|
||||
private void ReturnJudgeToPool(GameObject instance)
|
||||
{
|
||||
if (instance == null)
|
||||
return;
|
||||
|
||||
var tag = instance.GetComponent<PooledJudgeTag>();
|
||||
if (tag == null || tag.prefabSource == null)
|
||||
{
|
||||
Destroy(instance);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!judgePools.TryGetValue(tag.prefabSource, out var pool))
|
||||
{
|
||||
pool = new System.Collections.Generic.Stack<GameObject>();
|
||||
judgePools[tag.prefabSource] = pool;
|
||||
}
|
||||
|
||||
instance.transform.SetParent(transform, false);
|
||||
instance.transform.localPosition = new Vector3(99999f, 99999f, 0f);
|
||||
instance.transform.localRotation = Quaternion.identity;
|
||||
instance.SetActive(false);
|
||||
pool.Push(instance);
|
||||
}
|
||||
|
||||
private Transform GetSpawnPoint(string color)
|
||||
|
||||
@@ -9,6 +9,7 @@ public class NoteData
|
||||
public string color; // Documentation text normalized.
|
||||
public string type; // Documentation text normalized.
|
||||
public float length; // Documentation text normalized.
|
||||
public string noteFunction;
|
||||
|
||||
// New fields for judgement recording
|
||||
// judgeOffsetMs: signed offset in milliseconds recorded at judgement time
|
||||
|
||||
@@ -326,6 +326,9 @@ public class GameManager : MonoBehaviour
|
||||
{
|
||||
Debug.Log("GameManager Start() initialized");
|
||||
|
||||
// Move first-hit one-time setup cost into scene load instead of the first judged note.
|
||||
StartCoroutine(PrewarmGameplayFirstHitPath());
|
||||
|
||||
// --- Initialize Statistics ---
|
||||
currentSong = BeatmapManager.pendingSongData ?? SongDataHolder.SelectedSongData;
|
||||
if (currentSong != null && !GameConfig.autoPlayEnabled)
|
||||
@@ -489,6 +492,34 @@ public class GameManager : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator PrewarmGameplayFirstHitPath()
|
||||
{
|
||||
yield return null;
|
||||
|
||||
try
|
||||
{
|
||||
Note.PrewarmRuntimeCaches();
|
||||
HoldNote.PrewarmRuntimeCaches();
|
||||
|
||||
var judgeFx = Animation_GenerateJudgementSituationPrefab.Instance
|
||||
?? FindAnyObjectByType<Animation_GenerateJudgementSituationPrefab>();
|
||||
judgeFx?.PrewarmJudgePrefabs(1);
|
||||
|
||||
var fxEvent = effectEventController.Instance ?? FindAnyObjectByType<effectEventController>();
|
||||
if (fxEvent != null && fxEvent.isActiveAndEnabled)
|
||||
{
|
||||
// Cache target and pre-create SmoothShake via OnEnable/Awake path already present.
|
||||
}
|
||||
|
||||
var globalFx = globalNoteEffect.Instance ?? FindAnyObjectByType<globalNoteEffect>();
|
||||
globalFx?.PrewarmRuntime();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[GameManager] Gameplay prewarm failed: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
// Detect Space or yellow note key to request start (only before gameplay starts)
|
||||
|
||||
@@ -99,6 +99,18 @@ public class HoldNote : BaseNote
|
||||
return beatmapManagerCache;
|
||||
}
|
||||
|
||||
public static void PrewarmRuntimeCaches()
|
||||
{
|
||||
GetBeatmapManagerCached();
|
||||
if (allyCache == null || allyCache.Length < 10)
|
||||
allyCache = new AllyCombatant[10];
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
GetAllyForTrackCached(i);
|
||||
}
|
||||
}
|
||||
|
||||
private static float JudgeToPmMultiplier(string judgeResult)
|
||||
{
|
||||
switch (judgeResult)
|
||||
@@ -326,9 +338,10 @@ public class HoldNote : BaseNote
|
||||
}
|
||||
|
||||
private float cachedTravelTime = 1.0f; // Cached travel time for distance optimization
|
||||
private bool isSyncNote;
|
||||
|
||||
public void Setup(int id, int trackIndex, float speed, float time, float delay,
|
||||
bool isEnd, float scheduledEnd, string color, KeyCode key, string type, float travelTimeSeconds, NoteJudgeConfig judgeConfig, NoteData noteData)
|
||||
bool isEnd, float scheduledEnd, string color, KeyCode key, string type, float travelTimeSeconds, NoteJudgeConfig judgeConfig, NoteData noteData, bool isSync = false)
|
||||
{
|
||||
this.id = id;
|
||||
// Ensure singletons are up to date if they were re-initialized (e.g. on scene reload)
|
||||
@@ -347,6 +360,7 @@ public class HoldNote : BaseNote
|
||||
this.key = key;
|
||||
this.type = type;
|
||||
this.judgeConfig = judgeConfig;
|
||||
this.isSyncNote = isSync;
|
||||
|
||||
this.noteID = id.ToString();
|
||||
this.keyToPress = key;
|
||||
@@ -659,6 +673,13 @@ public class HoldNote : BaseNote
|
||||
InputManager.Instance?.ShowJudgeResult(trackIndex, result);
|
||||
teamUIController.Instance?.OnJudgeResult(result);
|
||||
JudgeSoundManager.Instance?.PlayJudgeSound(result);
|
||||
|
||||
if (isSyncNote)
|
||||
{
|
||||
effectEventController.TryTriggerMultiNoteShake();
|
||||
}
|
||||
|
||||
globalNoteEffect.TryTrigger(noteData != null ? noteData.noteFunction : null);
|
||||
}
|
||||
|
||||
private void OnTriggerEnter2D(Collider2D collision)
|
||||
@@ -975,6 +996,16 @@ public class HoldNote : BaseNote
|
||||
{
|
||||
ScheduleReturnToPool(0.2f);
|
||||
}
|
||||
|
||||
if (segment == NoteSegment.Start && isSyncNote && result != "Miss")
|
||||
{
|
||||
effectEventController.TryTriggerMultiNoteShake();
|
||||
}
|
||||
|
||||
if (segment == NoteSegment.Start && result != "Miss")
|
||||
{
|
||||
globalNoteEffect.TryTrigger(noteData != null ? noteData.noteFunction : null);
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator DelayedReturn()
|
||||
|
||||
@@ -11,6 +11,7 @@ public class Note : BaseNote
|
||||
private bool hasLock = false; // track whether we hold the track lock
|
||||
|
||||
private NoteData noteData;
|
||||
private bool isSyncNote;
|
||||
|
||||
[Header("Inspector")]
|
||||
public NoteJudgeConfig judgeConfig; // Documentation text normalized.
|
||||
@@ -42,6 +43,18 @@ public class Note : BaseNote
|
||||
return beatmapManagerCache;
|
||||
}
|
||||
|
||||
public static void PrewarmRuntimeCaches()
|
||||
{
|
||||
GetBeatmapManagerCached();
|
||||
if (allyCache == null || allyCache.Length < 10)
|
||||
allyCache = new AllyCombatant[10];
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
GetAllyForTrackCached(i);
|
||||
}
|
||||
}
|
||||
|
||||
private static float JudgeToPmMultiplier(string judgeResult)
|
||||
{
|
||||
switch (judgeResult)
|
||||
@@ -150,7 +163,7 @@ public class Note : BaseNote
|
||||
controller = GetComponent<NoteController>();
|
||||
}
|
||||
|
||||
public void Setup(KeyCode key, int trackIndex, float speed, float hitTime, string color, NoteJudgeConfig judgeConfig, NoteData data)
|
||||
public void Setup(KeyCode key, int trackIndex, float speed, float hitTime, string color, NoteJudgeConfig judgeConfig, NoteData data, bool isSync = false)
|
||||
{
|
||||
keyToPress = key;
|
||||
noteColor = color;
|
||||
@@ -161,6 +174,7 @@ public class Note : BaseNote
|
||||
hasLock = false;
|
||||
this.judgeConfig = judgeConfig;
|
||||
this.noteData = data;
|
||||
this.isSyncNote = isSync;
|
||||
|
||||
// Set miss deadline: hitTime + missRange (the latest time to judge before auto-miss)
|
||||
float missRange = (judgeConfig?.missRange ?? 0.5f);
|
||||
@@ -279,6 +293,13 @@ public class Note : BaseNote
|
||||
try { SkillBuilder.Instance?.NotifyNoteHit(TrackIndex, judgeResult, SkillDefinition.NoteTypeTrigger.Tap); } catch { }
|
||||
LogTapJudge(judgeResult, 0f, false, true, pressTime);
|
||||
|
||||
if (isSyncNote)
|
||||
{
|
||||
effectEventController.TryTriggerMultiNoteShake();
|
||||
}
|
||||
|
||||
globalNoteEffect.TryTrigger(noteData != null ? noteData.noteFunction : null);
|
||||
|
||||
Judge();
|
||||
}
|
||||
|
||||
@@ -437,6 +458,13 @@ public class Note : BaseNote
|
||||
|
||||
try { SkillBuilder.Instance?.NotifyNoteHit(TrackIndex, judgeResult, SkillDefinition.NoteTypeTrigger.Tap); } catch { }
|
||||
LogTapJudge(judgeResult, rawOffsetMs, rewrittenToPerfect, false, pressTime);
|
||||
|
||||
if (isSyncNote && judgeResult != "Miss")
|
||||
{
|
||||
effectEventController.TryTriggerMultiNoteShake();
|
||||
}
|
||||
|
||||
globalNoteEffect.TryTrigger(noteData != null ? noteData.noteFunction : null);
|
||||
}
|
||||
|
||||
Judge();
|
||||
|
||||
@@ -390,7 +390,7 @@ public class NoteSpawner : MonoBehaviour
|
||||
if (noteScript != null)
|
||||
{
|
||||
// Setup note script with timing parameters
|
||||
noteScript.Setup(key, noteData.trackIndex, noteSpeed, realtimeHit, noteData.color, judgeConfig, noteData);
|
||||
noteScript.Setup(key, noteData.trackIndex, noteSpeed, realtimeHit, noteData.color, judgeConfig, noteData, isSync);
|
||||
|
||||
// Configure controller for absolute positioning (replaces relative Translate)
|
||||
if (noteController != null)
|
||||
@@ -476,7 +476,7 @@ public class NoteSpawner : MonoBehaviour
|
||||
if (holdNote != null)
|
||||
{
|
||||
// pass realtime hit time (startTime + note.time) and delay 0, include globalHitDelay
|
||||
holdNote.Setup(holdNoteId, noteData.trackIndex, noteSpeed, baseHit, 0f, false, scheduledEndTime, noteData.color, key, "start", travelTime, judgeConfig, noteData);
|
||||
holdNote.Setup(holdNoteId, noteData.trackIndex, noteSpeed, baseHit, 0f, false, scheduledEndTime, noteData.color, key, "start", travelTime, judgeConfig, noteData, isSync);
|
||||
|
||||
// 使用流速倍率 sm 直接进行缩放,确保长条音符在 0.5-2.0 范围内依然能完美衔接
|
||||
float visualScale = sm;
|
||||
@@ -508,7 +508,7 @@ public class NoteSpawner : MonoBehaviour
|
||||
if (holdSeg != null)
|
||||
{
|
||||
// Documentation text normalized.
|
||||
holdSeg.Setup(holdNoteId, noteData.trackIndex, noteSpeed, baseHit, segmentDelay, false, scheduledEndTime, noteData.color, key, "middle", travelTime, judgeConfig, noteData);
|
||||
holdSeg.Setup(holdNoteId, noteData.trackIndex, noteSpeed, baseHit, segmentDelay, false, scheduledEndTime, noteData.color, key, "middle", travelTime, judgeConfig, noteData, false);
|
||||
|
||||
// 应用与开始段一致的流速缩放
|
||||
float visualScaleMid = sm;
|
||||
@@ -540,7 +540,7 @@ public class NoteSpawner : MonoBehaviour
|
||||
HoldNote holdEnd = endObj.GetComponent<HoldNote>();
|
||||
if (holdEnd != null)
|
||||
{
|
||||
holdEnd.Setup(holdNoteId, noteData.trackIndex, noteSpeed, baseHit, endDelay, true, scheduledEndTime, noteData.color, key, "end", travelTime, judgeConfig, noteData);
|
||||
holdEnd.Setup(holdNoteId, noteData.trackIndex, noteSpeed, baseHit, endDelay, true, scheduledEndTime, noteData.color, key, "end", travelTime, judgeConfig, noteData, false);
|
||||
|
||||
// 同样应用流速缩放
|
||||
float visualScaleEnd = sm;
|
||||
|
||||
@@ -0,0 +1,314 @@
|
||||
using SmoothShakeFree;
|
||||
using UnityEngine;
|
||||
|
||||
public class effectEventController : MonoBehaviour
|
||||
{
|
||||
public enum CameraOffsetAxis
|
||||
{
|
||||
X,
|
||||
Y,
|
||||
Z
|
||||
}
|
||||
|
||||
public static effectEventController Instance { get; private set; }
|
||||
|
||||
[Header("Multi Note Screen Shake")]
|
||||
public bool enableMultiNoteScreenShake = true;
|
||||
public float multiNoteScreenShakeAmplitude = 0.08f;
|
||||
|
||||
[Header("Camera Drift")]
|
||||
public bool enableCameraDrift = false;
|
||||
public Vector2 cameraDriftRange = new Vector2(0.15f, 0.08f);
|
||||
public float cameraDriftSpeed = 0.3f;
|
||||
|
||||
[Header("Player Skill 10 Camera Offset")]
|
||||
public float playerSkillCameraOffsetAmount = 0.6f;
|
||||
public CameraOffsetAxis playerSkillCameraOffsetAxis = CameraOffsetAxis.Y;
|
||||
|
||||
private Transform cachedShakeTarget;
|
||||
private Transform cachedCameraDriftPivot;
|
||||
private Transform cachedCameraSkillPivot;
|
||||
private Vector3 cameraDriftBaseLocalPosition;
|
||||
private Vector3 cameraSkillBaseLocalPosition;
|
||||
private float cameraDriftSeedX;
|
||||
private float cameraDriftSeedY;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance == null)
|
||||
{
|
||||
Instance = this;
|
||||
cameraDriftSeedX = Random.Range(0f, 1000f);
|
||||
cameraDriftSeedY = Random.Range(1000f, 2000f);
|
||||
CacheShakeTarget();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
CacheShakeTarget();
|
||||
ResetCameraDriftIfNeeded();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
UpdateCameraDrift();
|
||||
UpdatePlayerSkillCameraOffset();
|
||||
}
|
||||
|
||||
private void CacheShakeTarget()
|
||||
{
|
||||
if (Camera.main != null)
|
||||
{
|
||||
cachedShakeTarget = Camera.main.transform;
|
||||
PrewarmShakeComponent();
|
||||
EnsureCameraDriftPivot();
|
||||
EnsureCameraSkillPivot();
|
||||
}
|
||||
}
|
||||
|
||||
private void PrewarmShakeComponent()
|
||||
{
|
||||
if (cachedShakeTarget == null)
|
||||
return;
|
||||
|
||||
SmoothShake shake = cachedShakeTarget.GetComponent<SmoothShake>();
|
||||
if (shake == null)
|
||||
{
|
||||
shake = cachedShakeTarget.gameObject.AddComponent<SmoothShake>();
|
||||
}
|
||||
|
||||
if (shake.positionShake == null) shake.positionShake = new Shaker();
|
||||
if (shake.rotationShake == null) shake.rotationShake = new Shaker();
|
||||
if (shake.shakers == null || shake.shakers.Length != 2)
|
||||
shake.shakers = new[] { shake.positionShake, shake.rotationShake };
|
||||
if (shake.sum == null || shake.sum.Length != 2)
|
||||
shake.sum = new Vector3[2];
|
||||
}
|
||||
|
||||
private void EnsureCameraDriftPivot()
|
||||
{
|
||||
if (cachedShakeTarget == null)
|
||||
return;
|
||||
|
||||
if (cachedCameraDriftPivot != null)
|
||||
return;
|
||||
|
||||
Transform currentParent = cachedShakeTarget.parent;
|
||||
if (currentParent != null && currentParent.name == "__effect_event_camera_drift_pivot")
|
||||
{
|
||||
cachedCameraDriftPivot = currentParent;
|
||||
cameraDriftBaseLocalPosition = cachedCameraDriftPivot.localPosition;
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject pivotObject = new GameObject("__effect_event_camera_drift_pivot");
|
||||
Transform pivot = pivotObject.transform;
|
||||
|
||||
if (currentParent != null)
|
||||
{
|
||||
pivot.SetParent(currentParent, false);
|
||||
pivot.localPosition = cachedShakeTarget.localPosition;
|
||||
pivot.localRotation = cachedShakeTarget.localRotation;
|
||||
pivot.localScale = Vector3.one;
|
||||
}
|
||||
else
|
||||
{
|
||||
pivot.position = cachedShakeTarget.position;
|
||||
pivot.rotation = cachedShakeTarget.rotation;
|
||||
}
|
||||
|
||||
cachedShakeTarget.SetParent(pivot, true);
|
||||
cachedShakeTarget.localRotation = Quaternion.identity;
|
||||
|
||||
cachedCameraDriftPivot = pivot;
|
||||
cameraDriftBaseLocalPosition = cachedCameraDriftPivot.localPosition;
|
||||
}
|
||||
|
||||
private void EnsureCameraSkillPivot()
|
||||
{
|
||||
if (cachedShakeTarget == null)
|
||||
return;
|
||||
|
||||
if (cachedCameraSkillPivot != null)
|
||||
return;
|
||||
|
||||
Transform currentParent = cachedShakeTarget.parent;
|
||||
if (currentParent != null && currentParent.name == "__effect_event_camera_skill_pivot")
|
||||
{
|
||||
cachedCameraSkillPivot = currentParent;
|
||||
cameraSkillBaseLocalPosition = cachedCameraSkillPivot.localPosition;
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject pivotObject = new GameObject("__effect_event_camera_skill_pivot");
|
||||
Transform pivot = pivotObject.transform;
|
||||
|
||||
if (currentParent != null)
|
||||
{
|
||||
pivot.SetParent(currentParent, false);
|
||||
pivot.localPosition = cachedShakeTarget.localPosition;
|
||||
pivot.localRotation = cachedShakeTarget.localRotation;
|
||||
pivot.localScale = Vector3.one;
|
||||
}
|
||||
else
|
||||
{
|
||||
pivot.position = cachedShakeTarget.position;
|
||||
pivot.rotation = cachedShakeTarget.rotation;
|
||||
pivot.localScale = Vector3.one;
|
||||
}
|
||||
|
||||
cachedShakeTarget.SetParent(pivot, true);
|
||||
cachedShakeTarget.localPosition = Vector3.zero;
|
||||
cachedShakeTarget.localRotation = Quaternion.identity;
|
||||
|
||||
cachedCameraSkillPivot = pivot;
|
||||
cameraSkillBaseLocalPosition = cachedCameraSkillPivot.localPosition;
|
||||
}
|
||||
|
||||
private void UpdateCameraDrift()
|
||||
{
|
||||
if (cachedShakeTarget == null)
|
||||
{
|
||||
CacheShakeTarget();
|
||||
}
|
||||
|
||||
if (cachedShakeTarget == null)
|
||||
return;
|
||||
|
||||
EnsureCameraDriftPivot();
|
||||
if (cachedCameraDriftPivot == null)
|
||||
return;
|
||||
|
||||
if (!enableCameraDrift)
|
||||
{
|
||||
ResetCameraDriftIfNeeded();
|
||||
return;
|
||||
}
|
||||
|
||||
float speed = Mathf.Max(0f, cameraDriftSpeed);
|
||||
float time = Time.time * speed;
|
||||
float offsetX = (Mathf.PerlinNoise(cameraDriftSeedX, time) - 0.5f) * 2f * Mathf.Abs(cameraDriftRange.x);
|
||||
float offsetY = (Mathf.PerlinNoise(cameraDriftSeedY, time) - 0.5f) * 2f * Mathf.Abs(cameraDriftRange.y);
|
||||
|
||||
cachedCameraDriftPivot.localPosition = cameraDriftBaseLocalPosition + new Vector3(offsetX, offsetY, 0f);
|
||||
}
|
||||
|
||||
private void ResetCameraDriftIfNeeded()
|
||||
{
|
||||
if (cachedCameraDriftPivot == null)
|
||||
return;
|
||||
|
||||
cachedCameraDriftPivot.localPosition = cameraDriftBaseLocalPosition;
|
||||
}
|
||||
|
||||
private void UpdatePlayerSkillCameraOffset()
|
||||
{
|
||||
if (cachedShakeTarget == null)
|
||||
{
|
||||
CacheShakeTarget();
|
||||
}
|
||||
|
||||
if (cachedShakeTarget == null)
|
||||
return;
|
||||
|
||||
EnsureCameraSkillPivot();
|
||||
if (cachedCameraSkillPivot == null)
|
||||
return;
|
||||
|
||||
Vector3 targetLocalPosition = cameraSkillBaseLocalPosition;
|
||||
if (PlayerSkillService.IsSkillEnabled(10))
|
||||
{
|
||||
float offset = playerSkillCameraOffsetAmount;
|
||||
switch (playerSkillCameraOffsetAxis)
|
||||
{
|
||||
case CameraOffsetAxis.X:
|
||||
targetLocalPosition.x += offset;
|
||||
break;
|
||||
case CameraOffsetAxis.Y:
|
||||
targetLocalPosition.y += offset;
|
||||
break;
|
||||
case CameraOffsetAxis.Z:
|
||||
targetLocalPosition.z += offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cachedCameraSkillPivot.localPosition != targetLocalPosition)
|
||||
{
|
||||
cachedCameraSkillPivot.localPosition = targetLocalPosition;
|
||||
}
|
||||
}
|
||||
|
||||
public static void RefreshPlayerSkillCameraOffset()
|
||||
{
|
||||
effectEventController controller = Instance != null ? Instance : FindAnyObjectByType<effectEventController>();
|
||||
if (controller == null)
|
||||
return;
|
||||
|
||||
controller.CacheShakeTarget();
|
||||
controller.UpdatePlayerSkillCameraOffset();
|
||||
}
|
||||
|
||||
public static void TryTriggerMultiNoteShake()
|
||||
{
|
||||
effectEventController controller = Instance != null ? Instance : FindAnyObjectByType<effectEventController>();
|
||||
if (controller == null)
|
||||
return;
|
||||
|
||||
controller.TriggerMultiNoteShakeInternal();
|
||||
}
|
||||
|
||||
private void TriggerMultiNoteShakeInternal()
|
||||
{
|
||||
if (!enableMultiNoteScreenShake)
|
||||
return;
|
||||
|
||||
if (cachedShakeTarget == null)
|
||||
{
|
||||
CacheShakeTarget();
|
||||
}
|
||||
|
||||
if (cachedShakeTarget == null)
|
||||
return;
|
||||
|
||||
float amplitudeValue = Mathf.Max(0f, multiNoteScreenShakeAmplitude);
|
||||
if (amplitudeValue <= 0f)
|
||||
return;
|
||||
|
||||
SmoothShake shake = cachedShakeTarget.GetComponent<SmoothShake>();
|
||||
if (shake == null)
|
||||
{
|
||||
shake = cachedShakeTarget.gameObject.AddComponent<SmoothShake>();
|
||||
}
|
||||
|
||||
if (shake.positionShake == null) shake.positionShake = new Shaker();
|
||||
if (shake.rotationShake == null) shake.rotationShake = new Shaker();
|
||||
|
||||
shake.positionShake.noiseType = Shaker.NoiseType.SineWave;
|
||||
shake.positionShake.amplitude = new Vector3(amplitudeValue, amplitudeValue, 0f);
|
||||
shake.positionShake.frequency = new Vector3(20f, 20f, 0f);
|
||||
shake.rotationShake.amplitude = Vector3.zero;
|
||||
shake.rotationShake.frequency = Vector3.zero;
|
||||
|
||||
shake.timeSettings.constantShake = false;
|
||||
shake.timeSettings.fadeInDuration = 0.03f;
|
||||
shake.timeSettings.holdDuration = 0.04f;
|
||||
shake.timeSettings.fadeOutDuration = 0.05f;
|
||||
|
||||
if (shake.timeSettings.fadeInCurve == null || shake.timeSettings.fadeInCurve.length == 0)
|
||||
shake.timeSettings.fadeInCurve = AnimationCurve.Linear(0f, 0f, 1f, 1f);
|
||||
if (shake.timeSettings.fadeOutCurve == null || shake.timeSettings.fadeOutCurve.length == 0)
|
||||
shake.timeSettings.fadeOutCurve = AnimationCurve.Linear(0f, 1f, 1f, 0f);
|
||||
|
||||
shake.shakers = new[] { shake.positionShake, shake.rotationShake };
|
||||
shake.sum = new Vector3[2];
|
||||
shake.StartShake();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f65edb710af433c479467d8c932e5d59
|
||||
@@ -0,0 +1,361 @@
|
||||
using SmoothShakeFree;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class globalNoteEffect : MonoBehaviour
|
||||
{
|
||||
public static globalNoteEffect Instance { get; private set; }
|
||||
|
||||
[Header("Camera Shake Event")]
|
||||
public float cameraShakeAmplitude = 0.12f;
|
||||
|
||||
[Header("Flash Blink Event")]
|
||||
public Image flashBlinkImage;
|
||||
public float flashBlinkFadeDuration = 0.2f;
|
||||
|
||||
[Header("Camera Dash Event")]
|
||||
public float targetCameraZPosition = -6.5f;
|
||||
public AnimationCurve cameraDashCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
|
||||
public float cameraDashDuration = 0.12f;
|
||||
|
||||
[Header("Camera Wave FX")]
|
||||
public float cameraWaveEnterDuration = 0.12f;
|
||||
public float cameraWaveRecoverDuration = 0.12f;
|
||||
|
||||
[Header("Camera Glitch FX")]
|
||||
public float cameraGlitchEnterDuration = 0.08f;
|
||||
public float cameraGlitchRecoverDuration = 0.12f;
|
||||
|
||||
[Header("Camera Monochrome FX")]
|
||||
public float cameraMonochromeEnterDuration = 0.1f;
|
||||
public float cameraMonochromeRecoverDuration = 0.14f;
|
||||
|
||||
[Header("Screenshot Scale FX")]
|
||||
public float screenshotScaleStartOpacity = 0.5f;
|
||||
public float screenshotScaleFadeDuration = 0.22f;
|
||||
public float screenshotScaleEndScale = 1.12f;
|
||||
|
||||
private Transform cachedCameraTransform;
|
||||
private Coroutine flashBlinkCoroutine;
|
||||
private Coroutine cameraDashCoroutine;
|
||||
private float cameraBaseLocalZ;
|
||||
private bool hasCameraBaseLocalZ;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance == null)
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
else if (Instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
CacheCameraTransform();
|
||||
PrewarmRuntime();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
SetFlashImageAlpha(0f);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
CacheCameraTransform();
|
||||
SetFlashImageAlpha(0f);
|
||||
PrewarmRuntime();
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (cachedCameraTransform == null)
|
||||
{
|
||||
CacheCameraTransform();
|
||||
}
|
||||
|
||||
if (cachedCameraTransform != null && cameraDashCoroutine == null)
|
||||
{
|
||||
cameraBaseLocalZ = cachedCameraTransform.localPosition.z;
|
||||
hasCameraBaseLocalZ = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void CacheCameraTransform()
|
||||
{
|
||||
if (Camera.main != null)
|
||||
{
|
||||
cachedCameraTransform = Camera.main.transform;
|
||||
cameraBaseLocalZ = cachedCameraTransform.localPosition.z;
|
||||
hasCameraBaseLocalZ = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void PrewarmRuntime()
|
||||
{
|
||||
CacheCameraTransform();
|
||||
|
||||
if (cachedCameraTransform != null)
|
||||
{
|
||||
SmoothShake shake = cachedCameraTransform.GetComponent<SmoothShake>();
|
||||
if (shake == null)
|
||||
{
|
||||
shake = cachedCameraTransform.gameObject.AddComponent<SmoothShake>();
|
||||
}
|
||||
|
||||
if (shake.positionShake == null) shake.positionShake = new Shaker();
|
||||
if (shake.rotationShake == null) shake.rotationShake = new Shaker();
|
||||
if (shake.shakers == null || shake.shakers.Length != 2)
|
||||
shake.shakers = new[] { shake.positionShake, shake.rotationShake };
|
||||
if (shake.sum == null || shake.sum.Length != 2)
|
||||
shake.sum = new Vector3[2];
|
||||
}
|
||||
|
||||
GlobalDistortionRuntimeController.EnsureInstance();
|
||||
GlobalGlitchRuntimeController.EnsureInstance();
|
||||
GlobalMonochromeRuntimeController.EnsureInstance();
|
||||
GlobalAfterimageRuntimeController.EnsureInstance();
|
||||
}
|
||||
|
||||
public static void TryTrigger(string noteFunction)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(noteFunction))
|
||||
return;
|
||||
|
||||
globalNoteEffect controller = GetOrCreateInstance();
|
||||
if (controller == null)
|
||||
return;
|
||||
|
||||
controller.TriggerInternal(noteFunction.Trim());
|
||||
}
|
||||
|
||||
private static globalNoteEffect GetOrCreateInstance()
|
||||
{
|
||||
if (Instance != null)
|
||||
return Instance;
|
||||
|
||||
globalNoteEffect found = FindAnyObjectByType<globalNoteEffect>();
|
||||
if (found != null)
|
||||
{
|
||||
Instance = found;
|
||||
return found;
|
||||
}
|
||||
|
||||
GameObject runtimeObject = new GameObject("__global_note_effect_runtime");
|
||||
return runtimeObject.AddComponent<globalNoteEffect>();
|
||||
}
|
||||
|
||||
private void TriggerInternal(string noteFunction)
|
||||
{
|
||||
switch (noteFunction)
|
||||
{
|
||||
case "CameraShakeEvent":
|
||||
TriggerCameraShake();
|
||||
break;
|
||||
case "FlashBlinkEvent":
|
||||
TriggerFlashBlink();
|
||||
break;
|
||||
case "CameraScaleEvent":
|
||||
TriggerCameraDash();
|
||||
break;
|
||||
case "CameraWaveFX":
|
||||
TriggerCameraWaveFx();
|
||||
break;
|
||||
case "CameraGlitchFX":
|
||||
TriggerCameraGlitchFx();
|
||||
break;
|
||||
case "CameraMonochromeFX":
|
||||
TriggerCameraMonochromeFx();
|
||||
break;
|
||||
case "ScreenshotScale":
|
||||
TriggerScreenshotScaleFx();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void TriggerCameraShake()
|
||||
{
|
||||
CacheCameraTransform();
|
||||
if (cachedCameraTransform == null)
|
||||
return;
|
||||
|
||||
float amplitudeValue = Mathf.Max(0f, cameraShakeAmplitude);
|
||||
if (amplitudeValue <= 0f)
|
||||
return;
|
||||
|
||||
SmoothShake shake = cachedCameraTransform.GetComponent<SmoothShake>();
|
||||
if (shake == null)
|
||||
{
|
||||
shake = cachedCameraTransform.gameObject.AddComponent<SmoothShake>();
|
||||
}
|
||||
|
||||
if (shake.positionShake == null) shake.positionShake = new Shaker();
|
||||
if (shake.rotationShake == null) shake.rotationShake = new Shaker();
|
||||
|
||||
shake.positionShake.noiseType = Shaker.NoiseType.SineWave;
|
||||
shake.positionShake.amplitude = new Vector3(amplitudeValue, amplitudeValue, 0f);
|
||||
shake.positionShake.frequency = new Vector3(18f, 18f, 0f);
|
||||
shake.rotationShake.amplitude = Vector3.zero;
|
||||
shake.rotationShake.frequency = Vector3.zero;
|
||||
|
||||
shake.timeSettings.constantShake = false;
|
||||
shake.timeSettings.fadeInDuration = 0.02f;
|
||||
shake.timeSettings.holdDuration = 0.04f;
|
||||
shake.timeSettings.fadeOutDuration = 0.05f;
|
||||
|
||||
if (shake.timeSettings.fadeInCurve == null || shake.timeSettings.fadeInCurve.length == 0)
|
||||
shake.timeSettings.fadeInCurve = AnimationCurve.Linear(0f, 0f, 1f, 1f);
|
||||
if (shake.timeSettings.fadeOutCurve == null || shake.timeSettings.fadeOutCurve.length == 0)
|
||||
shake.timeSettings.fadeOutCurve = AnimationCurve.Linear(0f, 1f, 1f, 0f);
|
||||
|
||||
shake.shakers = new[] { shake.positionShake, shake.rotationShake };
|
||||
shake.sum = new Vector3[2];
|
||||
shake.StartShake();
|
||||
}
|
||||
|
||||
private void TriggerFlashBlink()
|
||||
{
|
||||
if (flashBlinkImage == null)
|
||||
return;
|
||||
|
||||
if (flashBlinkCoroutine != null)
|
||||
{
|
||||
StopCoroutine(flashBlinkCoroutine);
|
||||
}
|
||||
|
||||
flashBlinkCoroutine = StartCoroutine(FlashBlinkCoroutine());
|
||||
}
|
||||
|
||||
private IEnumerator FlashBlinkCoroutine()
|
||||
{
|
||||
SetFlashImageAlpha(1f);
|
||||
|
||||
float duration = Mathf.Max(0.01f, flashBlinkFadeDuration);
|
||||
float elapsed = 0f;
|
||||
while (elapsed < duration)
|
||||
{
|
||||
elapsed += Time.deltaTime;
|
||||
float t = Mathf.Clamp01(elapsed / duration);
|
||||
SetFlashImageAlpha(1f - t);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
SetFlashImageAlpha(0f);
|
||||
flashBlinkCoroutine = null;
|
||||
}
|
||||
|
||||
private void TriggerCameraDash()
|
||||
{
|
||||
CacheCameraTransform();
|
||||
if (cachedCameraTransform == null)
|
||||
return;
|
||||
|
||||
if (cameraDashCoroutine != null)
|
||||
{
|
||||
StopCoroutine(cameraDashCoroutine);
|
||||
if (hasCameraBaseLocalZ)
|
||||
{
|
||||
Vector3 resetPosition = cachedCameraTransform.localPosition;
|
||||
resetPosition.z = cameraBaseLocalZ;
|
||||
cachedCameraTransform.localPosition = resetPosition;
|
||||
}
|
||||
}
|
||||
|
||||
cameraDashCoroutine = StartCoroutine(CameraDashCoroutine());
|
||||
}
|
||||
|
||||
private IEnumerator CameraDashCoroutine()
|
||||
{
|
||||
if (!hasCameraBaseLocalZ)
|
||||
{
|
||||
cameraBaseLocalZ = cachedCameraTransform.localPosition.z;
|
||||
hasCameraBaseLocalZ = true;
|
||||
}
|
||||
|
||||
float baseLocalZ = cameraBaseLocalZ;
|
||||
float targetZ = targetCameraZPosition;
|
||||
if (Mathf.Approximately(targetZ, baseLocalZ))
|
||||
{
|
||||
targetZ = baseLocalZ + 1.5f;
|
||||
}
|
||||
float duration = Mathf.Max(0.01f, cameraDashDuration);
|
||||
AnimationCurve curve = cameraDashCurve == null || cameraDashCurve.length == 0
|
||||
? AnimationCurve.EaseInOut(0f, 0f, 1f, 1f)
|
||||
: cameraDashCurve;
|
||||
|
||||
float elapsed = 0f;
|
||||
while (elapsed < duration)
|
||||
{
|
||||
elapsed += Time.deltaTime;
|
||||
float t = Mathf.Clamp01(elapsed / duration);
|
||||
float curvedT = curve.Evaluate(t);
|
||||
Vector3 position = cachedCameraTransform.localPosition;
|
||||
position.z = Mathf.LerpUnclamped(baseLocalZ, targetZ, curvedT);
|
||||
cachedCameraTransform.localPosition = position;
|
||||
yield return null;
|
||||
}
|
||||
|
||||
elapsed = 0f;
|
||||
while (elapsed < duration)
|
||||
{
|
||||
elapsed += Time.deltaTime;
|
||||
float t = Mathf.Clamp01(elapsed / duration);
|
||||
float curvedT = curve.Evaluate(t);
|
||||
Vector3 position = cachedCameraTransform.localPosition;
|
||||
position.z = Mathf.LerpUnclamped(targetZ, baseLocalZ, curvedT);
|
||||
cachedCameraTransform.localPosition = position;
|
||||
yield return null;
|
||||
}
|
||||
|
||||
Vector3 finalPosition = cachedCameraTransform.localPosition;
|
||||
finalPosition.z = baseLocalZ;
|
||||
cachedCameraTransform.localPosition = finalPosition;
|
||||
cameraDashCoroutine = null;
|
||||
}
|
||||
|
||||
private void TriggerCameraWaveFx()
|
||||
{
|
||||
GlobalDistortionRuntimeController.TriggerWaveEffect(
|
||||
Mathf.Max(0.0001f, cameraWaveEnterDuration),
|
||||
Mathf.Max(0.0001f, cameraWaveRecoverDuration)
|
||||
);
|
||||
}
|
||||
|
||||
private void TriggerCameraGlitchFx()
|
||||
{
|
||||
GlobalGlitchRuntimeController.TriggerWaveEffect(
|
||||
Mathf.Max(0.0001f, cameraGlitchEnterDuration),
|
||||
Mathf.Max(0.0001f, cameraGlitchRecoverDuration)
|
||||
);
|
||||
}
|
||||
|
||||
private void TriggerCameraMonochromeFx()
|
||||
{
|
||||
GlobalMonochromeRuntimeController.Trigger(
|
||||
Mathf.Max(0.0001f, cameraMonochromeEnterDuration),
|
||||
Mathf.Max(0.0001f, cameraMonochromeRecoverDuration)
|
||||
);
|
||||
}
|
||||
|
||||
private void TriggerScreenshotScaleFx()
|
||||
{
|
||||
GlobalAfterimageRuntimeController.Trigger(
|
||||
Mathf.Clamp01(screenshotScaleStartOpacity),
|
||||
Mathf.Max(0.0001f, screenshotScaleFadeDuration),
|
||||
Mathf.Max(1f, screenshotScaleEndScale)
|
||||
);
|
||||
}
|
||||
|
||||
private void SetFlashImageAlpha(float alpha)
|
||||
{
|
||||
if (flashBlinkImage == null)
|
||||
return;
|
||||
|
||||
Color color = flashBlinkImage.color;
|
||||
color.a = Mathf.Clamp01(alpha);
|
||||
flashBlinkImage.color = color;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7aad6dbb8ac9a574b832837614506af8
|
||||
+75
-10
@@ -28,11 +28,19 @@ public class iNumberPrefabController : MonoBehaviour
|
||||
|
||||
private bool _warnedMissingPrefab;
|
||||
private bool _warnedMissingParents;
|
||||
private Transform pooledRoot;
|
||||
private readonly System.Collections.Generic.Dictionary<GameObject, System.Collections.Generic.Stack<playerInstantNumbersPrefab>> pools
|
||||
= new System.Collections.Generic.Dictionary<GameObject, System.Collections.Generic.Stack<playerInstantNumbersPrefab>>();
|
||||
private readonly System.Collections.Generic.Dictionary<playerInstantNumbersPrefab, GameObject> sourcePrefabs
|
||||
= new System.Collections.Generic.Dictionary<playerInstantNumbersPrefab, GameObject>();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance == null) Instance = this;
|
||||
else if (Instance != this) { Destroy(gameObject); return; }
|
||||
|
||||
pooledRoot = new GameObject("__instant_number_pool").transform;
|
||||
pooledRoot.SetParent(transform, false);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
@@ -150,19 +158,76 @@ public class iNumberPrefabController : MonoBehaviour
|
||||
return;
|
||||
}
|
||||
|
||||
var go = Instantiate(prefab, parent, false);
|
||||
if (go == null) return;
|
||||
|
||||
if (prefab.scene.IsValid())
|
||||
{
|
||||
if (prefab.activeSelf) prefab.SetActive(false);
|
||||
var view = GetPooledInstance(prefab, parent);
|
||||
if (view != null) view.Play(type, signedValue);
|
||||
}
|
||||
|
||||
// Ensure the newly created object is active before playing animation
|
||||
if (!go.activeInHierarchy) go.SetActive(true);
|
||||
private playerInstantNumbersPrefab GetPooledInstance(GameObject prefab, Transform parent)
|
||||
{
|
||||
if (prefab == null || parent == null)
|
||||
return null;
|
||||
|
||||
var view = go.GetComponent<playerInstantNumbersPrefab>();
|
||||
if (view != null) view.Play(type, signedValue);
|
||||
if (!pools.TryGetValue(prefab, out var pool))
|
||||
{
|
||||
pool = new System.Collections.Generic.Stack<playerInstantNumbersPrefab>();
|
||||
pools[prefab] = pool;
|
||||
}
|
||||
|
||||
playerInstantNumbersPrefab view = null;
|
||||
while (pool.Count > 0 && view == null)
|
||||
{
|
||||
view = pool.Pop();
|
||||
}
|
||||
|
||||
if (view == null)
|
||||
{
|
||||
var go = Instantiate(prefab, parent, false);
|
||||
if (go == null)
|
||||
return null;
|
||||
|
||||
view = go.GetComponent<playerInstantNumbersPrefab>();
|
||||
if (view == null)
|
||||
return null;
|
||||
|
||||
sourcePrefabs[view] = prefab;
|
||||
}
|
||||
else
|
||||
{
|
||||
view.transform.SetParent(parent, false);
|
||||
view.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
view.ResetForReuse();
|
||||
return view;
|
||||
}
|
||||
|
||||
public static bool ReturnInstance(playerInstantNumbersPrefab view)
|
||||
{
|
||||
if (Instance == null || view == null)
|
||||
return false;
|
||||
|
||||
return Instance.ReturnInstanceInternal(view);
|
||||
}
|
||||
|
||||
private bool ReturnInstanceInternal(playerInstantNumbersPrefab view)
|
||||
{
|
||||
if (view == null)
|
||||
return false;
|
||||
|
||||
if (!sourcePrefabs.TryGetValue(view, out var prefab) || prefab == null)
|
||||
return false;
|
||||
|
||||
if (!pools.TryGetValue(prefab, out var pool))
|
||||
{
|
||||
pool = new System.Collections.Generic.Stack<playerInstantNumbersPrefab>();
|
||||
pools[prefab] = pool;
|
||||
}
|
||||
|
||||
view.transform.SetParent(pooledRoot, false);
|
||||
view.ResetForReuse();
|
||||
view.gameObject.SetActive(false);
|
||||
pool.Push(view);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void WarnMissingPrefabOnce()
|
||||
|
||||
+23
@@ -51,14 +51,33 @@ public class playerInstantNumbersPrefab : MonoBehaviour
|
||||
_canvasGroup.alpha = 1f;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (_animationCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_animationCoroutine);
|
||||
_animationCoroutine = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Play(iNumberPrefabController.InstantNumberType type, int signedValue)
|
||||
{
|
||||
ResetForReuse();
|
||||
ApplyVisual(type, signedValue);
|
||||
|
||||
if (_animationCoroutine != null) StopCoroutine(_animationCoroutine);
|
||||
_animationCoroutine = StartCoroutine(Animate());
|
||||
}
|
||||
|
||||
public void ResetForReuse()
|
||||
{
|
||||
if (_canvasGroup != null) _canvasGroup.alpha = 1f;
|
||||
transform.localRotation = Quaternion.identity;
|
||||
transform.localScale = Vector3.one;
|
||||
if (_rectTransform != null) _rectTransform.anchoredPosition = Vector2.zero;
|
||||
else transform.localPosition = Vector3.zero;
|
||||
}
|
||||
|
||||
private void ApplyVisual(iNumberPrefabController.InstantNumberType type, int signedValue)
|
||||
{
|
||||
if (numberText != null)
|
||||
@@ -178,6 +197,10 @@ public class playerInstantNumbersPrefab : MonoBehaviour
|
||||
yield return null;
|
||||
}
|
||||
|
||||
_animationCoroutine = null;
|
||||
if (!iNumberPrefabController.ReturnInstance(this))
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -524,6 +524,8 @@ public class settlementController : MonoBehaviour
|
||||
targetTotalScore = targetPmScore + targetIdolScore;
|
||||
targetTotalPercent = (float)targetTotalScore / Mathf.Max(1, _1000000) * 100f;
|
||||
|
||||
PlayerSkillService.NotifySettlementCompleted(targetIdolScore);
|
||||
|
||||
finalScore_Text.text = targetTotalScore.ToString();
|
||||
pmScoreSum_Text.text = targetPmScore.ToString();
|
||||
|
||||
|
||||
@@ -370,45 +370,7 @@ public class teamUIController : MonoBehaviour
|
||||
#else
|
||||
// Runtime: prefer runtimeResourcesFolderPath, fallback to selectedProjectFolderPath
|
||||
string resourcesPath = ResolveResourcesRelativePath(!string.IsNullOrEmpty(runtimeResourcesFolderPath) ? runtimeResourcesFolderPath : selectedProjectFolderPath);
|
||||
|
||||
List<Object> runtimeDiscovered = new List<Object>();
|
||||
if (!string.IsNullOrEmpty(resourcesPath))
|
||||
{
|
||||
resourcesPath = resourcesPath.Trim('/');
|
||||
try
|
||||
{
|
||||
var arr = Resources.LoadAll(resourcesPath);
|
||||
if (arr != null && arr.Length > 0)
|
||||
runtimeDiscovered.AddRange(arr);
|
||||
|
||||
// If nothing loaded from the specific folder, fallback to loading all and filter by name later
|
||||
if (runtimeDiscovered.Count == 0)
|
||||
{
|
||||
var arrAll = Resources.LoadAll("");
|
||||
if (arrAll != null && arrAll.Length > 0) // Fixed: changed arr.Length to arrAll.Length
|
||||
{
|
||||
runtimeDiscovered.AddRange(arrAll);
|
||||
Debug.LogWarning($"[teamUIController] (Runtime) Resources.LoadAll returned 0 in '{resourcesPath}', fell back to loading all ScriptableObjects ({arrAll.Length})");
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log($"[teamUIcontroller] (Runtime) Loaded {runtimeDiscovered.Count} objects from Resources/{resourcesPath}");
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[teamUIController] (Runtime) Resources.LoadAll failed for '{resourcesPath}': {ex.Message}");
|
||||
var arrAll = Resources.LoadAll("");
|
||||
if (arrAll != null && arrAll.Length > 0) // Fixed: changed arr.Length to arrAll.Length
|
||||
runtimeDiscovered.AddRange(arrAll);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var arr = Resources.LoadAll("");
|
||||
if (arr != null && arr.Length > 0)
|
||||
runtimeDiscovered.AddRange(arr);
|
||||
Debug.Log($"[teamUIController] (Runtime) Loaded {arr?.Length ?? 0} objects from Resources (project-wide)");
|
||||
}
|
||||
List<Object> runtimeDiscovered = GetOrBuildRuntimeAllyDiscovered(resourcesPath);
|
||||
|
||||
TeamCharacterList globalList = null;
|
||||
if (teamSettingPanel.Instance != null)
|
||||
@@ -549,9 +511,7 @@ public class teamUIController : MonoBehaviour
|
||||
// attempt to set teammate image from underlying AllyHero_SO if possible
|
||||
try
|
||||
{
|
||||
var ahList = Resources.LoadAll<AllyHero_SO>("");
|
||||
AllyHero_SO matched = null;
|
||||
foreach (var a in ahList) if (a != null && a.ally_heroID == id) { matched = a; break; }
|
||||
AllyHero_SO matched = GetCachedRuntimeAllyHero(id);
|
||||
if (matched != null)
|
||||
{
|
||||
var sprite = matched.ally_heroProfile != null ? matched.ally_heroProfile : matched.ally_heroImage;
|
||||
@@ -570,6 +530,77 @@ public class teamUIController : MonoBehaviour
|
||||
#endif
|
||||
}
|
||||
|
||||
private List<Object> GetOrBuildRuntimeAllyDiscovered(string resourcesPath)
|
||||
{
|
||||
resourcesPath = (resourcesPath ?? string.Empty).Trim('/');
|
||||
if (_runtimeAllyDiscovered != null && _runtimeAllyResourcesPath == resourcesPath)
|
||||
return _runtimeAllyDiscovered;
|
||||
|
||||
var runtimeDiscovered = new List<Object>();
|
||||
if (!string.IsNullOrEmpty(resourcesPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
var arr = Resources.LoadAll(resourcesPath);
|
||||
if (arr != null && arr.Length > 0)
|
||||
runtimeDiscovered.AddRange(arr);
|
||||
|
||||
if (runtimeDiscovered.Count == 0)
|
||||
{
|
||||
var arrAll = Resources.LoadAll("");
|
||||
if (arrAll != null && arrAll.Length > 0)
|
||||
{
|
||||
runtimeDiscovered.AddRange(arrAll);
|
||||
Debug.LogWarning($"[teamUIController] (Runtime) Resources.LoadAll returned 0 in '{resourcesPath}', fell back to loading all ScriptableObjects ({arrAll.Length})");
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log($"[teamUIcontroller] (Runtime) Loaded {runtimeDiscovered.Count} objects from Resources/{resourcesPath}");
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[teamUIController] (Runtime) Resources.LoadAll failed for '{resourcesPath}': {ex.Message}");
|
||||
var arrAll = Resources.LoadAll("");
|
||||
if (arrAll != null && arrAll.Length > 0)
|
||||
runtimeDiscovered.AddRange(arrAll);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var arr = Resources.LoadAll("");
|
||||
if (arr != null && arr.Length > 0)
|
||||
runtimeDiscovered.AddRange(arr);
|
||||
Debug.Log($"[teamUIController] (Runtime) Loaded {arr?.Length ?? 0} objects from Resources (project-wide)");
|
||||
}
|
||||
|
||||
_runtimeAllyResourcesPath = resourcesPath;
|
||||
_runtimeAllyDiscovered = runtimeDiscovered;
|
||||
_cachedRuntimeAllyHeroes = null;
|
||||
_runtimeAllyHeroById = null;
|
||||
return runtimeDiscovered;
|
||||
}
|
||||
|
||||
private AllyHero_SO GetCachedRuntimeAllyHero(int id)
|
||||
{
|
||||
if (id <= 0) return null;
|
||||
|
||||
if (_runtimeAllyHeroById != null && _runtimeAllyHeroById.TryGetValue(id, out var cached))
|
||||
return cached;
|
||||
|
||||
if (_cachedRuntimeAllyHeroes == null)
|
||||
{
|
||||
_cachedRuntimeAllyHeroes = Resources.LoadAll<AllyHero_SO>("") ?? System.Array.Empty<AllyHero_SO>();
|
||||
_runtimeAllyHeroById = new Dictionary<int, AllyHero_SO>();
|
||||
foreach (var hero in _cachedRuntimeAllyHeroes)
|
||||
{
|
||||
if (hero == null) continue;
|
||||
_runtimeAllyHeroById[hero.ally_heroID] = hero;
|
||||
}
|
||||
}
|
||||
|
||||
return _runtimeAllyHeroById.TryGetValue(id, out var heroFound) ? heroFound : null;
|
||||
}
|
||||
|
||||
// ResolveResourcesRelativePath helper method is missing, assuming it exists externally or is part of a base class / extension.
|
||||
// Since the user is providing the full class, I will assume it's either defined outside this snippet or is implicitly handled,
|
||||
// but the code within #if UNITY_EDITOR is what matters for the file content.
|
||||
@@ -815,6 +846,10 @@ public class teamUIController : MonoBehaviour
|
||||
private const string EnemyDieAnimationName = "die";
|
||||
private string _runtimeEnemyResourcesPath;
|
||||
private List<Object> _runtimeEnemyDiscovered;
|
||||
private string _runtimeAllyResourcesPath;
|
||||
private List<Object> _runtimeAllyDiscovered;
|
||||
private AllyHero_SO[] _cachedRuntimeAllyHeroes;
|
||||
private Dictionary<int, AllyHero_SO> _runtimeAllyHeroById;
|
||||
|
||||
// For total enemy health bar
|
||||
private int totalMaxHP = 0; // Documentation text normalized.
|
||||
@@ -1031,6 +1066,8 @@ public class teamUIController : MonoBehaviour
|
||||
public bool isEnemy_active = true;
|
||||
[Tooltip("Documentation text normalized.")]
|
||||
public Image currentEnemy_characterImage;
|
||||
[Tooltip("Shown on currentEnemy_characterImage after the last enemy is defeated. If empty, falls back to the last enemy SO sprite.")]
|
||||
public Sprite allEnemiesDefeatedSprite;
|
||||
[Tooltip("Documentation text normalized.")]
|
||||
public Image currentEnemy_healthImage;
|
||||
[Tooltip("Documentation text normalized.")]
|
||||
@@ -1055,6 +1092,10 @@ public class teamUIController : MonoBehaviour
|
||||
public TextMeshProUGUI currentEnemy_manaRate;
|
||||
[Tooltip("Documentation text normalized.")]
|
||||
public TextMeshProUGUI currentEnemy_current_scoreText; // rate : now score / max score
|
||||
[Tooltip("Hidden after all enemies are defeated.")]
|
||||
public GameObject currentEnemy_bountyObject;
|
||||
[Tooltip("Displays the current enemy bounty score.")]
|
||||
public Text currentEnemy_bountyText;
|
||||
[Tooltip("Documentation text normalized.")]
|
||||
[SerializeField] private int enemy_id;
|
||||
[Tooltip("Documentation text normalized.")]
|
||||
@@ -1067,6 +1108,9 @@ public class teamUIController : MonoBehaviour
|
||||
[SerializeField] private Image spine_to_put_referenceImage;
|
||||
[SerializeField] private Color spineHurtFlashColor = new Color(1f, 0.2f, 0.2f, 1f);
|
||||
[SerializeField] private float spineUniformHeight = 0f;
|
||||
private Coroutine enemyBountyTextCoroutine;
|
||||
private bool enemyBountyTransitionActive = false;
|
||||
private int currentDisplayedEnemyBounty = 0;
|
||||
public float SpineUniformHeight
|
||||
{
|
||||
get => spineUniformHeight;
|
||||
@@ -1598,8 +1642,10 @@ public class teamUIController : MonoBehaviour
|
||||
}
|
||||
if (currentEnemy_characterImage != null)
|
||||
{
|
||||
// Set the sprite from SO
|
||||
var sprite = so.enemy_Image != null ? so.enemy_Image : (so.enemy_Profile != null ? so.enemy_Profile : null);
|
||||
// Use the configured victory sprite first, otherwise fall back to the defeated enemy sprite.
|
||||
var sprite = allEnemiesDefeatedSprite != null
|
||||
? allEnemiesDefeatedSprite
|
||||
: (so.enemy_Image != null ? so.enemy_Image : (so.enemy_Profile != null ? so.enemy_Profile : null));
|
||||
currentEnemy_characterImage.sprite = sprite;
|
||||
|
||||
// Apply grayscale material
|
||||
@@ -1716,6 +1762,7 @@ public class teamUIController : MonoBehaviour
|
||||
if (currentEnemy_manaImage != null) currentEnemy_manaImage.fillAmount = 0f;
|
||||
if (currentEnemy_fademanaImage != null) currentEnemy_fademanaImage.fillAmount = 0f;
|
||||
if (currentEnemy_typeText != null) currentEnemy_typeText.text = "(普通敌人)";
|
||||
HideEnemyBountyUiImmediate();
|
||||
UpdateEnemyListText();
|
||||
// Documentation text normalized.
|
||||
UpdateAllEnemyTotalHealthUIImmediate();
|
||||
@@ -1756,6 +1803,8 @@ public class teamUIController : MonoBehaviour
|
||||
if (currentEnemy_manaImage != null) currentEnemy_manaImage.fillAmount = 0f;
|
||||
if (currentEnemy_fademanaImage != null) currentEnemy_fademanaImage.fillAmount = 0f;
|
||||
if (currentEnemy_typeText != null) currentEnemy_typeText.text = "(普通敌人)";
|
||||
if (!enemyBountyTransitionActive)
|
||||
HideEnemyBountyUiImmediate();
|
||||
UpdateEnemyListText();
|
||||
// Update total health bar to 0
|
||||
UpdateAllEnemyTotalHealthUIImmediate();
|
||||
@@ -1834,6 +1883,23 @@ public class teamUIController : MonoBehaviour
|
||||
// ensure UI parent is visible
|
||||
if (objectFather_enemy != null) objectFather_enemy.SetActive(true);
|
||||
|
||||
int currentEnemyBounty = CalculateEnemyBountyScore(so);
|
||||
if (currentEnemy_bountyObject != null)
|
||||
currentEnemy_bountyObject.SetActive(true);
|
||||
if (enemyCurrentCount == 0 && currentDisplayedEnemyBounty == 0 && !enemyBountyTransitionActive)
|
||||
{
|
||||
if (enemyBountyTextCoroutine != null)
|
||||
{
|
||||
StopCoroutine(enemyBountyTextCoroutine);
|
||||
enemyBountyTextCoroutine = null;
|
||||
}
|
||||
SetEnemyBountyDisplayImmediate(currentEnemyBounty);
|
||||
}
|
||||
else
|
||||
{
|
||||
AnimateEnemyBountyRise(currentEnemyBounty);
|
||||
}
|
||||
|
||||
// reset previous values so Update picks up initial state
|
||||
prevEnemyHP = enemyCombatantInstance.currentHP;
|
||||
prevEnemyMana = enemyCombatantInstance.currentMana;
|
||||
@@ -1992,6 +2058,16 @@ public class teamUIController : MonoBehaviour
|
||||
}
|
||||
if (delay > 0f)
|
||||
{
|
||||
int nextIndex = enemyCurrentCount + 1;
|
||||
if (nextIndex >= recognizedEnemySOs.Length)
|
||||
{
|
||||
AnimateEnemyBountyToZero(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
AnimateEnemyBountyToZero(false);
|
||||
}
|
||||
|
||||
if (_enemySpineDeathCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_enemySpineDeathCoroutine);
|
||||
@@ -2004,6 +2080,16 @@ public class teamUIController : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
int nextEnemyIndex = enemyCurrentCount + 1;
|
||||
if (nextEnemyIndex >= recognizedEnemySOs.Length)
|
||||
{
|
||||
AnimateEnemyBountyToZero(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
AnimateEnemyBountyToZero(false);
|
||||
}
|
||||
|
||||
enemyCurrentCount++;
|
||||
SpawnNextEnemy();
|
||||
}
|
||||
@@ -2014,6 +2100,113 @@ public class teamUIController : MonoBehaviour
|
||||
UpdateEnemyUIImmediate();
|
||||
}
|
||||
|
||||
private int CalculateEnemyBountyScore(EnemyData_SO so)
|
||||
{
|
||||
if (so == null)
|
||||
return 0;
|
||||
|
||||
int difficultyID = BeatmapManager.Instance != null ? BeatmapManager.Instance.assignedDifficulty : 0;
|
||||
EnemyData_SO.EnemyDifficultyStats stats = so.GetStatsByDifficultyID(difficultyID);
|
||||
int calculatedMaxHp = Mathf.Max(0, stats.enemy_maxHP);
|
||||
float difficultyLevel = ResolveCurrentDifficultyLevel(difficultyID);
|
||||
float totalBounty = calculatedMaxHp * 0.05f * difficultyLevel + so.enemyBountyBonus;
|
||||
return Mathf.Max(0, Mathf.CeilToInt(totalBounty));
|
||||
}
|
||||
|
||||
private float ResolveCurrentDifficultyLevel(int difficultyID)
|
||||
{
|
||||
BeatmapManager beatmapManager = BeatmapManager.Instance;
|
||||
if (beatmapManager == null || beatmapManager.assignedSongData == null || beatmapManager.assignedSongData.chartFiles == null)
|
||||
return 1f;
|
||||
|
||||
List<ChartFileEntry> chartFiles = beatmapManager.assignedSongData.chartFiles;
|
||||
for (int i = 0; i < chartFiles.Count; i++)
|
||||
{
|
||||
ChartFileEntry entry = chartFiles[i];
|
||||
if (entry == null || entry.difficulty != difficultyID)
|
||||
continue;
|
||||
|
||||
return Mathf.Max(0f, entry.difficultyLEVEL);
|
||||
}
|
||||
|
||||
return 1f;
|
||||
}
|
||||
|
||||
private void SetEnemyBountyDisplayImmediate(int value)
|
||||
{
|
||||
currentDisplayedEnemyBounty = Mathf.Max(0, value);
|
||||
if (currentEnemy_bountyText != null)
|
||||
currentEnemy_bountyText.text = currentDisplayedEnemyBounty.ToString();
|
||||
}
|
||||
|
||||
private void HideEnemyBountyUiImmediate()
|
||||
{
|
||||
if (enemyBountyTextCoroutine != null)
|
||||
{
|
||||
StopCoroutine(enemyBountyTextCoroutine);
|
||||
enemyBountyTextCoroutine = null;
|
||||
}
|
||||
|
||||
enemyBountyTransitionActive = false;
|
||||
SetEnemyBountyDisplayImmediate(0);
|
||||
if (currentEnemy_bountyObject != null)
|
||||
currentEnemy_bountyObject.SetActive(false);
|
||||
}
|
||||
|
||||
private void AnimateEnemyBountyRise(int targetValue)
|
||||
{
|
||||
if (enemyBountyTextCoroutine != null)
|
||||
StopCoroutine(enemyBountyTextCoroutine);
|
||||
|
||||
if (currentEnemy_bountyObject != null)
|
||||
currentEnemy_bountyObject.SetActive(true);
|
||||
|
||||
enemyBountyTransitionActive = true;
|
||||
enemyBountyTextCoroutine = StartCoroutine(AnimateEnemyBountyValueRoutine(0, Mathf.Max(0, targetValue), 1f, false));
|
||||
}
|
||||
|
||||
private void AnimateEnemyBountyToZero(bool hideAfterZero)
|
||||
{
|
||||
if (enemyBountyTextCoroutine != null)
|
||||
StopCoroutine(enemyBountyTextCoroutine);
|
||||
|
||||
if (currentEnemy_bountyObject != null)
|
||||
currentEnemy_bountyObject.SetActive(true);
|
||||
|
||||
enemyBountyTransitionActive = true;
|
||||
enemyBountyTextCoroutine = StartCoroutine(AnimateEnemyBountyValueRoutine(currentDisplayedEnemyBounty, 0, 1f, hideAfterZero));
|
||||
}
|
||||
|
||||
private IEnumerator AnimateEnemyBountyValueRoutine(int startValue, int endValue, float duration, bool deactivateAtEnd)
|
||||
{
|
||||
enemyBountyTransitionActive = true;
|
||||
SetEnemyBountyDisplayImmediate(startValue);
|
||||
|
||||
if (duration <= 0f)
|
||||
{
|
||||
SetEnemyBountyDisplayImmediate(endValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
float elapsed = 0f;
|
||||
while (elapsed < duration)
|
||||
{
|
||||
elapsed += Time.deltaTime;
|
||||
float t = Mathf.Clamp01(elapsed / duration);
|
||||
int value = Mathf.RoundToInt(Mathf.Lerp(startValue, endValue, t));
|
||||
SetEnemyBountyDisplayImmediate(value);
|
||||
yield return null;
|
||||
}
|
||||
SetEnemyBountyDisplayImmediate(endValue);
|
||||
}
|
||||
|
||||
enemyBountyTransitionActive = false;
|
||||
enemyBountyTextCoroutine = null;
|
||||
|
||||
if (deactivateAtEnd && currentEnemy_bountyObject != null)
|
||||
currentEnemy_bountyObject.SetActive(false);
|
||||
}
|
||||
|
||||
// Documentation text normalized.
|
||||
|
||||
// =========================================================
|
||||
@@ -2066,6 +2259,15 @@ public class teamUIController : MonoBehaviour
|
||||
Debug.Log($"[teamUIController] Re-initializing current enemy instance with new HP: {stats.enemy_maxHP}");
|
||||
enemyCombatantInstance.InitializeFromSO(currentSO, diffID);
|
||||
UpdateEnemyUIImmediate();
|
||||
|
||||
// The first enemy can be spawned before BeatmapManager finishes writing
|
||||
// the calculated HP back into the enemy SO. Refresh bounty text here so it
|
||||
// reflects the final computed max HP rather than the pre-calculation value.
|
||||
int refreshedBounty = CalculateEnemyBountyScore(currentSO);
|
||||
if (currentEnemy_bountyObject != null)
|
||||
currentEnemy_bountyObject.SetActive(true);
|
||||
if (!enemyBountyTransitionActive)
|
||||
SetEnemyBountyDisplayImmediate(refreshedBounty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 90bd6951a29795d4a943028d2150ce08
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3211f9d28619bb347a531aa2252d51eb
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,159 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
|
||||
[InitializeOnLoad]
|
||||
public static class GlobalAfterimageInstaller
|
||||
{
|
||||
private const string RendererDataPath = "Assets/Settings/Renderer2D.asset";
|
||||
private const string GameplayVolumeProfilePath = "Assets/Scenes/gamePlay_gamePlay/gpGV.asset";
|
||||
private static bool installScheduled;
|
||||
|
||||
static GlobalAfterimageInstaller()
|
||||
{
|
||||
ScheduleInstall();
|
||||
}
|
||||
|
||||
[MenuItem("Bansonic/Rendering/Install Global Afterimage")]
|
||||
public static void EnsureInstalledMenu()
|
||||
{
|
||||
EnsureInstalled();
|
||||
}
|
||||
|
||||
private static void ScheduleInstall()
|
||||
{
|
||||
if (installScheduled)
|
||||
return;
|
||||
|
||||
installScheduled = true;
|
||||
EditorApplication.delayCall += RunScheduledInstall;
|
||||
}
|
||||
|
||||
private static void RunScheduledInstall()
|
||||
{
|
||||
installScheduled = false;
|
||||
EnsureInstalled();
|
||||
}
|
||||
|
||||
private static void EnsureInstalled()
|
||||
{
|
||||
if (EditorApplication.isCompiling || BuildPipeline.isBuildingPlayer)
|
||||
{
|
||||
ScheduleInstall();
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsUnsafeSelectionActive())
|
||||
{
|
||||
ScheduleInstall();
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureRendererFeatureInstalled();
|
||||
EnsureVolumeOverrideInstalled();
|
||||
}
|
||||
|
||||
private static void EnsureRendererFeatureInstalled()
|
||||
{
|
||||
ScriptableRendererData rendererData = AssetDatabase.LoadAssetAtPath<ScriptableRendererData>(RendererDataPath);
|
||||
if (rendererData == null)
|
||||
return;
|
||||
|
||||
if (!rendererData.TryGetRendererFeature<GlobalAfterimageRendererFeature>(out GlobalAfterimageRendererFeature feature))
|
||||
{
|
||||
feature = ScriptableObject.CreateInstance<GlobalAfterimageRendererFeature>();
|
||||
feature.name = "Global Afterimage Renderer Feature";
|
||||
AssetDatabase.AddObjectToAsset(feature, rendererData);
|
||||
rendererData.rendererFeatures.Add(feature);
|
||||
rendererData.SetDirty();
|
||||
EditorUtility.SetDirty(feature);
|
||||
EditorUtility.SetDirty(rendererData);
|
||||
TryValidateRendererFeatures(rendererData);
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.ImportAsset(RendererDataPath);
|
||||
return;
|
||||
}
|
||||
|
||||
if (feature.renderPassEvent != RenderPassEvent.AfterRenderingPostProcessing)
|
||||
{
|
||||
feature.renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
|
||||
rendererData.SetDirty();
|
||||
EditorUtility.SetDirty(feature);
|
||||
EditorUtility.SetDirty(rendererData);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureVolumeOverrideInstalled()
|
||||
{
|
||||
VolumeProfile profile = AssetDatabase.LoadAssetAtPath<VolumeProfile>(GameplayVolumeProfilePath);
|
||||
if (profile == null)
|
||||
return;
|
||||
|
||||
RemoveNullVolumeComponents(profile);
|
||||
|
||||
if (profile.TryGet<GlobalAfterimageVolume>(out _))
|
||||
return;
|
||||
|
||||
GlobalAfterimageVolume component = profile.Add<GlobalAfterimageVolume>(true);
|
||||
component.active = false;
|
||||
component.opacity.overrideState = true;
|
||||
component.opacity.value = 0f;
|
||||
component.scale.overrideState = true;
|
||||
component.scale.value = 1.05f;
|
||||
component.affectSceneView.overrideState = true;
|
||||
component.affectSceneView.value = false;
|
||||
EditorUtility.SetDirty(component);
|
||||
EditorUtility.SetDirty(profile);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
private static void RemoveNullVolumeComponents(VolumeProfile profile)
|
||||
{
|
||||
SerializedObject serializedObject = new SerializedObject(profile);
|
||||
SerializedProperty componentsProperty = serializedObject.FindProperty("components");
|
||||
if (componentsProperty == null || !componentsProperty.isArray)
|
||||
return;
|
||||
|
||||
bool removed = false;
|
||||
for (int i = componentsProperty.arraySize - 1; i >= 0; i--)
|
||||
{
|
||||
SerializedProperty element = componentsProperty.GetArrayElementAtIndex(i);
|
||||
if (element.objectReferenceValue != null)
|
||||
continue;
|
||||
|
||||
componentsProperty.DeleteArrayElementAtIndex(i);
|
||||
removed = true;
|
||||
}
|
||||
|
||||
if (!removed)
|
||||
return;
|
||||
|
||||
serializedObject.ApplyModifiedPropertiesWithoutUndo();
|
||||
EditorUtility.SetDirty(profile);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
private static void TryValidateRendererFeatures(ScriptableRendererData rendererData)
|
||||
{
|
||||
MethodInfo validateMethod = typeof(ScriptableRendererData).GetMethod("ValidateRendererFeatures", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
validateMethod?.Invoke(rendererData, null);
|
||||
}
|
||||
|
||||
private static bool IsUnsafeSelectionActive()
|
||||
{
|
||||
Object activeObject = Selection.activeObject;
|
||||
if (activeObject is VolumeProfile || activeObject is Volume)
|
||||
return true;
|
||||
|
||||
GameObject activeGameObject = Selection.activeGameObject;
|
||||
if (activeGameObject == null)
|
||||
return false;
|
||||
|
||||
return activeGameObject.TryGetComponent<Volume>(out _);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5a6ce7542914bd428842b45057360d0
|
||||
@@ -0,0 +1,167 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
|
||||
[InitializeOnLoad]
|
||||
public static class GlobalDistortionInstaller
|
||||
{
|
||||
private const string RendererDataPath = "Assets/Settings/Renderer2D.asset";
|
||||
private const string GameplayVolumeProfilePath = "Assets/Scenes/gamePlay_gamePlay/gpGV.asset";
|
||||
private static bool installScheduled;
|
||||
|
||||
static GlobalDistortionInstaller()
|
||||
{
|
||||
ScheduleInstall();
|
||||
}
|
||||
|
||||
[MenuItem("Bansonic/Rendering/Install Global Distortion")]
|
||||
public static void EnsureInstalledMenu()
|
||||
{
|
||||
EnsureInstalled();
|
||||
}
|
||||
|
||||
private static void ScheduleInstall()
|
||||
{
|
||||
if (installScheduled)
|
||||
return;
|
||||
|
||||
installScheduled = true;
|
||||
EditorApplication.delayCall += RunScheduledInstall;
|
||||
}
|
||||
|
||||
private static void RunScheduledInstall()
|
||||
{
|
||||
installScheduled = false;
|
||||
EnsureInstalled();
|
||||
}
|
||||
|
||||
private static void EnsureInstalled()
|
||||
{
|
||||
if (EditorApplication.isCompiling || BuildPipeline.isBuildingPlayer)
|
||||
{
|
||||
ScheduleInstall();
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsUnsafeSelectionActive())
|
||||
{
|
||||
ScheduleInstall();
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureRendererFeatureInstalled();
|
||||
EnsureVolumeOverrideInstalled();
|
||||
}
|
||||
|
||||
private static void EnsureRendererFeatureInstalled()
|
||||
{
|
||||
ScriptableRendererData rendererData = AssetDatabase.LoadAssetAtPath<ScriptableRendererData>(RendererDataPath);
|
||||
if (rendererData == null)
|
||||
return;
|
||||
|
||||
if (!rendererData.TryGetRendererFeature<GlobalDistortionRendererFeature>(out GlobalDistortionRendererFeature feature))
|
||||
{
|
||||
feature = ScriptableObject.CreateInstance<GlobalDistortionRendererFeature>();
|
||||
feature.name = "Global Distortion Renderer Feature";
|
||||
AssetDatabase.AddObjectToAsset(feature, rendererData);
|
||||
rendererData.rendererFeatures.Add(feature);
|
||||
rendererData.SetDirty();
|
||||
EditorUtility.SetDirty(feature);
|
||||
EditorUtility.SetDirty(rendererData);
|
||||
TryValidateRendererFeatures(rendererData);
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.ImportAsset(RendererDataPath);
|
||||
return;
|
||||
}
|
||||
|
||||
if (feature.renderPassEvent != RenderPassEvent.AfterRenderingPostProcessing)
|
||||
{
|
||||
feature.renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
|
||||
rendererData.SetDirty();
|
||||
EditorUtility.SetDirty(feature);
|
||||
EditorUtility.SetDirty(rendererData);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureVolumeOverrideInstalled()
|
||||
{
|
||||
VolumeProfile profile = AssetDatabase.LoadAssetAtPath<VolumeProfile>(GameplayVolumeProfilePath);
|
||||
if (profile == null)
|
||||
return;
|
||||
|
||||
RemoveNullVolumeComponents(profile);
|
||||
|
||||
if (profile.TryGet<GlobalDistortionVolume>(out _))
|
||||
return;
|
||||
|
||||
GlobalDistortionVolume component = profile.Add<GlobalDistortionVolume>(true);
|
||||
component.active = false;
|
||||
component.intensity.overrideState = true;
|
||||
component.intensity.value = 0f;
|
||||
component.noiseStrength.overrideState = true;
|
||||
component.noiseStrength.value = 0.16f;
|
||||
component.radialStrength.overrideState = true;
|
||||
component.radialStrength.value = 0.35f;
|
||||
component.noiseScale.overrideState = true;
|
||||
component.noiseScale.value = 12f;
|
||||
component.center.overrideState = true;
|
||||
component.center.value = new Vector2(0.5f, 0.5f);
|
||||
component.edgeFade.overrideState = true;
|
||||
component.edgeFade.value = 1.25f;
|
||||
component.affectSceneView.overrideState = true;
|
||||
component.affectSceneView.value = false;
|
||||
EditorUtility.SetDirty(component);
|
||||
EditorUtility.SetDirty(profile);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
private static void RemoveNullVolumeComponents(VolumeProfile profile)
|
||||
{
|
||||
SerializedObject serializedObject = new SerializedObject(profile);
|
||||
SerializedProperty componentsProperty = serializedObject.FindProperty("components");
|
||||
if (componentsProperty == null || !componentsProperty.isArray)
|
||||
return;
|
||||
|
||||
bool removed = false;
|
||||
for (int i = componentsProperty.arraySize - 1; i >= 0; i--)
|
||||
{
|
||||
SerializedProperty element = componentsProperty.GetArrayElementAtIndex(i);
|
||||
if (element.objectReferenceValue != null)
|
||||
continue;
|
||||
|
||||
componentsProperty.DeleteArrayElementAtIndex(i);
|
||||
removed = true;
|
||||
}
|
||||
|
||||
if (!removed)
|
||||
return;
|
||||
|
||||
serializedObject.ApplyModifiedPropertiesWithoutUndo();
|
||||
EditorUtility.SetDirty(profile);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
private static void TryValidateRendererFeatures(ScriptableRendererData rendererData)
|
||||
{
|
||||
MethodInfo validateMethod = typeof(ScriptableRendererData).GetMethod("ValidateRendererFeatures", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
validateMethod?.Invoke(rendererData, null);
|
||||
}
|
||||
|
||||
private static bool IsUnsafeSelectionActive()
|
||||
{
|
||||
Object activeObject = Selection.activeObject;
|
||||
if (activeObject is VolumeProfile || activeObject is Volume)
|
||||
return true;
|
||||
|
||||
GameObject activeGameObject = Selection.activeGameObject;
|
||||
if (activeGameObject == null)
|
||||
return false;
|
||||
|
||||
return activeGameObject.TryGetComponent<Volume>(out _);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8da344594051c8647abdb52bec165007
|
||||
@@ -0,0 +1,167 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
|
||||
[InitializeOnLoad]
|
||||
public static class GlobalGlitchInstaller
|
||||
{
|
||||
private const string RendererDataPath = "Assets/Settings/Renderer2D.asset";
|
||||
private const string GameplayVolumeProfilePath = "Assets/Scenes/gamePlay_gamePlay/gpGV.asset";
|
||||
private static bool installScheduled;
|
||||
|
||||
static GlobalGlitchInstaller()
|
||||
{
|
||||
ScheduleInstall();
|
||||
}
|
||||
|
||||
[MenuItem("Bansonic/Rendering/Install Global Glitch")]
|
||||
public static void EnsureInstalledMenu()
|
||||
{
|
||||
EnsureInstalled();
|
||||
}
|
||||
|
||||
private static void ScheduleInstall()
|
||||
{
|
||||
if (installScheduled)
|
||||
return;
|
||||
|
||||
installScheduled = true;
|
||||
EditorApplication.delayCall += RunScheduledInstall;
|
||||
}
|
||||
|
||||
private static void RunScheduledInstall()
|
||||
{
|
||||
installScheduled = false;
|
||||
EnsureInstalled();
|
||||
}
|
||||
|
||||
private static void EnsureInstalled()
|
||||
{
|
||||
if (EditorApplication.isCompiling || BuildPipeline.isBuildingPlayer)
|
||||
{
|
||||
ScheduleInstall();
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsUnsafeSelectionActive())
|
||||
{
|
||||
ScheduleInstall();
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureRendererFeatureInstalled();
|
||||
EnsureVolumeOverrideInstalled();
|
||||
}
|
||||
|
||||
private static void EnsureRendererFeatureInstalled()
|
||||
{
|
||||
ScriptableRendererData rendererData = AssetDatabase.LoadAssetAtPath<ScriptableRendererData>(RendererDataPath);
|
||||
if (rendererData == null)
|
||||
return;
|
||||
|
||||
if (!rendererData.TryGetRendererFeature<GlobalGlitchRendererFeature>(out GlobalGlitchRendererFeature feature))
|
||||
{
|
||||
feature = ScriptableObject.CreateInstance<GlobalGlitchRendererFeature>();
|
||||
feature.name = "Global Glitch Renderer Feature";
|
||||
AssetDatabase.AddObjectToAsset(feature, rendererData);
|
||||
rendererData.rendererFeatures.Add(feature);
|
||||
rendererData.SetDirty();
|
||||
EditorUtility.SetDirty(feature);
|
||||
EditorUtility.SetDirty(rendererData);
|
||||
TryValidateRendererFeatures(rendererData);
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.ImportAsset(RendererDataPath);
|
||||
return;
|
||||
}
|
||||
|
||||
if (feature.renderPassEvent != RenderPassEvent.AfterRenderingPostProcessing)
|
||||
{
|
||||
feature.renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
|
||||
rendererData.SetDirty();
|
||||
EditorUtility.SetDirty(feature);
|
||||
EditorUtility.SetDirty(rendererData);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureVolumeOverrideInstalled()
|
||||
{
|
||||
VolumeProfile profile = AssetDatabase.LoadAssetAtPath<VolumeProfile>(GameplayVolumeProfilePath);
|
||||
if (profile == null)
|
||||
return;
|
||||
|
||||
RemoveNullVolumeComponents(profile);
|
||||
|
||||
if (profile.TryGet<GlobalGlitchVolume>(out _))
|
||||
return;
|
||||
|
||||
GlobalGlitchVolume component = profile.Add<GlobalGlitchVolume>(true);
|
||||
component.active = false;
|
||||
component.intensity.overrideState = true;
|
||||
component.intensity.value = 0f;
|
||||
component.blockStrength.overrideState = true;
|
||||
component.blockStrength.value = 0.45f;
|
||||
component.colorSplit.overrideState = true;
|
||||
component.colorSplit.value = 0.01f;
|
||||
component.jitterAmount.overrideState = true;
|
||||
component.jitterAmount.value = 0.4f;
|
||||
component.stripFrequency.overrideState = true;
|
||||
component.stripFrequency.value = 48f;
|
||||
component.scanlineStrength.overrideState = true;
|
||||
component.scanlineStrength.value = 0.18f;
|
||||
component.affectSceneView.overrideState = true;
|
||||
component.affectSceneView.value = false;
|
||||
EditorUtility.SetDirty(component);
|
||||
EditorUtility.SetDirty(profile);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
private static void RemoveNullVolumeComponents(VolumeProfile profile)
|
||||
{
|
||||
SerializedObject serializedObject = new SerializedObject(profile);
|
||||
SerializedProperty componentsProperty = serializedObject.FindProperty("components");
|
||||
if (componentsProperty == null || !componentsProperty.isArray)
|
||||
return;
|
||||
|
||||
bool removed = false;
|
||||
for (int i = componentsProperty.arraySize - 1; i >= 0; i--)
|
||||
{
|
||||
SerializedProperty element = componentsProperty.GetArrayElementAtIndex(i);
|
||||
if (element.objectReferenceValue != null)
|
||||
continue;
|
||||
|
||||
componentsProperty.DeleteArrayElementAtIndex(i);
|
||||
removed = true;
|
||||
}
|
||||
|
||||
if (!removed)
|
||||
return;
|
||||
|
||||
serializedObject.ApplyModifiedPropertiesWithoutUndo();
|
||||
EditorUtility.SetDirty(profile);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
private static void TryValidateRendererFeatures(ScriptableRendererData rendererData)
|
||||
{
|
||||
MethodInfo validateMethod = typeof(ScriptableRendererData).GetMethod("ValidateRendererFeatures", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
validateMethod?.Invoke(rendererData, null);
|
||||
}
|
||||
|
||||
private static bool IsUnsafeSelectionActive()
|
||||
{
|
||||
Object activeObject = Selection.activeObject;
|
||||
if (activeObject is VolumeProfile || activeObject is Volume)
|
||||
return true;
|
||||
|
||||
GameObject activeGameObject = Selection.activeGameObject;
|
||||
if (activeGameObject == null)
|
||||
return false;
|
||||
|
||||
return activeGameObject.TryGetComponent<Volume>(out _);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7effde50fff3c34c8c188a696cf3bcf
|
||||
@@ -0,0 +1,157 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
|
||||
[InitializeOnLoad]
|
||||
public static class GlobalMonochromeInstaller
|
||||
{
|
||||
private const string RendererDataPath = "Assets/Settings/Renderer2D.asset";
|
||||
private const string GameplayVolumeProfilePath = "Assets/Scenes/gamePlay_gamePlay/gpGV.asset";
|
||||
private static bool installScheduled;
|
||||
|
||||
static GlobalMonochromeInstaller()
|
||||
{
|
||||
ScheduleInstall();
|
||||
}
|
||||
|
||||
[MenuItem("Bansonic/Rendering/Install Global Monochrome")]
|
||||
public static void EnsureInstalledMenu()
|
||||
{
|
||||
EnsureInstalled();
|
||||
}
|
||||
|
||||
private static void ScheduleInstall()
|
||||
{
|
||||
if (installScheduled)
|
||||
return;
|
||||
|
||||
installScheduled = true;
|
||||
EditorApplication.delayCall += RunScheduledInstall;
|
||||
}
|
||||
|
||||
private static void RunScheduledInstall()
|
||||
{
|
||||
installScheduled = false;
|
||||
EnsureInstalled();
|
||||
}
|
||||
|
||||
private static void EnsureInstalled()
|
||||
{
|
||||
if (EditorApplication.isCompiling || BuildPipeline.isBuildingPlayer)
|
||||
{
|
||||
ScheduleInstall();
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsUnsafeSelectionActive())
|
||||
{
|
||||
ScheduleInstall();
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureRendererFeatureInstalled();
|
||||
EnsureVolumeOverrideInstalled();
|
||||
}
|
||||
|
||||
private static void EnsureRendererFeatureInstalled()
|
||||
{
|
||||
ScriptableRendererData rendererData = AssetDatabase.LoadAssetAtPath<ScriptableRendererData>(RendererDataPath);
|
||||
if (rendererData == null)
|
||||
return;
|
||||
|
||||
if (!rendererData.TryGetRendererFeature<GlobalMonochromeRendererFeature>(out GlobalMonochromeRendererFeature feature))
|
||||
{
|
||||
feature = ScriptableObject.CreateInstance<GlobalMonochromeRendererFeature>();
|
||||
feature.name = "Global Monochrome Renderer Feature";
|
||||
AssetDatabase.AddObjectToAsset(feature, rendererData);
|
||||
rendererData.rendererFeatures.Add(feature);
|
||||
rendererData.SetDirty();
|
||||
EditorUtility.SetDirty(feature);
|
||||
EditorUtility.SetDirty(rendererData);
|
||||
TryValidateRendererFeatures(rendererData);
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.ImportAsset(RendererDataPath);
|
||||
return;
|
||||
}
|
||||
|
||||
if (feature.renderPassEvent != RenderPassEvent.AfterRenderingPostProcessing)
|
||||
{
|
||||
feature.renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
|
||||
rendererData.SetDirty();
|
||||
EditorUtility.SetDirty(feature);
|
||||
EditorUtility.SetDirty(rendererData);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureVolumeOverrideInstalled()
|
||||
{
|
||||
VolumeProfile profile = AssetDatabase.LoadAssetAtPath<VolumeProfile>(GameplayVolumeProfilePath);
|
||||
if (profile == null)
|
||||
return;
|
||||
|
||||
RemoveNullVolumeComponents(profile);
|
||||
|
||||
if (profile.TryGet<GlobalMonochromeVolume>(out _))
|
||||
return;
|
||||
|
||||
GlobalMonochromeVolume component = profile.Add<GlobalMonochromeVolume>(true);
|
||||
component.active = false;
|
||||
component.intensity.overrideState = true;
|
||||
component.intensity.value = 0f;
|
||||
component.affectSceneView.overrideState = true;
|
||||
component.affectSceneView.value = false;
|
||||
EditorUtility.SetDirty(component);
|
||||
EditorUtility.SetDirty(profile);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
private static void RemoveNullVolumeComponents(VolumeProfile profile)
|
||||
{
|
||||
SerializedObject serializedObject = new SerializedObject(profile);
|
||||
SerializedProperty componentsProperty = serializedObject.FindProperty("components");
|
||||
if (componentsProperty == null || !componentsProperty.isArray)
|
||||
return;
|
||||
|
||||
bool removed = false;
|
||||
for (int i = componentsProperty.arraySize - 1; i >= 0; i--)
|
||||
{
|
||||
SerializedProperty element = componentsProperty.GetArrayElementAtIndex(i);
|
||||
if (element.objectReferenceValue != null)
|
||||
continue;
|
||||
|
||||
componentsProperty.DeleteArrayElementAtIndex(i);
|
||||
removed = true;
|
||||
}
|
||||
|
||||
if (!removed)
|
||||
return;
|
||||
|
||||
serializedObject.ApplyModifiedPropertiesWithoutUndo();
|
||||
EditorUtility.SetDirty(profile);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
private static void TryValidateRendererFeatures(ScriptableRendererData rendererData)
|
||||
{
|
||||
MethodInfo validateMethod = typeof(ScriptableRendererData).GetMethod("ValidateRendererFeatures", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
validateMethod?.Invoke(rendererData, null);
|
||||
}
|
||||
|
||||
private static bool IsUnsafeSelectionActive()
|
||||
{
|
||||
Object activeObject = Selection.activeObject;
|
||||
if (activeObject is VolumeProfile || activeObject is Volume)
|
||||
return true;
|
||||
|
||||
GameObject activeGameObject = Selection.activeGameObject;
|
||||
if (activeGameObject == null)
|
||||
return false;
|
||||
|
||||
return activeGameObject.TryGetComponent<Volume>(out _);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9530a18d124454244a6fc70d833e3182
|
||||
@@ -0,0 +1,178 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.RenderGraphModule;
|
||||
using UnityEngine.Rendering.RenderGraphModule.Util;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
|
||||
public class GlobalAfterimageRendererFeature : ScriptableRendererFeature
|
||||
{
|
||||
[Tooltip("When the custom afterimage pass should execute.")]
|
||||
public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
|
||||
|
||||
private Material material;
|
||||
private GlobalAfterimagePass pass;
|
||||
|
||||
public override void Create()
|
||||
{
|
||||
if (pass == null)
|
||||
pass = new GlobalAfterimagePass();
|
||||
|
||||
pass.renderPassEvent = renderPassEvent;
|
||||
EnsureMaterial();
|
||||
}
|
||||
|
||||
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
|
||||
{
|
||||
if (!EnsureMaterial())
|
||||
return;
|
||||
|
||||
Camera camera = renderingData.cameraData.camera;
|
||||
if (camera == null)
|
||||
return;
|
||||
|
||||
if (renderingData.cameraData.cameraType == CameraType.Preview || renderingData.cameraData.cameraType == CameraType.Reflection)
|
||||
return;
|
||||
|
||||
if (!renderingData.cameraData.postProcessEnabled)
|
||||
return;
|
||||
|
||||
GlobalAfterimageVolume settings = VolumeManager.instance.stack.GetComponent<GlobalAfterimageVolume>();
|
||||
bool hasVolume = settings != null && settings.active;
|
||||
float runtimeOpacity = GlobalAfterimageRuntimeController.RuntimeOpacity;
|
||||
float baseOpacity = hasVolume ? settings.opacity.value : 0f;
|
||||
float finalOpacity = Mathf.Clamp01(Mathf.Max(baseOpacity, runtimeOpacity));
|
||||
if (finalOpacity <= 0.0001f)
|
||||
return;
|
||||
|
||||
if (camera.cameraType == CameraType.SceneView && hasVolume && !settings.affectSceneView.value)
|
||||
return;
|
||||
|
||||
float runtimeScale = Mathf.Max(1f, GlobalAfterimageRuntimeController.RuntimeScale);
|
||||
float baseScale = hasVolume ? settings.scale.value : 1.05f;
|
||||
float finalScale = Mathf.Max(baseScale, runtimeScale);
|
||||
bool captureRequested = GlobalAfterimageRuntimeController.ConsumeCaptureRequest();
|
||||
|
||||
pass.Setup(material, finalOpacity, finalScale, captureRequested, renderingData.cameraData.cameraTargetDescriptor);
|
||||
renderer.EnqueuePass(pass);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (pass != null)
|
||||
{
|
||||
pass.Dispose();
|
||||
pass = null;
|
||||
}
|
||||
|
||||
if (material != null)
|
||||
{
|
||||
CoreUtils.Destroy(material);
|
||||
material = null;
|
||||
}
|
||||
}
|
||||
|
||||
private bool EnsureMaterial()
|
||||
{
|
||||
if (material != null)
|
||||
return true;
|
||||
|
||||
Shader shader = Shader.Find("Hidden/Bansonic/GlobalAfterimage");
|
||||
if (shader == null)
|
||||
return false;
|
||||
|
||||
material = CoreUtils.CreateEngineMaterial(shader);
|
||||
return material != null;
|
||||
}
|
||||
|
||||
private sealed class GlobalAfterimagePass : ScriptableRenderPass
|
||||
{
|
||||
private static readonly int OpacityId = Shader.PropertyToID("_AfterimageOpacity");
|
||||
private static readonly int ScaleId = Shader.PropertyToID("_AfterimageScale");
|
||||
private static readonly int SnapshotTexId = Shader.PropertyToID("_SnapshotTex");
|
||||
|
||||
private Material passMaterial;
|
||||
private float opacity;
|
||||
private float scale;
|
||||
private bool captureRequested;
|
||||
private RenderTextureDescriptor descriptor;
|
||||
private RTHandle compatibilityCopy;
|
||||
private RTHandle snapshotTexture;
|
||||
|
||||
public void Setup(Material material, float passOpacity, float passScale, bool passCaptureRequested, RenderTextureDescriptor targetDescriptor)
|
||||
{
|
||||
passMaterial = material;
|
||||
opacity = passOpacity;
|
||||
scale = Mathf.Max(1f, passScale);
|
||||
captureRequested = passCaptureRequested;
|
||||
descriptor = targetDescriptor;
|
||||
descriptor.msaaSamples = 1;
|
||||
descriptor.depthBufferBits = 0;
|
||||
requiresIntermediateTexture = true;
|
||||
RenderingUtils.ReAllocateHandleIfNeeded(ref snapshotTexture, descriptor, FilterMode.Bilinear, TextureWrapMode.Clamp, name: "_GlobalAfterimageSnapshot");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
compatibilityCopy?.Release();
|
||||
compatibilityCopy = null;
|
||||
snapshotTexture?.Release();
|
||||
snapshotTexture = null;
|
||||
}
|
||||
|
||||
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
|
||||
{
|
||||
if (passMaterial == null || snapshotTexture == null)
|
||||
return;
|
||||
|
||||
UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
|
||||
if (resourceData.isActiveTargetBackBuffer)
|
||||
return;
|
||||
|
||||
ApplyMaterialProperties();
|
||||
|
||||
TextureHandle source = resourceData.activeColorTexture;
|
||||
TextureHandle importedSnapshot = renderGraph.ImportTexture(snapshotTexture);
|
||||
if (captureRequested)
|
||||
{
|
||||
renderGraph.AddBlitPass(source, importedSnapshot, Vector2.one, Vector2.zero, passName: "Global Afterimage Capture");
|
||||
}
|
||||
|
||||
TextureDesc tempDesc = renderGraph.GetTextureDesc(source);
|
||||
tempDesc.name = "CameraColor-GlobalAfterimageTemp";
|
||||
tempDesc.clearBuffer = false;
|
||||
TextureHandle tempTexture = renderGraph.CreateTexture(tempDesc);
|
||||
|
||||
RenderGraphUtils.BlitMaterialParameters effectParameters = new(source, tempTexture, passMaterial, 0);
|
||||
renderGraph.AddBlitPass(effectParameters, passName: "Global Afterimage Effect");
|
||||
renderGraph.AddBlitPass(tempTexture, resourceData.activeColorTexture, Vector2.one, Vector2.zero, passName: "Global Afterimage Restore");
|
||||
}
|
||||
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
if (passMaterial == null || snapshotTexture == null)
|
||||
return;
|
||||
|
||||
ApplyMaterialProperties();
|
||||
RenderingUtils.ReAllocateHandleIfNeeded(ref compatibilityCopy, descriptor, FilterMode.Bilinear, TextureWrapMode.Clamp, name: "_GlobalAfterimageCompatibilityCopy");
|
||||
|
||||
CommandBuffer cmd = CommandBufferPool.Get("Global Afterimage Pass");
|
||||
if (captureRequested)
|
||||
{
|
||||
Blitter.BlitCameraTexture(cmd, renderingData.cameraData.renderer.cameraColorTargetHandle, snapshotTexture);
|
||||
}
|
||||
|
||||
Blitter.BlitCameraTexture(cmd, renderingData.cameraData.renderer.cameraColorTargetHandle, compatibilityCopy);
|
||||
Blitter.BlitCameraTexture(cmd, compatibilityCopy, renderingData.cameraData.renderer.cameraColorTargetHandle, passMaterial, 0);
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
|
||||
private void ApplyMaterialProperties()
|
||||
{
|
||||
passMaterial.SetFloat(OpacityId, opacity);
|
||||
passMaterial.SetFloat(ScaleId, scale);
|
||||
if (snapshotTexture != null)
|
||||
passMaterial.SetTexture(SnapshotTexId, snapshotTexture);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a28c239b9c2736e489a75bd286167cb9
|
||||
@@ -0,0 +1,125 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class GlobalAfterimageRuntimeController : MonoBehaviour
|
||||
{
|
||||
public static GlobalAfterimageRuntimeController Instance { get; private set; }
|
||||
|
||||
[Header("Runtime Afterimage Defaults")]
|
||||
public float defaultStartOpacity = 0.5f;
|
||||
public float defaultFadeDuration = 0.22f;
|
||||
public float defaultEndScale = 1.12f;
|
||||
public bool useUnscaledTime = true;
|
||||
public bool triggerOnEnable = false;
|
||||
|
||||
private static float sRuntimeOpacity;
|
||||
private static float sRuntimeScale = 1f;
|
||||
private static bool sCaptureRequested;
|
||||
|
||||
private float activeStartOpacity;
|
||||
private float activeFadeDuration;
|
||||
private float activeEndScale = 1f;
|
||||
private float activeElapsed;
|
||||
private bool activeAfterimage;
|
||||
|
||||
public static float RuntimeOpacity => sRuntimeOpacity;
|
||||
public static float RuntimeScale => sRuntimeScale;
|
||||
public static bool HasActiveAfterimage => sRuntimeOpacity > 0.0001f;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance == null)
|
||||
{
|
||||
Instance = this;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Instance != this)
|
||||
Destroy(gameObject);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (triggerOnEnable)
|
||||
TriggerAfterimage();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
float delta = useUnscaledTime ? Time.unscaledDeltaTime : Time.deltaTime;
|
||||
UpdateAfterimage(delta);
|
||||
}
|
||||
|
||||
public void TriggerAfterimage()
|
||||
{
|
||||
TriggerAfterimage(defaultStartOpacity, defaultFadeDuration, defaultEndScale);
|
||||
}
|
||||
|
||||
public void TriggerAfterimage(float startOpacity, float fadeDuration, float endScale)
|
||||
{
|
||||
activeStartOpacity = Mathf.Clamp01(startOpacity);
|
||||
activeFadeDuration = Mathf.Max(0.0001f, fadeDuration);
|
||||
activeEndScale = Mathf.Max(1f, endScale);
|
||||
activeElapsed = 0f;
|
||||
activeAfterimage = activeStartOpacity > 0.0001f;
|
||||
|
||||
sRuntimeOpacity = activeStartOpacity;
|
||||
sRuntimeScale = 1f;
|
||||
sCaptureRequested = activeAfterimage;
|
||||
}
|
||||
|
||||
private void UpdateAfterimage(float delta)
|
||||
{
|
||||
if (!activeAfterimage)
|
||||
{
|
||||
sRuntimeOpacity = 0f;
|
||||
sRuntimeScale = 1f;
|
||||
return;
|
||||
}
|
||||
|
||||
activeElapsed += delta;
|
||||
float normalized = Mathf.Clamp01(activeElapsed / activeFadeDuration);
|
||||
sRuntimeOpacity = Mathf.Lerp(activeStartOpacity, 0f, normalized);
|
||||
sRuntimeScale = Mathf.Lerp(1f, activeEndScale, normalized);
|
||||
|
||||
if (normalized < 1f)
|
||||
return;
|
||||
|
||||
activeAfterimage = false;
|
||||
sRuntimeOpacity = 0f;
|
||||
sRuntimeScale = 1f;
|
||||
}
|
||||
|
||||
public static bool ConsumeCaptureRequest()
|
||||
{
|
||||
bool requested = sCaptureRequested;
|
||||
sCaptureRequested = false;
|
||||
return requested;
|
||||
}
|
||||
|
||||
public static GlobalAfterimageRuntimeController EnsureInstance()
|
||||
{
|
||||
if (Instance != null)
|
||||
return Instance;
|
||||
|
||||
GlobalAfterimageRuntimeController existing = FindFirstObjectByType<GlobalAfterimageRuntimeController>();
|
||||
if (existing != null)
|
||||
{
|
||||
Instance = existing;
|
||||
return existing;
|
||||
}
|
||||
|
||||
GameObject runtimeObject = new GameObject("__global_afterimage_runtime");
|
||||
Instance = runtimeObject.AddComponent<GlobalAfterimageRuntimeController>();
|
||||
return Instance;
|
||||
}
|
||||
|
||||
public static void Trigger(float startOpacity, float fadeDuration, float endScale)
|
||||
{
|
||||
EnsureInstance().TriggerAfterimage(startOpacity, fadeDuration, endScale);
|
||||
}
|
||||
|
||||
public static void TriggerDefault()
|
||||
{
|
||||
EnsureInstance().TriggerAfterimage();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user