void ICmpUpdatable.OnUpdate() { if (this.camera == null) { return; } if (this.microphone == null) { return; } Transform camTransform = this.camera.GameObj.Transform; Transform microTransform = this.microphone.GameObj.Transform; // Update screen shake behavior Vector3 lastScreenShakeOffset = this.screenShakeOffset; float lastScreenShakeAngle = this.screenShakeAngle; this.screenShakeOffset = MathF.Rnd.NextVector3() * 100.0f * this.screenShake; this.screenShakeAngle = MathF.Rnd.NextFloat(-1.0f, 1.0f) * MathF.DegToRad(5.0f) * this.screenShake; this.screenShake += (0.0f - this.screenShake) * 0.2f * Time.TimeMult; // Remove old screen shake camTransform.Pos -= lastScreenShakeOffset; camTransform.Angle -= lastScreenShakeAngle; // Remove disposed / null follow targets this.followTargets.RemoveAll(obj => obj == null || obj.Disposed); // Follow a group of objects behavior if (this.followTargets.Count > 0) { // Determine the position to focus on. It's the average of all follow object positions. this.focusPos = Vector3.Zero; foreach (Transform obj in this.followTargets) { this.focusPos += obj.Pos; } this.focusPos /= this.followTargets.Count; // Determine how far these objects are away from each other this.focusRadius = 0.0f; foreach (Transform obj in this.followTargets) { this.focusRadius = MathF.Max((obj.Pos - this.focusPos).Length, this.focusRadius); } // Move the camera so it can most likely see all of the required objects Vector3 targetPos = this.focusPos + this.GetTargetOffset(this.focusRadius); Vector3 posDiff = (targetPos - camTransform.Pos); Vector3 targetVelocity = posDiff * 0.1f * MathF.Pow(2.0f, -this.smoothness); camTransform.MoveByAbs(targetVelocity * Time.TimeMult); microTransform.MoveToAbs(new Vector3(camTransform.Pos.Xy)); } // Apply new screen shake camTransform.Pos += this.screenShakeOffset; camTransform.Angle += this.screenShakeAngle; }