7 protected static const float SETTLE_THRESHOLD = 0.01;
10 private string m_sActionTeleportToCursor;
13 private string m_sActionTeleportToPlayer;
16 private float m_fMinDistance;
19 private float m_fMaxDistance;
21 [
Attribute(
desc:
"How far from the target position is camera teleported before it plays settle-in animation.", defvalue:
"5")]
22 private float m_fSettleInDistance;
24 [
Attribute(defvalue:
"275",
desc:
"When further than this limit, teleport the camera instantly, otherwise start transition from its current position.")]
25 private float m_fTeleportDistance;
28 private float m_fTransitionStrength;
31 private float m_fMinAngle;
34 private float m_fDefaultAngle;
37 private string m_sSoundEvent;
39 private bool m_bIsSettling;
40 private bool m_bIsTeleportInit;
41 private bool m_bIsDefaultDistance;
42 private bool m_bIsDefaultAngle;
43 private bool m_bIsStartAtCurrentPos;
44 private bool m_bDisableInterruption;
45 private vector m_vInitPos;
46 private vector m_vTargetPos;
47 private vector m_vTargetRot;
48 private float m_fDistance;
49 private float m_fDistancePrev;
61 bool TeleportCamera(vector
position,
bool forceDefaultDistance =
false,
bool forceDefaultAngle =
false,
bool forceStartAtCurrentPos =
false,
bool disableInterruption =
false,
float distance = -1,
bool noSound =
false)
69 m_bIsTeleportInit =
true;
70 m_bIsDefaultDistance = forceDefaultDistance;
71 m_bIsDefaultAngle = forceDefaultAngle;
72 m_bIsStartAtCurrentPos = forceStartAtCurrentPos;
73 m_bDisableInterruption = disableInterruption;
80 ArmaReforgerScripted game =
GetGame();
81 if (game && !m_bIsDefaultAngle)
83 WorkspaceWidget workspace = game.GetWorkspace();
86 vector screenPos = workspace.ProjWorldToScreen(
m_vTargetPos, game.GetWorld());
87 float screenW, screenH;
88 workspace.GetScreenSize(screenW, screenH);
89 screenW = workspace.DPIUnscale(screenW);
90 screenH = workspace.DPIUnscale(screenH);
91 if (screenPos[0] < 0 || screenPos[1] < 0 || screenPos[0] > screenW || screenPos[1] > screenH)
93 m_bIsDefaultAngle =
true;
98 if (!noSound && !m_sSoundEvent.IsEmpty())
107 if (param.isManualInputEnabled)
109 if (m_sActionTeleportToCursor &&
GetInputManager().GetActionValue(m_sActionTeleportToCursor))
113 if (!param.GetCursorWorldPos(pos))
116 if (!TeleportCamera(pos))
119 if (m_sActionTeleportToPlayer &&
GetInputManager().GetActionValue(m_sActionTeleportToPlayer))
122 vector pos = m_vInitPos;
125 pos = player.GetOrigin();
127 if (!TeleportCamera(pos,
false,
true))
133 if (m_bIsTeleportInit)
136 vector angles = param.transform[2].VectorToAngles().MapAngles();
137 if (m_bIsDefaultAngle)
139 angles[1] = m_fDefaultAngle;
141 else if (angles[1] > -m_fMinAngle)
143 angles[1] = -m_fMinAngle;
145 m_vTargetRot = angles.AnglesToVector();
149 if (!m_bIsDefaultDistance)
151 dis = Math.Min(dis, vector.Distance(
m_vTargetPos, param.transform[3]));
156 vector pos = param.transform[3];
157 float height = pos[1] - param.world.GetSurfaceY(pos[0], pos[2]);
158 dis = Math.Min(dis, height);
160 dis = Math.Max(dis, m_fMinDistance);
163 param.isManualInput =
false;
166 if (!m_bIsStartAtCurrentPos && vector.Distance(
m_vTargetPos, param.transform[3]) > m_fTeleportDistance)
169 param.transformOriginal[2] = m_vTargetRot;
170 vector dirTo = (
m_vTargetPos - param.transformOriginal[3]).Normalized();
171 param.transformOriginal[3] =
m_vTargetPos - dirTo * m_fSettleInDistance;
174 m_bIsSettling =
true;
175 m_bIsTeleportInit =
false;
178 if (param.isManualInput && !m_bDisableInterruption)
181 m_bIsSettling =
false;
183 else if (m_bIsSettling)
186 Math3D.MatrixCopy(param.transformOriginal, param.transform);
189 float dis = vector.Distance(param.transform[3],
m_vTargetPos);
190 if (vector.Distance(param.transform[3],
m_vTargetPos) < SETTLE_THRESHOLD || Math.AbsFloat(dis - m_fDistancePrev) < SETTLE_THRESHOLD)
192 m_bIsSettling =
false;
195 m_fDistancePrev = dis;
198 float progress = Math.Min(param.timeSlice / m_fTransitionStrength, 1);
199 param.transform[2] = vector.Lerp(param.transform[2], m_vTargetRot, progress);
200 param.transform[3] = vector.Lerp(param.transform[3],
m_vTargetPos, progress);
201 param.rotDelta = vector.Zero;
202 param.isDirty =
true;
207 override bool EOnCameraInit()
214 override void EOnCameraParentChange(
bool attached, IEntity parent)