feat: MCP Unity 场景优化 — 完整交互体系搭建

- 删除重复 Ground
- 创建 [Managers] 空物体,挂载 GameManager + StepManager + ExperimentFlowCoordinator + AudioManager
- Main Camera 挂载 InteractionSystem
- 伤者 InjectedPerson 下创建 5 个交互子物体 (InjuryVisual/Swelling/Pain/VitalSigns/Neuro)
- 创建绑带位置、踝关节、衬垫、夹板位置等空物体
- 道具摆放到位:伤者(2,0.05,5) 施救者(3,0,5) 鞋(2.7,0.15,5.5) 绷带/夹板/急救箱在旁
- InjuryLeg Tag 修正,Ground Tag 修正
- 全部新脚本同步导入 (ExperimentTypes/StepData/ExperimentConfig/StepManager/GameManager/ExperimentFlowCoordinator/InteractionSystem/DraggableObject/HighlightEffect/UIManager/ExamPopup/ScoreDisplay/VideoController/AudioManager/CharacterAnimController/StepAnimationHandler)
- 旧脚本 (ExperimentController/ConfigLoader/AnimationController/HUDController/VideoPlayerController/PopupSystem/ModeSelectionUI) 全部兼容修复或 stub
- 编译通过,0 错误
- Canvas 挂载 UIManager
This commit is contained in:
yangbear
2026-06-24 02:33:48 +08:00
parent 23d3d282f8
commit f0a6b96da5
111 changed files with 11023 additions and 440 deletions
+3
View File
@@ -0,0 +1,3 @@
{
"mcpServers": {}
}
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 64271bef662af4a249d3b26db806b4b9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3bdbe9aa40f514e1987b69dabd75457d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 85c758bad9d614989adac8e5ba7bd207
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b2f8e3f67a24d4846a754cd805cc514b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2d74c755f0b3d4f24883be1486e1ebb3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: bcc075cfc542648268ca8c360fa79e45
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2e5cb2cde3d3145e2a9e84cae6d45d07
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d4a0758449a944eceb61d2d1628effbd
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5e895eb5a64d940eaa1d0a25076fa6f6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 61caee4db972540ce8a75e126457b7f6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,179 @@
{
"experimentName": "骨折固定",
"experimentId": "FractureFixation",
"description": "运动伤害现场急救处理——骨折固定虚拟仿真实验",
"fixationType": 0,
"totalScore": 100,
"passingScore": 60,
"steps": [
{
"stepIndex": 0,
"stepName": "环境评估",
"tipText": "观察周围环境是否有危险,做好防护措施。",
"dialogueText": "周围环境安全。我是救护志愿者,我可以帮助您吗?",
"interactionType": 4,
"targetTag": "",
"targetName": "",
"showVideo": false,
"voiceClip": "",
"requiredForCompletion": true
},
{
"stepIndex": 1,
"stepName": "伤情检查",
"tipText": "请检查伤员受伤位置",
"dialogueText": "伤员左大腿疑似骨折,无伤口。",
"interactionType": 1,
"targetTag": "InjuryLeg",
"targetName": "InjuryLeg",
"showVideo": false,
"voiceClip": "",
"requiredForCompletion": true
},
{
"stepIndex": 2,
"stepName": "脱鞋袜检查",
"tipText": "请将伤员鞋袜脱掉并保存好,观察末端血液循环、运动及感觉",
"dialogueText": "",
"interactionType": 1,
"targetTag": "Shoe",
"targetName": "Shoe",
"showVideo": false,
"voiceClip": "",
"requiredForCompletion": true
},
{
"stepIndex": 3,
"stepName": "放置衬带",
"tipText": "请在正确的位置穿宽度约10cm的带子",
"dialogueText": "",
"interactionType": 3,
"targetTag": "Bandage",
"targetName": "Bandage",
"showVideo": true,
"voiceClip": "",
"requiredForCompletion": true
},
{
"stepIndex": 4,
"stepName": "肢体并拢",
"tipText": "请在两下肢间加衬垫,移动健肢,将双下肢轻轻并拢",
"dialogueText": "",
"interactionType": 4,
"targetTag": "",
"targetName": "",
"showVideo": false,
"voiceClip": "",
"requiredForCompletion": true
},
{
"stepIndex": 5,
"stepName": "主干固定",
"tipText": "请在未受伤腿分别固定骨折近心端(上端)、骨折远心端(下端),然后固定膝关节下,结打在右侧。",
"dialogueText": "",
"interactionType": 3,
"targetTag": "Bandage",
"targetName": "Bandage",
"showVideo": false,
"voiceClip": "",
"requiredForCompletion": true
},
{
"stepIndex": 6,
"stepName": "踝关节固定",
"tipText": "踝关节\"8\"字固定,结打在两足背之间。",
"dialogueText": "",
"interactionType": 3,
"targetTag": "Bandage",
"targetName": "Bandage",
"showVideo": false,
"voiceClip": "",
"requiredForCompletion": true
},
{
"stepIndex": 7,
"stepName": "终末检查",
"tipText": "包扎完毕请检查伤肢血液循环,运动及感觉。",
"dialogueText": "伤员一切正常,包扎完毕。",
"interactionType": 4,
"targetTag": "",
"targetName": "",
"showVideo": false,
"voiceClip": "",
"requiredForCompletion": true
}
],
"examQuestions": [
{
"questionIndex": 0,
"questionText": "点击确认后,请按正确顺序进行环境评估与自我介绍",
"choices": ["确定"],
"correctChoiceIndex": 0,
"correctFeedback": "正确",
"incorrectFeedback": "",
"questionType": 0,
"targetTag": ""
},
{
"questionIndex": 1,
"questionText": "点击确认后,请按正确顺序检查伤情",
"choices": ["确定"],
"correctChoiceIndex": 0,
"correctFeedback": "正确",
"incorrectFeedback": "",
"questionType": 0,
"targetTag": ""
},
{
"questionIndex": 2,
"questionText": "请选择合适的带子宽度",
"choices": ["5cm", "10cm", "20cm"],
"correctChoiceIndex": 1,
"correctFeedback": "正确!",
"incorrectFeedback": "应选择10cm宽度的带子",
"questionType": 0,
"targetTag": ""
},
{
"questionIndex": 3,
"questionText": "请选择正确的放带子顺序",
"choices": ["确定"],
"correctChoiceIndex": 0,
"correctFeedback": "正确",
"incorrectFeedback": "",
"questionType": 2,
"targetTag": "Bandage"
},
{
"questionIndex": 4,
"questionText": "请选择正确的系带子顺序",
"choices": ["确定"],
"correctChoiceIndex": 0,
"correctFeedback": "正确",
"incorrectFeedback": "",
"questionType": 2,
"targetTag": "Bandage"
},
{
"questionIndex": 5,
"questionText": "请选择带子打结位置",
"choices": ["确定"],
"correctChoiceIndex": 0,
"correctFeedback": "正确",
"incorrectFeedback": "",
"questionType": 1,
"targetTag": "BandageKnot"
},
{
"questionIndex": 6,
"questionText": "请选择踝关节打结位置",
"choices": ["足底", "足背"],
"correctChoiceIndex": 1,
"correctFeedback": "正确!",
"incorrectFeedback": "应选择足背位置打结",
"questionType": 0,
"targetTag": ""
}
],
"summaryNotes": "下肢损伤选择仰卧位;\n骨折固定前后要脱掉鞋袜并检查下肢末梢循环、运动、感觉;\n穿带子时应从健侧穿向伤侧;\n骨折固定时先固定伤口的近心端,后固定远心端,再由上而下进行固定;\n固定后尽可能抬高下肢。"
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 460759f55f4d740eb98e141d10be6978
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,135 @@
{
"experimentName": "骨折固定(夹板固定)",
"experimentId": "SplintFixation",
"description": "运动伤害现场急救处理——夹板固定虚拟仿真实验",
"fixationType": 1,
"totalScore": 100,
"passingScore": 60,
"steps": [
{
"stepIndex": 0,
"stepName": "环境评估",
"tipText": "观察周围环境是否有危险,做好防护措施。",
"dialogueText": "周围环境安全。我是救护志愿者,我可以帮助您吗?",
"interactionType": 4,
"targetTag": "",
"targetName": "",
"showVideo": false,
"voiceClip": "",
"requiredForCompletion": true
},
{
"stepIndex": 1,
"stepName": "伤情检查",
"tipText": "请检查伤员受伤位置",
"dialogueText": "伤员左大腿疑似骨折,无伤口。",
"interactionType": 1,
"targetTag": "InjuryLeg",
"targetName": "InjuryLeg",
"showVideo": false,
"voiceClip": "",
"requiredForCompletion": true
},
{
"stepIndex": 2,
"stepName": "脱鞋袜检查",
"tipText": "请将伤员鞋袜脱掉并保存好,观察末端血液循环、运动及感觉",
"dialogueText": "",
"interactionType": 1,
"targetTag": "Shoe",
"targetName": "Shoe",
"showVideo": false,
"voiceClip": "",
"requiredForCompletion": true
},
{
"stepIndex": 3,
"stepName": "加衬垫并用夹板固定",
"tipText": "请在骨折肢体加衬垫,并用夹板固定",
"dialogueText": "",
"interactionType": 3,
"targetTag": "Splint",
"targetName": "Splint",
"showVideo": true,
"voiceClip": "",
"requiredForCompletion": true
},
{
"stepIndex": 4,
"stepName": "用带子固定夹板",
"tipText": "请用带子将夹板固定在腿上",
"dialogueText": "",
"interactionType": 3,
"targetTag": "Bandage",
"targetName": "Bandage",
"showVideo": false,
"voiceClip": "",
"requiredForCompletion": true
},
{
"stepIndex": 5,
"stepName": "终末检查",
"tipText": "包扎完毕请检查伤肢血液循环,运动及感觉。",
"dialogueText": "伤员一切正常,包扎完毕。",
"interactionType": 4,
"targetTag": "",
"targetName": "",
"showVideo": false,
"voiceClip": "",
"requiredForCompletion": true
}
],
"examQuestions": [
{
"questionIndex": 0,
"questionText": "点击确认后,请按正确顺序进行环境评估与自我介绍",
"choices": ["确定"],
"correctChoiceIndex": 0,
"correctFeedback": "正确",
"incorrectFeedback": "",
"questionType": 0,
"targetTag": ""
},
{
"questionIndex": 1,
"questionText": "点击确认后,请按正确顺序检查伤情",
"choices": ["确定"],
"correctChoiceIndex": 0,
"correctFeedback": "正确",
"incorrectFeedback": "",
"questionType": 0,
"targetTag": ""
},
{
"questionIndex": 2,
"questionText": "请选择正确的固定方式",
"choices": ["肢体固定", "夹板固定", "绷带包扎"],
"correctChoiceIndex": 1,
"correctFeedback": "正确!夹板固定适用于骨折固定。",
"incorrectFeedback": "应选择夹板固定方式",
"questionType": 0,
"targetTag": ""
},
{
"questionIndex": 3,
"questionText": "请选择正确放置夹板的位置",
"choices": ["确定"],
"correctChoiceIndex": 0,
"correctFeedback": "正确",
"incorrectFeedback": "",
"questionType": 1,
"targetTag": "Splint"
},
{
"questionIndex": 4,
"questionText": "请选择正确的绑带固定顺序",
"choices": ["先上后下", "先下后上"],
"correctChoiceIndex": 0,
"correctFeedback": "正确!应先固定近心端再固定远心端。",
"incorrectFeedback": "应先固定近心端(上端),再固定远心端(下端)",
"questionType": 0,
"targetTag": ""
}
],
"summaryNotes": "下肢损伤选择仰卧位;\n骨折固定前后要脱掉鞋袜并检查下肢末梢循环、运动、感觉;\n夹板固定时先在骨折肢体加衬垫;\n穿带子时应从健侧穿向伤侧;\n固定后尽可能抬高下肢。"
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a7bcf7c9d0296430db1384005ca925e3
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because it is too large Load Diff
+7
View File
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a37b51f5c4beb4b4398199d197af7d37
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because it is too large Load Diff
+7
View File
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: cffb0242a91904c5986f45e78b1820b3
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
-407
View File
@@ -1,407 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.18028305, g: 0.22571313, b: 0.3069213, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 12
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 12
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAmbientOcclusion: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 1
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 512
m_PVRBounces: 2
m_PVREnvironmentSampleCount: 256
m_PVREnvironmentReferencePointCount: 2048
m_PVRFilteringMode: 1
m_PVRDenoiserTypeDirect: 1
m_PVRDenoiserTypeIndirect: 1
m_PVRDenoiserTypeAO: 1
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVREnvironmentMIS: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 0}
m_LightingSettings: {fileID: 0}
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &330585543
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 330585546}
- component: {fileID: 330585545}
- component: {fileID: 330585544}
- component: {fileID: 330585547}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &330585544
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 330585543}
m_Enabled: 1
--- !u!20 &330585545
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 330585543}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &330585546
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 330585543}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &330585547
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 330585543}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
m_Name:
m_EditorClassIdentifier:
m_RenderShadows: 1
m_RequiresDepthTextureOption: 2
m_RequiresOpaqueTextureOption: 2
m_CameraType: 0
m_Cameras: []
m_RendererIndex: -1
m_VolumeLayerMask:
serializedVersion: 2
m_Bits: 1
m_VolumeTrigger: {fileID: 0}
m_VolumeFrameworkUpdateModeOption: 2
m_RenderPostProcessing: 1
m_Antialiasing: 0
m_AntialiasingQuality: 2
m_StopNaN: 0
m_Dithering: 0
m_ClearDepth: 1
m_AllowXRRendering: 1
m_RequiresDepthTexture: 0
m_RequiresColorTexture: 0
m_Version: 2
--- !u!1 &410087039
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 410087041}
- component: {fileID: 410087040}
- component: {fileID: 410087042}
m_Layer: 0
m_Name: Directional Light
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!108 &410087040
Light:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 410087039}
m_Enabled: 1
serializedVersion: 10
m_Type: 1
m_Shape: 0
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_Intensity: 2
m_Range: 10
m_SpotAngle: 30
m_InnerSpotAngle: 21.80208
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_CullingMatrixOverride:
e00: 1
e01: 0
e02: 0
e03: 0
e10: 0
e11: 1
e12: 0
e13: 0
e20: 0
e21: 0
e22: 1
e23: 0
e30: 0
e31: 0
e32: 0
e33: 1
m_UseCullingMatrixOverride: 0
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingLayerMask: 1
m_Lightmapping: 4
m_LightShadowCasterMode: 0
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_ColorTemperature: 5000
m_UseColorTemperature: 1
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
m_UseBoundingSphereOverride: 0
m_UseViewFrustumForShadowCasterCull: 1
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!4 &410087041
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 410087039}
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
m_LocalPosition: {x: 0, y: 3, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!114 &410087042
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 410087039}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Version: 1
m_UsePipelineSettings: 1
m_AdditionalLightsShadowResolutionTier: 2
m_LightLayerMask: 1
m_CustomShadowLayers: 0
m_ShadowLayerMask: 1
m_LightCookieSize: {x: 1, y: 1}
m_LightCookieOffset: {x: 0, y: 0}
--- !u!1 &832575517
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 832575519}
- component: {fileID: 832575518}
m_Layer: 0
m_Name: Global Volume
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &832575518
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 832575517}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 172515602e62fb746b5d573b38a5fe58, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IsGlobal: 1
priority: 0
blendDistance: 0
weight: 1
sharedProfile: {fileID: 11400000, guid: a6560a915ef98420e9faacc1c7438823, type: 2}
--- !u!4 &832575519
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 832575517}
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: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
File diff suppressed because it is too large Load Diff
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4b8054ca510a246b2bf82ce19b92e5ca
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

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

