123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- """
- 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 : C12712452
- # Test Case Title : Verify ScriptCanvas Collision Events
- # fmt: off
- class Tests:
- enter_game_mode = ("Entered game mode", "Failed to enter game mode")
- terrain_found_valid = ("PhysX Terrain found and validated", "PhysX Terrain not found and validated")
- sphere_found_valid = ("Sphere found and validated", "Sphere not found and validated")
- begin_signal_found_valid = ("Begin Signal found and validated", "Begin Signal not found and validated")
- persist_signal_found_valid = ("Persist Signal found and validated", "Persist Signal not found and validated")
- end_signal_found_valid = ("End Signal found and validated", "End Signal not found and validated")
- sphere_above_terrain = ("Sphere is above terrain", "Sphere is not above terrain")
- sphere_gravity_enabled = ("Gravity is enabled on Sphere", "Gravity is not enabled on Sphere")
- sphere_started_bouncing = ("Sphere started bouncing", "Sphere did not start bouncing")
- sphere_stopped_bouncing = ("Sphere stopped bouncing", "Sphere did not stop bouncing")
- event_records_match = ("Event records match", "Event records do not match")
- exit_game_mode = ("Exited game mode", "Failed to exit game mode")
- # fmt: on
- def ScriptCanvas_CollisionEvents():
- """
- Summary:
- This script runs an automated test to verify that the Script Canvas nodes "On Collision Begin", "On Collision
- Persist", and "On Collision End" will function as intended for the entity to which their Script Canvas is attached.
- Level Description:
- A sphere (entity: Sphere) is above a terrain (entity: PhysX Terrain). The sphere has a PhysX Rigid Body, a PhysX
- Collider with shape Sphere, and gravity enabled. The sphere has a Script Canvas attached to it which will toggle the
- activation of three signal entities (entity: Begin Signal), (entity: Persist Signal), and (entity: End Signal).
- Begin Signal's activation will toggle (switch from activated to deactivated or vice versa) when a collision begins
- with the sphere, Persist Signal's activation will toggle when a collision persists with the sphere, and End Signal's
- activation will toggle when a collision ends with the sphere.
- Expected behavior:
- The sphere will fall toward and collide with the terrain. The sphere will bounce until it comes to rest. The Script
- Canvas will cause the signal entities to activate and deactivate in the same pattern as the collision events which
- occur on the sphere.
- Test Steps:
- 1) Open level and enter game mode
- 2) Retrieve and validate entities
- 3) Check that the sphere is above the terrain
- 4) Check that gravity is enabled on the sphere
- 5) Wait for the initial collision between the sphere and the terrain or timeout
- 6) Wait for the sphere to stop bouncing
- 7 Check that the event records match
- 8) Exit game mode and close editor
- Note:
- - This test file must be called from the Open 3D Engine Editor command terminal
- - Any passed and failed tests are written to the Editor.log file.
- Parsing the file or running a log_monitor are required to observe the test results.
- :return: None
- """
- # Setup path
- import os
- import sys
- import azlmbr.legacy.general as general
- import azlmbr.bus
- import azlmbr.components
- import azlmbr.entity
- import azlmbr.physics
- from editor_python_test_tools.utils import Report
- from editor_python_test_tools.utils import TestHelper as helper
- # Constants
- TIME_OUT_SECONDS = 3.0
- TERRAIN_START_Z = 32.0
- SPHERE_RADIUS = 1.0
- class Entity:
- def __init__(self, name, found_valid_test):
- self.name = name
- self.id = general.find_game_entity(name)
- self.found_valid_test = found_valid_test
- class Sphere(Entity):
- def __init__(self, name, found_valid_test, event_records_match_test):
- Entity.__init__(self, name, found_valid_test)
- self.event_records_match_test = event_records_match_test
- self.collided = False
- self.stopped_bouncing = False
- self.collision_event_record = []
- self.script_canvas_event_record = []
- # Set up collision notification handler
- self.handler = azlmbr.physics.CollisionNotificationBusHandler()
- self.handler.connect(self.id)
- self.handler.add_callback("OnCollisionBegin", self.on_collision_begin)
- self.handler.add_callback("OnCollisionPersist", self.on_collision_persist)
- self.handler.add_callback("OnCollisionEnd", self.on_collision_end)
- def get_z_position(self):
- z_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", self.id)
- Report.info("{}'s z-position: {}".format(self.name, z_position))
- return z_position
- def is_gravity_enabled(self):
- return azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsGravityEnabled", self.id)
- # Set up reporting of the event records and whether they match
- def match_event_records(self):
- Report.info("{} collision event record: {}".format(self.name, self.collision_event_record))
- Report.info("Script Canvas event record: {}".format(self.script_canvas_event_record))
- return self.collision_event_record == self.script_canvas_event_record
- # Set up collision event detection and update collision event record
- def on_collision(self, event, other_id):
- if not self.collided:
- self.collided = True
- other_name = azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "GetEntityName", other_id)
- Report.info("{} collision {}s with {}".format(self.name, event, other_name))
- self.collision_event_record.append(event)
- def on_collision_begin(self, args):
- self.on_collision("begin", args[0])
- def on_collision_persist(self, args):
- self.on_collision("persist", args[0])
- def on_collision_end(self, args):
- self.on_collision("end", args[0])
- # Set up detection of the sphere coming to rest
- def bouncing_stopped(self):
- if not azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsAwake", self.id):
- self.stopped_bouncing = True
- return self.stopped_bouncing
- class SignalEntity(Entity):
- def __init__(self, name, found_valid_test, monitored_entity, event):
- Entity.__init__(self, name, found_valid_test)
- self.monitored_entity = monitored_entity
- self.event = event
- # Set up activation and deactivation notification handler
- self.handler = azlmbr.entity.EntityBusHandler()
- self.handler.connect(self.id)
- self.handler.add_callback("OnEntityActivated", self.on_entity_activated)
- self.handler.add_callback("OnEntityDeactivated", self.on_entity_deactivated)
- # Set up activation and deactivation detection and update Script Canvas event record
- def on_entity_activated(self, args):
- self.monitored_entity.script_canvas_event_record.append(self.event)
- def on_entity_deactivated(self, args):
- self.monitored_entity.script_canvas_event_record.append(self.event)
- # 1) Open level and enter game mode
- helper.init_idle()
- helper.open_level("Physics", "ScriptCanvas_CollisionEvents")
- helper.enter_game_mode(Tests.enter_game_mode)
- # 2) Retrieve and validate entities
- terrain = Entity("PhysX Terrain", Tests.terrain_found_valid)
- sphere = Sphere("Sphere", Tests.sphere_found_valid, Tests.event_records_match)
- begin_signal = SignalEntity("Begin Signal", Tests.begin_signal_found_valid, sphere, "begin")
- persist_signal = SignalEntity("Persist Signal", Tests.persist_signal_found_valid, sphere, "persist")
- end_signal = SignalEntity("End Signal", Tests.end_signal_found_valid, sphere, "end")
- entities = [terrain, sphere, begin_signal, persist_signal, end_signal]
- for entity in entities:
- Report.critical_result(entity.found_valid_test, entity.id.IsValid())
- # 3) Check that the sphere is above the terrain
- Report.critical_result(Tests.sphere_above_terrain, sphere.get_z_position() - SPHERE_RADIUS > TERRAIN_START_Z)
- # 4) Check that gravity is enabled on the sphere
- Report.critical_result(Tests.sphere_gravity_enabled, sphere.is_gravity_enabled())
- # 5) Wait for the initial collision between the sphere and the terrain or timeout
- helper.wait_for_condition(lambda: sphere.collided, TIME_OUT_SECONDS)
- Report.critical_result(Tests.sphere_started_bouncing, sphere.collided)
- # 6) Wait for the sphere to stop bouncing
- helper.wait_for_condition(sphere.bouncing_stopped, TIME_OUT_SECONDS)
- Report.result(Tests.sphere_stopped_bouncing, sphere.stopped_bouncing)
- # 7 Check that the event records match
- Report.result(Tests.event_records_match, sphere.match_event_records())
- # 8) Exit game mode and close editor
- helper.exit_game_mode(Tests.exit_game_mode)
- if __name__ == "__main__":
- from editor_python_test_tools.utils import Report
- Report.start_test(ScriptCanvas_CollisionEvents)
|