Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
@@ -0,0 +1,192 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "VirtualGamepad_precompiled.h"
#include "InputDeviceVirtualGamepad.h"
#include "VirtualGamepadButtonRequestBus.h"
#include "VirtualGamepadThumbStickRequestBus.h"
#include <AzFramework/Input/Devices/Touch/InputDeviceTouch.h>
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace VirtualGamepad
{
using namespace AzFramework;
////////////////////////////////////////////////////////////////////////////////////////////////
const InputDeviceId InputDeviceVirtualGamepad::Id("virtual_gamepad");
////////////////////////////////////////////////////////////////////////////////////////////////
bool InputDeviceVirtualGamepad::IsVirtualGamepadDevice(const InputDeviceId& inputDeviceId)
{
return (inputDeviceId.GetNameCrc32() == Id.GetNameCrc32());
}
////////////////////////////////////////////////////////////////////////////////////////////////
InputDeviceVirtualGamepad::InputDeviceVirtualGamepad(
const AZStd::unordered_set<AZStd::string>& buttonNames,
const AZStd::unordered_set<AZStd::string>& thumbStickNames)
: InputDevice(Id)
, m_allChannelsById()
, m_buttonChannelsByName()
, m_thumbStickAxis1DChannelsByName()
, m_thumbStickAxis2DChannelsByName()
, m_thumbStickDirectionChannelsByName()
{
// Create all button input channels
for (const AZStd::string& buttonName : buttonNames)
{
CreateButtonChannel(buttonName);
}
// Create all thumb-stick input channels
for (const AZStd::string& thumbStickName : thumbStickNames)
{
CreateThumbStickAxis2DChannel(thumbStickName);
CreateThumbStickAxis1DChannel(thumbStickName + "_x");
CreateThumbStickAxis1DChannel(thumbStickName + "_y");
CreateThumbStickDirectionChannel(thumbStickName + "_u");
CreateThumbStickDirectionChannel(thumbStickName + "_d");
CreateThumbStickDirectionChannel(thumbStickName + "_l");
CreateThumbStickDirectionChannel(thumbStickName + "_r");
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
InputDeviceVirtualGamepad::~InputDeviceVirtualGamepad()
{
// Destroy all thumb-stick direction input channels
for (const auto& channelByName : m_thumbStickDirectionChannelsByName)
{
delete channelByName.second;
}
// Destroy all thumb-stick 2D axis input channels
for (const auto& channelByName : m_thumbStickAxis2DChannelsByName)
{
delete channelByName.second;
}
// Destroy all thumb-stick 1D axis input channels
for (const auto& channelByName : m_thumbStickAxis1DChannelsByName)
{
delete channelByName.second;
}
// Destroy all button input channels
for (const auto& channelByName : m_buttonChannelsByName)
{
delete channelByName.second;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
const InputDevice::InputChannelByIdMap& InputDeviceVirtualGamepad::GetInputChannelsById() const
{
return m_allChannelsById;
}
////////////////////////////////////////////////////////////////////////////////////////////////
bool InputDeviceVirtualGamepad::IsSupported() const
{
// Touch input must be supported
const InputDevice* inputDevice = nullptr;
InputDeviceRequestBus::EventResult(inputDevice,
InputDeviceTouch::Id,
&InputDeviceRequests::GetInputDevice);
return inputDevice && inputDevice->IsSupported();
}
////////////////////////////////////////////////////////////////////////////////////////////////
bool InputDeviceVirtualGamepad::IsConnected() const
{
// Touch input must be connected
const InputDevice* inputDevice = nullptr;
InputDeviceRequestBus::EventResult(inputDevice,
InputDeviceTouch::Id,
&InputDeviceRequests::GetInputDevice);
return inputDevice && inputDevice->IsConnected();
}
////////////////////////////////////////////////////////////////////////////////////////////////
void InputDeviceVirtualGamepad::TickInputDevice()
{
for (const auto& buttonChannelByName : m_buttonChannelsByName)
{
bool isButtonPressed = false;
VirtualGamepadButtonRequestBus::EventResult(isButtonPressed,
buttonChannelByName.first,
&VirtualGamepadButtonRequests::IsPressed);
buttonChannelByName.second->ProcessRawInputEvent(isButtonPressed);
}
for (const auto& thumbStickAxis2DChannelByName : m_thumbStickAxis2DChannelsByName)
{
const AZStd::string& thumbStickName = thumbStickAxis2DChannelByName.first;
AZ::Vector2 axisValues(0.0f, 0.0f);
VirtualGamepadThumbStickRequestBus::EventResult(axisValues,
thumbStickName,
&VirtualGamepadThumbStickRequests::GetCurrentAxisValuesNormalized);
thumbStickAxis2DChannelByName.second->ProcessRawInputEvent(axisValues);
m_thumbStickAxis1DChannelsByName[thumbStickName + "_x"]->ProcessRawInputEvent(axisValues.GetX());
m_thumbStickAxis1DChannelsByName[thumbStickName + "_y"]->ProcessRawInputEvent(axisValues.GetY());
const float upValue = AZ::GetClamp(axisValues.GetY(), 0.0f, 1.0f);
const float downValue = AZ::GetClamp(axisValues.GetY(), -1.0f, 0.0f);
const float leftValue = AZ::GetClamp(axisValues.GetX(), -1.0f, 0.0f);
const float rightValue = AZ::GetClamp(axisValues.GetX(), 0.0f, 1.0f);
m_thumbStickDirectionChannelsByName[thumbStickName + "_u"]->ProcessRawInputEvent(upValue);
m_thumbStickDirectionChannelsByName[thumbStickName + "_d"]->ProcessRawInputEvent(downValue);
m_thumbStickDirectionChannelsByName[thumbStickName + "_l"]->ProcessRawInputEvent(leftValue);
m_thumbStickDirectionChannelsByName[thumbStickName + "_r"]->ProcessRawInputEvent(rightValue);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void InputDeviceVirtualGamepad::CreateButtonChannel(const AZStd::string& channelName)
{
const InputChannelId channelId(channelName.c_str());
InputChannelDigital* channel = aznew InputChannelDigital(channelId, *this);
m_allChannelsById[channelId] = channel;
m_buttonChannelsByName[channelName] = channel;
}
////////////////////////////////////////////////////////////////////////////////////////////////
void InputDeviceVirtualGamepad::CreateThumbStickAxis1DChannel(const AZStd::string& channelName)
{
const InputChannelId channelId(channelName.c_str());
InputChannelAxis1D* channel = aznew InputChannelAxis1D(channelId, *this);
m_allChannelsById[channelId] = channel;
m_thumbStickAxis1DChannelsByName[channelName] = channel;
}
////////////////////////////////////////////////////////////////////////////////////////////////
void InputDeviceVirtualGamepad::CreateThumbStickAxis2DChannel(const AZStd::string& channelName)
{
const InputChannelId channelId(channelName.c_str());
InputChannelAxis2D* channel = aznew InputChannelAxis2D(channelId, *this);
m_allChannelsById[channelId] = channel;
m_thumbStickAxis2DChannelsByName[channelName] = channel;
}
////////////////////////////////////////////////////////////////////////////////////////////////
void InputDeviceVirtualGamepad::CreateThumbStickDirectionChannel(const AZStd::string& channelName)
{
const InputChannelId channelId(channelName.c_str());
InputChannelAnalog* channel = aznew InputChannelAnalog(channelId, *this);
m_allChannelsById[channelId] = channel;
m_thumbStickDirectionChannelsByName[channelName] = channel;
}
} // namespace VirtualGamepad
@@ -0,0 +1,115 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzFramework/Input/Devices/InputDevice.h>
#include <AzFramework/Input/Channels/InputChannelAnalog.h>
#include <AzFramework/Input/Channels/InputChannelAxis1D.h>
#include <AzFramework/Input/Channels/InputChannelAxis2D.h>
#include <AzFramework/Input/Channels/InputChannelDigital.h>
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace VirtualGamepad
{
////////////////////////////////////////////////////////////////////////////////////////////////
//! Implementation for a virtual gamepad input device that is controlled using a touch screen.
class InputDeviceVirtualGamepad : public AzFramework::InputDevice
{
public:
////////////////////////////////////////////////////////////////////////////////////////////
//! The id used to identify the primary virtual gamepad input device
static const AzFramework::InputDeviceId Id;
////////////////////////////////////////////////////////////////////////////////////////////
//! Check whether an input device id identifies a virtual gamepad (regardless of index)
//! \param[in] inputDeviceId The input device id to check
//! \return True if the input device id identifies a virtual gamepad, false otherwise
static bool IsVirtualGamepadDevice(const AzFramework::InputDeviceId& inputDeviceId);
////////////////////////////////////////////////////////////////////////////////////////////
// Allocator
AZ_CLASS_ALLOCATOR(InputDeviceVirtualGamepad, AZ::SystemAllocator, 0);
////////////////////////////////////////////////////////////////////////////////////////////
// Type Info
AZ_RTTI(InputDeviceVirtualGamepad, "{DC4B939E-66C7-4F76-B7DF-049A3F13A1C3}", InputDevice);
////////////////////////////////////////////////////////////////////////////////////////////
//! Constructor
//! \param[in] buttonNames The list of button names supported by the virtual gamepad
//! \param[in] thumbStickNames The list of thumbstick names supported by the virtual gamepad
explicit InputDeviceVirtualGamepad(const AZStd::unordered_set<AZStd::string>& buttonNames,
const AZStd::unordered_set<AZStd::string>& thumbStickNames);
public:
////////////////////////////////////////////////////////////////////////////////////////////
//! Destructor
~InputDeviceVirtualGamepad() override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref AzFramework::InputDevice::GetInputChannelsById
const InputChannelByIdMap& GetInputChannelsById() const override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref AzFramework::InputDevice::IsSupported
bool IsSupported() const override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref AzFramework::InputDevice::IsConnected
bool IsConnected() const override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref AzFramework::InputDeviceRequests::TickInputDevice
void TickInputDevice() override;
protected:
////////////////////////////////////////////////////////////////////////////////////////////
//! Create a button input channel
//! \param[in] channelName The input channel name
void CreateButtonChannel(const AZStd::string& channelName);
////////////////////////////////////////////////////////////////////////////////////////////
//! Create a thumb-stick axis 1D input channel
//! \param[in] channelName The input channel name
void CreateThumbStickAxis1DChannel(const AZStd::string& channelName);
////////////////////////////////////////////////////////////////////////////////////////////
//! Create a thumb-stick axis 2D input channel
//! \param[in] channelName The input channel name
void CreateThumbStickAxis2DChannel(const AZStd::string& channelName);
////////////////////////////////////////////////////////////////////////////////////////////
//! Create a thumb-stick direction input channel
//! \param[in] channelName The input channel name
void CreateThumbStickDirectionChannel(const AZStd::string& channelName);
private:
////////////////////////////////////////////////////////////////////////////////////////////
///@{
//! Alias for verbose container class
using ButtonChannelByNameMap = AZStd::unordered_map<AZStd::string, AzFramework::InputChannelDigital*>;
using ThumbStickAxis1DChannelByNameMap = AZStd::unordered_map<AZStd::string, AzFramework::InputChannelAxis1D*>;
using ThumbStickAxis2DChannelByNameMap = AZStd::unordered_map<AZStd::string, AzFramework::InputChannelAxis2D*>;
using ThumbStickDirectionChannelByNameMap = AZStd::unordered_map<AZStd::string, AzFramework::InputChannelAnalog*>;
///@}
////////////////////////////////////////////////////////////////////////////////////////////
// Variables
InputChannelByIdMap m_allChannelsById; //!< All virtual input channels by id
ButtonChannelByNameMap m_buttonChannelsByName; //!< All virtual button channels by id
ThumbStickAxis1DChannelByNameMap m_thumbStickAxis1DChannelsByName; //!< All thumb-stick axis 1D channels by id
ThumbStickAxis2DChannelByNameMap m_thumbStickAxis2DChannelsByName; //!< All thumb-stick axis 2D channels by id
ThumbStickDirectionChannelByNameMap m_thumbStickDirectionChannelsByName; //!< All thumb-stick direction channels by id
};
} // namespace VirtualGamepad
@@ -0,0 +1,120 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "VirtualGamepad_precompiled.h"
#include "VirtualGamepadButtonComponent.h"
#include <VirtualGamepad/VirtualGamepadBus.h>
#include <LyShine/Bus/UiInteractableBus.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/std/sort.h>
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace VirtualGamepad
{
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadButtonComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC("VirtualGamepadButtonService"));
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadButtonComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
incompatible.push_back(AZ_CRC("VirtualGamepadButtonService"));
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadButtonComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
{
required.push_back(AZ_CRC("UiInteractableService", 0x1d474c98));
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadButtonComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
{
AZ_UNUSED(dependent);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadButtonComponent::Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
{
serialize->Class<VirtualGamepadButtonComponent, AZ::Component>()
->Version(0)
->Field("AssignedInputChannelName", &VirtualGamepadButtonComponent::m_assignedInputChannelName)
;
if (AZ::EditContext* ec = serialize->GetEditContext())
{
ec->Class<VirtualGamepadButtonComponent>("VirtualGamepadButton", "A component that designates this entity as a virtual gamepad button")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/UiVirtualButton.png")
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Editor/Icons/Components/Viewport/UiVirtualButton.png")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("UI", 0x27ff46b0))
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(AZ::Edit::UIHandlers::ComboBox, &VirtualGamepadButtonComponent::m_assignedInputChannelName,
"Input Channel", "The input channel that will be updated when the user interacts with this virtual control")
->Attribute(AZ::Edit::Attributes::StringList, &VirtualGamepadButtonComponent::GetAssignableInputChannelNames)
;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadButtonComponent::Init()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadButtonComponent::Activate()
{
VirtualGamepadButtonRequestBus::Handler::BusConnect(m_assignedInputChannelName);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadButtonComponent::Deactivate()
{
VirtualGamepadButtonRequestBus::Handler::BusDisconnect(m_assignedInputChannelName);
}
////////////////////////////////////////////////////////////////////////////////////////////////
bool VirtualGamepadButtonComponent::IsPressed() const
{
bool isPressed = false;
UiInteractableBus::EventResult(isPressed,
GetEntityId(),
&UiInteractableInterface::IsPressed);
return isPressed;
}
////////////////////////////////////////////////////////////////////////////////////////////////
AZStd::vector<AZStd::string> VirtualGamepadButtonComponent::GetAssignableInputChannelNames() const
{
AZStd::unordered_set<AZStd::string> buttonNames;
VirtualGamepadRequestBus::BroadcastResult(buttonNames, &VirtualGamepadRequests::GetButtonNames);
AZStd::vector<AZStd::string> assignableInputChannelNames;
for (const AZStd::string& buttonName : buttonNames)
{
assignableInputChannelNames.push_back(buttonName);
}
AZStd::sort(assignableInputChannelNames.begin(), assignableInputChannelNames.end());
return assignableInputChannelNames;
}
} // namespace VirtualGamepad
@@ -0,0 +1,72 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include "VirtualGamepadButtonRequestBus.h"
#include <AzCore/Component/Component.h>
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace VirtualGamepad
{
////////////////////////////////////////////////////////////////////////////////////////////////
class VirtualGamepadButtonComponent : public AZ::Component
, public VirtualGamepadButtonRequestBus::Handler
{
public:
////////////////////////////////////////////////////////////////////////////////////////////
// AZ::Component Setup
AZ_COMPONENT(VirtualGamepadButtonComponent, "{F3B59A12-BD6F-4CEC-A151-2EBC619912C5}", AZ::Component);
////////////////////////////////////////////////////////////////////////////////////////////
// AZ::ComponentDescriptor Services
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref AZ::ComponentDescriptor::Reflect
static void Reflect(AZ::ReflectContext* context);
protected:
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref AZ::Component::Init
void Init() override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref AZ::Component::Activate
void Activate() override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref AZ::Component::Deactivate
void Deactivate() override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref VirtualGamepad::VirtualGamepadButtonRequests::IsPressed
bool IsPressed() const override;
////////////////////////////////////////////////////////////////////////////////////////////
//! Get all potentially assignable input channel names
AZStd::vector<AZStd::string> GetAssignableInputChannelNames() const;
private:
////////////////////////////////////////////////////////////////////////////////////////////
//! The input channel that will be updated when the user interacts with this virtual control
AZStd::string m_assignedInputChannelName;
////////////////////////////////////////////////////////////////////////////////////////////
//! Is the interactable attached to the same component currently pressed or not?
bool m_isPressed = false;
};
} // namespace VirtualGamepad
@@ -0,0 +1,38 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/string/string.h>
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace VirtualGamepad
{
////////////////////////////////////////////////////////////////////////////////////////////////
class VirtualGamepadButtonRequests : public AZ::EBusTraits
{
public:
////////////////////////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
using BusIdType = AZStd::string;
////////////////////////////////////////////////////////////////////////////////////////////
//! Query whether the virtual button is currently pressed or not
//! \return True if the virtual button is currently pressed, false otherwise
virtual bool IsPressed() const = 0;
};
using VirtualGamepadButtonRequestBus = AZ::EBus<VirtualGamepadButtonRequests>;
}
@@ -0,0 +1,58 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "VirtualGamepad_precompiled.h"
#include <AzCore/Memory/SystemAllocator.h>
#include "VirtualGamepadButtonComponent.h"
#include "VirtualGamepadSystemComponent.h"
#include "VirtualGamepadThumbStickComponent.h"
#include <IGem.h>
namespace VirtualGamepad
{
class VirtualGamepadModule
: public CryHooksModule
{
public:
AZ_RTTI(VirtualGamepadModule, "{0454CF83-A35E-443B-A9BE-858EBE9C908F}", CryHooksModule);
AZ_CLASS_ALLOCATOR(VirtualGamepadModule, AZ::SystemAllocator, 0);
VirtualGamepadModule()
: CryHooksModule()
{
// Push results of [MyComponent]::CreateDescriptor() into m_descriptors here.
m_descriptors.insert(m_descriptors.end(), {
VirtualGamepadSystemComponent::CreateDescriptor(),
VirtualGamepadButtonComponent::CreateDescriptor(),
VirtualGamepadThumbStickComponent::CreateDescriptor(),
});
}
/**
* Add required SystemComponents to the SystemEntity.
*/
AZ::ComponentTypeList GetRequiredSystemComponents() const override
{
return AZ::ComponentTypeList{
azrtti_typeid<VirtualGamepadSystemComponent>(),
};
}
};
}
// DO NOT MODIFY THIS LINE UNLESS YOU RENAME THE GEM
// The first parameter should be GemName_GemIdLower
// The second should be the fully qualified name of the class above
AZ_DECLARE_MODULE_CLASS(Gem_VirtualGamepad, VirtualGamepad::VirtualGamepadModule)
@@ -0,0 +1,121 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "VirtualGamepad_precompiled.h"
#include "VirtualGamepadSystemComponent.h"
#include "InputDeviceVirtualGamepad.h"
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace VirtualGamepad
{
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC("VirtualGamepadService"));
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
incompatible.push_back(AZ_CRC("VirtualGamepadService"));
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
{
required.push_back(AZ_CRC("InputSystemService", 0x5438d51a));
required.push_back(AZ_CRC("LyShineService", 0xae98ab29));
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
{
AZ_UNUSED(dependent);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadSystemComponent::Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
{
serialize->Class<VirtualGamepadSystemComponent, AZ::Component>()
->Version(0)
->Field("ButtonNames", &VirtualGamepadSystemComponent::m_buttonNames)
->Field("ThumbStickNames", &VirtualGamepadSystemComponent::m_thumbStickNames);
if (AZ::EditContext* ec = serialize->GetEditContext())
{
ec->Class<VirtualGamepadSystemComponent>("VirtualGamepad", "Provides an example of a virtual gamepad that can be used by mobile devices with touch screens in place of a physical gamepad.")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System"))
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(0, &VirtualGamepadSystemComponent::m_buttonNames, "Button Names", "The button names made available by the virtual gamepad.")
->DataElement(0, &VirtualGamepadSystemComponent::m_thumbStickNames, "Thumb-Stick Names", "The thumb-stick names made available by the virtual gamepad.")
;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
VirtualGamepadSystemComponent::VirtualGamepadSystemComponent()
{
m_buttonNames =
{
"virtual_gamepad_button_a",
"virtual_gamepad_button_b",
"virtual_gamepad_button_x",
"virtual_gamepad_button_y"
};
m_thumbStickNames =
{
"virtual_gamepad_thumbstick_l",
"virtual_gamepad_thumbstick_r"
};
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadSystemComponent::Init()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadSystemComponent::Activate()
{
VirtualGamepadRequestBus::Handler::BusConnect();
m_virtualGamepad.reset(aznew InputDeviceVirtualGamepad(m_buttonNames,
m_thumbStickNames));
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadSystemComponent::Deactivate()
{
m_virtualGamepad.reset(nullptr);
VirtualGamepadRequestBus::Handler::BusDisconnect();
}
////////////////////////////////////////////////////////////////////////////////////////////////
const AZStd::unordered_set<AZStd::string>& VirtualGamepadSystemComponent::GetButtonNames() const
{
return m_buttonNames;
}
////////////////////////////////////////////////////////////////////////////////////////////////
const AZStd::unordered_set<AZStd::string>& VirtualGamepadSystemComponent::GetThumbStickNames() const
{
return m_thumbStickNames;
}
} // namespace VirtualGamepad
@@ -0,0 +1,90 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Component/Component.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <LyShine/UiAssetTypes.h>
#include <VirtualGamepad/VirtualGamepadBus.h>
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace VirtualGamepad
{
class InputDeviceVirtualGamepad;
////////////////////////////////////////////////////////////////////////////////////////////////
class VirtualGamepadSystemComponent : public AZ::Component
, public VirtualGamepadRequestBus::Handler
{
public:
////////////////////////////////////////////////////////////////////////////////////////////
// AZ::Component Setup
AZ_COMPONENT(VirtualGamepadSystemComponent, "{0FA16F21-B2A6-4057-BC0A-2D783973531E}");
////////////////////////////////////////////////////////////////////////////////////////////
// AZ::ComponentDescriptor Services
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref AZ::ComponentDescriptor::Reflect
static void Reflect(AZ::ReflectContext* context);
////////////////////////////////////////////////////////////////////////////////////////////
//! Constructor
VirtualGamepadSystemComponent();
protected:
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref AZ::Component::Init
void Init() override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref AZ::Component::Activate
void Activate() override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref AZ::Component::Deactivate
void Deactivate() override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref VirtualGamepad::VirtualGamepadRequests::GetButtonNames
const AZStd::unordered_set<AZStd::string>& GetButtonNames() const override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref VirtualGamepad::VirtualGamepadRequests::GetThumbStickNames
const AZStd::unordered_set<AZStd::string>& GetThumbStickNames() const override;
private:
////////////////////////////////////////////////////////////////////////////////////////////
//! The list of button names made available by the virtual gamepad. These can be customized
//! by editing the virtual gamepad system component, but these default values have been set
//! (and are used by the provided canvas) so that the gem is able to work "out of the box".
AZStd::unordered_set<AZStd::string> m_buttonNames;
////////////////////////////////////////////////////////////////////////////////////////////
//! The list of thumb-stick names made available by the virtual gamepad. Can be customized
//! by editing the virtual gamepad system component, but these default values have been set
//! (and are used by the provided canvas) so that the gem is able to work "out of the box".
AZStd::unordered_set<AZStd::string> m_thumbStickNames;
////////////////////////////////////////////////////////////////////////////////////////////
//! Unique pointer to the virtual gamepad device
AZStd::unique_ptr<InputDeviceVirtualGamepad> m_virtualGamepad;
};
} // namespace VirtualGamepad
@@ -0,0 +1,318 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "VirtualGamepad_precompiled.h"
#include "VirtualGamepadThumbStickComponent.h"
#include <VirtualGamepad/VirtualGamepadBus.h>
#include <LyShine/Bus/UiElementBus.h>
#include <LyShine/Bus/UiTransformBus.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/std/sort.h>
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace VirtualGamepad
{
////////////////////////////////////////////////////////////////////////////////////////////////
static const int InactiveTouchIndex = -1;
////////////////////////////////////////////////////////////////////////////////////////////////
static const int PrimaryTouchIndex = 0;
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadThumbStickComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC("VirtualGamepadThumbStickService"));
provided.push_back(AZ_CRC("UiInteractableService"));
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadThumbStickComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
incompatible.push_back(AZ_CRC("VirtualGamepadThumbStickService"));
incompatible.push_back(AZ_CRC("UiInteractableService"));
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadThumbStickComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
{
required.push_back(AZ_CRC("UiTransformService", 0x3a838e34));
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadThumbStickComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
{
AZ_UNUSED(dependent);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadThumbStickComponent::Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
{
serialize->Class<VirtualGamepadThumbStickComponent, AZ::Component>()
->Version(0)
->Field("AssignedInputChannelName", &VirtualGamepadThumbStickComponent::m_assignedInputChannelName)
->Field("ThumbStickImageCentre", &VirtualGamepadThumbStickComponent::m_thumbStickImageCentre)
->Field("ThumbStickImageRadial", &VirtualGamepadThumbStickComponent::m_thumbStickImageRadial)
->Field("CentreWhenPressed", &VirtualGamepadThumbStickComponent::m_centreWhenPressed)
->Field("AdjustPositionWhilePressed", &VirtualGamepadThumbStickComponent::m_adjustPositionWhilePressed)
;
if (AZ::EditContext* ec = serialize->GetEditContext())
{
ec->Class<VirtualGamepadThumbStickComponent>("VirtualGamepadThumbStick", "A component that designates this entity as a virtual gamepad thumb-stick")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/UiVirtualThumbStick.png")
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Editor/Icons/Components/Viewport/UiVirtualThumbStick.png")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("UI", 0x27ff46b0))
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(AZ::Edit::UIHandlers::ComboBox, &VirtualGamepadThumbStickComponent::m_assignedInputChannelName,
"Input Channel", "The input channel that will be updated when the user interacts with this virtual control")
->Attribute(AZ::Edit::Attributes::StringList, &VirtualGamepadThumbStickComponent::GetAssignableInputChannelNames)
->DataElement(AZ::Edit::UIHandlers::ComboBox, &VirtualGamepadThumbStickComponent::m_thumbStickImageCentre,
"Thumb Stick Image Centre", "The child element that will be positioned at the centre of the virtual thumb-stick.")
->Attribute(AZ::Edit::Attributes::EnumValues, &VirtualGamepadThumbStickComponent::GetChildEntityIdNamePairs)
->DataElement(AZ::Edit::UIHandlers::ComboBox, &VirtualGamepadThumbStickComponent::m_thumbStickImageRadial,
"Thumb Stick Image Radial", "The child element that will be positioned under the user's finger while the virtual thumb-stick is active.\n"
"The position of this image will always be clamped to the radial edge of the virtual thumb-stick centre image.")
->Attribute(AZ::Edit::Attributes::EnumValues, &VirtualGamepadThumbStickComponent::GetChildEntityIdNamePairs)
->DataElement(AZ::Edit::UIHandlers::CheckBox, &VirtualGamepadThumbStickComponent::m_centreWhenPressed,
"Centre When Pressed", "Whether or not to centre the virtual thumb-stick when it is pressed.")
->DataElement(AZ::Edit::UIHandlers::CheckBox, &VirtualGamepadThumbStickComponent::m_adjustPositionWhilePressed,
"Adjust Position While Pressed", "Whether or not to adjust the position of the virtual thumb-stick while it is active,\n"
"such that it will track the user's finger when it moves outside the thumb-stick radius.")
;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadThumbStickComponent::Init()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadThumbStickComponent::Activate()
{
m_activeTouchIndex = InactiveTouchIndex;
m_currentAxisValuesNormalized = AZ::Vector2::CreateZero();
m_currentViewportPositionPixels = AZ::Vector2::CreateZero();
VirtualGamepadThumbStickRequestBus::Handler::BusConnect(m_assignedInputChannelName);
UiInteractableBus::Handler::BusConnect(GetEntityId());
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadThumbStickComponent::Deactivate()
{
UiInteractableBus::Handler::BusDisconnect(GetEntityId());
VirtualGamepadThumbStickRequestBus::Handler::BusDisconnect(m_assignedInputChannelName);
m_currentViewportPositionPixels = AZ::Vector2::CreateZero();
m_currentAxisValuesNormalized = AZ::Vector2::CreateZero();
m_activeTouchIndex = InactiveTouchIndex;
}
////////////////////////////////////////////////////////////////////////////////////////////////
bool VirtualGamepadThumbStickComponent::CanHandleEvent(AZ::Vector2 point)
{
AZ_UNUSED(point);
return m_activeTouchIndex == InactiveTouchIndex;
}
////////////////////////////////////////////////////////////////////////////////////////////////
bool VirtualGamepadThumbStickComponent::HandlePressed(AZ::Vector2 point, bool& shouldStayActive)
{
shouldStayActive = false;
return OnAnyTouchPressed(point, PrimaryTouchIndex);
}
////////////////////////////////////////////////////////////////////////////////////////////////
bool VirtualGamepadThumbStickComponent::HandleReleased(AZ::Vector2 point)
{
return OnAnyTouchReleased(point, PrimaryTouchIndex);
}
////////////////////////////////////////////////////////////////////////////////////////////////
bool VirtualGamepadThumbStickComponent::HandleMultiTouchPressed(AZ::Vector2 point, int multiTouchIndex)
{
return OnAnyTouchPressed(point, multiTouchIndex);
}
////////////////////////////////////////////////////////////////////////////////////////////////
bool VirtualGamepadThumbStickComponent::HandleMultiTouchReleased(AZ::Vector2 point, int multiTouchIndex)
{
return OnAnyTouchReleased(point, multiTouchIndex);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadThumbStickComponent::InputPositionUpdate(AZ::Vector2 point)
{
OnAnyTouchPositionUpdate(point, PrimaryTouchIndex);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadThumbStickComponent::MultiTouchPositionUpdate(AZ::Vector2 point, int multiTouchIndex)
{
OnAnyTouchPositionUpdate(point, multiTouchIndex);
}
////////////////////////////////////////////////////////////////////////////////////////////////
AZ::Vector2 VirtualGamepadThumbStickComponent::GetCurrentAxisValuesNormalized() const
{
return m_currentAxisValuesNormalized;
}
////////////////////////////////////////////////////////////////////////////////////////////////
bool VirtualGamepadThumbStickComponent::OnAnyTouchPressed(AZ::Vector2 viewportPositionPixels,
int touchIndex)
{
if (m_activeTouchIndex != InactiveTouchIndex)
{
return false;
}
// Set the active touch index, current thumb-stick position, and axis values
m_activeTouchIndex = touchIndex;
m_currentAxisValuesNormalized = AZ::Vector2::CreateZero();
// Store the default thumb-stick position and radius
UiTransformInterface::RectPoints rectPoints;
UiTransformBus::Event(m_thumbStickImageCentre,
&UiTransformInterface::GetViewportSpacePoints,
rectPoints);
m_thumbStickPixelRadius = AZStd::max(rectPoints.GetAxisAlignedSize().GetX() * 0.5f, 1.0f);
UiTransformBus::EventResult(m_defaultViewportPositionPixels,
m_thumbStickImageCentre,
&UiTransformInterface::GetViewportPosition);
if (m_centreWhenPressed)
{
// Position both thumb-stick images at the touch start position
m_currentViewportPositionPixels = viewportPositionPixels;
UiTransformBus::Event(m_thumbStickImageCentre,
&UiTransformInterface::SetViewportPosition,
m_currentViewportPositionPixels);
UiTransformBus::Event(m_thumbStickImageRadial,
&UiTransformInterface::SetViewportPosition,
m_currentViewportPositionPixels);
}
else
{
// Leave both thumb-sticks at their default position
m_currentViewportPositionPixels = m_defaultViewportPositionPixels;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////
bool VirtualGamepadThumbStickComponent::OnAnyTouchReleased(AZ::Vector2 viewportPositionPixels,
int touchIndex)
{
AZ_UNUSED(viewportPositionPixels);
if (m_activeTouchIndex != touchIndex)
{
return false;
}
// Reset the active touch index, current thumb-stick position, and axis values
m_activeTouchIndex = InactiveTouchIndex;
m_currentViewportPositionPixels = AZ::Vector2::CreateZero();
m_currentAxisValuesNormalized = AZ::Vector2::CreateZero();
// Position both thumb-stick images at their default position
UiTransformBus::Event(m_thumbStickImageCentre,
&UiTransformInterface::SetViewportPosition,
m_defaultViewportPositionPixels);
UiTransformBus::Event(m_thumbStickImageRadial,
&UiTransformInterface::SetViewportPosition,
m_defaultViewportPositionPixels);
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////
void VirtualGamepadThumbStickComponent::OnAnyTouchPositionUpdate(AZ::Vector2 viewportPositionPixels,
[[maybe_unused]] int touchIndex)
{
// Calculate the current virtual thumb-stick axis values
AZ::Vector2 pixelDelta = viewportPositionPixels - m_currentViewportPositionPixels;
const float deltaLength = pixelDelta.GetLength();
if (deltaLength > m_thumbStickPixelRadius)
{
if (m_adjustPositionWhilePressed)
{
// Reposition the centre virtual thumb-stick image so the press stays at the edge
AZ::Vector2 radialDelta = pixelDelta;
radialDelta.SetLength(deltaLength - m_thumbStickPixelRadius);
m_currentViewportPositionPixels += radialDelta;
UiTransformBus::Event(m_thumbStickImageCentre,
&UiTransformInterface::SetViewportPosition,
m_currentViewportPositionPixels);
}
// Clamp the pixel delta to the radius of the thumb-stick
pixelDelta *= m_thumbStickPixelRadius / deltaLength;
}
// Position the radial thumb-stick image accordingly
const AZ::Vector2 radialImagePosition = m_currentViewportPositionPixels + pixelDelta;
UiTransformBus::Event(m_thumbStickImageRadial,
&UiTransformInterface::SetViewportPosition,
radialImagePosition);
// Set the current normalized axis values
m_currentAxisValuesNormalized.SetX(pixelDelta.GetX() / m_thumbStickPixelRadius);
m_currentAxisValuesNormalized.SetY(-pixelDelta.GetY() / m_thumbStickPixelRadius);
}
////////////////////////////////////////////////////////////////////////////////////////////////
AZStd::vector<AZStd::string> VirtualGamepadThumbStickComponent::GetAssignableInputChannelNames() const
{
AZStd::unordered_set<AZStd::string> buttonNames;
VirtualGamepadRequestBus::BroadcastResult(buttonNames, &VirtualGamepadRequests::GetThumbStickNames);
AZStd::vector<AZStd::string> assignableInputChannelNames;
for (const AZStd::string& buttonName : buttonNames)
{
assignableInputChannelNames.push_back(buttonName);
}
AZStd::sort(assignableInputChannelNames.begin(), assignableInputChannelNames.end());
return assignableInputChannelNames;
}
////////////////////////////////////////////////////////////////////////////////////////////////
AZStd::vector<AZStd::pair<AZ::EntityId, AZStd::string>> VirtualGamepadThumbStickComponent::GetChildEntityIdNamePairs() const
{
AZStd::vector<AZStd::pair<AZ::EntityId, AZStd::string>> result;
// Add a first entry for "None"
result.push_back(AZStd::make_pair(AZ::EntityId(AZ::EntityId()), "<None>"));
// Get a list of all child elements and add them to the result
LyShine::EntityArray childElements;
UiElementBus::EventResult(childElements, GetEntityId(), &UiElementInterface::GetChildElements);
for (const auto& childElement : childElements)
{
result.push_back(AZStd::make_pair(AZ::EntityId(childElement->GetId()), childElement->GetName()));
}
return result;
}
} // namespace VirtualGamepad
@@ -0,0 +1,176 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include "VirtualGamepadThumbStickRequestBus.h"
#include <LyShine/Bus/UiInteractableBus.h>
#include <AzCore/Component/Component.h>
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace VirtualGamepad
{
////////////////////////////////////////////////////////////////////////////////////////////////
class VirtualGamepadThumbStickComponent : public AZ::Component
, public UiInteractableBus::Handler
, public VirtualGamepadThumbStickRequestBus::Handler
{
public:
////////////////////////////////////////////////////////////////////////////////////////////
// AZ::Component Setup
AZ_COMPONENT(VirtualGamepadThumbStickComponent, "{F3B59A92-BD6F-9CEC-A751-2EBC699992C5}", AZ::Component);
////////////////////////////////////////////////////////////////////////////////////////////
// AZ::ComponentDescriptor Services
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref AZ::ComponentDescriptor::Reflect
static void Reflect(AZ::ReflectContext* context);
protected:
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref AZ::Component::Init
void Init() override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref AZ::Component::Activate
void Activate() override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref AZ::Component::Deactivate
void Deactivate() override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref UiInteractableInterface::CanHandleEvent
bool CanHandleEvent(AZ::Vector2 point) override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref UiInteractableInterface::HandlePressed
bool HandlePressed(AZ::Vector2 point, bool& shouldStayActive) override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref UiInteractableInterface::HandleReleased
bool HandleReleased(AZ::Vector2 point) override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref UiInteractableInterface::HandleMultiTouchPressed
bool HandleMultiTouchPressed(AZ::Vector2 point, int multiTouchIndex) override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref UiInteractableInterface::HandleMultiTouchReleased
bool HandleMultiTouchReleased(AZ::Vector2 point, int multiTouchIndex) override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref UiInteractableInterface::InputPositionUpdate
void InputPositionUpdate(AZ::Vector2 point) override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref UiInteractableInterface::MultiTouchPositionUpdate
void MultiTouchPositionUpdate(AZ::Vector2 point, int multiTouchIndex) override;
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref UiInteractableInterface::HandleHoverStart
void HandleHoverStart() override {}
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref UiInteractableInterface::HandleHoverEnd
void HandleHoverEnd() override {}
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref UiInteractableInterface::GetIsAutoActivationEnabled
bool GetIsAutoActivationEnabled() override { return false; }
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref UiInteractableInterface::SetIsAutoActivationEnabled
void SetIsAutoActivationEnabled(bool) override {}
////////////////////////////////////////////////////////////////////////////////////////////
//! \ref VirtualGamepad::VirtualGamepadThumbStickRequests::GetCurrentAxisValuesNormalized
AZ::Vector2 GetCurrentAxisValuesNormalized() const override;
////////////////////////////////////////////////////////////////////////////////////////////
//! Called when any touch is pressed
//! \param[in] viewportPositionPixels The viewport position of the touch in pixels
//! \param[in] touchIndex The touch index (0 based)
//! \return True if the touch was handled, false otherwise
bool OnAnyTouchPressed(AZ::Vector2 viewportPositionPixels, int touchIndex);
////////////////////////////////////////////////////////////////////////////////////////////
//! Called when any touch is released
//! \param[in] viewportPositionPixels The viewport position of the touch in pixels
//! \param[in] touchIndex The touch index (0 based)
//! \return True if the touch was handled, false otherwise
bool OnAnyTouchReleased(AZ::Vector2 viewportPositionPixels, int touchIndex);
////////////////////////////////////////////////////////////////////////////////////////////
//! Called when any touch position is updated
//! \param[in] viewportPositionPixels The viewport position of the touch in pixels
//! \param[in] touchIndex The touch index (0 based)
void OnAnyTouchPositionUpdate(AZ::Vector2 viewportPositionPixels, int touchIndex);
////////////////////////////////////////////////////////////////////////////////////////////
//! Get all potentially assignable input channel names
AZStd::vector<AZStd::string> GetAssignableInputChannelNames() const;
////////////////////////////////////////////////////////////////////////////////////////////
//! Get all child entity id/name pairs
AZStd::vector<AZStd::pair<AZ::EntityId, AZStd::string>> GetChildEntityIdNamePairs() const;
private:
////////////////////////////////////////////////////////////////////////////////////////////
//! The input channel that will be updated when the user interacts with this virtual control
AZStd::string m_assignedInputChannelName;
////////////////////////////////////////////////////////////////////////////////////////////
//! The ui element that will be drawn at the centre of the virtual thumb-stick while active
AZ::EntityId m_thumbStickImageCentre;
////////////////////////////////////////////////////////////////////////////////////////////
//! The ui element that will be drawn at the radius of the virtual thumb-stick while active
AZ::EntityId m_thumbStickImageRadial;
////////////////////////////////////////////////////////////////////////////////////////////
//! The default viewport position of the virtual thumb-stick in pixels
AZ::Vector2 m_defaultViewportPositionPixels;
////////////////////////////////////////////////////////////////////////////////////////////
//! The current viewport position of the virtual thumb-stick in pixels
AZ::Vector2 m_currentViewportPositionPixels;
////////////////////////////////////////////////////////////////////////////////////////////
//! The current virtual thumb-stick axis values normalized
AZ::Vector2 m_currentAxisValuesNormalized;
////////////////////////////////////////////////////////////////////////////////////////////
//! The pixel radius of the virtual thumb-stick in pixels
float m_thumbStickPixelRadius;
////////////////////////////////////////////////////////////////////////////////////////////
//! The index of the currently active touch index
int m_activeTouchIndex;
////////////////////////////////////////////////////////////////////////////////////////////
//! Whether or not to centre the virtual thumb-stick when it is pressed
bool m_centreWhenPressed = true;
////////////////////////////////////////////////////////////////////////////////////////////
//! Whether or not to adjust the position of the virtual thumb-stick while it is pressed, so
//! that the pressed finger will always remain within the radius of the thumb-stick image.
bool m_adjustPositionWhilePressed = true;
};
} // namespace VirtualGamepad
@@ -0,0 +1,39 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/Math/Vector2.h>
#include <AzCore/std/string/string.h>
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace VirtualGamepad
{
////////////////////////////////////////////////////////////////////////////////////////////////
class VirtualGamepadThumbStickRequests : public AZ::EBusTraits
{
public:
////////////////////////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
using BusIdType = AZStd::string;
////////////////////////////////////////////////////////////////////////////////////////////
//! Get the current virtual thumb-stick axis values
//! \return Current virtual thumb-stick axis values
virtual AZ::Vector2 GetCurrentAxisValuesNormalized() const = 0;
};
using VirtualGamepadThumbStickRequestBus = AZ::EBus<VirtualGamepadThumbStickRequests>;
}
@@ -0,0 +1,13 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "VirtualGamepad_precompiled.h"
@@ -0,0 +1,13 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once