After

Width:  |  Height:  |  Size: 34 KiB

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

After

Width:  |  Height:  |  Size: 7.8 KiB

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

After

Width:  |  Height:  |  Size: 27 KiB

@@ -0,0 +1,127 @@
fileFormatVersion: 2
guid: aeae0dec279fb4db19f309dfb541ab10
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a74fee214fee248ca8bce545fe9ba60a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e185e7ef2b2bc41a3952d401ed28b894
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,3 @@
using UnityEngine;
/// <summary>Legacy — replaced by StepAnimationHandler.</summary>
public class AnimationController : MonoBehaviour { }
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 05b8d5cbfd0e74474a937b3cc7ad120c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,87 @@
using UnityEngine;
/// <summary>
/// 角色动画控制器:管理伤者和施救者的动画状态切换。
/// 挂在角色根 GameObject 上,引用其 Animator 组件。
/// </summary>
public class CharacterAnimController : MonoBehaviour
{
public enum CharacterRole { Patient, Rescuer }
public CharacterRole Role = CharacterRole.Patient;
[Header("Animator 引用")]
[SerializeField] private Animator _animator;
private static readonly int ParamRun = Animator.StringToHash("IsRunning");
private static readonly int ParamJump = Animator.StringToHash("Jump");
private static readonly int ParamFall = Animator.StringToHash("Fall");
private static readonly int ParamLying = Animator.StringToHash("IsLying");
private static readonly int ParamCrouch = Animator.StringToHash("Crouch");
private static readonly int ParamCheck = Animator.StringToHash("Check");
private static readonly int ParamBandage = Animator.StringToHash("Bandage");
private static readonly int ParamRemoveShoe = Animator.StringToHash("RemoveShoe");
private void Awake()
{
if (_animator == null) _animator = GetComponent<Animator>();
}
public void PlayRun()
{
if (_animator == null) return;
_animator.SetBool(ParamRun, true);
}
public void StopRun()
{
if (_animator == null) return;
_animator.SetBool(ParamRun, false);
}
public void TriggerJump()
{
_animator?.SetTrigger(ParamJump);
}
public void TriggerFall()
{
_animator?.SetTrigger(ParamFall);
_animator?.SetBool(ParamLying, true);
}
public void SetLying(bool lying)
{
_animator?.SetBool(ParamLying, lying);
}
public void PlayCrouch()
{
_animator?.SetBool(ParamCrouch, true);
}
public void StopCrouch()
{
_animator?.SetBool(ParamCrouch, false);
}
public void TriggerCheck()
{
_animator?.SetTrigger(ParamCheck);
}
public void TriggerBandage()
{
_animator?.SetTrigger(ParamBandage);
}
public void TriggerRemoveShoe()
{
_animator?.SetTrigger(ParamRemoveShoe);
}
public void TriggerByName(string triggerName)
{
if (_animator == null || string.IsNullOrEmpty(triggerName)) return;
_animator.SetTrigger(Animator.StringToHash(triggerName));
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 23fb87b6a5b9544d3aed3b307715504c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,181 @@
using UnityEngine;
using System.Collections;
/// <summary>
/// 按步骤触发对应动画:开场动画、脱鞋、绑带、夹板放置等。
/// 挂在场景中有动画关联物体的 GameObject 上。
/// 由 ExperimentFlowCoordinator 绑定到 StepManager.OnStepChanged。
/// </summary>
public class StepAnimationHandler : MonoBehaviour
{
[Header("角色引用")]
[SerializeField] private CharacterAnimController _patient;
[SerializeField] private CharacterAnimController _rescuer;
[Header("道具引用")]
[SerializeField] private GameObject _shoeLeft; // 伤者左脚鞋
[SerializeField] private GameObject _shoeRight; // 伤者右脚鞋
[SerializeField] private GameObject[] _bandages; // 绑带物件列表
[SerializeField] private GameObject[] _splints; // 夹板物件列表
[SerializeField] private GameObject _padding; // 衬垫
[Header("夹板固定专用道具")]
[SerializeField] private GameObject _splintLeft;
[SerializeField] private GameObject _splintRight;
[Header("伤口高亮")]
[SerializeField] private GameObject _woundHighlight;
[Header("动画时长")]
[SerializeField] private float _shoeRemoveDuration = 1.5f;
[SerializeField] private float _bandageAppearDuration = 0.5f;
/// <summary>由 StepManager.OnStepChanged 调用</summary>
public void PlayStepAnimation(int stepIndex)
{
var sm = FindObjectOfType<StepManager>();
if (sm == null) return;
var step = sm.GetCurrentStep();
if (step == null) return;
StopAllCoroutines();
// 根据步骤名称匹配动画
switch (step.StepName)
{
case "OpeningScene":
StartCoroutine(PlayOpeningScene());
break;
case "RemoveShoes":
StartCoroutine(PlayRemoveShoes());
break;
case "PlaceBandage":
StartCoroutine(PlayPlaceBandage());
break;
case "LimbFixation":
StartCoroutine(PlayLimbFixation());
break;
case "SplintFixation":
StartCoroutine(PlaySplintFixation());
break;
case "AnkleFixation":
StartCoroutine(PlayAnkleFixation());
break;
case "FinalCheck":
break;
default:
Debug.Log($"StepAnimationHandler: 步骤 {step.StepName} 无专属动画");
break;
}
}
#region
private IEnumerator PlayOpeningScene()
{
// 伤者跑步 → 跳高 → 摔倒
_patient?.PlayRun();
yield return new WaitForSeconds(4f);
_patient?.TriggerJump();
yield return new WaitForSeconds(1f);
_patient?.TriggerFall();
yield return new WaitForSeconds(1.5f);
_patient?.StopRun();
}
private IEnumerator PlayRemoveShoes()
{
// 鞋子弹开/移出
if (_shoeLeft != null)
{
Vector3 target = _shoeLeft.transform.position + Vector3.right * 0.5f + Vector3.up * 0.2f;
yield return StartCoroutine(MoveToPosition(_shoeLeft, target, _shoeRemoveDuration));
_shoeLeft.SetActive(false);
}
if (_shoeRight != null)
{
Vector3 target = _shoeRight.transform.position + Vector3.right * 0.5f + Vector3.up * 0.2f;
yield return StartCoroutine(MoveToPosition(_shoeRight, target, _shoeRemoveDuration));
_shoeRight.SetActive(false);
}
}
private IEnumerator PlayPlaceBandage()
{
// 显示绑带
foreach (var b in _bandages)
{
if (b != null) b.SetActive(true);
}
yield return null;
}
private IEnumerator PlayLimbFixation()
{
// 显示衬垫 + 激活绑带
if (_padding != null) _padding.SetActive(true);
yield return new WaitForSeconds(0.5f);
// 依次显示绑带
for (int i = 0; i < _bandages.Length; i++)
{
if (_bandages[i] != null)
{
_bandages[i].SetActive(true);
yield return new WaitForSeconds(_bandageAppearDuration);
}
}
}
private IEnumerator PlaySplintFixation()
{
// 显示夹板
if (_splintLeft != null) _splintLeft.SetActive(true);
if (_splintRight != null) _splintRight.SetActive(true);
yield return new WaitForSeconds(0.5f);
foreach (var s in _splints)
{
if (s != null) s.SetActive(true);
yield return new WaitForSeconds(_bandageAppearDuration);
}
}
private IEnumerator PlayAnkleFixation()
{
// 8 字绑带动画 - 激活脚踝处绑带
if (_bandages.Length > 0 && _bandages[_bandages.Length - 1] != null)
{
_bandages[_bandages.Length - 1].SetActive(true);
}
yield return null;
}
#endregion
#region
private IEnumerator MoveToPosition(GameObject obj, Vector3 target, float duration)
{
if (obj == null) yield break;
Vector3 start = obj.transform.position;
float elapsed = 0f;
while (elapsed < duration)
{
elapsed += Time.deltaTime;
obj.transform.position = Vector3.Lerp(start, target, elapsed / duration);
yield return null;
}
obj.transform.position = target;
}
/// <summary>显示伤口高亮</summary>
public void ShowWoundHighlight(bool show)
{
if (_woundHighlight != null) _woundHighlight.SetActive(show);
}
#endregion
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bbe25e570b15b41d98e77259d82a8f1d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0501e3f1ed8cc4ec3ba149c9cd7b20af
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+92
View File
@@ -0,0 +1,92 @@
using UnityEngine;
/// <summary>
/// 音频管理器:管理背景音乐和步骤语音解说。
/// 挂在场景 GameObject 上,通过 AudioSource 组件播放。
/// </summary>
[RequireComponent(typeof(AudioSource))]
public class AudioManager : MonoBehaviour
{
public static AudioManager Instance { get; private set; }
[Header("音频源")]
[SerializeField] private AudioSource _bgmSource;
[SerializeField] private AudioSource _voiceSource;
[Header("背景音乐")]
public AudioClip BGMClip;
[Range(0f, 1f)] public float BGMVolume = 0.3f;
private void Awake()
{
if (Instance != null) { Destroy(gameObject); return; }
Instance = this;
DontDestroyOnLoad(gameObject);
if (_bgmSource == null) _bgmSource = GetComponent<AudioSource>();
if (_voiceSource == null)
{
_voiceSource = gameObject.AddComponent<AudioSource>();
_voiceSource.playOnAwake = false;
_voiceSource.loop = false;
}
}
private void Start()
{
PlayBGM();
}
public void PlayBGM()
{
if (_bgmSource == null || BGMClip == null) return;
_bgmSource.clip = BGMClip;
_bgmSource.volume = BGMVolume;
_bgmSource.loop = true;
_bgmSource.Play();
}
public void StopBGM()
{
if (_bgmSource != null) _bgmSource.Stop();
}
/// <summary>播放一步语音解说,自动打断前一条</summary>
public void PlayVoice(AudioClip clip, float volume = 1f)
{
if (_voiceSource == null || clip == null) return;
_voiceSource.Stop();
_voiceSource.clip = clip;
_voiceSource.volume = volume;
_voiceSource.Play();
}
/// <summary>停止语音</summary>
public void StopVoice()
{
if (_voiceSource != null) _voiceSource.Stop();
}
/// <summary>按文件名从 StreamingAssets 加载并播放语音</summary>
public void PlayVoiceFromFile(string fileName)
{
if (string.IsNullOrEmpty(fileName)) return;
StartCoroutine(LoadAndPlayVoice(fileName));
}
private System.Collections.IEnumerator LoadAndPlayVoice(string fileName)
{
string path = System.IO.Path.Combine(Application.streamingAssetsPath, "Voice", fileName);
using var www = UnityEngine.Networking.UnityWebRequestMultimedia.GetAudioClip(path, AudioType.WAV);
yield return www.SendWebRequest();
if (www.result == UnityEngine.Networking.UnityWebRequest.Result.Success)
{
var clip = UnityEngine.Networking.DownloadHandlerAudioClip.GetContent(www);
PlayVoice(clip);
}
else
{
Debug.LogWarning($"AudioManager: 加载语音失败 {path}");
}
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 55eccc8daa89f482193b0fcb1aa0f2bc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4d8a4c89bbd0d457494bb8c6130ff34b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+3
View File
@@ -0,0 +1,3 @@
using UnityEngine;
/// <summary>Legacy — replaced by ExperimentConfig ScriptableObject.</summary>
public class ConfigLoader : MonoBehaviour { }
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bda8b3bd9c4a14051b7821859e6095f6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,3 @@
using UnityEngine;
/// <summary>Legacy — replaced by ExperimentFlowCoordinator.</summary>
public class ExperimentController : MonoBehaviour { }
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5d499f2451702432ebbf25bfccbe1fa9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,100 @@
using UnityEngine;
/// <summary>
/// 实验场景的总协调器:挂载在 Experiment 场景的根 GameObject 上,
/// 负责将 StepManager / InteractionSystem / UIManager 串联在一起。
/// 考核模式以 proportion0~1)计分。
/// </summary>
public class ExperimentFlowCoordinator : MonoBehaviour
{
[Header("核心组件引用")]
[SerializeField] private StepManager _stepManager;
[SerializeField] private InteractionSystem _interactionSystem;
[SerializeField] private UIManager _uiManager;
[SerializeField] private StepAnimationHandler _animationHandler;
[SerializeField] private AudioManager _audioManager;
[Header("配置")]
[SerializeField] private ExperimentConfig _defaultConfig;
private void Start()
{
if (_interactionSystem != null && _stepManager != null)
{
_interactionSystem.OnObjectClicked.AddListener(OnObjectClicked);
_interactionSystem.OnAnywhereClicked.AddListener(OnAnywhereClicked);
}
if (_stepManager != null && _animationHandler != null)
{
_stepManager.OnStepChanged.AddListener(_animationHandler.PlayStepAnimation);
}
if (_defaultConfig != null)
{
_stepManager.Config = _defaultConfig;
}
_stepManager.InitializeFromGameManager();
}
#region
private void OnObjectClicked(string tag)
{
var step = _stepManager.GetCurrentStep();
if (step == null) return;
switch (step.CompleteType)
{
case StepCompleteType.ClickObject:
if (tag == step.TargetTag)
{
Debug.Log($"ExperimentFlowCoordinator: 正确点击了 {tag}");
_stepManager.OnStepInteractionComplete(1f);
}
else
{
Debug.Log($"ExperimentFlowCoordinator: 点击了 {tag},需要的是 {step.TargetTag}");
if (_stepManager.Mode == ExperimentMode.Exam)
_stepManager.OnStepInteractionComplete(0f, "点击位置不正确");
}
break;
case StepCompleteType.SequenceClick:
// 按子项命中比例计分
bool isComplete;
bool isCorrect = _interactionSystem.TrySequenceClick(tag, out isComplete);
if (isComplete)
{
// 取当前序列已命中数 / 总子项数
int hit = _interactionSystem.GetSequenceHitCount();
int total = step.ClickSequenceTags?.Length ?? step.SubStepCount;
float proportion = total > 0 ? (float)hit / total : 1f;
string fb = proportion < 1f ? $"顺序部分正确({hit}/{total} 步正确)" : "";
_stepManager.OnStepInteractionComplete(proportion, fb);
}
else if (!isCorrect)
{
_stepManager.OnStepInteractionComplete(0f, "点击顺序不正确");
}
break;
default:
break;
}
}
private void OnAnywhereClicked()
{
var step = _stepManager.GetCurrentStep();
if (step == null) return;
if (step.CompleteType == StepCompleteType.ClickAnywhere)
{
_stepManager.OnStepInteractionComplete(1f);
}
}
#endregion
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e3dd6cb15ae1a4f0e92e2826f64ee6cf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+38
View File
@@ -0,0 +1,38 @@
// ============================================================
// 实验类型、模式、固定方式的枚举定义
// ============================================================
/// <summary>五大急救实验类型</summary>
public enum ExperimentType
{
CPR, // 心肺复苏
FractureFixation, // 骨折固定
SprainBandaging, // 扭伤包扎
BleedingBandaging, // 出血包扎
CasualtyTransport // 伤员搬运
}
/// <summary>运行模式</summary>
public enum ExperimentMode
{
Learn, // 学习模式
Exam // 考核模式
}
/// <summary>骨折固定方式(仅骨折固定实验使用)</summary>
public enum FixationMethod
{
LimbFixation, // 肢体固定
SplintFixation // 夹板固定
}
/// <summary>单个步骤完成的判定类型</summary>
public enum StepCompleteType
{
None, // 无需交互,自动进入下一步
ClickObject, // 点击指定 3D 物体
DragToTarget, // 拖拽物体到目标位置
ClickAnywhere, // 点击任意空白处
MultipleChoice, // 选择题(考核模式)
SequenceClick // 按顺序点击多个物体(考核模式)
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 13ab85c5e00ee4765918090eeac6de36
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+75
View File
@@ -0,0 +1,75 @@
using UnityEngine;
/// <summary>
/// 全局单例管理器:持有当前实验的类型、模式、固定方式与加权分数。
/// 挂在场景第一个 GameObject 上,设置 DontDestroyOnLoad。
/// </summary>
public class GameManager : MonoBehaviour
{
public static GameManager Instance { get; private set; }
[Header("当前实验设置(运行时赋值)")]
public ExperimentType CurrentExperimentType = ExperimentType.FractureFixation;
public ExperimentMode CurrentMode = ExperimentMode.Learn;
public FixationMethod CurrentFixationMethod = FixationMethod.LimbFixation;
[Header("加权评分")]
public float TotalWeightedScore; // 实际得分(加权累加)
public float MaxWeightedScore = 100f; // 总分
[Header("考核记录")]
public float[] StepScores; // 每步实际得分(含权重)
public float[] StepMaxScores; // 每步满分(权重值)
public string[] StepFeedback; // 每题错误反馈文本
public bool[] StepCorrect; // 每题是否有任何得分
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
}
/// <summary>初始化考核记录数组</summary>
public void InitExamRecord(int stepCount)
{
StepScores = new float[stepCount];
StepMaxScores = new float[stepCount];
StepFeedback = new string[stepCount];
StepCorrect = new bool[stepCount];
TotalWeightedScore = 0f;
}
/// <summary>
/// 记录一个考核步骤的结果。
/// proportion 为 0~1,表示得分比例(SequenceClick 类型部分正确时用到)。
/// </summary>
public void RecordExamResult(int stepIndex, float maxScore, float proportion, string feedback)
{
if (StepScores == null || stepIndex >= StepScores.Length) return;
StepMaxScores[stepIndex] = maxScore;
float earned = maxScore * Mathf.Clamp01(proportion);
StepScores[stepIndex] = earned;
StepFeedback[stepIndex] = feedback;
StepCorrect[stepIndex] = proportion > 0f;
TotalWeightedScore += earned;
}
/// <summary>按百分比返回考核分数</summary>
public float GetExamPercentage()
{
if (MaxWeightedScore <= 0f) return 0f;
return TotalWeightedScore / MaxWeightedScore * 100f;
}
/// <summary>获取总分(整数)</summary>
public int GetExamScoreRounded()
{
return Mathf.RoundToInt(TotalWeightedScore);
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c57598038a100447ab7f5396d0f0e49c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+172
View File
@@ -0,0 +1,172 @@
using UnityEngine;
using UnityEngine.Events;
/// <summary>
/// 实验流程状态机——整个项目的核心控制器。
/// 负责步骤推进、模式切换、UI 更新、加权考核判分调度。
/// 挂在一个持久化的 GameObject 上。
/// </summary>
public class StepManager : MonoBehaviour
{
[Header("配置")]
public ExperimentConfig Config;
[Header("事件(拖入场景对象或通过代码绑定)")]
public UnityEvent<int> OnStepChanged; // 步骤切换时触发,传新步骤索引
public UnityEvent<string> OnTipChanged; // Tip 文案更新
public UnityEvent<string> OnDialogueChanged; // 角色对话更新
public UnityEvent<StepData> OnExamPopup; // 考核弹窗触发,传当前 StepData
public UnityEvent<string> OnDetailedContent; // 详细操作说明更新(甲方补充)
public UnityEvent OnExperimentComplete; // 实验全部完成
public UnityEvent<string, bool> OnVideoToggle; // 画中画视频开关(文件名, 是否激活)
public UnityEvent<bool> OnModeUIUpdate; // 通知 UI 刷新模式按钮状态
// 私有状态
private StepData[] _activeSteps;
private int _currentStepIndex = -1;
private ExperimentMode _mode;
private FixationMethod _fixation;
public int CurrentStepIndex => _currentStepIndex;
public int TotalSteps => _activeSteps != null ? _activeSteps.Length : 0;
public ExperimentMode Mode => _mode;
public FixationMethod Fixation => _fixation;
/// <summary>用 GameManager 的当前设置初始化实验流程</summary>
public void InitializeFromGameManager()
{
var gm = GameManager.Instance;
if (gm == null) { Debug.LogError("StepManager: GameManager.Instance is null!"); return; }
Initialize(gm.CurrentExperimentType, gm.CurrentMode, gm.CurrentFixationMethod);
}
/// <summary>显式指定参数初始化</summary>
public void Initialize(ExperimentType type, ExperimentMode mode, FixationMethod fixation)
{
_mode = mode;
_fixation = fixation;
Config = Resources.Load<ExperimentConfig>($"Configs/{type}Config");
if (Config == null)
{
Debug.LogError($"StepManager: 找不到 ExperimentConfig for {type},请在 Resources/Configs/ 下创建");
return;
}
_activeSteps = Config.GetStepsFor(mode, fixation);
if (_activeSteps == null || _activeSteps.Length == 0)
{
Debug.LogError($"StepManager: 实验 {type} 模式 {mode} 固定方式 {fixation} 无步骤数据!");
return;
}
_currentStepIndex = -1;
if (mode == ExperimentMode.Exam)
GameManager.Instance.InitExamRecord(_activeSteps.Length);
OnModeUIUpdate?.Invoke(mode == ExperimentMode.Exam);
GoToStep(0);
}
/// <summary>跳转到指定步骤(含边界检查)</summary>
public void GoToStep(int index)
{
if (_activeSteps == null) return;
index = Mathf.Clamp(index, 0, _activeSteps.Length - 1);
if (index == _currentStepIndex) return;
_currentStepIndex = index;
var step = _activeSteps[index];
if (_mode == ExperimentMode.Learn)
{
OnTipChanged?.Invoke(step.TipText);
OnDialogueChanged?.Invoke(step.DialogueText);
OnDetailedContent?.Invoke(step.DetailedContent);
if (step.ShowPipVideo)
OnVideoToggle?.Invoke(step.VideoFileName, true);
else
OnVideoToggle?.Invoke(null, false);
}
else
{
OnTipChanged?.Invoke("");
OnDialogueChanged?.Invoke("");
OnDetailedContent?.Invoke("");
OnVideoToggle?.Invoke(null, false);
if (!string.IsNullOrEmpty(step.ExamQuestionText))
OnExamPopup?.Invoke(step);
}
OnStepChanged?.Invoke(_currentStepIndex);
}
/// <summary>下一步</summary>
public void NextStep()
{
if (_activeSteps == null) return;
if (_currentStepIndex >= _activeSteps.Length - 1)
{
CompleteExperiment();
return;
}
GoToStep(_currentStepIndex + 1);
}
/// <summary>上一步</summary>
public void PreviousStep()
{
if (_activeSteps == null || _currentStepIndex <= 0) return;
GoToStep(_currentStepIndex - 1);
}
/// <summary>获取当前步骤数据(只读)</summary>
public StepData GetCurrentStep()
{
if (_activeSteps == null || _currentStepIndex < 0 || _currentStepIndex >= _activeSteps.Length)
return null;
return _activeSteps[_currentStepIndex];
}
/// <summary>
/// 当前步骤互动完成后的回调。
/// proportion: 得分比例 0~1SequenceClick 按子项命中比例,其余全对=1,全错=0)。
/// </summary>
public void OnStepInteractionComplete(float proportion = 1f, string feedback = "")
{
var step = GetCurrentStep();
if (step == null) return;
if (_mode == ExperimentMode.Exam)
{
string fb = string.IsNullOrEmpty(feedback) ? step.ErrorFeedback : feedback;
GameManager.Instance.RecordExamResult(_currentStepIndex, step.ScoreWeight, proportion, fb);
}
if (_mode == ExperimentMode.Learn)
NextStep();
}
/// <summary>实验完成</summary>
private void CompleteExperiment()
{
Debug.Log("StepManager: 实验流程结束");
OnExperimentComplete?.Invoke();
}
/// <summary>切换模式(学习 ↔ 考核),从头开始</summary>
public void SwitchMode(ExperimentMode newMode)
{
GameManager.Instance.CurrentMode = newMode;
Initialize(GameManager.Instance.CurrentExperimentType, newMode, GameManager.Instance.CurrentFixationMethod);
}
/// <summary>切换固定方式,从头开始</summary>
public void SwitchFixation(FixationMethod newFixation)
{
GameManager.Instance.CurrentFixationMethod = newFixation;
Initialize(GameManager.Instance.CurrentExperimentType, GameManager.Instance.CurrentMode, newFixation);
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a2535da3ddf9046e686f9b0d2ce5f569
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 49013f1e509fe47b18f6e8480e546996
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+34
View File
@@ -0,0 +1,34 @@
using UnityEngine;
/// <summary>
/// Defines an exam question with multiple choices.
/// </summary>
[CreateAssetMenu(fileName = "ExamQuestion", menuName = "VFS/Exam Question")]
public class ExamQuestionData : ScriptableObject
{
[Header("Question Info")]
public int questionIndex;
[TextArea(2, 4)]
public string questionText;
[Header("Choices")]
public string[] choices;
public int correctChoiceIndex;
[Header("Feedback")]
[TextArea(2, 4)]
public string correctFeedback;
[TextArea(2, 4)]
public string incorrectFeedback;
[Header("Interaction")]
public QuestionType questionType;
public string targetTag;
public enum QuestionType
{
MultipleChoice,
ClickTarget,
SequenceOrder
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1ac09a60490764c18ba4d4b5616370e8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+38
View File
@@ -0,0 +1,38 @@
using UnityEngine;
/// <summary>
/// 单个实验类型的完整配置:包含学习模式与考核模式的所有步骤。
/// 在 Unity Editor 中为每种实验类型各创建一份 Asset。
/// </summary>
[CreateAssetMenu(fileName = "ExperimentConfig", menuName = "VFS/Experiment Config")]
public class ExperimentConfig : ScriptableObject
{
[Header("实验标识")]
public ExperimentType Type;
[Header("实验名称")]
public string DisplayName;
[Header("骨折固定专属 - 固定方式对应的步骤覆盖")]
public FixationMethod DefaultFixationMethod = FixationMethod.LimbFixation;
[Header("学习模式步骤列表(肢体固定)")]
public StepData[] LearnStepsLimb;
[Header("学习模式步骤列表(夹板固定)")]
public StepData[] LearnStepsSplint;
[Header("考核模式步骤列表(肢体固定)")]
public StepData[] ExamStepsLimb;
[Header("考核模式步骤列表(夹板固定)")]
public StepData[] ExamStepsSplint;
public StepData[] GetStepsFor(ExperimentMode mode, FixationMethod fixation)
{
if (mode == ExperimentMode.Learn)
return fixation == FixationMethod.SplintFixation ? LearnStepsSplint : LearnStepsLimb;
else
return fixation == FixationMethod.SplintFixation ? ExamStepsSplint : ExamStepsLimb;
}
public int StepCount(ExperimentMode mode, FixationMethod fixation)
{
var steps = GetStepsFor(mode, fixation);
return steps != null ? steps.Length : 0;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 24d3a8cba581943e1a2b2c167c7dd259
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+63
View File
@@ -0,0 +1,63 @@
using UnityEngine;
/// <summary>
/// 单个实验步骤的数据配置(ScriptableObject)。
/// 在 Unity Editor 中为每个实验创建一份 StepData 列表。
/// </summary>
[CreateAssetMenu(fileName = "StepData", menuName = "VFS/Step Data")]
public class StepData : ScriptableObject
{
[Header("=== 评分 ===")]
[Tooltip("本步骤满分(考核模式下使用,总分 100 分)")]
[Range(0f, 100f)]
public float ScoreWeight = 10f;
[Tooltip("本步骤的子项数量(如伤情检查有 5 个子项,用于 SequenceClick 按比例计分)")]
public int SubStepCount = 1;
[Header("基础信息")]
[Tooltip("步骤序号,从 0 开始")]
public int StepIndex;
[Tooltip("步骤名称(内部标识)")]
public string StepName;
[Header("学习模式文案")]
[TextArea(2, 4)]
public string TipText; // 顶部 Tip 提示框文案
[TextArea(2, 4)]
public string DialogueText; // 角色对话气泡文案
[Header("学习模式 - 详细操作说明(甲方补充内容)")]
[TextArea(3, 8)]
public string DetailedContent; // 伤情检查/夹板固定等详细操作须知
[Header("考核模式文案")]
[TextArea(2, 4)]
public string ExamQuestionText; // 考核弹窗题目文案
[Header("考核选项")]
public string[] ExamOptions; // 选择题选项(如 {"5cm", "10cm", "20cm"}
public int CorrectOptionIndex; // 正确选项的索引(-1 表示非选择题)
public string ErrorFeedback; // 答错时的反馈文案
[Header("交互配置")]
public StepCompleteType CompleteType = StepCompleteType.ClickObject;
[Tooltip("交互目标的 Tag(如 InjuryLeg, Shoe, Bandage")]
public string TargetTag;
[Tooltip("考核模式点击顺序(SequenceClick 类型时使用)")]
public string[] ClickSequenceTags;
[Header("额外配置")]
[Tooltip("是否为夹板固定专属步骤")]
public bool IsSplintOnly;
[Tooltip("是否需要播放画中画视频")]
public bool ShowPipVideo;
[Tooltip("画中画视频文件名(StreamingAssets 下)")]
public string VideoFileName;
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dac314898f2b743efa29d166b0ed2980
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: aa42089b59739481481ee9e714b88438
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,54 @@
using UnityEngine;
using UnityEngine.Events;
/// <summary>
/// 挂载在可拖拽的 3D 物体上(如绷带、夹板)。
/// 配合 InteractionSystem 使用。
/// </summary>
public class DraggableObject : MonoBehaviour
{
[Header("拖拽状态")]
public bool IsDraggable = true;
[Header("吸附目标")]
public Transform SnapTarget;
[Header("事件")]
public UnityEvent OnDragStartEvent;
public UnityEvent OnDragEndEvent;
public UnityEvent OnSnappedEvent; // 吸附成功
private Vector3 _originalPosition;
private Quaternion _originalRotation;
private void Start()
{
_originalPosition = transform.position;
_originalRotation = transform.rotation;
}
public void OnDragStart()
{
OnDragStartEvent?.Invoke();
}
public void OnDragEnd()
{
OnDragEndEvent?.Invoke();
}
public void OnSnapped()
{
Debug.Log($"DraggableObject: {name} 已吸附到目标");
OnSnappedEvent?.Invoke();
IsDraggable = false; // 吸附后不可再拖动
}
/// <summary>重置到初始位置</summary>
public void ResetPosition()
{
transform.position = _originalPosition;
transform.rotation = _originalRotation;
IsDraggable = true;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cbf0e86605f7b485f8ff25c5810d30c0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,83 @@
using UnityEngine;
/// <summary>
/// 物体高亮效果:鼠标悬停时切换 Emission 或轮廓材质。
/// 挂在可交互的 3D 物体上。
/// </summary>
public class HighlightEffect : MonoBehaviour
{
[Header("高亮设置")]
[SerializeField] private Color _highlightColor = Color.yellow;
[SerializeField] private float _highlightIntensity = 0.5f;
[Header("可选 - 使用 Outline 组件")]
[SerializeField] private bool _useOutline = true;
[SerializeField] private float _outlineWidth = 0.02f;
private Renderer[] _renderers;
private Material[] _originalMaterials;
private Material[] _highlightMaterials;
private bool _isHighlighted;
[Header("考核高亮 - 始终显示")]
public bool AlwaysHighlighted;
private void Start()
{
_renderers = GetComponentsInChildren<Renderer>();
}
private void OnMouseEnter()
{
if (_isHighlighted) return;
SetHighlight(true);
}
private void OnMouseExit()
{
if (AlwaysHighlighted) return;
SetHighlight(false);
}
public void SetHighlight(bool on)
{
_isHighlighted = on;
if (_renderers == null) return;
foreach (var r in _renderers)
{
if (r == null) continue;
foreach (var mat in r.materials)
{
if (on)
{
mat.EnableKeyword("_EMISSION");
mat.SetColor("_EmissionColor", _highlightColor * _highlightIntensity);
}
else
{
mat.DisableKeyword("_EMISSION");
}
}
}
}
/// <summary>闪烁效果,用于提示用户点击</summary>
public void Flash(float duration = 0.5f)
{
StopAllCoroutines();
StartCoroutine(FlashRoutine(duration));
}
private System.Collections.IEnumerator FlashRoutine(float duration)
{
float half = duration / 2f;
SetHighlight(true);
yield return new WaitForSeconds(half);
SetHighlight(false);
yield return new WaitForSeconds(half);
SetHighlight(true);
yield return new WaitForSeconds(half);
SetHighlight(false);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 289a67afae9f64a8fbff818821d6ea91
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,168 @@
using UnityEngine;
using UnityEngine.Events;
/// <summary>
/// 核心交互系统:射线检测 + 点击/拖拽处理。
/// 挂在主相机或专用 GameObject 上。
/// </summary>
public class InteractionSystem : MonoBehaviour
{
[Header("射线配置")]
[SerializeField] private Camera _mainCamera;
[SerializeField] private LayerMask _interactableMask = ~0;
[SerializeField] private float _maxRayDistance = 100f;
[Header("事件 - 由 StepManager 绑定")]
public UnityEvent<string> OnObjectClicked; // 点击到 Tag 时触发,传 Tag
public UnityEvent OnAnywhereClicked; // 点击空白处触发
[Header("拖拽配置")]
[SerializeField] private float _dragPlaneDistance = 2f;
[SerializeField] private float _snapDistance = 0.3f;
private GameObject _draggedObject;
private Vector3 _dragOffset;
private float _dragZ;
private bool _isDragging;
// 考核模式序列点击
private int _sequenceClickCount;
private string[] _expectedSequence;
private void Awake()
{
if (_mainCamera == null)
_mainCamera = Camera.main;
}
private void Update()
{
HandleClick();
HandleDrag();
}
#region
private void HandleClick()
{
if (!Input.GetMouseButtonDown(0)) return;
if (UnityEngine.EventSystems.EventSystem.current != null &&
UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject())
return;
Ray ray = _mainCamera.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out RaycastHit hit, _maxRayDistance, _interactableMask))
{
string tag = hit.collider.tag;
if (!string.IsNullOrEmpty(tag))
{
Debug.Log($"InteractionSystem: 点击到物体 Tag={tag}");
OnObjectClicked?.Invoke(tag);
return;
}
}
OnAnywhereClicked?.Invoke();
}
#endregion
#region
private void HandleDrag()
{
if (Input.GetMouseButtonDown(0))
{
if (UnityEngine.EventSystems.EventSystem.current != null &&
UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject())
return;
Ray ray = _mainCamera.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out RaycastHit hit, _maxRayDistance, _interactableMask))
{
var draggable = hit.collider.GetComponent<DraggableObject>();
if (draggable != null && draggable.IsDraggable)
{
_draggedObject = hit.collider.gameObject;
_dragZ = _mainCamera.WorldToScreenPoint(_draggedObject.transform.position).z;
_isDragging = true;
draggable.OnDragStart();
}
}
}
if (Input.GetMouseButton(0) && _isDragging && _draggedObject != null)
{
Vector3 screenPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, _dragZ);
Vector3 worldPos = _mainCamera.ScreenToWorldPoint(screenPos);
_draggedObject.transform.position = worldPos;
}
if (Input.GetMouseButtonUp(0) && _isDragging && _draggedObject != null)
{
var draggable = _draggedObject.GetComponent<DraggableObject>();
if (draggable != null && draggable.SnapTarget != null)
{
float dist = Vector3.Distance(_draggedObject.transform.position, draggable.SnapTarget.position);
if (dist <= _snapDistance)
{
_draggedObject.transform.position = draggable.SnapTarget.position;
_draggedObject.transform.rotation = draggable.SnapTarget.rotation;
draggable.OnSnapped();
}
}
draggable?.OnDragEnd();
_draggedObject = null;
_isDragging = false;
}
}
#endregion
#region
public void BeginSequenceCheck(string[] expectedTags)
{
_expectedSequence = expectedTags;
_sequenceClickCount = 0;
}
public bool TrySequenceClick(string clickedTag, out bool isComplete)
{
isComplete = false;
if (_expectedSequence == null || _sequenceClickCount >= _expectedSequence.Length)
return false;
if (clickedTag == _expectedSequence[_sequenceClickCount])
{
_sequenceClickCount++;
if (_sequenceClickCount >= _expectedSequence.Length)
{
isComplete = true;
_expectedSequence = null;
return true;
}
return true;
}
return false;
}
/// <summary>获取当前序列已正确命中的步数(用于 proportion 计分)</summary>
public int GetSequenceHitCount()
{
return _sequenceClickCount;
}
#endregion
#region
public void SetInteractionEnabled(bool enabled)
{
this.enabled = enabled;
}
#endregion
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1de9da6001ff949cf9bedcd003c48487
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2f65bedef5c694798a8ddf6bcaad27ee
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+154
View File
@@ -0,0 +1,154 @@
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System;
/// <summary>
/// 考核弹窗:选择题 + 操作确认。
/// 挂在弹窗 Panel 上,由 UIManager 调用 Show()。
/// 回调返回 proportion (0~1 得分比例) 和 feedback。
/// </summary>
public class ExamPopup : MonoBehaviour
{
[Header("UI 组件")]
[SerializeField] private GameObject _popupRoot;
[SerializeField] private TMP_Text _questionText;
[SerializeField] private Toggle[] _optionToggles;
[SerializeField] private TMP_Text[] _optionLabels;
[SerializeField] private Button _confirmButton;
[SerializeField] private TMP_Text _feedbackText;
[Header("操作题 UI(点击序列)")]
[SerializeField] private GameObject _operationPanel;
[SerializeField] private TMP_Text _operationHint;
private StepData _currentStep;
private Action<float, string> _onAnswerCallback;
private int _selectedIndex = -1;
private void Awake()
{
_confirmButton?.onClick.AddListener(OnConfirm);
if (_popupRoot != null) _popupRoot.SetActive(false);
}
public void Show(StepData step, Action<float, string> onAnswer)
{
_currentStep = step;
_onAnswerCallback = onAnswer;
_selectedIndex = -1;
if (_feedbackText != null) _feedbackText.text = "";
if (_popupRoot != null) _popupRoot.SetActive(true);
_questionText?.SetText(step.ExamQuestionText);
switch (step.CompleteType)
{
case StepCompleteType.MultipleChoice:
SetupMultipleChoice(step);
break;
case StepCompleteType.ClickObject:
SetupClickObject(step);
break;
case StepCompleteType.SequenceClick:
SetupSequenceClick(step);
break;
default:
SetupDefault(step);
break;
}
}
#region
private void SetupMultipleChoice(StepData step)
{
if (_operationPanel != null) _operationPanel.SetActive(false);
int optionCount = step.ExamOptions?.Length ?? 0;
for (int i = 0; i < _optionToggles.Length; i++)
{
bool active = i < optionCount;
_optionToggles[i].gameObject.SetActive(active);
_optionToggles[i].isOn = false;
_optionToggles[i].onValueChanged.RemoveAllListeners();
int idx = i;
_optionToggles[i].onValueChanged.AddListener((val) => { if (val) _selectedIndex = idx; });
if (active) _optionLabels[i]?.SetText(step.ExamOptions[i]);
}
_confirmButton?.gameObject.SetActive(true);
}
private void SetupClickObject(StepData step)
{
if (_operationPanel != null) _operationPanel.SetActive(true);
if (_optionToggles != null)
foreach (var t in _optionToggles) t.gameObject.SetActive(false);
_confirmButton?.gameObject.SetActive(true);
_operationHint?.SetText($"请点击场景中的 {step.TargetTag} 物体");
}
private void SetupSequenceClick(StepData step)
{
if (_operationPanel != null) _operationPanel.SetActive(true);
if (_optionToggles != null)
foreach (var t in _optionToggles) t.gameObject.SetActive(false);
_confirmButton?.gameObject.SetActive(true);
_operationHint?.SetText("请按正确顺序点击物体,完成后按确定");
}
private void SetupDefault(StepData step)
{
if (_operationPanel != null) _operationPanel.SetActive(false);
if (_optionToggles != null)
foreach (var t in _optionToggles) t.gameObject.SetActive(false);
_confirmButton?.gameObject.SetActive(true);
}
#endregion
#region
private void OnConfirm()
{
if (_currentStep == null) return;
float proportion = 1f;
string feedback = "";
switch (_currentStep.CompleteType)
{
case StepCompleteType.MultipleChoice:
bool correct = _selectedIndex == _currentStep.CorrectOptionIndex;
proportion = correct ? 1f : 0f;
feedback = correct ? "" : _currentStep.ErrorFeedback;
if (!correct && _feedbackText != null)
_feedbackText.text = feedback;
break;
default:
proportion = 1f;
break;
}
if (proportion <= 0f && !string.IsNullOrEmpty(feedback))
{
_onAnswerCallback?.Invoke(0f, feedback);
Hide();
}
else
{
_onAnswerCallback?.Invoke(proportion, feedback);
Hide();
}
}
public void Hide()
{
if (_popupRoot != null) _popupRoot.SetActive(false);
_currentStep = null;
_onAnswerCallback = null;
}
#endregion
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1b7f4e3b0a85d4c75860bf9060f8c3a8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+6
View File
@@ -0,0 +1,6 @@
using UnityEngine;
/// <summary>
/// Legacy HUD controller — replaced by UIManager. Kept for backward compatibility.
/// </summary>
public class HUDController : MonoBehaviour { }
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ded61052e4f7c449ca21983fdaa9060b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+38
View File
@@ -0,0 +1,38 @@
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
/// <summary>
/// Main menu UI — assign all fields in Inspector.
/// </summary>
public class MainMenuUI : MonoBehaviour
{
[Header("Text")]
public Text titleText;
public Text versionText;
[Header("Buttons")]
public Button cprButton;
public Button fractureButton;
public Button sprainButton;
public Button bleedingButton;
public Button transportButton;
private void Start()
{
if (titleText != null) titleText.text = "运动伤害现场急救处理虚拟仿真实验";
if (versionText != null) versionText.text = $"v{Application.version}";
if (cprButton != null) cprButton.onClick.AddListener(() => OnSelect("CPR"));
if (fractureButton != null) fractureButton.onClick.AddListener(() => OnSelect("FractureFixation"));
if (sprainButton != null) sprainButton.onClick.AddListener(() => OnSelect("SprainBandage"));
if (bleedingButton != null) bleedingButton.onClick.AddListener(() => OnSelect("BleedingBandage"));
if (transportButton != null) transportButton.onClick.AddListener(() => OnSelect("CasualtyTransport"));
}
private void OnSelect(string experimentId)
{
PlayerPrefs.SetString("SelectedExperiment", experimentId);
SceneManager.LoadScene("ModeSelection");
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7fca7ea321dc34ab19b4bea56e90e8a2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+72
View File
@@ -0,0 +1,72 @@
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class ModeSelectionUI : MonoBehaviour
{
[Header("Tip")]
public Text tipText;
[Header("Fixation Mode")]
public Button limbFixationButton;
public Button splintFixationButton;
public GameObject limbFixationCheck;
public GameObject splintFixationCheck;
[Header("Run Mode")]
public Button learnModeButton;
public Button examModeButton;
public GameObject learnModeCheck;
public GameObject examModeCheck;
[Header("Actions")]
public Button startButton;
public Button backButton;
private FixationMethod selectedFixation = FixationMethod.LimbFixation;
private ExperimentMode selectedRunMode = ExperimentMode.Learn;
private void Start()
{
tipText.text = "Tip:请选择实验模式";
limbFixationButton.onClick.AddListener(() => SelectFixation(FixationMethod.LimbFixation));
splintFixationButton.onClick.AddListener(() => SelectFixation(FixationMethod.SplintFixation));
learnModeButton.onClick.AddListener(() => SelectRunMode(ExperimentMode.Learn));
examModeButton.onClick.AddListener(() => SelectRunMode(ExperimentMode.Exam));
startButton.onClick.AddListener(OnStart);
backButton.onClick.AddListener(() => SceneManager.LoadScene("main"));
UpdateSelectionVisuals();
}
private void SelectFixation(FixationMethod mode)
{
selectedFixation = mode;
UpdateSelectionVisuals();
}
private void SelectRunMode(ExperimentMode mode)
{
selectedRunMode = mode;
UpdateSelectionVisuals();
}
private void UpdateSelectionVisuals()
{
limbFixationCheck.SetActive(selectedFixation == FixationMethod.LimbFixation);
splintFixationCheck.SetActive(selectedFixation == FixationMethod.SplintFixation);
learnModeCheck.SetActive(selectedRunMode == ExperimentMode.Learn);
examModeCheck.SetActive(selectedRunMode == ExperimentMode.Exam);
}
private void OnStart()
{
if (GameManager.Instance != null)
{
GameManager.Instance.CurrentFixationMethod = selectedFixation;
GameManager.Instance.CurrentMode = selectedRunMode;
}
SceneManager.LoadScene("Experiment");
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2106746edd5ca43288aff94f664b16ae
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+3
View File
@@ -0,0 +1,3 @@
using UnityEngine;
/// <summary>Legacy — replaced by ExamPopup + ScoreDisplay.</summary>
public class PopupSystem : MonoBehaviour { }
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c0eab9dd709f74ddf9f6728ef6bb4edf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+109
View File
@@ -0,0 +1,109 @@
using UnityEngine;
using UnityEngine.UI;
using TMPro;
/// <summary>
/// 实验结束后的结果展示面板。
/// 考核模式:显示加权成绩 + 错题分析列表(含每步得分/满分)。
/// 学习模式:显示注意事项。
/// </summary>
public class ScoreDisplay : MonoBehaviour
{
[Header("面板根节点")]
[SerializeField] private GameObject _panelRoot;
[Header("考核模式")]
[SerializeField] private GameObject _examResultRoot;
[SerializeField] private TMP_Text _scoreTitle;
[SerializeField] private TMP_Text _scoreValue;
[SerializeField] private Transform _analysisListParent;
[SerializeField] private GameObject _analysisItemPrefab;
[Header("学习模式 - 注意事项")]
[SerializeField] private GameObject _notesRoot;
[SerializeField] private TMP_Text _notesText;
[Header("底部按钮")]
[SerializeField] private Button _confirmButton;
private static readonly string NotesContent =
"1. 下肢损伤选择仰卧位;\n" +
"2. 骨折固定前后要脱掉鞋袜并检查下肢末梢循环、运动、感觉;\n" +
"3. 穿带子时应从健侧穿向伤侧;\n" +
"4. 骨折固定时先固定伤口的近心端,后固定远心端,再由上而下进行固定;\n" +
"5. 固定后尽可能抬高下肢。";
private void Awake()
{
_confirmButton?.onClick.AddListener(OnConfirm);
if (_panelRoot != null) _panelRoot.SetActive(false);
}
/// <summary>考核模式 - 显示加权成绩</summary>
public void ShowExamScore()
{
if (_panelRoot != null) _panelRoot.SetActive(true);
if (_examResultRoot != null) _examResultRoot.SetActive(true);
if (_notesRoot != null) _notesRoot.SetActive(false);
var gm = GameManager.Instance;
if (gm == null) return;
int score = gm.GetExamScoreRounded();
float pct = gm.GetExamPercentage();
if (_scoreTitle != null) _scoreTitle.text = "成绩显示栏";
if (_scoreValue != null) _scoreValue.text = $"考试成绩:{score} 分({pct:F0}%";
BuildAnalysisList();
}
/// <summary>学习模式 - 显示注意事项</summary>
public void ShowNotesOnly()
{
if (_panelRoot != null) _panelRoot.SetActive(true);
if (_examResultRoot != null) _examResultRoot.SetActive(false);
if (_notesRoot != null) _notesRoot.SetActive(true);
if (_notesText != null) _notesText.text = NotesContent;
}
private void BuildAnalysisList()
{
if (_analysisListParent == null || _analysisItemPrefab == null) return;
foreach (Transform child in _analysisListParent)
Destroy(child.gameObject);
var gm = GameManager.Instance;
if (gm == null || gm.StepScores == null) return;
for (int i = 0; i < gm.StepScores.Length; i++)
{
var item = Instantiate(_analysisItemPrefab, _analysisListParent);
var text = item.GetComponentInChildren<TMP_Text>();
if (text == null) continue;
float earned = gm.StepScores[i];
float max = gm.StepMaxScores[i];
bool fullScore = Mathf.Approximately(earned, max);
bool zeroScore = earned <= 0f;
string status;
if (fullScore) status = "<color=#00FF00>正确</color>";
else if (zeroScore) status = "<color=#FF0000>错误</color>";
else status = $"<color=#FFAA00>部分正确</color>";
string scorePart = $"{earned:F0}/{max:F0} 分)";
string fbPart = (!fullScore && !string.IsNullOrEmpty(gm.StepFeedback[i]))
? $"{gm.StepFeedback[i]}" : "";
text.text = $"第{i + 1}题:{status} {scorePart}{fbPart}";
}
}
private void OnConfirm()
{
if (_panelRoot != null) _panelRoot.SetActive(false);
UnityEngine.SceneManagement.SceneManager.LoadScene("MainMenu");
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8315bbe42105640af89ceda53b039e65
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+221
View File
@@ -0,0 +1,221 @@
using UnityEngine;
using UnityEngine.UI;
using TMPro;
/// <summary>
/// UI 中央调度器:引用所有子面板,绑定 StepManager 事件。
/// 挂在 Canvas GameObject 上。
/// </summary>
public class UIManager : MonoBehaviour
{
[Header("管理器引用")]
[SerializeField] private StepManager _stepManager;
[SerializeField] private InteractionSystem _interactionSystem;
[Header("=== 顶部提示栏 ===")]
[SerializeField] private GameObject _tipPanel;
[SerializeField] private TMP_Text _tipText;
[Header("=== 详细操作说明(甲方补充 - 学习模式) ===")]
[SerializeField] private GameObject _detailPanel;
[SerializeField] private TMP_Text _detailText;
[Header("=== 对话气泡 ===")]
[SerializeField] private GameObject _dialogueBubble;
[SerializeField] private TMP_Text _dialogueText;
[Header("=== 画中画视频 ===")]
[SerializeField] private VideoController _videoController;
[Header("=== 右侧功能按钮 ===")]
[SerializeField] private Button _btnFullScreen;
[SerializeField] private Button _btnPrevious;
[SerializeField] private Button _btnNext;
[SerializeField] private Button _btnSwitchMode;
[SerializeField] private Button _btnReturn;
[SerializeField] private TMP_Text _btnSwitchModeLabel;
[Header("=== 底部进度条 ===")]
[SerializeField] private Slider _progressBar;
[SerializeField] private TMP_Text _progressText;
[Header("=== 弹窗 ===")]
[SerializeField] private ExamPopup _examPopup;
[SerializeField] private ScoreDisplay _scoreDisplay;
[Header("=== 底部主菜单图标 ===")]
[SerializeField] private Button _btnCPR;
[SerializeField] private Button _btnFracture;
[SerializeField] private Button _btnSprain;
[SerializeField] private Button _btnBleeding;
[SerializeField] private Button _btnTransport;
[Header("=== 固定方式选择(仅骨折固定) ===")]
[SerializeField] private GameObject _fixationPanel;
[SerializeField] private Button _btnLimbFixation;
[SerializeField] private Button _btnSplintFixation;
private void Start()
{
BindEvents();
BindButtons();
}
#region
private void BindEvents()
{
if (_stepManager == null) return;
_stepManager.OnStepChanged.AddListener(OnStepChanged);
_stepManager.OnTipChanged.AddListener(UpdateTip);
_stepManager.OnDialogueChanged.AddListener(UpdateDialogue);
_stepManager.OnDetailedContent.AddListener(UpdateDetailContent);
_stepManager.OnExamPopup.AddListener(ShowExamPopup);
_stepManager.OnExperimentComplete.AddListener(OnExperimentComplete);
_stepManager.OnVideoToggle.AddListener(ToggleVideo);
}
private void BindButtons()
{
_btnFullScreen?.onClick.AddListener(ToggleFullScreen);
_btnPrevious?.onClick.AddListener(OnPreviousClicked);
_btnNext?.onClick.AddListener(OnNextClicked);
_btnSwitchMode?.onClick.AddListener(OnSwitchModeClicked);
_btnReturn?.onClick.AddListener(OnReturnClicked);
_btnLimbFixation?.onClick.AddListener(() => _stepManager?.SwitchFixation(FixationMethod.LimbFixation));
_btnSplintFixation?.onClick.AddListener(() => _stepManager?.SwitchFixation(FixationMethod.SplintFixation));
}
#endregion
#region UI
private void OnStepChanged(int index)
{
UpdateProgressBar();
UpdateNavigationButtons();
}
private void UpdateTip(string text)
{
if (_tipPanel != null) _tipPanel.SetActive(!string.IsNullOrEmpty(text));
if (_tipText != null) _tipText.text = text;
}
private void UpdateDialogue(string text)
{
if (_dialogueBubble != null) _dialogueBubble.SetActive(!string.IsNullOrEmpty(text));
if (_dialogueText != null) _dialogueText.text = text;
}
private void UpdateDetailContent(string text)
{
if (_detailPanel != null) _detailPanel.SetActive(!string.IsNullOrEmpty(text));
if (_detailText != null) _detailText.text = text;
}
private void ToggleVideo(string fileName, bool active)
{
if (_videoController == null) return;
if (active && !string.IsNullOrEmpty(fileName))
_videoController.PlayVideo(fileName);
else
_videoController.StopVideo();
}
private void UpdateProgressBar()
{
if (_stepManager == null) return;
int cur = _stepManager.CurrentStepIndex + 1;
int total = _stepManager.TotalSteps;
if (_progressBar != null) _progressBar.value = (float)cur / total;
if (_progressText != null) _progressText.text = $"{cur}/{total}";
}
private void UpdateNavigationButtons()
{
if (_stepManager == null) return;
_btnPrevious.interactable = _stepManager.CurrentStepIndex > 0;
bool isLast = _stepManager.CurrentStepIndex >= _stepManager.TotalSteps - 1;
if (_btnNext != null)
{
var label = _btnNext.GetComponentInChildren<TMP_Text>();
if (label != null) label.text = isLast ? "完成" : "下一步";
}
}
#endregion
#region
private void ShowExamPopup(StepData step)
{
if (_examPopup == null) return;
_examPopup.Show(step, OnExamAnswer);
}
private void OnExamAnswer(float proportion, string feedback)
{
_stepManager?.OnStepInteractionComplete(proportion, feedback);
_stepManager?.NextStep();
}
#endregion
#region
private void OnExperimentComplete()
{
var gm = GameManager.Instance;
if (gm == null) return;
if (gm.CurrentMode == ExperimentMode.Exam)
{
_scoreDisplay?.ShowExamScore();
}
else
{
_scoreDisplay?.ShowNotesOnly();
}
}
#endregion
#region
private void ToggleFullScreen()
{
Screen.fullScreen = !Screen.fullScreen;
}
private void OnPreviousClicked()
{
_stepManager?.PreviousStep();
}
private void OnNextClicked()
{
if (_stepManager.Mode == ExperimentMode.Exam)
{
var step = _stepManager.GetCurrentStep();
if (step != null && step.CompleteType != StepCompleteType.MultipleChoice)
_stepManager.OnStepInteractionComplete(1f);
}
_stepManager.NextStep();
}
private void OnSwitchModeClicked()
{
var newMode = _stepManager.Mode == ExperimentMode.Learn
? ExperimentMode.Exam : ExperimentMode.Learn;
_stepManager.SwitchMode(newMode);
}
private void OnReturnClicked()
{
UnityEngine.SceneManagement.SceneManager.LoadScene("MainMenu");
}
#endregion
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 11edd93e0776546a3b8545535d7dd5e1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+83
View File
@@ -0,0 +1,83 @@
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Video;
/// <summary>
/// 画中画视频控制器:用 VideoPlayer 渲染到 RenderTexture,再赋给 RawImage。
/// 挂在包含 RawImage 和 VideoPlayer 的 GameObject 上。
/// </summary>
[RequireComponent(typeof(RawImage))]
public class VideoController : MonoBehaviour
{
[SerializeField] private VideoPlayer _videoPlayer;
[SerializeField] private RawImage _rawImage;
private RenderTexture _renderTexture;
private bool _isPlaying;
private void Awake()
{
if (_rawImage == null) _rawImage = GetComponent<RawImage>();
if (_videoPlayer == null) _videoPlayer = GetComponentInChildren<VideoPlayer>();
if (_videoPlayer != null)
{
_videoPlayer.loopPointReached += OnVideoEnd;
}
}
/// <summary>播放指定视频文件(StreamingAssets/Videos/ 下)</summary>
public void PlayVideo(string fileName)
{
if (_videoPlayer == null) return;
string path = System.IO.Path.Combine(Application.streamingAssetsPath, "Videos", fileName);
_videoPlayer.url = path;
// 创建 RenderTexture
if (_renderTexture == null)
{
int w = _videoPlayer.targetTexture != null ? _videoPlayer.targetTexture.width : 640;
int h = _videoPlayer.targetTexture != null ? _videoPlayer.targetTexture.height : 360;
_renderTexture = new RenderTexture(w, h, 0);
_videoPlayer.targetTexture = _renderTexture;
if (_rawImage != null) _rawImage.texture = _renderTexture;
}
_videoPlayer.Play();
_isPlaying = true;
gameObject.SetActive(true);
}
public void StopVideo()
{
if (_videoPlayer != null) _videoPlayer.Stop();
_isPlaying = false;
gameObject.SetActive(false);
}
public void PauseVideo()
{
if (_videoPlayer != null) _videoPlayer.Pause();
}
public void ResumeVideo()
{
if (_videoPlayer != null) _videoPlayer.Play();
}
private void OnVideoEnd(VideoPlayer vp)
{
// 真人演示视频播完自动循环
vp.Play();
}
private void OnDestroy()
{
if (_renderTexture != null)
{
_renderTexture.Release();
Destroy(_renderTexture);
}
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3a31c697647c74734811ac323080d78a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,3 @@
using UnityEngine;
/// <summary>Legacy — replaced by VideoController.</summary>
public class VideoPlayerController : MonoBehaviour { }
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4c7b16cd23ebf4299be89ef8311ed579
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+49 -4
View File
@@ -12,8 +12,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: bf2edee5c58d82540a51f03df9d42094, type: 3} m_Script: {fileID: 11500000, guid: bf2edee5c58d82540a51f03df9d42094, type: 3}
m_Name: URP-Balanced m_Name: URP-Balanced
m_EditorClassIdentifier: m_EditorClassIdentifier:
k_AssetVersion: 9 k_AssetVersion: 11
k_AssetPreviousVersion: 9 k_AssetPreviousVersion: 11
m_RendererType: 1 m_RendererType: 1
m_RendererData: {fileID: 0} m_RendererData: {fileID: 0}
m_RendererDataList: m_RendererDataList:
@@ -23,10 +23,16 @@ MonoBehaviour:
m_RequireOpaqueTexture: 0 m_RequireOpaqueTexture: 0
m_OpaqueDownsampling: 1 m_OpaqueDownsampling: 1
m_SupportsTerrainHoles: 1 m_SupportsTerrainHoles: 1
m_StoreActionsOptimization: 0
m_SupportsHDR: 1 m_SupportsHDR: 1
m_HDRColorBufferPrecision: 0
m_MSAA: 1 m_MSAA: 1
m_RenderScale: 1 m_RenderScale: 1
m_UpscalingFilter: 0
m_FsrOverrideSharpness: 0
m_FsrSharpness: 0.92
m_EnableLODCrossFade: 1
m_LODCrossFadeDitheringType: 1
m_ShEvalMode: 0
m_MainLightRenderingMode: 1 m_MainLightRenderingMode: 1
m_MainLightShadowsSupported: 1 m_MainLightShadowsSupported: 1
m_MainLightShadowmapResolution: 1024 m_MainLightShadowmapResolution: 1024
@@ -47,23 +53,62 @@ MonoBehaviour:
m_CascadeBorder: 0.1 m_CascadeBorder: 0.1
m_ShadowDepthBias: 1 m_ShadowDepthBias: 1
m_ShadowNormalBias: 1 m_ShadowNormalBias: 1
m_AnyShadowsSupported: 1
m_SoftShadowsSupported: 1 m_SoftShadowsSupported: 1
m_ConservativeEnclosingSphere: 0
m_NumIterationsEnclosingSphere: 64
m_SoftShadowQuality: 2
m_AdditionalLightsCookieResolution: 512 m_AdditionalLightsCookieResolution: 512
m_AdditionalLightsCookieFormat: 1 m_AdditionalLightsCookieFormat: 1
m_UseSRPBatcher: 1 m_UseSRPBatcher: 1
m_SupportsDynamicBatching: 0 m_SupportsDynamicBatching: 0
m_MixedLightingSupported: 1 m_MixedLightingSupported: 1
m_SupportsLightCookies: 1
m_SupportsLightLayers: 0 m_SupportsLightLayers: 0
m_DebugLevel: 0 m_DebugLevel: 0
m_StoreActionsOptimization: 0
m_EnableRenderGraph: 0
m_UseAdaptivePerformance: 1 m_UseAdaptivePerformance: 1
m_ColorGradingMode: 0 m_ColorGradingMode: 0
m_ColorGradingLutSize: 32 m_ColorGradingLutSize: 32
m_UseFastSRGBLinearConversion: 0 m_UseFastSRGBLinearConversion: 0
m_SupportDataDrivenLensFlare: 1
m_ShadowType: 1 m_ShadowType: 1
m_LocalShadowsSupported: 0 m_LocalShadowsSupported: 0
m_LocalShadowsAtlasResolution: 256 m_LocalShadowsAtlasResolution: 256
m_MaxPixelLights: 0 m_MaxPixelLights: 0
m_ShadowAtlasResolution: 256 m_ShadowAtlasResolution: 256
m_ShaderVariantLogLevel: 0
m_VolumeFrameworkUpdateMode: 0 m_VolumeFrameworkUpdateMode: 0
m_Textures:
blueNoise64LTex: {fileID: 2800000, guid: e3d24661c1e055f45a7560c033dbb837, type: 3}
bayerMatrixTex: {fileID: 2800000, guid: f9ee4ed84c1d10c49aabb9b210b0fc44, type: 3}
m_PrefilteringModeMainLightShadows: 1
m_PrefilteringModeAdditionalLight: 4
m_PrefilteringModeAdditionalLightShadows: 1
m_PrefilterXRKeywords: 0
m_PrefilteringModeForwardPlus: 1
m_PrefilteringModeDeferredRendering: 1
m_PrefilteringModeScreenSpaceOcclusion: 1
m_PrefilterDebugKeywords: 0
m_PrefilterWriteRenderingLayers: 0
m_PrefilterHDROutput: 0
m_PrefilterSSAODepthNormals: 0
m_PrefilterSSAOSourceDepthLow: 0
m_PrefilterSSAOSourceDepthMedium: 0
m_PrefilterSSAOSourceDepthHigh: 0
m_PrefilterSSAOInterleaved: 0
m_PrefilterSSAOBlueNoise: 0
m_PrefilterSSAOSampleCountLow: 0
m_PrefilterSSAOSampleCountMedium: 0
m_PrefilterSSAOSampleCountHigh: 0
m_PrefilterDBufferMRT1: 0
m_PrefilterDBufferMRT2: 0
m_PrefilterDBufferMRT3: 0
m_PrefilterSoftShadowsQualityLow: 0
m_PrefilterSoftShadowsQualityMedium: 0
m_PrefilterSoftShadowsQualityHigh: 0
m_PrefilterSoftShadows: 0
m_PrefilterScreenCoord: 0
m_PrefilterNativeRenderPass: 0
m_ShaderVariantLogLevel: 0
m_ShadowCascades: 0 m_ShadowCascades: 0
+33 -1
View File
@@ -13,7 +13,7 @@ MonoBehaviour:
m_Name: URP-HighFidelity m_Name: URP-HighFidelity
m_EditorClassIdentifier: m_EditorClassIdentifier:
k_AssetVersion: 11 k_AssetVersion: 11
k_AssetPreviousVersion: 10 k_AssetPreviousVersion: 11
m_RendererType: 1 m_RendererType: 1
m_RendererData: {fileID: 0} m_RendererData: {fileID: 0}
m_RendererDataList: m_RendererDataList:
@@ -32,6 +32,7 @@ MonoBehaviour:
m_FsrSharpness: 0.92 m_FsrSharpness: 0.92
m_EnableLODCrossFade: 1 m_EnableLODCrossFade: 1
m_LODCrossFadeDitheringType: 1 m_LODCrossFadeDitheringType: 1
m_ShEvalMode: 0
m_MainLightRenderingMode: 1 m_MainLightRenderingMode: 1
m_MainLightShadowsSupported: 1 m_MainLightShadowsSupported: 1
m_MainLightShadowmapResolution: 4096 m_MainLightShadowmapResolution: 4096
@@ -52,9 +53,11 @@ MonoBehaviour:
m_CascadeBorder: 0.1 m_CascadeBorder: 0.1
m_ShadowDepthBias: 1 m_ShadowDepthBias: 1
m_ShadowNormalBias: 1 m_ShadowNormalBias: 1
m_AnyShadowsSupported: 1
m_SoftShadowsSupported: 1 m_SoftShadowsSupported: 1
m_ConservativeEnclosingSphere: 0 m_ConservativeEnclosingSphere: 0
m_NumIterationsEnclosingSphere: 64 m_NumIterationsEnclosingSphere: 64
m_SoftShadowQuality: 2
m_AdditionalLightsCookieResolution: 4096 m_AdditionalLightsCookieResolution: 4096
m_AdditionalLightsCookieFormat: 4 m_AdditionalLightsCookieFormat: 4
m_UseSRPBatcher: 1 m_UseSRPBatcher: 1
@@ -69,6 +72,7 @@ MonoBehaviour:
m_ColorGradingMode: 0 m_ColorGradingMode: 0
m_ColorGradingLutSize: 32 m_ColorGradingLutSize: 32
m_UseFastSRGBLinearConversion: 0 m_UseFastSRGBLinearConversion: 0
m_SupportDataDrivenLensFlare: 1
m_ShadowType: 1 m_ShadowType: 1
m_LocalShadowsSupported: 0 m_LocalShadowsSupported: 0
m_LocalShadowsAtlasResolution: 256 m_LocalShadowsAtlasResolution: 256
@@ -78,5 +82,33 @@ MonoBehaviour:
m_Textures: m_Textures:
blueNoise64LTex: {fileID: 2800000, guid: e3d24661c1e055f45a7560c033dbb837, type: 3} blueNoise64LTex: {fileID: 2800000, guid: e3d24661c1e055f45a7560c033dbb837, type: 3}
bayerMatrixTex: {fileID: 2800000, guid: f9ee4ed84c1d10c49aabb9b210b0fc44, type: 3} bayerMatrixTex: {fileID: 2800000, guid: f9ee4ed84c1d10c49aabb9b210b0fc44, type: 3}
m_PrefilteringModeMainLightShadows: 1
m_PrefilteringModeAdditionalLight: 4
m_PrefilteringModeAdditionalLightShadows: 1
m_PrefilterXRKeywords: 0
m_PrefilteringModeForwardPlus: 1
m_PrefilteringModeDeferredRendering: 1
m_PrefilteringModeScreenSpaceOcclusion: 1
m_PrefilterDebugKeywords: 0
m_PrefilterWriteRenderingLayers: 0
m_PrefilterHDROutput: 0
m_PrefilterSSAODepthNormals: 0
m_PrefilterSSAOSourceDepthLow: 0
m_PrefilterSSAOSourceDepthMedium: 0
m_PrefilterSSAOSourceDepthHigh: 0
m_PrefilterSSAOInterleaved: 0
m_PrefilterSSAOBlueNoise: 0
m_PrefilterSSAOSampleCountLow: 0
m_PrefilterSSAOSampleCountMedium: 0
m_PrefilterSSAOSampleCountHigh: 0
m_PrefilterDBufferMRT1: 0
m_PrefilterDBufferMRT2: 0
m_PrefilterDBufferMRT3: 0
m_PrefilterSoftShadowsQualityLow: 0
m_PrefilterSoftShadowsQualityMedium: 0
m_PrefilterSoftShadowsQualityHigh: 0
m_PrefilterSoftShadows: 0
m_PrefilterScreenCoord: 0
m_PrefilterNativeRenderPass: 0
m_ShaderVariantLogLevel: 0 m_ShaderVariantLogLevel: 0
m_ShadowCascades: 1 m_ShadowCascades: 1
+49 -4
View File
@@ -12,8 +12,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: bf2edee5c58d82540a51f03df9d42094, type: 3} m_Script: {fileID: 11500000, guid: bf2edee5c58d82540a51f03df9d42094, type: 3}
m_Name: URP-Performant m_Name: URP-Performant
m_EditorClassIdentifier: m_EditorClassIdentifier:
k_AssetVersion: 9 k_AssetVersion: 11
k_AssetPreviousVersion: 9 k_AssetPreviousVersion: 11
m_RendererType: 1 m_RendererType: 1
m_RendererData: {fileID: 0} m_RendererData: {fileID: 0}
m_RendererDataList: m_RendererDataList:
@@ -23,10 +23,16 @@ MonoBehaviour:
m_RequireOpaqueTexture: 0 m_RequireOpaqueTexture: 0
m_OpaqueDownsampling: 1 m_OpaqueDownsampling: 1
m_SupportsTerrainHoles: 1 m_SupportsTerrainHoles: 1
m_StoreActionsOptimization: 0
m_SupportsHDR: 0 m_SupportsHDR: 0
m_HDRColorBufferPrecision: 0
m_MSAA: 1 m_MSAA: 1
m_RenderScale: 1 m_RenderScale: 1
m_UpscalingFilter: 0
m_FsrOverrideSharpness: 0
m_FsrSharpness: 0.92
m_EnableLODCrossFade: 1
m_LODCrossFadeDitheringType: 1
m_ShEvalMode: 0
m_MainLightRenderingMode: 1 m_MainLightRenderingMode: 1
m_MainLightShadowsSupported: 0 m_MainLightShadowsSupported: 0
m_MainLightShadowmapResolution: 1024 m_MainLightShadowmapResolution: 1024
@@ -47,23 +53,62 @@ MonoBehaviour:
m_CascadeBorder: 0.1 m_CascadeBorder: 0.1
m_ShadowDepthBias: 1 m_ShadowDepthBias: 1
m_ShadowNormalBias: 1 m_ShadowNormalBias: 1
m_AnyShadowsSupported: 1
m_SoftShadowsSupported: 0 m_SoftShadowsSupported: 0
m_ConservativeEnclosingSphere: 0
m_NumIterationsEnclosingSphere: 64
m_SoftShadowQuality: 2
m_AdditionalLightsCookieResolution: 2048 m_AdditionalLightsCookieResolution: 2048
m_AdditionalLightsCookieFormat: 3 m_AdditionalLightsCookieFormat: 3
m_UseSRPBatcher: 1 m_UseSRPBatcher: 1
m_SupportsDynamicBatching: 0 m_SupportsDynamicBatching: 0
m_MixedLightingSupported: 1 m_MixedLightingSupported: 1
m_SupportsLightCookies: 1
m_SupportsLightLayers: 0 m_SupportsLightLayers: 0
m_DebugLevel: 0 m_DebugLevel: 0
m_StoreActionsOptimization: 0
m_EnableRenderGraph: 0
m_UseAdaptivePerformance: 1 m_UseAdaptivePerformance: 1
m_ColorGradingMode: 0 m_ColorGradingMode: 0
m_ColorGradingLutSize: 16 m_ColorGradingLutSize: 16
m_UseFastSRGBLinearConversion: 0 m_UseFastSRGBLinearConversion: 0
m_SupportDataDrivenLensFlare: 1
m_ShadowType: 1 m_ShadowType: 1
m_LocalShadowsSupported: 0 m_LocalShadowsSupported: 0
m_LocalShadowsAtlasResolution: 256 m_LocalShadowsAtlasResolution: 256
m_MaxPixelLights: 0 m_MaxPixelLights: 0
m_ShadowAtlasResolution: 256 m_ShadowAtlasResolution: 256
m_ShaderVariantLogLevel: 0
m_VolumeFrameworkUpdateMode: 0 m_VolumeFrameworkUpdateMode: 0
m_Textures:
blueNoise64LTex: {fileID: 2800000, guid: e3d24661c1e055f45a7560c033dbb837, type: 3}
bayerMatrixTex: {fileID: 2800000, guid: f9ee4ed84c1d10c49aabb9b210b0fc44, type: 3}
m_PrefilteringModeMainLightShadows: 1
m_PrefilteringModeAdditionalLight: 4
m_PrefilteringModeAdditionalLightShadows: 1
m_PrefilterXRKeywords: 0
m_PrefilteringModeForwardPlus: 1
m_PrefilteringModeDeferredRendering: 1
m_PrefilteringModeScreenSpaceOcclusion: 1
m_PrefilterDebugKeywords: 0
m_PrefilterWriteRenderingLayers: 0
m_PrefilterHDROutput: 0
m_PrefilterSSAODepthNormals: 0
m_PrefilterSSAOSourceDepthLow: 0
m_PrefilterSSAOSourceDepthMedium: 0
m_PrefilterSSAOSourceDepthHigh: 0
m_PrefilterSSAOInterleaved: 0
m_PrefilterSSAOBlueNoise: 0
m_PrefilterSSAOSampleCountLow: 0
m_PrefilterSSAOSampleCountMedium: 0
m_PrefilterSSAOSampleCountHigh: 0
m_PrefilterDBufferMRT1: 0
m_PrefilterDBufferMRT2: 0
m_PrefilterDBufferMRT3: 0
m_PrefilterSoftShadowsQualityLow: 0
m_PrefilterSoftShadowsQualityMedium: 0
m_PrefilterSoftShadowsQualityHigh: 0
m_PrefilterSoftShadows: 0
m_PrefilterScreenCoord: 0
m_PrefilterNativeRenderPass: 0
m_ShaderVariantLogLevel: 0
m_ShadowCascades: 0 m_ShadowCascades: 0
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b9a81bc6c945d4299ba496b54f270aee
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 645c38bb4de3549b4857a287d83f3dc6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ba062aa6c92b140379dbc06b43dd3b9b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+9
View File
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 8a0c9218a650547d98138cd835033977
folderAsset: yes
timeCreated: 1484670163
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

+134
View File
@@ -0,0 +1,134 @@
fileFormatVersion: 2
guid: 727a75301c3d24613a3ebcec4a24c2c8
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 0
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: iPhone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
+654
View File
@@ -0,0 +1,654 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &1
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12004, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_PixelRect:
serializedVersion: 2
x: 0
y: 45
width: 1666
height: 958
m_ShowMode: 4
m_Title:
m_RootView: {fileID: 6}
m_MinSize: {x: 950, y: 542}
m_MaxSize: {x: 10000, y: 10000}
--- !u!114 &2
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 0
y: 466
width: 290
height: 442
m_MinSize: {x: 234, y: 271}
m_MaxSize: {x: 10004, y: 10021}
m_ActualView: {fileID: 14}
m_Panes:
- {fileID: 14}
m_Selected: 0
m_LastSelected: 0
--- !u!114 &3
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children:
- {fileID: 4}
- {fileID: 2}
m_Position:
serializedVersion: 2
x: 973
y: 0
width: 290
height: 908
m_MinSize: {x: 234, y: 492}
m_MaxSize: {x: 10004, y: 14042}
vertical: 1
controlID: 226
--- !u!114 &4
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 0
y: 0
width: 290
height: 466
m_MinSize: {x: 204, y: 221}
m_MaxSize: {x: 4004, y: 4021}
m_ActualView: {fileID: 17}
m_Panes:
- {fileID: 17}
m_Selected: 0
m_LastSelected: 0
--- !u!114 &5
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 0
y: 466
width: 973
height: 442
m_MinSize: {x: 202, y: 221}
m_MaxSize: {x: 4002, y: 4021}
m_ActualView: {fileID: 15}
m_Panes:
- {fileID: 15}
m_Selected: 0
m_LastSelected: 0
--- !u!114 &6
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12008, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children:
- {fileID: 7}
- {fileID: 8}
- {fileID: 9}
m_Position:
serializedVersion: 2
x: 0
y: 0
width: 1666
height: 958
m_MinSize: {x: 950, y: 542}
m_MaxSize: {x: 10000, y: 10000}
--- !u!114 &7
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12011, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 0
y: 0
width: 1666
height: 30
m_MinSize: {x: 0, y: 0}
m_MaxSize: {x: 0, y: 0}
m_LastLoadedLayoutName: Tutorial
--- !u!114 &8
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children:
- {fileID: 10}
- {fileID: 3}
- {fileID: 11}
m_Position:
serializedVersion: 2
x: 0
y: 30
width: 1666
height: 908
m_MinSize: {x: 713, y: 492}
m_MaxSize: {x: 18008, y: 14042}
vertical: 0
controlID: 74
--- !u!114 &9
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12042, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 0
y: 938
width: 1666
height: 20
m_MinSize: {x: 0, y: 0}
m_MaxSize: {x: 0, y: 0}
--- !u!114 &10
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children:
- {fileID: 12}
- {fileID: 5}
m_Position:
serializedVersion: 2
x: 0
y: 0
width: 973
height: 908
m_MinSize: {x: 202, y: 442}
m_MaxSize: {x: 4002, y: 8042}
vertical: 1
controlID: 75
--- !u!114 &11
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 1263
y: 0
width: 403
height: 908
m_MinSize: {x: 277, y: 71}
m_MaxSize: {x: 4002, y: 4021}
m_ActualView: {fileID: 13}
m_Panes:
- {fileID: 13}
m_Selected: 0
m_LastSelected: 0
--- !u!114 &12
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 0
y: 0
width: 973
height: 466
m_MinSize: {x: 202, y: 221}
m_MaxSize: {x: 4002, y: 4021}
m_ActualView: {fileID: 16}
m_Panes:
- {fileID: 16}
m_Selected: 0
m_LastSelected: 0
--- !u!114 &13
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12019, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_AutoRepaintOnSceneChange: 0
m_MinSize: {x: 275, y: 50}
m_MaxSize: {x: 4000, y: 4000}
m_TitleContent:
m_Text: Inspector
m_Image: {fileID: -6905738622615590433, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_DepthBufferBits: 0
m_Pos:
serializedVersion: 2
x: 2
y: 19
width: 401
height: 887
m_ScrollPosition: {x: 0, y: 0}
m_InspectorMode: 0
m_PreviewResizer:
m_CachedPref: -160
m_ControlHash: -371814159
m_PrefName: Preview_InspectorPreview
m_PreviewWindow: {fileID: 0}
--- !u!114 &14
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12014, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_AutoRepaintOnSceneChange: 0
m_MinSize: {x: 230, y: 250}
m_MaxSize: {x: 10000, y: 10000}
m_TitleContent:
m_Text: Project
m_Image: {fileID: -7501376956915960154, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_DepthBufferBits: 0
m_Pos:
serializedVersion: 2
x: 2
y: 19
width: 286
height: 421
m_SearchFilter:
m_NameFilter:
m_ClassNames: []
m_AssetLabels: []
m_AssetBundleNames: []
m_VersionControlStates: []
m_ReferencingInstanceIDs:
m_ScenePaths: []
m_ShowAllHits: 0
m_SearchArea: 0
m_Folders:
- Assets
m_ViewMode: 0
m_StartGridSize: 64
m_LastFolders:
- Assets
m_LastFoldersGridSize: -1
m_LastProjectPath: /Users/danielbrauer/Unity Projects/New Unity Project 47
m_IsLocked: 0
m_FolderTreeState:
scrollPos: {x: 0, y: 0}
m_SelectedIDs: ee240000
m_LastClickedID: 9454
m_ExpandedIDs: ee24000000ca9a3bffffff7f
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
m_OriginalName:
m_EditFieldRect:
serializedVersion: 2
x: 0
y: 0
width: 0
height: 0
m_UserData: 0
m_IsWaitingForDelay: 0
m_IsRenaming: 0
m_OriginalEventType: 11
m_IsRenamingFilename: 1
m_ClientGUIView: {fileID: 0}
m_SearchString:
m_CreateAssetUtility:
m_EndAction: {fileID: 0}
m_InstanceID: 0
m_Path:
m_Icon: {fileID: 0}
m_ResourceFile:
m_AssetTreeState:
scrollPos: {x: 0, y: 0}
m_SelectedIDs: 68fbffff
m_LastClickedID: 0
m_ExpandedIDs: ee240000
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
m_OriginalName:
m_EditFieldRect:
serializedVersion: 2
x: 0
y: 0
width: 0
height: 0
m_UserData: 0
m_IsWaitingForDelay: 0
m_IsRenaming: 0
m_OriginalEventType: 11
m_IsRenamingFilename: 1
m_ClientGUIView: {fileID: 0}
m_SearchString:
m_CreateAssetUtility:
m_EndAction: {fileID: 0}
m_InstanceID: 0
m_Path:
m_Icon: {fileID: 0}
m_ResourceFile:
m_ListAreaState:
m_SelectedInstanceIDs: 68fbffff
m_LastClickedInstanceID: -1176
m_HadKeyboardFocusLastEvent: 0
m_ExpandedInstanceIDs: c6230000
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
m_OriginalName:
m_EditFieldRect:
serializedVersion: 2
x: 0
y: 0
width: 0
height: 0
m_UserData: 0
m_IsWaitingForDelay: 0
m_IsRenaming: 0
m_OriginalEventType: 11
m_IsRenamingFilename: 1
m_ClientGUIView: {fileID: 0}
m_CreateAssetUtility:
m_EndAction: {fileID: 0}
m_InstanceID: 0
m_Path:
m_Icon: {fileID: 0}
m_ResourceFile:
m_NewAssetIndexInList: -1
m_ScrollPosition: {x: 0, y: 0}
m_GridSize: 64
m_DirectoriesAreaWidth: 110
--- !u!114 &15
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12015, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_AutoRepaintOnSceneChange: 1
m_MinSize: {x: 200, y: 200}
m_MaxSize: {x: 4000, y: 4000}
m_TitleContent:
m_Text: Game
m_Image: {fileID: -2087823869225018852, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_DepthBufferBits: 32
m_Pos:
serializedVersion: 2
x: 0
y: 19
width: 971
height: 421
m_MaximizeOnPlay: 0
m_Gizmos: 0
m_Stats: 0
m_SelectedSizes: 00000000000000000000000000000000000000000000000000000000000000000000000000000000
m_TargetDisplay: 0
m_ZoomArea:
m_HRangeLocked: 0
m_VRangeLocked: 0
m_HBaseRangeMin: -242.75
m_HBaseRangeMax: 242.75
m_VBaseRangeMin: -101
m_VBaseRangeMax: 101
m_HAllowExceedBaseRangeMin: 1
m_HAllowExceedBaseRangeMax: 1
m_VAllowExceedBaseRangeMin: 1
m_VAllowExceedBaseRangeMax: 1
m_ScaleWithWindow: 0
m_HSlider: 0
m_VSlider: 0
m_IgnoreScrollWheelUntilClicked: 0
m_EnableMouseInput: 1
m_EnableSliderZoom: 0
m_UniformScale: 1
m_UpDirection: 1
m_DrawArea:
serializedVersion: 2
x: 0
y: 17
width: 971
height: 404
m_Scale: {x: 2, y: 2}
m_Translation: {x: 485.5, y: 202}
m_MarginLeft: 0
m_MarginRight: 0
m_MarginTop: 0
m_MarginBottom: 0
m_LastShownAreaInsideMargins:
serializedVersion: 2
x: -242.75
y: -101
width: 485.5
height: 202
m_MinimalGUI: 1
m_defaultScale: 2
m_TargetTexture: {fileID: 0}
m_CurrentColorSpace: 0
m_LastWindowPixelSize: {x: 1942, y: 842}
m_ClearInEditMode: 1
m_NoCameraWarning: 1
m_LowResolutionForAspectRatios: 01000000000100000100
--- !u!114 &16
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12013, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_AutoRepaintOnSceneChange: 1
m_MinSize: {x: 200, y: 200}
m_MaxSize: {x: 4000, y: 4000}
m_TitleContent:
m_Text: Scene
m_Image: {fileID: 2318424515335265636, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_DepthBufferBits: 32
m_Pos:
serializedVersion: 2
x: 0
y: 19
width: 971
height: 445
m_SceneLighting: 1
lastFramingTime: 0
m_2DMode: 0
m_isRotationLocked: 0
m_AudioPlay: 0
m_Position:
m_Target: {x: 0, y: 0, z: 0}
speed: 2
m_Value: {x: 0, y: 0, z: 0}
m_RenderMode: 0
m_ValidateTrueMetals: 0
m_SceneViewState:
showFog: 1
showMaterialUpdate: 0
showSkybox: 1
showFlares: 1
showImageEffects: 1
grid:
xGrid:
m_Target: 0
speed: 2
m_Value: 0
yGrid:
m_Target: 1
speed: 2
m_Value: 1
zGrid:
m_Target: 0
speed: 2
m_Value: 0
m_Rotation:
m_Target: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226}
speed: 2
m_Value: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226}
m_Size:
m_Target: 10
speed: 2
m_Value: 10
m_Ortho:
m_Target: 0
speed: 2
m_Value: 0
m_LastSceneViewRotation: {x: 0, y: 0, z: 0, w: 0}
m_LastSceneViewOrtho: 0
m_ReplacementShader: {fileID: 0}
m_ReplacementString:
m_LastLockedObject: {fileID: 0}
m_ViewIsLockedToObject: 0
--- !u!114 &17
MonoBehaviour:
m_ObjectHideFlags: 52
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12061, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_AutoRepaintOnSceneChange: 0
m_MinSize: {x: 200, y: 200}
m_MaxSize: {x: 4000, y: 4000}
m_TitleContent:
m_Text: Hierarchy
m_Image: {fileID: -590624980919486359, guid: 0000000000000000d000000000000000,
type: 0}
m_Tooltip:
m_DepthBufferBits: 0
m_Pos:
serializedVersion: 2
x: 2
y: 19
width: 286
height: 445
m_TreeViewState:
scrollPos: {x: 0, y: 0}
m_SelectedIDs: 68fbffff
m_LastClickedID: -1176
m_ExpandedIDs: 7efbffff00000000
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
m_OriginalName:
m_EditFieldRect:
serializedVersion: 2
x: 0
y: 0
width: 0
height: 0
m_UserData: 0
m_IsWaitingForDelay: 0
m_IsRenaming: 0
m_OriginalEventType: 11
m_IsRenamingFilename: 0
m_ClientGUIView: {fileID: 0}
m_SearchString:
m_ExpandedScenes:
-
m_CurrenRootInstanceID: 0
m_Locked: 0
m_CurrentSortingName: TransformSorting
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: eabc9546105bf4accac1fd62a63e88e6
timeCreated: 1487337779
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+9
View File
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 5a9bcd70e6a4b4b05badaa72e827d8e0
folderAsset: yes
timeCreated: 1475835190
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More