FIx bug animation not stop. add more QOL for test animation scene. add AnimationSceneSkillTest.md to show how to use

This commit is contained in:
Tran Hai Nam
2026-05-20 15:16:24 +07:00
parent 7301f9897c
commit d2aa2c8001
45 changed files with 118360 additions and 23 deletions
@@ -505,6 +505,11 @@ MonoBehaviour:
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 537aaa290c1d9b540bbd480a617d9929
m_Address: "gfx/\u4EBA\u7269/\u6280\u80FD/\u5996\u517D/\u5316\u8840\u6210\u9B54\u9884\u5907.gfx"
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 539710a69297f704e9a0d1c1cdda6390
m_Address: "gfx/\u4EBA\u7269/\u6280\u80FD/\u6B66\u4FA0/\u4E91\u9F99\u4E5D\u73B01.gfx"
m_ReadOnly: 0
@@ -660,6 +665,11 @@ MonoBehaviour:
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 6dad60b1e8f9feb4bbbb7a09443d6f58
m_Address: "gfx/\u4EBA\u7269/\u6280\u80FD/\u5996\u517D/\u5316\u8840\u6210\u9B54\u9884\u5907\u65BD\u653E\u8D77.gfx"
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 6e10cdd12acec704bbe95ee569e4b41b
m_Address: "gfx/\u7B56\u5212\u8054\u5165/\u4EBA\u7269\u6280\u80FD/\u51FB\u4E2D/\u7FBD\u7BAD\u51FB\u4E2D.gfx"
m_ReadOnly: 0
@@ -830,6 +840,11 @@ MonoBehaviour:
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 90589782f70dd234b970ee3dfd8ac37a
m_Address: "gfx/\u4EBA\u7269/\u6280\u80FD/\u5996\u517D/\u5316\u8840\u6210\u9B54\u9884\u59071.gfx"
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 90b73df583cd78c458a92d5c3d55a136
m_Address: "gfx/\u4EBA\u7269/\u6280\u80FD/\u6CD5\u5E08/\u6C99\u9677\u9884\u59072.gfx"
m_ReadOnly: 0
@@ -1110,6 +1125,11 @@ MonoBehaviour:
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: c1ba74f0f1bae7f4eb8a96fc7319ebc1
m_Address: "gfx/\u4EBA\u7269/\u6280\u80FD/\u5996\u517D/\u5316\u8840\u6210\u9B54\u91CA\u653E.gfx"
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: c2bfba6b27255834b805caffd1e7db8b
m_Address: "gfx/\u7B56\u5212\u8054\u5165/\u4EBA\u7269\u6280\u80FD/\u51FB\u4E2D/\u5BF8\u529B\u51FB\u4E2D.gfx"
m_ReadOnly: 0
@@ -1380,6 +1400,11 @@ MonoBehaviour:
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: fa805bed635aea543bb135ef5456bb6d
m_Address: "gfx/\u4EBA\u7269/\u6280\u80FD/\u5996\u517D/\u5316\u8840\u6210\u9B54\u9884\u5907\u65BD\u653E\u8D771.gfx"
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: fa9f8176eb7b40c428689a5a3f528931
m_Address: "gfx/\u4EBA\u7269/\u6280\u80FD/\u6B66\u4FA0/\u9F99\u73B0\u9884\u5907.gfx"
m_ReadOnly: 0
Binary file not shown.
+107
View File
@@ -0,0 +1,107 @@
fileFormatVersion: 2
guid: 1cb35c4ec25f5e646ace941cdb627ab9
ModelImporter:
serializedVersion: 22200
internalIDToNameTable: []
externalObjects: {}
materials:
materialImportMode: 2
materialName: 0
materialSearch: 1
materialLocation: 1
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleCurves: 1
optimizeGameObjects: 0
removeConstantScaleCurves: 0
motionNodeName:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
importAnimatedCustomProperties: 0
importConstraints: 0
animationCompression: 1
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
extraUserProperties: []
clipAnimations: []
isReadable: 0
meshes:
lODScreenPercentages: []
globalScale: 1
meshCompression: 0
addColliders: 0
useSRGBMaterialColor: 1
sortHierarchyByName: 1
importPhysicalCameras: 1
importVisibility: 1
importBlendShapes: 1
importCameras: 1
importLights: 1
nodeNameCollisionStrategy: 1
fileIdsGeneration: 2
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
keepQuads: 0
weldVertices: 1
bakeAxisConversion: 0
preserveHierarchy: 0
skinWeightsMode: 0
maxBonesPerVertex: 4
minBoneWeight: 0.001
optimizeBones: 1
meshOptimizationFlags: -1
indexFormat: 0
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVMarginMethod: 1
secondaryUVMinLightmapResolution: 40
secondaryUVMinObjectScale: 1
secondaryUVPackMargin: 4
useFileScale: 1
strictVertexDataChecks: 0
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 3
normalCalculationMode: 4
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
blendShapeNormalImportMode: 1
normalSmoothingSource: 0
referencedClips: []
importAnimation: 1
humanDescription:
serializedVersion: 3
human: []
skeleton: []
armTwist: 0.5
foreArmTwist: 0.5
upperLegTwist: 0.5
legTwist: 0.5
armStretch: 0.05
legStretch: 0.05
feetSpacing: 0
globalScale: 1
rootMotionBoneName:
hasTranslationDoF: 0
hasExtraRoot: 0
skeletonHasParents: 1
lastHumanDescriptionAvatarSource: {instanceID: 0}
autoGenerateAvatarMappingIfUnspecified: 1
animationType: 2
humanoidOversampling: 1
avatarSetup: 0
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
importBlendShapeDeformPercent: 1
remapMaterialsIfMaterialImportModeIsNone: 0
additionalBone: 0
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c1ba74f0f1bae7f4eb8a96fc7319ebc1
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 537aaa290c1d9b540bbd480a617d9929
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 90589782f70dd234b970ee3dfd8ac37a
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 6dad60b1e8f9feb4bbbb7a09443d6f58
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: fa805bed635aea543bb135ef5456bb6d
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 238903d30fdd9b54d9713ea145885b06
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,209 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: zsj7
m_Shader: {fileID: 4800000, guid: 0a016a83287664641b867743f19faf14, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _DISSOLVETEXUVS_NORMAL
- _DISTORTTEXUVS_NORMAL
- _MAINTEXUVS_NORMAL
- _MASKTEXUVS_NORMAL
m_InvalidKeywords:
- _DISSOLVETEXAR_ON
- _DISTORTTEXAR_ON
- _MASKTEXAR_ON
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DissolveTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DistortTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: 495b63cf335ed554bb329f12cfc4aab5, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MaskTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AddPrecomputedVelocity: 0
- _AlphaClip: 0
- _AlphaCutoff: 0.5
- _AlphaToMask: 0
- _Blend: 0
- _BlendMode: 1
- _BlendModePreserveSpecular: 1
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _CullMode: 0
- _CustomDissolve: 0
- _CustomMainTex: 0
- _Cutoff: 0.5
- _DepthFade: 1
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DissolveFactor: 0
- _DissolveSoft: 0.1
- _DissolveTexAR: 1
- _DissolveTexClampU: 0
- _DissolveTexClampV: 0
- _DissolveTexRotate: 0
- _DissolveTexUSpeed: 0
- _DissolveTexUVS: 0
- _DissolveTexVSpeed: 0
- _DissolveWide: 0.05
- _DistortDissolveTex: 0
- _DistortFactor: 0
- _DistortMainTex: 0
- _DistortMaskTex: 0
- _DistortTexAR: 1
- _DistortTexClampU: 0
- _DistortTexClampV: 0
- _DistortTexRotate: 0
- _DistortTexUSpeed: 0
- _DistortTexUVS: 0
- _DistortTexVSpeed: 0
- _Dst: 1
- _DstBlend: 0
- _DstBlendAlpha: 0
- _EnvironmentReflections: 1
- _FDepth: 0
- _FDissolveTex: 0
- _FDistortTex: 0
- _FFnl: 0
- _FMaskTex: 0
- _FnlPower: 1
- _FnlScale: 0
- _GlossMapScale: 0
- _Glossiness: 0
- _GlossyReflections: 0
- _MainAlpha: 1
- _MainTexAR: 0
- _MainTexClampU: 0
- _MainTexClampV: 0
- _MainTexRotate: 0
- _MainTexUSpeed: 0
- _MainTexUVS: 0
- _MainTexVSpeed: 0
- _MaskTexAR: 1
- _MaskTexClampU: 0
- _MaskTexClampV: 0
- _MaskTexRotate: 0
- _MaskTexUSpeed: 0
- _MaskTexUVS: 0
- _MaskTexVSpeed: 0
- _Metallic: 0
- _OcclusionStrength: 1
- _Parallax: 0.005
- _QueueOffset: 0
- _ReFnl: 0
- _ReceiveShadows: 1
- _Scr: 1
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
- _WorkflowMode: 1
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _DissolveColor: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _FnlColor: {r: 1, g: 1, b: 1, a: 1}
- _MainColor: {r: 1, g: 1, b: 1, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &4443430480060671443
MonoBehaviour:
m_ObjectHideFlags: 11
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: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 10
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ea9b38b62e811874ca186b045df86462
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,209 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: "\u5929\u5730\u65E0\u7EA7\u5185\u5708"
m_Shader: {fileID: 4800000, guid: 0a016a83287664641b867743f19faf14, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _DISSOLVETEXUVS_NORMAL
- _DISTORTTEXUVS_NORMAL
- _MAINTEXUVS_NORMAL
- _MASKTEXUVS_NORMAL
m_InvalidKeywords:
- _DISSOLVETEXAR_ON
- _DISTORTTEXAR_ON
- _MASKTEXAR_ON
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DissolveTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DistortTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: b47323c0537631d43b4f3666c6844188, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MaskTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AddPrecomputedVelocity: 0
- _AlphaClip: 0
- _AlphaCutoff: 0.5
- _AlphaToMask: 0
- _Blend: 0
- _BlendMode: 1
- _BlendModePreserveSpecular: 1
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _CullMode: 0
- _CustomDissolve: 0
- _CustomMainTex: 0
- _Cutoff: 0.5
- _DepthFade: 1
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DissolveFactor: 0
- _DissolveSoft: 0.1
- _DissolveTexAR: 1
- _DissolveTexClampU: 0
- _DissolveTexClampV: 0
- _DissolveTexRotate: 0
- _DissolveTexUSpeed: 0
- _DissolveTexUVS: 0
- _DissolveTexVSpeed: 0
- _DissolveWide: 0.05
- _DistortDissolveTex: 0
- _DistortFactor: 0
- _DistortMainTex: 0
- _DistortMaskTex: 0
- _DistortTexAR: 1
- _DistortTexClampU: 0
- _DistortTexClampV: 0
- _DistortTexRotate: 0
- _DistortTexUSpeed: 0
- _DistortTexUVS: 0
- _DistortTexVSpeed: 0
- _Dst: 1
- _DstBlend: 0
- _DstBlendAlpha: 0
- _EnvironmentReflections: 1
- _FDepth: 0
- _FDissolveTex: 0
- _FDistortTex: 0
- _FFnl: 0
- _FMaskTex: 0
- _FnlPower: 1
- _FnlScale: 0
- _GlossMapScale: 0
- _Glossiness: 0
- _GlossyReflections: 0
- _MainAlpha: 1
- _MainTexAR: 0
- _MainTexClampU: 0
- _MainTexClampV: 0
- _MainTexRotate: 0
- _MainTexUSpeed: 0
- _MainTexUVS: 0
- _MainTexVSpeed: 0
- _MaskTexAR: 1
- _MaskTexClampU: 0
- _MaskTexClampV: 0
- _MaskTexRotate: 0
- _MaskTexUSpeed: 0
- _MaskTexUVS: 0
- _MaskTexVSpeed: 0
- _Metallic: 0
- _OcclusionStrength: 1
- _Parallax: 0.005
- _QueueOffset: 0
- _ReFnl: 0
- _ReceiveShadows: 1
- _Scr: 1
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
- _WorkflowMode: 1
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _DissolveColor: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _FnlColor: {r: 1, g: 1, b: 1, a: 1}
- _MainColor: {r: 1.4980394, g: 1.4980394, b: 1.4980394, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &6085187289834300244
MonoBehaviour:
m_ObjectHideFlags: 11
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: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 9
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 315cfcbdf34c6024ea2899ffcc5f14d1
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 33413d4cf2f637f4f8c60020dce6e464
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,209 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: circle027
m_Shader: {fileID: 4800000, guid: 0a016a83287664641b867743f19faf14, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _DISSOLVETEXUVS_NORMAL
- _DISTORTTEXUVS_NORMAL
- _MAINTEXUVS_NORMAL
- _MASKTEXUVS_NORMAL
m_InvalidKeywords:
- _DISSOLVETEXAR_ON
- _DISTORTTEXAR_ON
- _MASKTEXAR_ON
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DissolveTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DistortTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: 34c57316d248ac544b9f88d1c7f678ce, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MaskTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AddPrecomputedVelocity: 0
- _AlphaClip: 0
- _AlphaCutoff: 0.5
- _AlphaToMask: 0
- _Blend: 0
- _BlendMode: 1
- _BlendModePreserveSpecular: 1
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _CullMode: 0
- _CustomDissolve: 0
- _CustomMainTex: 0
- _Cutoff: 0.5
- _DepthFade: 1
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DissolveFactor: 0
- _DissolveSoft: 0.1
- _DissolveTexAR: 1
- _DissolveTexClampU: 0
- _DissolveTexClampV: 0
- _DissolveTexRotate: 0
- _DissolveTexUSpeed: 0
- _DissolveTexUVS: 0
- _DissolveTexVSpeed: 0
- _DissolveWide: 0.05
- _DistortDissolveTex: 0
- _DistortFactor: 0
- _DistortMainTex: 0
- _DistortMaskTex: 0
- _DistortTexAR: 1
- _DistortTexClampU: 0
- _DistortTexClampV: 0
- _DistortTexRotate: 0
- _DistortTexUSpeed: 0
- _DistortTexUVS: 0
- _DistortTexVSpeed: 0
- _Dst: 1
- _DstBlend: 0
- _DstBlendAlpha: 0
- _EnvironmentReflections: 1
- _FDepth: 0
- _FDissolveTex: 0
- _FDistortTex: 0
- _FFnl: 0
- _FMaskTex: 0
- _FnlPower: 1
- _FnlScale: 0
- _GlossMapScale: 0
- _Glossiness: 0
- _GlossyReflections: 0
- _MainAlpha: 1
- _MainTexAR: 0
- _MainTexClampU: 0
- _MainTexClampV: 0
- _MainTexRotate: 0
- _MainTexUSpeed: 0
- _MainTexUVS: 0
- _MainTexVSpeed: 0
- _MaskTexAR: 1
- _MaskTexClampU: 0
- _MaskTexClampV: 0
- _MaskTexRotate: 0
- _MaskTexUSpeed: 0
- _MaskTexUVS: 0
- _MaskTexVSpeed: 0
- _Metallic: 0
- _OcclusionStrength: 1
- _Parallax: 0.005
- _QueueOffset: 0
- _ReFnl: 0
- _ReceiveShadows: 1
- _Scr: 1
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
- _WorkflowMode: 1
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _DissolveColor: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _FnlColor: {r: 1, g: 1, b: 1, a: 1}
- _MainColor: {r: 2.0000002, g: 2.0000002, b: 2.0000002, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &6085187289834300244
MonoBehaviour:
m_ObjectHideFlags: 11
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: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 9
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 160c2696d17c0d74a910b788ea9c496a
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,209 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: purpletelep
m_Shader: {fileID: 4800000, guid: 0a016a83287664641b867743f19faf14, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _DISSOLVETEXUVS_NORMAL
- _DISTORTTEXUVS_NORMAL
- _MAINTEXUVS_NORMAL
- _MASKTEXUVS_NORMAL
m_InvalidKeywords:
- _DISSOLVETEXAR_ON
- _DISTORTTEXAR_ON
- _MASKTEXAR_ON
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DissolveTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DistortTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: 80935dc8c0a01fb44a63ef46ce1e055f, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MaskTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AddPrecomputedVelocity: 0
- _AlphaClip: 0
- _AlphaCutoff: 0.5
- _AlphaToMask: 0
- _Blend: 0
- _BlendMode: 1
- _BlendModePreserveSpecular: 1
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _CullMode: 0
- _CustomDissolve: 0
- _CustomMainTex: 0
- _Cutoff: 0.5
- _DepthFade: 1
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DissolveFactor: 0
- _DissolveSoft: 0.1
- _DissolveTexAR: 1
- _DissolveTexClampU: 0
- _DissolveTexClampV: 0
- _DissolveTexRotate: 0
- _DissolveTexUSpeed: 0
- _DissolveTexUVS: 0
- _DissolveTexVSpeed: 0
- _DissolveWide: 0.05
- _DistortDissolveTex: 0
- _DistortFactor: 0
- _DistortMainTex: 0
- _DistortMaskTex: 0
- _DistortTexAR: 1
- _DistortTexClampU: 0
- _DistortTexClampV: 0
- _DistortTexRotate: 0
- _DistortTexUSpeed: 0
- _DistortTexUVS: 0
- _DistortTexVSpeed: 0
- _Dst: 1
- _DstBlend: 0
- _DstBlendAlpha: 0
- _EnvironmentReflections: 1
- _FDepth: 0
- _FDissolveTex: 0
- _FDistortTex: 0
- _FFnl: 0
- _FMaskTex: 0
- _FnlPower: 1
- _FnlScale: 0
- _GlossMapScale: 0
- _Glossiness: 0
- _GlossyReflections: 0
- _MainAlpha: 1
- _MainTexAR: 0
- _MainTexClampU: 0
- _MainTexClampV: 0
- _MainTexRotate: 0
- _MainTexUSpeed: 0
- _MainTexUVS: 0
- _MainTexVSpeed: 0
- _MaskTexAR: 1
- _MaskTexClampU: 0
- _MaskTexClampV: 0
- _MaskTexRotate: 0
- _MaskTexUSpeed: 0
- _MaskTexUVS: 0
- _MaskTexVSpeed: 0
- _Metallic: 0
- _OcclusionStrength: 1
- _Parallax: 0.005
- _QueueOffset: 0
- _ReFnl: 0
- _ReceiveShadows: 1
- _Scr: 1
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
- _WorkflowMode: 1
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _DissolveColor: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _FnlColor: {r: 1, g: 1, b: 1, a: 1}
- _MainColor: {r: 2.0000002, g: 2.0000002, b: 2.0000002, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &6085187289834300244
MonoBehaviour:
m_ObjectHideFlags: 11
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: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 9
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d6df5b5f597f5d845a064a2ec59bf6c4
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
@@ -0,0 +1,21 @@
fileFormatVersion: 2
guid: 34c57316d248ac544b9f88d1c7f678ce
IHVImageFormatImporter:
externalObjects: {}
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
isReadable: 0
sRGBTexture: 1
streamingMipmaps: 0
streamingMipmapsPriority: 0
ignoreMipmapLimit: 0
mipmapLimitGroupName:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,21 @@
fileFormatVersion: 2
guid: 80935dc8c0a01fb44a63ef46ce1e055f
IHVImageFormatImporter:
externalObjects: {}
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
isReadable: 0
sRGBTexture: 1
streamingMipmaps: 0
streamingMipmapsPriority: 0
ignoreMipmapLimit: 0
mipmapLimitGroupName:
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
@@ -0,0 +1,21 @@
fileFormatVersion: 2
guid: 495b63cf335ed554bb329f12cfc4aab5
IHVImageFormatImporter:
externalObjects: {}
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
isReadable: 0
sRGBTexture: 1
streamingMipmaps: 0
streamingMipmapsPriority: 0
ignoreMipmapLimit: 0
mipmapLimitGroupName:
userData:
assetBundleName:
assetBundleVariant:
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:11f16ce7ddd16e5c3de941b56358deb495efb2d5d4783c8d59c75aab0dad1975
size 92966
oid sha256:4370d12d63b3f482d2c5f38066604b3ba3cd462fa451d6ec7fe2f81b43614f82
size 124399
@@ -493,25 +493,27 @@ namespace BrewMonster.Scripts
/// <returns>True if the key exists, false otherwise.</returns>
public static bool KeyExists(object key, System.Type type = null)
{
string keyStr = key?.ToString();
if (string.IsNullOrEmpty(keyStr))
return false;
#if UNITY_EDITOR
return !Instance._invalidAssetPaths.Contains(key.ToString());
#else
// Iterate through all loaded locators (catalogs)
// Failed loads are cached; still verify against catalog (do not assume unknown keys exist).
if (Instance != null && Instance._invalidAssetPaths.Contains(keyStr))
return false;
#endif
foreach (IResourceLocator locator in Addressables.ResourceLocators)
{
// If the locator finds the key, it returns true
if (locator.Locate(key, type, out var locations))
if (locator.Locate(key, type, out var locations)
&& locations != null
&& locations.Count > 0)
{
// Double check that it actually yielded at least one location
if (locations != null && locations.Count > 0)
{
return true;
}
return true;
}
}
return false;
#endif
}
#endregion
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c5c28e526fd689b4ba33afac281ab524
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -38,7 +38,6 @@ namespace PerfectWorld.Scripts
[Range(0, 10)]
private int activeCameraPos;
[Header("Initial Role")]
[SerializeField]
private Profession profession = Profession.PROF_WARRIOR;
@@ -0,0 +1,28 @@
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class CopyTextButton : MonoBehaviour
{
[SerializeField] private TMP_Text textToCopy;
[SerializeField] private TMP_Text labelText;
[SerializeField] Button button;
public void Awake()
{
button.onClick.AddListener(CopyText);
}
public void CopyText()
{
GUIUtility.systemCopyBuffer = textToCopy.text;
}
public void SetText(string labeltext, string text, bool? inAddressables = null)
{
labelText.text = labeltext;
textToCopy.text = text;
if (inAddressables == null)
labelText.color = Color.white;
else
labelText.color = inAddressables.Value ? Color.green : Color.red;
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 475fda581c4d66c49a0bee08cfab75fe
@@ -0,0 +1,217 @@
using System;
using System.Collections.Generic;
using BrewMonster.Scripts;
using BrewMonster.Scripts.Skills;
using ModelViewer.Common;
using UnityEngine;
namespace BrewMonster
{
public class LogPanelAnimeScene : MonoBehaviour
{
[SerializeField] private CopyTextButton copyTextButtonPrefab;
[SerializeField] private List<CopyTextButton> copyTextButtons;
[SerializeField] private Transform copyTextButtonsParent;
private int currentIndex = 0;
public void Awake()
{
copyTextButtons = new List<CopyTextButton>();
currentIndex = 0;
Reset();
}
public void Reset()
{
currentIndex = 0;
foreach (var copyText in copyTextButtons)
{
copyText.gameObject.SetActive(false);
}
}
public void AddCopyTextButton(string labeltext, string text, bool? inAddressables = null)
{
if (currentIndex >= copyTextButtons.Count)
{
var copyTextButton = Instantiate(copyTextButtonPrefab, copyTextButtonsParent);
copyTextButton.gameObject.SetActive(true);
copyTextButton.SetText(labeltext, text, inAddressables);
copyTextButtons.Add(copyTextButton);
}
else
{
copyTextButtons[currentIndex].gameObject.SetActive(true);
copyTextButtons[currentIndex].SetText(labeltext, text, inAddressables);
}
currentIndex++;
}
/// <summary>
/// Display name: last path segment only, no gfx/ prefix, no .gfx suffix.
/// 显示名:仅最后一段,无 gfx/ 前缀、无 .gfx 后缀。
/// </summary>
public static string GfxBasename(string path)
{
if (string.IsNullOrWhiteSpace(path))
return null;
path = AFile.NormalizePath(path, true);
if (path.StartsWith("gfx/", StringComparison.OrdinalIgnoreCase))
path = path.Substring(4);
int slash = path.LastIndexOf('/');
string file = slash >= 0 ? path.Substring(slash + 1) : path;
if (file.EndsWith(".gfx", StringComparison.OrdinalIgnoreCase))
file = file.Substring(0, file.Length - 4);
return string.IsNullOrEmpty(file) ? null : file;
}
/// <summary>
/// Candidate Addressables keys (runtime CECModel path + catalog .gfx tail).
/// </summary>
static IEnumerable<string> GfxAddressableKeyCandidates(string rawPath)
{
if (string.IsNullOrWhiteSpace(rawPath))
yield break;
string path = AFile.NormalizePath(rawPath, true);
string runtimeKey = path.StartsWith("gfx/", StringComparison.OrdinalIgnoreCase)
? path
: "gfx/" + path.TrimStart('/');
yield return runtimeKey;
if (!runtimeKey.EndsWith(".gfx", StringComparison.OrdinalIgnoreCase))
yield return runtimeKey + ".gfx";
}
public static bool GfxAddressableExists(string rawPath)
{
var mgr = AddressableManager.Instance;
if (mgr == null || !mgr.IsInitialized())
return false;
foreach (string key in GfxAddressableKeyCandidates(rawPath))
{
if (AddressableManager.KeyExists(key, typeof(GameObject)))
return true;
}
return false;
}
/// <summary>
/// Has path → show row. Green if Addressables has key, red if not. No path → skip.
/// 有路径则显示:Addressables 有则绿,无则红;无路径不显示。
/// </summary>
void AddGfxPathRow(string label, string rawPath)
{
if (string.IsNullOrWhiteSpace(rawPath))
return;
string displayText = GfxBasename(rawPath);
if (string.IsNullOrEmpty(displayText))
return;
AddCopyTextButton(label, displayText, GfxAddressableExists(rawPath));
}
public void LogSkillCastGfx(CECHostPlayer player, int skillId)
{
AddGfxEventsFromComAct(player?.GetSkillCastComAct(skillId), "Cast");
}
public void LogPlayAttackEffectGfx(CECHostPlayer player, int skillId, int section = 0)
{
if (player == null)
return;
AddGfxEventsFromComAct(player.GetSkillAttackComActRise(skillId, section), "Attack");
AddGfxEventsFromComAct(player.GetSkillAttackComActFall(skillId, section), "Attack");
LogSkillStubFlyHitGfx(skillId, section);
}
public void LogAttackEventGfx(CECAttackEvent ev)
{
if (ev == null || ev.m_idSkill == 0)
return;
LogSkillStubFlyHitGfx(ev.m_idSkill, ev.m_nSkillSection);
}
public void AddGfxEventsFromComAct(A3DCombinedAction comAct, string label)
{
if (string.IsNullOrEmpty(label) || comAct?.m_EventInfoLst == null)
return;
var seen = new HashSet<string>();
foreach (var ev in comAct.m_EventInfoLst)
{
if (ev is not GFX_INFO gfx || gfx.m_strFilePaths == null)
continue;
foreach (string path in gfx.m_strFilePaths)
{
if (string.IsNullOrWhiteSpace(path))
continue;
string displayText = GfxBasename(path);
if (string.IsNullOrEmpty(displayText) || !seen.Add(displayText))
continue;
AddCopyTextButton(label, displayText, GfxAddressableExists(path));
}
}
}
void LogSkillStubFlyHitGfx(int skillId, int section)
{
string fly = null;
string hitGrnd = null;
string hit = null;
var atkMan = CECAttacksMan.Instance;
if (section > 0 && atkMan?.m_pMultiSkillGfxComposerMan != null)
{
var composer = atkMan.m_pMultiSkillGfxComposerMan.GetSkillGfxComposer(skillId, section);
if (composer != null)
{
fly = composer.flyGfxName;
hit = composer.hitGfxName;
hitGrnd = composer.hitGrdGfxName;
}
}
else
{
var composer = atkMan?.GetSkillGfxComposerMan()?.GetSkillGfxComposer(skillId);
if (composer != null)
{
fly = composer.flyGfxName;
hit = composer.hitGfxName;
hitGrnd = composer.hitGrdGfxName;
}
}
if (string.IsNullOrEmpty(fly) && string.IsNullOrEmpty(hit) && string.IsNullOrEmpty(hitGrnd))
{
var paths = ElementSkill.GetAllGFX((uint)skillId);
fly = paths.Item1;
hitGrnd = paths.Item2;
hit = paths.Item3;
}
AddGfxPathRow("Fly", fly);
AddGfxPathRow("Hit", hit);
AddGfxPathRow("HitGrnd", hitGrnd);
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 4c02249851b66b948809cc1a2a1a9f13
@@ -63,6 +63,9 @@ namespace BrewMonster
[SerializeField] private bool isEvilSkillPath;
[SerializeField] private int skillCatalogLevel = 1;
[SerializeField]
private LogPanelAnimeScene logPanelAnimeScene;
/// <summary>
/// World position of the draggable target marker, read by CECSkillGfxMan.get_pos_by_id.
@@ -455,18 +458,21 @@ namespace BrewMonster
{
if (player == null || skill == null)
return;
logPanelAnimeScene.Reset();
int skillId = skill.GetSkillID();
logPanelAnimeScene.AddCopyTextButton("ID", skillId.ToString());
logPanelAnimeScene.LogSkillCastGfx(player, skillId);
logPanelAnimeScene.LogPlayAttackEffectGfx(player, skillId, 0);
// Self-cast skills target the host; all others target the draggable marker.
// 自身施法技能以主角为目标;其余技能以可拖动标记为目标。
int targetId = ResolveLocalCastTargetId(skill);
BMLogger.Log($"[SkillTriggerPanel] LocalCastSkill: skillID={skillId}, targetId={targetId}, hostCid={player.GetCharacterID()}");
// 1. Trigger cast animation (PlaySkillCastAction resolves action name internally)
// 触发施法动画(PlaySkillCastAction 内部解析动作名)
bool animOk = player.PlaySkillCastAction(skillId);
if (!animOk)
Debug.LogWarning($"[SkillTriggerPanel] PlaySkillCastAction returned false for skill {skillId} — animation may not play.");
@@ -521,7 +527,7 @@ namespace BrewMonster
ElementSkill.GetType((uint)skillId) == 2)
{
pAttack = CECAttacksMan.Instance.AddSkillAttack(
hostPlayer.GetPlayerInfo().cid, hostPlayer.GetPlayerInfo().cid, targetMarker.GetNPCID(), hostPlayer.GetWeaponID(), skillId, 0, 0x0200, 0);
hostPlayer.GetPlayerInfo().cid, hostPlayer.GetPlayerInfo().cid, hostPlayer.GetPlayerInfo().cid, hostPlayer.GetWeaponID(), skillId, 0, 0x0200, 0);
}
else
{
@@ -22,6 +22,7 @@ using DG.Tweening.Plugins;
using PerfectWorld.Scripts.Managers;
using BrewMonster.Scripts.ECModel;
using Animancer;
using ModelViewer.Common;
namespace BrewMonster
{
public abstract partial class CECPlayer : CECObject, ITickable
@@ -2518,6 +2519,153 @@ namespace BrewMonster
//UpdateWeaponHangerPosBySkillAction(idSkill);// ¸ù¾Ý¼¼Äܲ¥·ÅµÄ¶¯×÷£¬¸ü¸ÄÎäÆ÷Ðü¹ÒλÖã¨Ö»Äܼì²é²»ÅŶӶ¯×÷£©
return true;
}
/// <summary>
/// Resolves cast (吟唱) combined-action name for anim-test / debug. Does not call or alter <see cref="PlaySkillCastAction"/>.
/// 解析吟唱组合动作名(动画测试用),不调用、不改变 PlaySkillCastAction。use for test animtion.
/// </summary>
public bool TryBuildSkillCastActionName(int idSkill, out string szAct)
{
szAct = string.Empty;
int weapon_type = GetShowingWeaponType();
int moveEnv = GetMoveEnv();
if (!_default_skill_actions.TryGetValue((uint)idSkill, out PLAYER_ACTION_INFO_CONFIG data) || data.action_prefix == null || data.action_prefix.Length == 0 || data.action_prefix[0] == 0)
{
if (ElementSkill.GetCommonCoolDown((uint)idSkill) > 1 << 4)
{
data = m_PlayerActions[(int)PLAYER_ACTION_TYPE.ACT_USING_TARGET_ITEM].data;
if (data.action_prefix == null || data.action_prefix.Length == 0 || data.action_prefix[0] == 0)
{
return false;
}
}
else
{
return false;
}
}
if (moveEnv == (int)MoveEnvironment.MOVEENV_GROUND)
{
szAct = EC_Utility.BuildActionName(data, weapon_type, "_吟唱_");
}
else
{
string szAirCastMid =
((m_wingType == enumWingType.WINGTYPE_WING && IsFlying()) ||
GetProfession() == (int)PROFESSION.PROF_ANGEL ||
GetProfession() == (int)PROFESSION.PROF_ARCHOR ||
GetProfession() == (int)PROFESSION.PROF_MONK ||
GetProfession() == (int)PROFESSION.PROF_GHOST)
? "_空中翅膀_吟唱_" // Air cast with wings / 空中翅膀吟唱
: "_空中飞剑_吟唱_"; // Air cast with flysword / 空中飞剑吟唱
szAct = EC_Utility.BuildActionName(data, weapon_type, szAirCastMid);
}
return !string.IsNullOrEmpty(szAct);
}
/// <summary>
/// Combined action for skill cast GFX lookup (anim-test). / 技能吟唱组合动作(动画测试 GFX 查询)。
/// </summary>
public A3DCombinedAction GetSkillCastComAct(int idSkill)
{
if (!TryBuildSkillCastActionName(idSkill, out string szAct) || m_pPlayerCECModel == null)
return null;
return m_pPlayerCECModel.GetComActByName(szAct);
}
/// <summary>
/// Resolves skill attack (施放起/落) combined-action names for anim-test GFX lookup.
/// 解析技能施放组合动作名(动画测试 GFX 查询),不播放动作。
/// </summary>
public bool TryBuildSkillAttackActionNames(int idSkill, int nSection, out string riseName, out string fallName)
{
riseName = string.Empty;
fallName = string.Empty;
int weapon_type = GetShowingWeaponType();
if (!_default_skill_actions.TryGetValue((uint)idSkill, out PLAYER_ACTION_INFO_CONFIG data) ||
data.action_prefix == null || data.action_prefix.Length == 0 || data.action_prefix[0] == 0)
{
if (ElementSkill.GetCommonCoolDown((uint)idSkill) > 1 << 4)
{
PLAYER_ACTION_INFO_CONFIG? data2 = m_PlayerActions[(int)PLAYER_ACTION_TYPE.ACT_USING_TARGET_ITEM].data;
if (data2 == null || data2.Value.action_prefix == null || data2.Value.action_prefix.Length == 0 ||
data2.Value.action_prefix[0] == 0)
return false;
data = data2.Value;
}
else
return false;
}
if (GetMoveEnv() == (int)MoveEnvironment.MOVEENV_GROUND)
{
riseName = EC_Utility.BuildActionName(data, weapon_type, "_施放起_");
fallName = EC_Utility.BuildActionName(data, weapon_type, "_施放落_");
}
else
{
string szActionMiddleName;
if ((m_wingType == enumWingType.WINGTYPE_WING && IsFlying()) ||
(m_iProfession == (int)PROFESSION.PROF_ANGEL) ||
(m_iProfession == (int)PROFESSION.PROF_ARCHOR) ||
(m_iProfession == (int)PROFESSION.PROF_MONK) ||
(m_iProfession == (int)PROFESSION.PROF_GHOST))
{
szActionMiddleName = "_空中翅膀";
}
else
{
szActionMiddleName = "_空中飞剑";
}
szActionMiddleName += "_施放起_";
riseName = EC_Utility.BuildActionName(data, weapon_type, szActionMiddleName);
fallName =
$"{data.ActionPrefix}_{szActionMiddleName}_施法行_{data.action_weapon_suffix[weapon_type].Suffix}";
}
if (nSection != 0)
{
var pAtkMan = CECAttacksMan.Instance;
if (pAtkMan != null && pAtkMan.GetSkillSectionActionSuffix(idSkill, nSection, out string suffix))
{
riseName += "_" + suffix;
fallName += "_" + suffix;
}
}
return !string.IsNullOrEmpty(riseName);
}
/// <summary>
/// Combined action for skill attack rise (施放起) GFX lookup (anim-test).
/// 技能施放起组合动作(动画测试 GFX 查询)。
/// </summary>
public A3DCombinedAction GetSkillAttackComActRise(int idSkill, int nSection = 0)
{
if (!TryBuildSkillAttackActionNames(idSkill, nSection, out string riseName, out _) ||
m_pPlayerCECModel == null)
return null;
return m_pPlayerCECModel.GetComActByName(riseName);
}
/// <summary>
/// Combined action for skill attack fall (施放落) GFX lookup (anim-test).
/// 技能施放落组合动作(动画测试 GFX 查询)。
/// </summary>
public A3DCombinedAction GetSkillAttackComActFall(int idSkill, int nSection = 0)
{
if (!TryBuildSkillAttackActionNames(idSkill, nSection, out _, out string fallName) ||
m_pPlayerCECModel == null)
return null;
return m_pPlayerCECModel.GetComActByName(fallName);
}
public bool OnDamaged(int skill)
{
var atkMan = CECAttacksMan.Instance;
+1 -2
View File
@@ -501,7 +501,6 @@ public class A3DCombActDynData
RemoveAllActiveFx();
if (ActiveAttackEvent != null)
{
Debug.Log($"[Nam Debug]Stop: ActiveAttackEvent.m_bSignaled = true, Action name: {m_pAct.m_strName}");
ActiveAttackEvent.m_bSignaled = true;
}
@@ -1553,7 +1552,7 @@ public class CECModel
{
foreach (var ca in m_ChannelActs)
ca?.Release();
//EventBus.PublishChannel(m_nId, new ClearComActFlagAllRankNodesEvent(bSignalCurrent));
EventBus.PublishChannel(m_nId, new ClearComActFlagAllRankNodesEvent(bSignalCurrent));
return false;
}
@@ -2,7 +2,9 @@
This document tracks **Editor-only tooling** used with the runtime animation test workflow described in **`AnimationSceneSetup.md`**.
**Scene docs (runtime hierarchy, managers, APIs):** see `Assets/PerfectWorld/Scripts/_Doc/AnimationSceneSetup.md`.
**Scene docs (runtime hierarchy, managers, APIs):** see [`AnimationSceneSetup.md`](AnimationSceneSetup.md).
**Play Mode skill test (scene UI + SkillPanel):** see [`AnimationSceneSkillTest.md`](AnimationSceneSkillTest.md).
**How to extend this file:** whenever you add or plan a new piece of Editor UI / automation for the animation scene, append a **`### Feature`** block under **[Feature log](#feature-log)** using the **[Feature template](#feature-template)** below. Keep one feature per numbered section so history stays searchable.
@@ -3,6 +3,8 @@
A standalone scene for testing character animations, skill VFX, weapon logic, and shape-change
without any server connection. All triggers are issued via local commands.
**Skill test workflow (AnimatedModifier / LogPanel / SkillPanel):** see [`AnimationSceneSkillTest.md`](AnimationSceneSkillTest.md).
---
## Related Source Files
@@ -0,0 +1,188 @@
# Animation Test Scene — Skill Animation Workflow
**Scene:** [`Assets/PerfectWorld/Scene/AnimationTest.unity`](Assets/PerfectWorld/Scene/AnimationTest.unity)
Use **AnimatedModifier**, **LogPanel**, and **SkillPanel** to load a character, pick a skill, and verify **cast + attack animations** and **GFX path coverage** without a server.
**See also:** [`AnimationSceneSetup.md`](AnimationSceneSetup.md) (runtime APIs), [`AnimationSceneEditor.md`](AnimationSceneEditor.md) (bootstrap inspector tools).
---
## Scene objects
| Hierarchy name | Component | Script |
|---|---|---|
| **AnimatedModifier** | `AnimScenePlayerBootstrap` | `Assets/PerfectWorld/Scripts/AnimTestScene/AnimScenePlayerBootstrap.cs` |
| **LogPanel** | `LogPanelAnimeScene` | `Assets/PerfectWorld/Scripts/AnimTestScene/LogPanelAnimeScene.cs` |
| **SkillPanel** | `SkillTriggerPanel` | `Assets/PerfectWorld/Scripts/Debug/SkillTriggerPanel.cs` |
---
## Prerequisites
The scene must include the managers from `AnimationSceneSetup.md` (§911):
- `AutoInitializer` / `ElementDataManProvider`
- `NPCManager`, `CECAttacksMan`, `EC_ManMessageMono`
- **CECHostPlayer** (referenced by AnimatedModifier and SkillPanel)
- UI init so `CECUIManager` / `CECGameUIMan` is ready (skill icons)
**AnimatedModifier** must not be on the same GameObject as `CECHostPlayer` if **Replace host on role switch** is enabled.
---
## Inspector wiring
### AnimatedModifier (`AnimScenePlayerBootstrap`)
| Field | Assign |
|---|---|
| **Player** | Scene `CECHostPlayer` |
| **Camera Object** | Main camera |
| **Camera Poses** | Preset transforms for orbit views |
| **Initial Role** | Default profession + gender on Play |
| **Weapon By Action Type** | 15 slots (index = `action_type` / `m_uAttackType`) |
| **Active Weapon Action Type Index** | Slot applied after each load |
| **Anim Scene Avoid Fashion Weapon Config Path** | On (recommended) |
| **Bind Player Visual After Model Load** | On (required for `PlayActionEvent` / Animancer) |
| **Is Evil Skill Path** | God vs evil catalog (same as `CDlgSkillSubList`) |
| **Skill Catalog Level** | Level for `CECHostSkillModel` injection (default `1`) |
**Scene UI (camera):**
| Button | Typical `OnClick()` target |
|---|---|
| **NextView** | `AnimatedModifier``AnimScenePlayerBootstrap.ChangeNextCamera()` |
| **PreviosView** | `AnimatedModifier``AnimScenePlayerBootstrap.ChangePreviosCamera()` |
These cycle **Camera Poses** and reparent **Camera Object** (wraps at ends of the list).
**Play Mode inspector** (select AnimatedModifier): **Switch model**, **Play action**, **Re-apply active weapon slot**.
### SkillPanel (`SkillTriggerPanel`)
| Field | Assign |
|---|---|
| **Player** | Same `CECHostPlayer` as AnimatedModifier |
| **Target Marker** | `CECMonsterTest` in front of the player |
| **Skill Grid Container** | `RectTransform` + `GridLayoutGroup` |
| **Skill Button Prefab** | Button + Image (icon) + Text |
| **Filter By Restrictions** | Off = full catalog; On = weapon/form/env filter |
| **Is Evil Skill Path** | Align with AnimatedModifier |
| **Skill Catalog Level** | Align with AnimatedModifier |
| **Log Panel Anime Scene** | **LogPanel** component |
### LogPanel (`LogPanelAnimeScene`)
| Field | Assign |
|---|---|
| **Copy Text Button Prefab** | `CopyTextButton` row |
| **Copy Text Buttons Parent** | Layout parent for rows |
Filled automatically when you click a skill on SkillPanel.
---
## How to test a skill animation
### 1. Enter Play Mode
1. Open `Assets/PerfectWorld/Scene/AnimationTest.unity`.
2. Press **Play**.
3. Filter Console: `[AnimSceneBootstrap]`.
Expected logs: element data ready → `SetPlayerModel` done → `CECHostSkillModel initialized``[SkillTriggerPanel] Refreshed: N buttons added`.
### 2. Character, weapon, camera
- **Role:** AnimatedModifier **Initial Role**, or Play Mode **Switch model** on AnimatedModifier.
- **Weapon:** set **Active Weapon Action Type Index** and prefabs in **Weapon By Action Type**; **Re-apply active weapon slot** in Play Mode if you change the index.
- **Camera:** **NextView** / **PreviosView** to step through **Camera Poses**.
Skill clip names depend on weapon suffix (`{prefix}_{weapon_suffix}_吟唱_`, `_施放起_`, `_施放落_`).
### 3. Skill list filter (optional)
On SkillPanel, **Filter By Restrictions**:
- **Off** — full profession catalog (bootstrap default after load).
- **On** — only skills passing weapon/form/move-env (MP/AP faked unlimited).
Context menu: **Debug: Refresh From Skill Model**, **Debug: Inject All Config Skills**.
### 4. Target marker
Place **Target Marker** (`CECMonsterTest`) ~5 units in front of the player for non-self skills. Self-target skills use the host id.
### 5. Click a skill (SkillPanel)
`LocalCastSkill` does the following:
1. **LogPanel**`Reset()`, skill **ID**, then GFX rows:
- **Cast** — from cast combined action
- **Attack** — rise/fall combined actions
- **Fly** / **Hit** / **HitGrnd** — composer or `ElementSkill.GetAllGFX`
2. **Cast animation**`PlaySkillCastAction(skillId)` immediately.
3. **Attack animation** — after ~**1 s**, `CECAttacksMan.AddSkillAttack` + `PlaySkillAttackAction`.
Click a LogPanel row to copy the GFX basename (green = Addressables key exists, red = missing).
### 6. Raw actions (optional)
AnimatedModifier Play Mode inspector: **Stand (0)**, **Run (3)**, or custom action index + **Play action** (not full skill chains).
---
## VFX note (commented composer path)
In `SkillTriggerPanel.LocalCastSkill`, the direct **`composerMan.Play(...)`** block is **commented out**. VFX in this scene is driven mainly by:
- Combined-action GFX events logged on **LogPanel**
- The **delayed** `AddSkillAttack` / `PlaySkillAttackAction` path (attack event + `CECAttacksMan` tick)
You may see **animations** without all **fly/hit GFX** playing until those events run. Re-enabling `composerMan.Play` would be a separate local-VFX experiment; the current workflow matches “animation-first” debugging.
---
## Data flow
```mermaid
sequenceDiagram
participant User
participant SkillPanel
participant LogPanel
participant Host as CECHostPlayer
participant Attacks as CECAttacksMan
User->>SkillPanel: Click skill button
SkillPanel->>LogPanel: Reset + cast/attack/fly/hit GFX rows
SkillPanel->>Host: PlaySkillCastAction(skillId)
Note over SkillPanel: Wait ~1s
SkillPanel->>Attacks: AddSkillAttack(...)
SkillPanel->>Host: PlaySkillAttackAction(skillId, ...)
```
---
## Troubleshooting
| Symptom | Check |
|---|---|
| No model | `NPCManager`, Addressables, `[AnimSceneBootstrap]`; **Player** on AnimatedModifier |
| No skill motion | **Bind Player Visual After Model Load**; Animancer + `CombinedActionSO` on `.ecm` |
| `PlaySkillCastAction returned false` | Skill not in action map; wrong weapon suffix |
| Empty skill grid | Wait for bootstrap; **Inject All Config Skills**; evil/god path vs profession |
| GFX at origin | **Target Marker** assigned and positioned |
| LogPanel all red | Register GFX in Addressables (`gfx/...`) |
| Camera buttons dead | **NextView** / **PreviosView** wired to `ChangeNextCamera` / `ChangePreviosCamera` on AnimatedModifier |
**Console:** `[AnimSceneBootstrap]`, `[SkillTriggerPanel]`
---
## Script references
- `Assets/PerfectWorld/Scripts/AnimTestScene/AnimScenePlayerBootstrap.cs`
- `Assets/PerfectWorld/Scripts/AnimTestScene/LogPanelAnimeScene.cs`
- `Assets/PerfectWorld/Scripts/Debug/SkillTriggerPanel.cs`
- `Assets/PerfectWorld/Scripts/Editor/AnimScenePlayerBootstrapEditor.cs`
+3 -2
View File
@@ -33,11 +33,13 @@ namespace BrewMonster
private const float FadeTime = 100;
private const FadeMode FadeMode = Animancer.FadeMode.FixedDuration;
private string previousAnimationName;
private string lastQueueAnimationName;
private void PlayActionEventHandler(PlayActionEvent @event)
{
//prevent enqueue the same loop animation
bool loopcheck = @event.IsLoop == true && previousAnimationName == @event.AnimationName;
if(loopcheck)
bool queuecheck = lastQueueAnimationName == @event.AnimationName;
if(loopcheck || queuecheck)
{
return;
}
@@ -162,7 +164,6 @@ namespace BrewMonster
}
private void PlayNext()
{
if (_animationQueue.Count == 0)
{
return;