You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
9.0 KiB
Python
207 lines
9.0 KiB
Python
"""
|
|
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
|
|
"""
|
|
|
|
# Test case ID : C12712453
|
|
# Test Case Title : Verify Raycast Multiple Node
|
|
|
|
|
|
# fmt:off
|
|
class Tests:
|
|
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
|
|
exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
|
|
test_completed = ("The test successfully completed", "The test timed out")
|
|
# entities found
|
|
caster_found = ("Caster entity found", "Caster entity NOT found")
|
|
multi_target_close_found = ("Multicast close target entity found", "Multicast close target NOT found")
|
|
multi_target_far_found = ("Multicast far target entity found", "Multicast far target NOT found")
|
|
single_target_found = ("Single close target entity found", "Single close target NOT found")
|
|
fail_entities_found = ("Found all fail entities", "Failed to find at least one fail entities")
|
|
# entity results
|
|
caster_result = ("Caster was activated", "Caster was NOT activated")
|
|
multi_target_close_result = ("Multicast close target was hit with a ray", "Multicast close target WAS NOT hit with a ray")
|
|
multi_target_far_result = ("Multicast far target was hit with a ray", "Multicast far target WAS NOT hit with a ray")
|
|
single_target_result = ("Single target was hit with a ray", "Single target WAS NOT hit with a ray")
|
|
|
|
# fmt:on
|
|
|
|
|
|
# Lines to search for by the log monitor
|
|
class Lines:
|
|
# FAILURE (in all caps) is used as the failure flag for both this python script and ScriptCanvas.
|
|
# If this is present in the log, something has gone fatally wrong and the test will fail.
|
|
# Additional details as to why the test fails will be printed in the log accompanying this entry.
|
|
unexpected = ["FAILURE"]
|
|
|
|
|
|
def C12712453_ScriptCanvas_MultipleRaycastNode():
|
|
"""
|
|
Summary:
|
|
Uses script canvas to cast two types of rays in game mode (multiple raycast and single raycast). Script canvas
|
|
validates the results from the raycasts, then deactivates any entities hit. This python script ensures only
|
|
the expected entities were deactivated.
|
|
|
|
Level Description:
|
|
Caster - A sphere with gravity disabled and a scriptcanvas component for emitting raycasts. Caster starts inactive.
|
|
Targets - Three spheres with gravity disabled. They are the expected targets of the raycasts.
|
|
Fail Boxes - These boxes are positioned in various places where no ray should collide with them. They are set
|
|
up print a fail message if any ray should hit them.
|
|
ScriptCanvas - The ScriptCanvas script is attached to the Caster entity, and is set to start on entity Activation.
|
|
The script will activate two different raycast nodes, a single raycast and a multiple raycast. For every raycast
|
|
hit, the script validates all properties of a raycast (while printing to log) and then deactivates any entity
|
|
that is [raycast] hit. This ScriptCanvas file can be found in this test's level folder named
|
|
"Raycast.scrpitcanvas".
|
|
|
|
Expected Behavior:
|
|
The level should load and appear to instantly close. After setup the Caster sphere should emit the raycasts which
|
|
should deactivate all expected Targets (via script canvas). The python script waits for the Targets to be
|
|
deactivated then prints the results.
|
|
|
|
Steps:
|
|
1) Load level / enter game mode
|
|
2) Retrieve entities
|
|
3) Start the test (activate the caster entity)
|
|
4) Wait for Target entities to deactivate
|
|
5) Exit game mode and close the editor
|
|
|
|
:return: None
|
|
"""
|
|
|
|
# Disabled until Script Canvas merges the new backend
|
|
return
|
|
|
|
import os
|
|
import sys
|
|
|
|
import ImportPathHelper as imports
|
|
|
|
imports.init()
|
|
|
|
from editor_python_test_tools.utils import Report
|
|
from editor_python_test_tools.utils import TestHelper as helper
|
|
|
|
import azlmbr.legacy.general as general
|
|
import azlmbr.bus
|
|
import azlmbr
|
|
|
|
# Constants
|
|
TIME_OUT = 1.0
|
|
FAIL_ENTITIES = 5
|
|
|
|
# Entity base class handles very general entity initialization
|
|
class EntityBase:
|
|
def __init__(self, name):
|
|
# type: (str) -> None
|
|
self.name = name
|
|
self.id = general.find_game_entity(name)
|
|
|
|
# Stores entity "is active" state. Most entities start as "Active"
|
|
self.activated = True
|
|
|
|
# Caster starts deactivated. When the caster is activated the script canvas test will begin.
|
|
class Caster(EntityBase):
|
|
def __init__(self, name):
|
|
# type: (str) -> None
|
|
EntityBase.__init__(self, name)
|
|
found_tuple = Tests.__dict__[name.lower() + "_found"]
|
|
Report.critical_result(found_tuple, self.id.isValid())
|
|
|
|
# Caster starts as "Inactive" because the script canvas starts when Caster is Activated
|
|
self.activated = False
|
|
|
|
# Activates the Caster which starts it's ScriptCanvas script (and the test)
|
|
def activate(self):
|
|
# type: () -> None
|
|
azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "ActivateGameEntity", self.id)
|
|
self.activated = True
|
|
Report.success(Tests.__dict__[self.name + "_result"])
|
|
|
|
# Targets start activated and only get deactivated by the ScriptCanvas script.
|
|
# Successful execution means every Target gets deactivated via ScriptCanvas
|
|
class Target(EntityBase):
|
|
def __init__(self, name):
|
|
# type: (str) -> None
|
|
EntityBase.__init__(self, name)
|
|
found_tuple = Tests.__dict__[name.lower() + "_found"]
|
|
Report.critical_result(found_tuple, self.id.isValid())
|
|
|
|
self.handler = azlmbr.entity.EntityBusHandler()
|
|
self.handler.connect(self.id)
|
|
self.handler.add_callback("OnEntityDeactivated", self.on_deactivation)
|
|
|
|
# Callback: gets called when entity is deactivated. This is expected for Target entities.
|
|
def on_deactivation(self, args):
|
|
# type: ([EntityId, ...]) -> None
|
|
if args[0].Equal(self.id):
|
|
Report.success(Tests.__dict__[self.name + "_result"])
|
|
self.activated = False
|
|
|
|
# Disconnects event handler.
|
|
# (Needed so the deactivation callback doesn't not get called on level clean up)
|
|
def disconnect(self):
|
|
# type: () -> None
|
|
self.handler.disconnect()
|
|
self.handler = None
|
|
|
|
# Failure entities start activated and get deactivated via the ScriptCanvas. Ideally none will be deactivated
|
|
# during the test. If one is deactivated, and Failure message is logged that will be caught by the log monitor.
|
|
class Failure(EntityBase):
|
|
def __init__(self, num):
|
|
# type: (int) -> None
|
|
EntityBase.__init__(self, "fail_" + str(num))
|
|
if not self.id.IsValid():
|
|
Report.info("FAILURE: {} could not be found".format(self.name))
|
|
self.handler = azlmbr.entity.EntityBusHandler()
|
|
self.handler.connect(self.id)
|
|
self.handler.add_callback("OnEntityDeactivated", self.on_deactivation)
|
|
|
|
# Callback: gets called when entity is deactivated. This is expected for Target entities.
|
|
def on_deactivation(self, args):
|
|
# type: ([EntityId, ...]) -> None
|
|
if args[0].Equal(self.id):
|
|
Report.info("{}: FAILURE".format(self.name))
|
|
self.activated = False
|
|
|
|
# Disconnects event handler.
|
|
# (Needed so the deactivation callback doesn't not get called on level clean up)
|
|
def disconnect(self):
|
|
# type: () -> None
|
|
self.handler.disconnect()
|
|
self.handler = None
|
|
|
|
# 1) Open level
|
|
helper.init_idle()
|
|
helper.open_level("Physics", "C12712453_ScriptCanvas_MultipleRaycastNode")
|
|
helper.enter_game_mode(Tests.enter_game_mode)
|
|
|
|
# 2) Retrieve entities
|
|
caster = Caster("caster")
|
|
targets = [Target("multi_target_close"), Target("multi_target_far"), Target("single_target")]
|
|
fails = [Failure(i) for i in range(FAIL_ENTITIES)]
|
|
Report.critical_result(Tests.fail_entities_found, all(entity.id.isValid() for entity in fails))
|
|
|
|
# 3) Start the test
|
|
caster.activate()
|
|
|
|
# 4) Wait for Target entities to deactivate
|
|
test_completed = helper.wait_for_condition(lambda: all(not target.activated for target in targets), TIME_OUT)
|
|
Report.result(Tests.test_completed, test_completed)
|
|
|
|
# Disconnect all "on deactivated" event handlers so they don't get called implicitly on level cleanup
|
|
for entity in targets + fails:
|
|
entity.disconnect()
|
|
|
|
# 5) Close test
|
|
helper.exit_game_mode(Tests.exit_game_mode)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import ImportPathHelper as imports
|
|
imports.init()
|
|
|
|
from editor_python_test_tools.utils import Report
|
|
Report.start_test(C12712453_ScriptCanvas_MultipleRaycastNode)
|