Деревянный ящик (разбиваемый) наподобие WoodenBox, использующий ту же физику, модель и текстуру, но может иметь смешанное "содержимое" в виде 3-х предметов инвентаря (оружия, боеприпасов) и/или декораций. Инвентарь указывается в секции Decoration (наследуется из корня Engine.u для всех актёров-декораций) в полях Contents, Content2, Content3. Причём, "заполнение" ящика инвентарём нужно обязательно производить последовательно, начиная со слота Contents. Т.е. если ящик содержит, например, обойму к Automag, то её нужно указать в слоте Contents секции Decoration. После сохранения карты и её повторного открытия обойма к Automag окажется в слоте Contents секции UMSBox. Это связано с тем, что в коде ящика слоты для декораций называются также, как наследуемые из Engine.u слоты для инвентаря. Именно поэтому нужно внимательно заполнять смешанное содержимое. Декорации указываются в секции UMSBox в полях Contents, Content2, Content3. Причём, "заполнение" ящика декорациями нужно обязательно производить последовательно, начиная со слота UMSBox\Contents. Выпавшие декорации переходят в состояние Active или Animate. Это позволяет бьющимся или толкаемым декорациям выполнять физические законы движка. Скрипт для создания: //============================================================================= // UMSBox. Based on code of RtNP's MarineBox. Re-coded by Stvaan Ivanhoe, 2014 // May contain 3 decorations, also as well as 3 inventory items. Or both. //============================================================================= class UMSBox expands Decoration; var bool bChainedExplosion, bDestroy; var() class contents; var() class content2; var() class content3; var() int Health; var() int FragChunks; var() Float Fragsize; function PostBeginPlay() { if( Health == 0 ) Health = 30; } auto state active { function TakeDamage( int NDamage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { Instigator = InstigatedBy; if (Health<0) Return; if ( Instigator != None ) MakeNoise(1.0); bBobbing = false; Health -= NDamage; if (Health <0) { Frag(Class'WoodFragments',Momentum,FragSize,FragChunks); Destroy(); } else { SetPhysics(PHYS_Falling); Momentum.Z = 900; Velocity=Momentum*0.016; } } Begin: } // override Destroyed function to allow for multiple box contents (and give them velocity) function Destroyed() { local actor dropped, A; local actor dropped2, B; local actor dropped3, C; if( (Pawn(Base) != None) && (Pawn(Base).CarriedDecoration == self) ) Pawn(Base).DropDecoration(); if( Contents != none && !Level.bStartup ) { if( contents != none ) { dropped = Spawn( contents ); if (Dropped != None) { dropped.RemoteRole = ROLE_DumbProxy; dropped.SetPhysics( PHYS_Falling ); Dropped.Velocity = VRand()*(75+FRand()*150.0+100.0 + (250)/80); dropped.bCollideWorld = true; } if( Decoration( Dropped ) != none ) Decoration( Dropped ).GotoState( 'Active', 'Animate'); dropped2 = Spawn( content2 ); if (Dropped2 != None) { dropped2.RemoteRole = ROLE_DumbProxy; dropped2.SetPhysics( PHYS_Falling ); Dropped2.Velocity = VRand()*(55+FRand()*190.0+110.0 + (250)/70); dropped2.bCollideWorld = true; } if( Decoration( Dropped2 ) != none ) Decoration( Dropped2 ).GotoState( 'Active', 'Animate'); dropped3 = Spawn( content3 ); if (Dropped2 != None) { dropped3.RemoteRole = ROLE_DumbProxy; dropped3.SetPhysics( PHYS_Falling ); Dropped3.Velocity = VRand()*(85+FRand()*140.0+90.0 + (280)/60); dropped3.bCollideWorld = true; } if( Decoration( Dropped3 ) != none ) Decoration( Dropped3 ).GotoState( 'Active', 'Animate'); } } if( Event != '' ) foreach AllActors( class 'Actor', A, Event ) A.Trigger( Self, None ); foreach AllActors( class 'Actor', B, Event ) A.Trigger( Self, None ); foreach AllActors( class 'Actor', C, Event ) A.Trigger( Self, None ); } defaultproperties { bPushable=True Health=30 FragChunks=12 Fragsize=1.700000 Mesh=LodMesh'UnrealShare.WoodenBoxM' Skin=Texture'UnrealShare.Skins.JWoodenBox1' CollisionRadius=29.000000 CollisionHeight=26.000000 bCollideActors=True bCollideWorld=True bBlockActors=True bBlockPlayers=True bProjTarget=True bStatic=False Mass=35.000000 } ==================== Пример заполнения ящика смешаннным содержимым: двумя книжками и оружием ASMD: Секция Decoration |-Content3 <пусто> |-Content2 |-Contents <пусто> Секция UMSBox |-Content3 |-Content2 <пусто> |-Contents После сохранения карты и её повторного открытия картина окажется такой: Секция Decoration |-Content3 <пусто> |-Content2 <пусто> |-Contents <пусто> Секция UMSBox |-Content3 |-Content2 |-Contents При разбивании ящика из 1-го слота выпадет красная книжка, из 2-го - ASMD, а из 3-го слота выпадет зелёная книжка. Если нарушить порядок чередования (например, очистить слот Content2 в вышеуказанном наборе), то из ящика при разбивании выпадут обе книжки, но одна из них с большой вероятностью может "повиснуть" в воздухе.