123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- """
- 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.
- """
- # Built-in Imports
- from __future__ import annotations
- from typing import List, Tuple, Union
- # Helper file Imports
- import utils
- # Lumberyard Imports
- import azlmbr
- import azlmbr.bus as bus
- import azlmbr.editor as editor
- import azlmbr.math as math
- import azlmbr.legacy.general as general
- class EditorComponent:
- """
- EditorComponent class used to set and get the component property value using path
- EditorComponent object is returned from either of
- EditorEntity.add_component() or Entity.add_components() or EditorEntity.get_component_objects()
- which also assigns self.id and self.type_id to the EditorComponent object.
- """
- # Methods
- def get_component_name(self) -> str:
- """
- Used to get name of component
- :return: name of component
- """
- type_names = editor.EditorComponentAPIBus(bus.Broadcast, "FindComponentTypeNames", [self.type_id])
- assert len(type_names) != 0, "Component object does not have type id"
- return type_names[0]
- def get_property_tree(self):
- """
- Used to get the property tree object of component that has following functions associated with it:
- 1. prop_tree.is_container(path)
- 2. prop_tree.get_container_count(path)
- 3. prop_tree.reset_container(path)
- 4. prop_tree.add_container_item(path, key, item)
- 5. prop_tree.remove_container_item(path, key)
- 6. prop_tree.update_container_item(path, key, value)
- 7. prop_tree.get_container_item(path, key)
- :return: Property tree object of a component
- """
- build_prop_tree_outcome = editor.EditorComponentAPIBus(
- bus.Broadcast, "BuildComponentPropertyTreeEditor", self.id
- )
- assert (
- build_prop_tree_outcome.IsSuccess()
- ), f"Failure: Could not build property tree of component: '{self.get_component_name()}'"
- prop_tree = build_prop_tree_outcome.GetValue()
- utils.Report.info(prop_tree.build_paths_list())
- return prop_tree
- def get_component_property_value(self, component_property_path: str):
- """
- Given a component property path, outputs the property's value
- :param component_property_path: String of component property. (e.g. 'Settings|Visible')
- :return: Value set in given component_property_path. Type is dependent on component property
- """
- get_component_property_outcome = editor.EditorComponentAPIBus(
- bus.Broadcast, "GetComponentProperty", self.id, component_property_path
- )
- assert (
- get_component_property_outcome.IsSuccess()
- ), f"Failure: Could not get value from {self.get_component_name()} : {component_property_path}"
- return get_component_property_outcome.GetValue()
- def set_component_property_value(self, component_property_path: str, value: object):
- """
- Used to set component property value
- :param component_property_path: Path of property in the component to act on
- :param value: new value for the variable being changed in the component
- """
- outcome = editor.EditorComponentAPIBus(
- bus.Broadcast, "SetComponentProperty", self.id, component_property_path, value
- )
- assert (
- outcome.IsSuccess()
- ), f"Failure: Could not set value to '{self.get_component_name()}' : '{component_property_path}'"
- @staticmethod
- def get_type_ids(component_names: list) -> list:
- """
- Used to get type ids of given components list
- :param: component_names: List of components to get type ids
- :return: List of type ids of given components.
- """
- type_ids = editor.EditorComponentAPIBus(
- bus.Broadcast, "FindComponentTypeIdsByEntityType", component_names, azlmbr.entity.EntityType().Game
- )
- return type_ids
- class EditorEntity:
- """
- Entity class is used to create and interact with Editor Entities.
- Example: To create Editor Entity, Use the code:
- test_entity = Entity.create_editor_entity("TestEntity")
- # This creates a python object with 'test_entity' linked to entity name "TestEntity" in Editor.
- # To add component, use:
- test_entity.add_component(<COMPONENT_NAME>)
- """
- def __init__(self, id: azlmbr.entity.EntityId):
- self.id: azlmbr.entity.EntityId = id
- # Creation functions
- @classmethod
- def find_editor_entity(cls, entity_name: str) -> EditorEntity:
- """
- Given Entity name, outputs entity object
- :param entity_name: Name of entity to find
- :return: EditorEntity class object
- """
- entity_id = general.find_editor_entity(entity_name)
- assert entity_id.IsValid(), f"Failure: Couldn't find entity with name: '{entity_name}'"
- entity = cls(entity_id)
- return entity
- @classmethod
- def create_editor_entity(cls, name: str = None, parent_id=None) -> EditorEntity:
- """
- Used to create entity at default position using 'CreateNewEntity' Bus
- :param name: Name of the Entity to be created
- :param parent_id: (optional) Used to create child entity under parent_id if specified
- :return: EditorEntity class object
- """
- if parent_id is None:
- parent_id = azlmbr.entity.EntityId()
- new_id = azlmbr.editor.ToolsApplicationRequestBus(bus.Broadcast, "CreateNewEntity", parent_id)
- assert new_id.IsValid(), "Failure: Could not create Editor Entity"
- entity = cls(new_id)
- if name:
- entity.set_name(name)
- return entity
- @classmethod
- def create_editor_entity_at(
- cls,
- entity_position: Union[List, Tuple, math.Vector3],
- name: str = None,
- parent_id: azlmbr.entity.EntityId = None,
- ) -> EditorEntity:
- """
- Used to create entity at position using 'CreateNewEntityAtPosition' Bus.
- :param entity_position: World Position(X, Y, Z) of entity in viewport.
- Example: [512.0, 512.0, 32.0]
- :param name: Name of the Entity to be created
- :parent_id: (optional) Used to create child entity under parent_id if specified
- :Example: test_entity = EditorEntity.create_editor_entity_at([512.0, 512.0, 32.0], "TestEntity")
- :return: EditorEntity class object
- """
- def convert_to_azvector3(xyz) -> math.Vector3:
- if isinstance(xyz, Tuple) or isinstance(xyz, List):
- assert len(xyz) == 3, ValueError("vector must be a 3 element list/tuple or azlmbr.math.Vector3")
- return math.Vector3(*xyz)
- elif isinstance(xyz, type(math.Vector3())):
- return xyz
- else:
- raise ValueError("vector must be a 3 element list/tuple or azlmbr.math.Vector3")
- if parent_id is None:
- parent_id = azlmbr.entity.EntityId()
- new_id = azlmbr.editor.ToolsApplicationRequestBus(
- bus.Broadcast, "CreateNewEntityAtPosition", convert_to_azvector3(entity_position), parent_id
- )
- assert new_id.IsValid(), "Failure: Could not create Editor Entity"
- entity = cls(new_id)
- if name:
- entity.set_name(name)
- return entity
- # Methods
- def set_name(self, entity_name: str):
- """
- Given entity_name, sets name to Entity
- :param: entity_name: Name of the entity to set
- """
- editor.EditorEntityAPIBus(bus.Event, "SetName", self.id, entity_name)
- def get_name(self) -> str:
- """
- Used to get the name of entity
- """
- return editor.EditorEntityInfoRequestBus(bus.Event, "GetName", self.id)
- def set_parent_entity(self, parent_entity_id):
- """
- Used to set this entity to be child of parent entity passed in
- :param: parent_entity_id: Entity Id of parent to set
- """
- assert (
- parent_entity_id.IsValid()
- ), f"Failure: Could not set parent to entity: {self.get_name()}, Invalid parent id"
- editor.EditorEntityAPIBus(bus.Event, "SetParent", self.id, parent_entity_id)
- def get_parent_id(self) -> azlmbr.entity.EntityId:
- """
- :return: Entity id of parent. Type: entity.EntityId()
- """
- return editor.EditorEntityInfoRequestBus(bus.Event, "GetParent", self.id)
- def add_component(self, component_name: str) -> EditorComponent:
- """
- Used to add new component to Entity.
- :param component_name: String of component name to add.
- :return: Component object of newly added component.
- """
- component = self.add_components([component_name])[0]
- return component
- def add_components(self, component_names: list) -> List[EditorComponent]:
- """
- Used to add multiple components
- :param: component_names: List of components to add to entity
- :return: List of newly added components to the entity
- """
- components = []
- type_ids = EditorComponent.get_type_ids(component_names)
- for type_id in type_ids:
- new_comp = EditorComponent()
- new_comp.type_id = type_id
- add_component_outcome = editor.EditorComponentAPIBus(
- bus.Broadcast, "AddComponentsOfType", self.id, [type_id]
- )
- assert (
- add_component_outcome.IsSuccess()
- ), f"Failure: Could not add component: '{new_comp.get_component_name()}' to entity: '{self.get_name()}'"
- new_comp.id = add_component_outcome.GetValue()[0]
- components.append(new_comp)
- return components
- def get_components_of_type(self, component_names: list) -> List[EditorComponent]:
- """
- Used to get components of type component_name that already exists on Entity
- :param component_name: Name to component to check
- :return: List of Entity Component objects of given component name
- """
- component_list = []
- type_ids = EditorComponent.get_type_ids(component_names)
- for type_id in type_ids:
- component = EditorComponent()
- component.type_id = type_id
- get_component_of_type_outcome = editor.EditorComponentAPIBus(
- bus.Broadcast, "GetComponentOfType", self.id, type_id
- )
- assert (
- get_component_of_type_outcome.IsSuccess()
- ), f"Failure: Entity: '{self.get_name()}' does not have component:'{component.get_component_name()}'"
- component.id = get_component_of_type_outcome.GetValue()
- component_list.append(component)
- return component_list
- def has_component(self, component_name: str) -> bool:
- """
- Used to verify if the entity has the specified component
- :param component_name: Name of component to check for
- :return: True, if entity has specified component. Else, False
- """
- type_ids = EditorComponent.get_type_ids([component_name])
- return editor.EditorComponentAPIBus(bus.Broadcast, "HasComponentOfType", self.id, type_ids[0])
- def get_start_status(self) -> int:
- """
- This will return a value for an entity's starting status (active, inactive, or editor) in the form of azlmbr.globals.property.EditorEntityStartStatus_<start type>. For comparisons using this value, should compare against the azlmbr property and not the int value
- """
- status = editor.EditorEntityInfoRequestBus(bus.Event, "GetStartStatus", self.id)
- if status == azlmbr.globals.property.EditorEntityStartStatus_StartActive:
- status_text = "active"
- elif status == azlmbr.globals.property.EditorEntityStartStatus_StartInactive:
- status_text = "inactive"
- elif status == azlmbr.globals.property.EditorEntityStartStatus_EditorOnly:
- status_text = "editor"
- utils.Report.info(f"The start status for {self.get_name} is {status_text}")
- self.start_status = status
- return status
- def set_start_status(self, desired_start_status: str):
- """
- Set an entity as active/inactive at beginning of runtime or it is editor-only,
- given its entity id and the start status then return set success
- :param desired_start_status: must be one of three choices: active, inactive, or editor
- """
- if desired_start_status == "active":
- status_to_set = azlmbr.globals.property.EditorEntityStartStatus_StartActive
- elif desired_start_status == "inactive":
- status_to_set = azlmbr.globals.property.EditorEntityStartStatus_StartInactive
- elif desired_start_status == "editor":
- status_to_set = azlmbr.globals.property.EditorEntityStartStatus_EditorOnly
- else:
- utils.Report.info(
- f"Invalid desired_start_status argument for {self.get_name} set_start_status command;\
- Use editor, active, or inactive"
- )
- editor.EditorEntityAPIBus(bus.Event, "SetStartStatus", self.id, status_to_set)
- set_status = self.get_start_status()
- assert set_status == status_to_set, f"Failed to set start status of {desired_start_status} to {self.get_name}"
|