@ -53,12 +53,13 @@ public class EvacuationPanel : MonoBehaviour
[Header("可分配列表")]
List < int > nonZeroAreas = new List < int > ( ) ;
Dictionary < int , PersonnelItem > personnelItemsDict = new Dictionary < int , PersonnelItem > ( ) ;
private HashSet < int > excludedAreas = new HashSet < int > ( ) ; // 被清空的区域 ID
Dictionary < int , PersonnelItem > personnelItemsDict = new Dictionary < int , PersonnelItem > ( ) ; //储存分配结果
//private HashSet<int> excludedAreas = new HashSet<int>(); // 被清空的区域 ID
public SelectScenePanel selectScene ;
private HashSet < int > clearedAreas = new HashSet < int > ( ) ;
// 保存分配结果的字典
public Dictionary < int , int > allocatedPeople = new Dictionary < int , int > ( ) ;
public List < int > clearRegion = new List < int > ( ) ; //被清除的区域
// Start is called before the first frame update
void Start ( )
{
@ -85,13 +86,6 @@ public class EvacuationPanel : MonoBehaviour
CheckInput ( StuCountInputField . text ) ;
IsRedistribution ( ) ;
IsOpen ( selectScene . difficultyId ) ;
if ( Input . GetKey ( KeyCode . A ) )
{
foreach ( var item in personnelItems )
{
Debug . Log ( item . sceneId ) ;
}
}
}
//上传数据
public void totalSubmit ( )
@ -140,30 +134,31 @@ public class EvacuationPanel : MonoBehaviour
// 获取输入的总人数
int count = int . Parse ( StuCountInputField . text ) ; // 总人数
StuCountInputField . text = "" ;
// 使用分配方法
foreach ( var item in personnelItems )
{
personnelItemsDict [ item . sceneId ] = item ; // 使用 sceneId 作为键
}
// 将 nonZeroAreas 转换为场景 ID 数组
int [ ] sceneIds = nonZeroAreas . ToArray ( ) ;
// 调用分配方法
var result = DistributePeopleWithBalance ( sceneIds , personnelItemsDict , count ) ;
// 保存并使用分配结果
allocatedPeople = result ; // 你已经保存了分配结果在 allocatedPeople 字典中
allocatedPeople = result ;
// 更新 UI 显示
foreach ( var kvp in result )
{
if ( personnelItemsDict . ContainsKey ( kvp . Key ) )
{
personnelItemsDict [ kvp . Key ] . SetInfo ( kvp . Value . ToString ( ) ) ; // 更新UI
personnelItemsDict [ kvp . Key ] . NpcNum = kvp . Value ;
personnelItemsDict [ kvp . Key ] . personnelImage . gameObject . SetActive ( true ) ;
Debug . LogError ( ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+++++++++++++++++++Key" + kvp . Key ) ;
Debug . LogError ( ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+++++++++++++++++++Num" + kvp . Value ) ;
}
}
}
//分配Npc
public Dictionary < int , int > DistributePeopleWithBalance ( int [ ] scenes , Dictionary < int , PersonnelItem > personnelItemsDict , int totalPeople )
{
// 1. 计算当前每个区域的总人数(初始人数 + 已分配人数)
@ -173,19 +168,16 @@ public class EvacuationPanel : MonoBehaviour
// 如果 personnelItemsDict 中包含该场景,取其初始人数;否则设为 0
if ( personnelItemsDict . ContainsKey ( scene ) )
{
totalPeoplePerScene [ scene ] = personnelItemsDict [ scene ] . Num ; // 初始人数
totalPeoplePerScene [ scene ] = personnelItemsDict [ scene ] . Num +personnelItemsDict [ scene ] . NpcNum ; // 初始人数
}
else
{
totalPeoplePerScene [ scene ] = 0 ;
}
// Debug 输出每个场景的初始人数
Debug . Log ( $"Scene {scene}: Initial People = {totalPeoplePerScene[scene]}" ) ;
}
// 保存初始人数以便后续计算
Dictionary < int , int > initialPeoplePerScene = new Dictionary < int , int > ( totalPeoplePerScene ) ;
// 2. 分配剩余人数
int remainingPeople = totalPeople ;
while ( remainingPeople > 0 )
@ -193,7 +185,6 @@ public class EvacuationPanel : MonoBehaviour
// 找出当前人数最少的区域
int minScene = - 1 ; // 用于记录人数最少的场景 ID
int minPeople = int . MaxValue ;
foreach ( var scene in totalPeoplePerScene )
{
if ( scene . Value < minPeople )
@ -202,7 +193,6 @@ public class EvacuationPanel : MonoBehaviour
minScene = scene . Key ;
}
}
// 分配一个 NPC 到人数最少的区域
if ( minScene ! = - 1 ) // 确保找到有效的场景
{
@ -214,7 +204,6 @@ public class EvacuationPanel : MonoBehaviour
break ; // 如果没有找到有效的场景,终止分配
}
}
// 3. 计算分配结果,减去初始人数
Dictionary < int , int > allocatedPeople = new Dictionary < int , int > ( ) ;
foreach ( var scene in totalPeoplePerScene )
@ -222,31 +211,11 @@ public class EvacuationPanel : MonoBehaviour
int initialPeople = initialPeoplePerScene . GetValueOrDefault ( scene . Key , 0 ) ;
allocatedPeople [ scene . Key ] = scene . Value - initialPeople ; // 分配人数 = 总人数 - 初始人数
}
// 保存分配结果
this . allocatedPeople = allocatedPeople ;
return allocatedPeople ;
}
//清除
//private void ClearData()
//{
// jc.classItem.isSet = false;
// foreach (var item in classItemList)
// {
// item.isSet = false;
// item.setClassItem("");
// }
// jc.classMate.isBeSet = false;
// foreach(var item in jc.classMateList)
// {
// item.isBeSet = false;
// item.setName();
// }
//}
//判断NPC的比例字段, 列出分配比例不为0的所有区域名称。
public List < int > GetNonZeroNpcRatioAreas ( )
{
@ -302,7 +271,6 @@ public class EvacuationPanel : MonoBehaviour
// 返回符合条件的区域 ID 列表
return nonZeroAreas ;
}
//设置左侧场景显示
public void SetPersonnel ( )
{
@ -319,7 +287,6 @@ public class EvacuationPanel : MonoBehaviour
foreach ( var sceneInfo in sceneEntry . Value )
{
LocationData area = js . GetAreaDateById ( int . Parse ( sceneInfo . sceneId ) ) ;
// 如果NpcRatio不为"-1"表示该场景有效
if ( area . NpcRatio ! = "-1" )
{
@ -339,29 +306,24 @@ public class EvacuationPanel : MonoBehaviour
personnelItem . sceneText . text = sceneEntry . Key ;
personnelItem . sceneId = area . ID ;
personnelItem . Num = 1 ; // 设置初始值为 1
// 点击事件监听
button . onClick . AddListener ( ( ) = >
{
// 标记当前选择的区域
OnSceneItemClicked ( item , Color . yellow , selectedScene ) ;
// 如果被点击的区域已经有人员
if ( personnelItem . N um > 0 )
if ( personnelItem . N pcN um > 0 )
{
redistributeBtn . onClick . AddListener ( ( ) = > {
// 清除选定区域的人员数据
RedistributeLogic ( personnelItem . sceneId , personnelItem . N um) ;
RedistributeLogic ( personnelItem . sceneId , personnelItem . N pcN um) ;
} ) ;
}
// 清空现有场景下的所有人员UI
foreach ( Transform child in sceneCount )
{
Destroy ( child . gameObject ) ;
}
// 执行后续的场景级别配置
LocationData locationData = js . GetAreaDateById ( personnelItem . sceneId ) ;
if ( locationData . Level . ToString ( ) ! = "0" )
@ -378,7 +340,6 @@ public class EvacuationPanel : MonoBehaviour
classItem . classname . text = locationData . Level . ToString ( ) ;
}
} ) ;
personnelItems . Add ( personnelItem ) ;
}
}
@ -465,17 +426,17 @@ public class EvacuationPanel : MonoBehaviour
// 清除当前选中区域的人员数据
PersonnelItem excludedItem = personnelItemsDict [ excludedSceneId ] ;
excludedItem . N um = 0 ;
excludedItem . N pcN um = 0 ;
excludedItem . SetInfo ( "" ) ; // 更新 UI 显示
excludedItem . personnelImage . gameObject . SetActive ( false ) ; // 隐藏图标
excludedAreas . Add ( excludedSceneId ) ; // 记录清空的区域 ID
clearRegion . Add ( excludedSceneId ) ; // 记录清空的区域 ID
Debug . Log ( $"Cleared NPCs from Scene ID: {excludedSceneId}" ) ;
// 准备有效分配区域列表(排除被清空的区域)
List < int > validAreas = new List < int > ( ) ;
foreach ( var kvp in personnelItemsDict )
{
if ( ! excludedAreas . Contains ( kvp . Key ) ) // 排除清空的区域
if ( ! clearRegion . Contains ( kvp . Key ) ) // 排除清空的区域
{
validAreas . Add ( kvp . Key ) ;
}
@ -486,11 +447,12 @@ public class EvacuationPanel : MonoBehaviour
Debug . LogWarning ( "No valid areas available for redistribution." ) ;
return ;
}
// 将有效区域转换为数组
int [ ] validSceneIds = validAreas . ToArray ( ) ;
// 调用分配方法,将清空区域的 NPC 分配到有效区域
foreach ( int sceneId in validSceneIds )
{
Debug . Log ( "Valid Scene ID: " + sceneId ) ;
}
var redistributionResult = DistributePeopleWithBalance ( validSceneIds , personnelItemsDict , totalRedistributePeople ) ;
// 更新分配结果到 UI
@ -499,8 +461,8 @@ public class EvacuationPanel : MonoBehaviour
if ( personnelItemsDict . ContainsKey ( kvp . Key ) )
{
PersonnelItem redistributedItem = personnelItemsDict [ kvp . Key ] ;
redistributedItem . N um + = kvp . Value ; // 更新人数
redistributedItem . SetInfo ( redistributedItem . N um. ToString ( ) ) ; // 更新 UI 显示
redistributedItem . N pcN um + = kvp . Value ; // 更新人数
redistributedItem . SetInfo ( redistributedItem . N pcN um. ToString ( ) ) ; // 更新 UI 显示
redistributedItem . personnelImage . gameObject . SetActive ( true ) ; // 确保图标显示
redistributedItem . personnelNum . gameObject . SetActive ( true ) ; // 确保图标显示
Debug . Log ( $"Assigned {kvp.Value} NPCs to Scene ID: {kvp.Key}" ) ;
@ -545,4 +507,6 @@ public class EvacuationPanel : MonoBehaviour
classCount . gameObject . SetActive ( false ) ;
}
}
//
}