1 [
EntityEditorProps(
category:
"GameScripted/Editor", description:
"Image generator for pecific subset of entities", color:
"255 0 0 255")]
14 [
Attribute(
"0", uiwidget: UIWidgets.SearchComboBox,
"Use this location fo entities with these labels.",
"", ParamEnumArray.FromEnum(
EEditableEntityLabel),
category:
"Configuration")]
15 protected ref array<EEditableEntityLabel> m_Labels;
17 [
Attribute(
"2", uiwidget:UIWidgets.Slider,
"Delay between creating the entity and taking a screenshot.",
params:
"1 5 0.5",
category:
"Configuration")]
18 protected float m_fDelay;
20 [
Attribute(
"0",
desc:
"Order in which the position will be evaluated.\nHigher numbers are processed first.",
category:
"Configuration")]
21 protected int m_iPriority;
24 protected ResourceName m_PreviewMesh;
27 protected bool m_bEnablePhysics;
29 [
Attribute(
desc:
"Position the entity by center of its bounding box, not by center of the prefab.",
category:
"Configuration")]
30 protected bool m_bUseBoundingCenter;
32 [
Attribute(
desc:
"When enabled, the prefab must fit into camera view. When that's not the game, another camera tied to the position will be searched for.",
category:
"Configuration")]
33 protected bool m_bMustFitInView;
35 [
Attribute(
desc:
"Names of camera entities belonging to this position. Multiple positions could refer to the same camera.",
category:
"Configuration")]
36 protected ref array<string> m_aCameraNames;
39 protected ResourceName m_PosesGraph;
42 protected ResourceName m_PosesInstance;
45 protected string m_sStartNode;
48 protected string m_sPoseVar;
51 protected int m_iPoseID;
54 protected int m_iArmIK;
57 protected ResourceName m_ArmIKResource;
63 protected float m_fLatitude;
66 protected float m_fLongitude;
69 protected float m_fTime;
72 protected int m_iYear;
75 protected int m_iMonth;
80 [
Attribute(defvalue:
"Clear", uiwidget: UIWidgets.ComboBox,
category:
"Environment", enums: { ParamEnum(
"Clear",
"Clear"), ParamEnum(
"Cloudy",
"Cloudy"), ParamEnum(
"Overcast",
"Overcast"), ParamEnum(
"Rainy",
"Rainy") },
desc:
"Area shape")]
81 private string m_sWeatherState;
84 protected ref array<SCR_CameraBase> m_aCameras = {};
86 protected ref SCR_SortedArray<SCR_EditorImagePositionEntity> m_aSubPositions =
new SCR_SortedArray<SCR_EditorImagePositionEntity>();
88 protected ref array<IEntity> m_aCurrentNearbyEntities = {};
89 protected ref array<IEntity> m_aOriginalNearbyEntities = {};
90 protected string m_sNewWeaponMesh;
91 protected string m_sCurrentWeaponMesh;
93 protected CharacterAnimationComponent m_CharacterAnimation;
103 bool IsSuitable(array<EEditableEntityLabel> labels)
108 if (!labels.Contains(label))
113 SCR_EditorImagePositionEntity FindSuitableSubPosition(SCR_SortedArray<SCR_EditorImagePositionEntity> subPositions, array<EEditableEntityLabel> labels)
115 for (
int i = subPositions.Count() - 1; i >= 0; i--)
117 if (subPositions.GetValue(i).IsSuitable(labels))
118 return subPositions.GetValue(i);
122 bool ActivatePosition(ResourceName prefab)
128 EntitySpawnParams spawnParams =
new EntitySpawnParams();
129 GetTransform(spawnParams.Transform);
130 m_Entity =
GetGame().SpawnEntityPrefab(Resource.Load(prefab), GetWorld(), spawnParams);
133 Debug.Error2(Type().ToString(),
string.Format(
"Error when creating prefab '%1'!", prefab));
142 editableComposition.SetTransformWithChildren(spawnParams.Transform);
148 TimeAndWeatherManagerEntity envManager = world.GetTimeAndWeatherManager();
152 envManager.SetCurrentLatitude(m_fLatitude);
153 envManager.SetCurrentLongitude(m_fLongitude);
154 envManager.TimeToHoursMinutesSeconds(
m_fTime * 24, h, m, s);
155 envManager.SetHoursMinutesSeconds(h, m, s,
false);
156 envManager.SetDate(m_iYear, m_iMonth,
m_iDay,
true);
160 if (weatherTransitionManager)
162 WeatherStateTransitionNode transitionNode = weatherTransitionManager.CreateStateTransition(m_sWeatherState, 0, 1);
163 transitionNode.SetLooping(
true);
165 weatherTransitionManager.EnqueueStateTransition(transitionNode,
false);
166 weatherTransitionManager.RequestStateTransitionImmediately(transitionNode);
179 group.SetMemberSpawnDelay(0);
182 array<AIAgent> agents = {};
183 int agentCount = group.GetAgents(agents);
184 if (agentCount <= m_aSubPositions.Count())
189 SCR_SortedArray<SCR_EditorImagePositionEntity> subPositions =
new SCR_SortedArray<SCR_EditorImagePositionEntity>();
190 subPositions.CopyFrom(m_aSubPositions);
193 for (
int i = 0; i < agentCount; i++)
195 member = agents[i].GetControlledEntity();
200 array<EEditableEntityLabel> memberLabels = {};
202 info.GetEntityLabels(memberLabels);
205 subPosition = FindSuitableSubPosition(subPositions, memberLabels);
208 subPositions.RemoveValues(subPosition);
209 subPosition.GetTransform(transform);
211 CloneCharacter(member, transform);
213 subPosition.SetPose(member);
214 subPosition.EOnImagePositonActivate(member);
218 Print(
string.Format(
"Cannot capture group member @\"%1\"! Unable to find suitable sub-position for %1!", member.GetPrefabData().GetPrefabName()), LogLevel.WARNING);
229 Print(
string.Format(
"Cannot capture group @\"%1\"! It has %2 members, but the position '%3' has only %4 sub-positions!", prefab, agentCount, GetPositionName(), m_aSubPositions.Count()), LogLevel.WARNING);
237 ChimeraCharacter character = ChimeraCharacter.Cast(
m_Entity);
240 if (m_ForceWeaponType >= 0)
243 if (inventoryStorage)
245 array<IEntity> items = {};
246 for (
int i = inventoryStorage.GetItems(items) - 1; i >= 0; i--)
251 if (weapon.GetWeaponType() == m_ForceWeaponType)
253 m_sNewWeaponMesh = items[i].GetVObject().GetResourceName();
260 BaseWeaponManagerComponent weaponManager = BaseWeaponManagerComponent.Cast(
m_Entity.FindComponent(BaseWeaponManagerComponent));
265 m_sCurrentWeaponMesh = currentWeapon.GetOwner().GetVObject().GetResourceName();
270 CharacterControllerComponent characterController = character.GetCharacterController();
271 m_CharacterAnimation = characterController.GetAnimationComponent();
275 CloneCharacter(
m_Entity, transform);
280 if (m_bUseBoundingCenter)
284 vector bCenter = min + (max - min) / 2;
291 if (m_bEnablePhysics)
293 Physics phys =
m_Entity.GetPhysics();
295 phys.SetActive(
true);
300 if (m_bMustFitInView)
304 array<vector> corners = {
306 Vector(min[0], min[1], max[2]),
307 Vector(min[0], max[1], min[2]),
308 Vector(max[0], min[1], min[2]),
309 Vector(max[0], max[1], min[2]),
310 Vector(max[0], min[1], max[2]),
311 Vector(min[0], max[1], max[2]),
317 bool isInView =
true;
318 for (
int i = 0; i < 8; i++)
320 if (!cameraCandidate.IsInView(corners[i]))
328 camera = cameraCandidate;
335 camera = m_aCameras[0];
340 CameraManager cameraManager =
GetGame().GetCameraManager();
342 cameraManager.SetCamera(camera);
345 Debug.Error2(Type().ToString(),
string.Format(
"No camera which would fit '%1' found on position '%2'!", prefab, GetPositionName()));
349 void DeactivatePosition()
351 UpdateNearbyEntities();
352 foreach (IEntity entity: m_aCurrentNearbyEntities)
354 if (!m_aOriginalNearbyEntities.Contains(entity))
358 protected void CloneCharacter(out IEntity character, vector transform[4])
361 if (!inventoryComponent)
365 IEntity clone = inventoryComponent.CreatePreviewEntity(GetWorld(), GetWorld().GetCurrentCameraId());
370 if (m_sNewWeaponMesh != m_sCurrentWeaponMesh)
372 IEntity currentWeapon, newWeapon;
373 TNodeId currentPivot, newPivot;
374 vector currentLocalTransform[4], newLocalTransform[4];
376 IEntity child = clone.GetChildren();
379 VObject mesh = child.GetVObject();
382 if (mesh.GetResourceName() == m_sCurrentWeaponMesh)
384 currentWeapon = child;
385 currentPivot = child.GetPivot();
386 child.GetLocalTransform(currentLocalTransform);
388 if (mesh.GetResourceName() == m_sNewWeaponMesh)
391 newPivot = child.GetPivot();
392 child.GetLocalTransform(newLocalTransform);
395 child = child.GetSibling();
398 clone.AddChild(newWeapon, currentPivot);
399 newWeapon.SetLocalTransform(currentLocalTransform);
401 clone.AddChild(currentWeapon, newPivot);
402 currentWeapon.SetLocalTransform(newLocalTransform);
408 character.SetTransform(transform);
410 protected void SetPose(IEntity entity)
412 if (m_PosesGraph.IsEmpty() && m_PosesInstance.IsEmpty() && m_sStartNode.IsEmpty())
415 PreviewAnimationComponent animComponent = PreviewAnimationComponent.Cast(entity.FindComponent(PreviewAnimationComponent));
416 animComponent.SetGraphResource(entity, m_PosesGraph, m_PosesInstance, m_sStartNode);
422 animComponent.UpdateFrameStep(entity, 1.0 / 30.0);
425 int poseVar = animComponent.BindIntVariable(m_sPoseVar);
429 animComponent.SetIntVariable(poseVar, m_iPoseID);
432 int armIkVar = animComponent.BindIntVariable(
"ArmIK");
435 animComponent.SetIntVariable(armIkVar, m_iArmIK);
436 animComponent.SetHandsIKPose(entity, m_ArmIKResource);
440 animComponent.UpdateFrameStep(entity, 1.0 / 30.0);
444 Debug.Error2(Type().ToString(),
string.Format(
"Unable to set character pose at positon '%1'!", GetPositionName()));
449 m_aSubPositions.Insert(subPosition.GetPriority(), subPosition);
451 protected void UpdateNearbyEntities()
453 m_aCurrentNearbyEntities.Clear();
454 GetWorld().QueryEntitiesByAABB(
GetOrigin() + vector.One * -128,
GetOrigin() + vector.One * 128, QueryEntitiesCallback);
456 protected bool QueryEntitiesCallback(IEntity e)
458 m_aCurrentNearbyEntities.Insert(e);
461 protected string GetPositionName()
468 event void EOnImagePositonActivate(IEntity entity)
472 override void EOnInit(IEntity owner)
480 Debug.Error2(Type().ToString(),
"SCR_EditorImageGeneratorEntity is missing in the world!");
487 m_Parent.AddSubPosition(
this);
495 for (
int i = 0, count = m_aCameraNames.Count(); i < count; i++)
498 if (camera && !m_aCameras.Contains(camera))
499 m_aCameras.Insert(camera);
507 if (camera && !m_aCameras.Contains(camera))
508 m_aCameras.Insert(camera);
510 child = child.GetSibling();
513 if (m_aCameras.IsEmpty())
515 Print(
"SCR_EditorImagePositionEntity is missing child entity of type SCR_CameraBase!", LogLevel.WARNING);
519 manager.AddPosition(
this);
523 UpdateNearbyEntities();
524 m_aOriginalNearbyEntities.Copy(m_aCurrentNearbyEntities);
534 Resource resource = Resource.Load(m_PreviewMesh);
535 if (!resource.IsValid())
537 Print(
"Cannot load " + m_PreviewMesh +
" | " + FilePath.StripPath(__FILE__) +
":" + __LINE__, LogLevel.WARNING);
541 SetObject(resource.GetResource().ToVObject(),
"");
547 SetEventMask(EntityEvent.INIT);
551 WorldEditorAPI api = _WB_GetEditorAPI();
552 if (api && api.IsEntitySelected(api.EntityToSource(
this)))
555 override void _WB_AfterWorldUpdate(
float timeSlice)
557 if (m_Labels.IsEmpty())
561 for (
int i = 0, count = m_Labels.Count(); i < count; i++)
579 DebugTextWorldSpace.Create(GetWorld(), name, DebugTextFlags.CENTER | DebugTextFlags.FACE_CAMERA | DebugTextFlags.ONCE, pos[0], pos[1], pos[2], fontSize, Color.WHITE, ARGBF(1, 0.5, 0, 1));