/* * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #include #include #include #include #include #include namespace MultiplayerSample { AZ_CVAR(AZ::Vector3, cl_cameraOffset, AZ::Vector3(0.0f, -5.0f, 3.0f), nullptr, AZ::ConsoleFunctorFlags::Null, "Offset to use for the player camera"); NetworkSimplePlayerCameraComponentController::NetworkSimplePlayerCameraComponentController(NetworkSimplePlayerCameraComponent& parent) : NetworkSimplePlayerCameraComponentControllerBase(parent) { ; } void NetworkSimplePlayerCameraComponentController::OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) { // Synchronize aim angles with initial transform AZ::Vector3& aimAngles = ModifyAimAngles(); aimAngles.SetZ(GetEntity()->GetTransform()->GetLocalRotation().GetZ()); SetSyncAimImmediate(true); if (IsAutonomous()) { m_aiEnabled = FindComponent()->GetEnabled(); if (!m_aiEnabled) { AZ::EntityId activeCameraId; Camera::CameraSystemRequestBus::BroadcastResult(activeCameraId, &Camera::CameraSystemRequestBus::Events::GetActiveCamera); m_activeCameraEntity = AZ::Interface::Get()->FindEntity(activeCameraId); } } AZ::TickBus::Handler::BusConnect(); } void NetworkSimplePlayerCameraComponentController::OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) { AZ::TickBus::Handler::BusDisconnect(); } float NetworkSimplePlayerCameraComponentController::GetCameraYaw() const { return GetAimAngles().GetZ(); } float NetworkSimplePlayerCameraComponentController::GetCameraPitch() const { return GetAimAngles().GetX(); } float NetworkSimplePlayerCameraComponentController::GetCameraRoll() const { return GetAimAngles().GetY(); } float NetworkSimplePlayerCameraComponentController::GetCameraYawPrevious() const { return GetAimAnglesPrevious().GetZ(); } float NetworkSimplePlayerCameraComponentController::GetCameraPitchPrevious() const { return GetAimAnglesPrevious().GetX(); } float NetworkSimplePlayerCameraComponentController::GetCameraRollPrevious() const { return GetAimAnglesPrevious().GetY(); } void NetworkSimplePlayerCameraComponentController::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time) { if (m_activeCameraEntity != nullptr && m_activeCameraEntity->GetState() == AZ::Entity::State::Active) { const AZ::Quaternion targetRotation = AZ::Quaternion::CreateRotationZ(GetCameraYaw()) * AZ::Quaternion::CreateRotationX(GetCameraPitch()); const float blendFactor = Multiplayer::GetMultiplayer()->GetCurrentBlendFactor(); AZ::Quaternion aimRotation = targetRotation; if (!GetSyncAimImmediate() && !AZ::IsClose(blendFactor, 1.0f)) { const AZ::Quaternion prevRotation = AZ::Quaternion::CreateRotationZ(GetCameraYawPrevious()) * AZ::Quaternion::CreateRotationX(GetCameraPitchPrevious()); if (!prevRotation.IsClose(targetRotation)) { aimRotation = prevRotation.Slerp(targetRotation, blendFactor).GetNormalized(); } } const AZ::Vector3 targetTranslation = GetEntity()->GetTransform()->GetWorldTM().GetTranslation(); const AZ::Vector3 cameraOffset = aimRotation.TransformVector(cl_cameraOffset); const AZ::Transform cameraTransform = AZ::Transform::CreateFromQuaternionAndTranslation(aimRotation, targetTranslation + cameraOffset); m_activeCameraEntity->GetTransform()->SetWorldTM(cameraTransform); } if (GetSyncAimImmediate()) { SetSyncAimImmediate(false); } } int NetworkSimplePlayerCameraComponentController::GetTickOrder() { return AZ::TICK_PRE_RENDER; } }