Browse Source

3D physics tests - Moving platform (#623)

Agnis "NeZvērs" Aldiņš 4 years ago
parent
commit
2d4d23302a

+ 18 - 0
3d/physics_tests/project.godot

@@ -88,6 +88,24 @@ toggle_pause={
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":80,"unicode":0,"echo":false,"script":null)
  ]
 }
+character_right={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null)
+ ]
+}
+character_left={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"unicode":0,"echo":false,"script":null)
+ ]
+}
+character_jump={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"unicode":0,"echo":false,"script":null)
+ ]
+}
 
 [rendering]
 

+ 6 - 2
3d/physics_tests/tests.gd

@@ -35,13 +35,17 @@ var _tests = [
 		"path": "res://tests/functional/test_raycasting.tscn",
 	},
 	{
-		"id": "Functional Tests/RigidBody impact",
+		"id": "Functional Tests/RigidBody Impact",
 		"path": "res://tests/functional/test_rigidbody_impact.tscn",
 	},
 	{
-		"id": "Functional Tests/RigidBody ground check",
+		"id": "Functional Tests/RigidBody Ground Check",
 		"path": "res://tests/functional/test_rigidbody_ground_check.tscn",
 	},
+	{
+		"id": "Functional Tests/Moving Platform",
+		"path": "res://tests/functional/test_moving_platform.tscn",
+	},
 	{
 		"id": "Performance Tests/Broadphase",
 		"path": "res://tests/performance/test_perf_broadphase.tscn",

+ 137 - 0
3d/physics_tests/tests/functional/test_moving_platform.gd

@@ -0,0 +1,137 @@
+extends Test
+
+
+const OPTION_BODY_TYPE = "Body Type/%s (%d)"
+
+const OPTION_GRAVITY = "Physics options/Gravity on floor (Kinematic only)"
+const OPTION_SLOPE = "Physics options/Stop on slope (Kinematic only)"
+const OPTION_SNAP = "Physics options/Use snap (Kinematic only)"
+const OPTION_FRICTION = "Physics options/Friction (Rigid only)"
+const OPTION_ROUGH = "Physics options/Rough (Rigid only)"
+const OPTION_PROCESS_PHYSICS = "Physics options/AnimationPlayer physics process mode"
+
+var _gravity = false
+var _slope = false
+var _snap = false
+var _friction = false
+var _rough = false
+var _animation_physics = false
+
+var _body_scene = {}
+var _key_list = []
+var _current_body_index = 0
+var _current_body_key = ""
+var _current_body = null
+var _body_type = ["KinematicBody", "RigidBody"]
+
+
+func _ready():
+	var options = $Options
+	var bodies = $Bodies.get_children()
+	for i in bodies.size():
+		var body = bodies[i]
+		var option_name = OPTION_BODY_TYPE % [body.name, i + 1]
+		options.add_menu_item(option_name)
+		_key_list.append(option_name)
+		_body_scene[option_name] = get_packed_scene(body)
+		body.queue_free()
+
+	options.add_menu_item(OPTION_GRAVITY, true, false)
+	options.add_menu_item(OPTION_SLOPE, true, false)
+	options.add_menu_item(OPTION_SNAP, true, false)
+	options.add_menu_item(OPTION_FRICTION, true, false)
+	options.add_menu_item(OPTION_ROUGH, true, false)
+	options.add_menu_item(OPTION_PROCESS_PHYSICS, true, false)
+
+	options.connect("option_selected", self, "_on_option_selected")
+	options.connect("option_changed", self, "_on_option_changed")
+
+	spawn_body_index(_current_body_index)
+
+
+func _input(event):
+	var key_event = event as InputEventKey
+	if key_event and not key_event.pressed:
+		var _index = key_event.scancode - KEY_1
+		if _index >= 0 and _index < _key_list.size():
+			spawn_body_index(_index)
+
+
+func _on_option_selected(option):
+	if _body_scene.has(option):
+		spawn_body_key(option)
+
+
+func _on_option_changed(option, checked):
+	match option:
+		OPTION_GRAVITY:
+			_gravity = checked
+			spawn_body_index(_current_body_index)
+		OPTION_SLOPE:
+			_slope = checked
+			spawn_body_index(_current_body_index)
+		OPTION_SNAP:
+			_snap = checked
+			spawn_body_index(_current_body_index)
+		OPTION_FRICTION:
+			_friction = checked
+			spawn_body_index(_current_body_index)
+		OPTION_ROUGH:
+			_rough = checked
+			spawn_body_index(_current_body_index)
+		OPTION_PROCESS_PHYSICS:
+			_animation_physics = checked
+			spawn_body_index(_current_body_index)
+
+
+func spawn_body_index(body_index):
+	if _current_body:
+		_current_body.queue_free()
+	_current_body_index = body_index
+	_current_body_key = _key_list[body_index]
+	var body_parent = $Bodies
+	var body = _body_scene[_key_list[body_index]].instance()
+	body_parent.add_child(body)
+	_current_body = body
+	init_body()
+
+
+func spawn_body_key(body_key):
+	if _current_body:
+		_current_body.queue_free()
+	_current_body_key = body_key
+	_current_body_index = _key_list.find(body_key)
+	var body_parent = $Bodies
+	var body = _body_scene[body_key].instance()
+	body_parent.add_child(body)
+	_current_body = body
+	init_body()
+
+
+func init_body():
+	if _current_body is KinematicBody:
+		_current_body._gravity_on_floor = _gravity
+		_current_body._stop_on_slopes = _slope
+		_current_body._use_snap = _snap
+	elif _current_body is RigidBody:
+		_current_body.physics_material_override.rough = _rough
+		_current_body.physics_material_override.friction = 1.0 if _friction else 0.0
+
+	var animation_player = $Platforms/KinematicPlatform/AnimationPlayer
+	animation_player.stop()
+	if _animation_physics:
+		animation_player.playback_process_mode = AnimationPlayer.ANIMATION_PROCESS_PHYSICS
+	else:
+		animation_player.playback_process_mode = AnimationPlayer.ANIMATION_PROCESS_IDLE
+	animation_player.play("Move")
+
+	$LabelBodyType.text = "Body Type: " + _body_type[_current_body_index]
+
+
+func get_packed_scene(node):
+	node.owner = self
+	for child in node.get_children():
+		child.owner = node
+	var packed_scene = PackedScene.new()
+	packed_scene.pack(node)
+	return packed_scene

+ 86 - 0
3d/physics_tests/tests/functional/test_moving_platform.tscn

@@ -0,0 +1,86 @@
+[gd_scene load_steps=9 format=2]
+
+[ext_resource path="res://utils/camera_orbit.gd" type="Script" id=1]
+[ext_resource path="res://tests/functional/test_moving_platform.gd" type="Script" id=2]
+[ext_resource path="res://tests/test_options.tscn" type="PackedScene" id=3]
+[ext_resource path="res://utils/kinematicbody_physics.gd" type="Script" id=4]
+
+[sub_resource type="CapsuleShape" id=1]
+radius = 0.3
+
+[sub_resource type="PhysicsMaterial" id=2]
+
+[sub_resource type="BoxShape" id=3]
+extents = Vector3( 2, 0.2, 1 )
+
+[sub_resource type="Animation" id=4]
+length = 4.0
+tracks/0/type = "bezier"
+tracks/0/path = NodePath(".:translation:x")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/keys = {
+"points": PoolRealArray( -7, -0.25, 0, 0.25, 0, -7, -0.25, 0, 0.245766, 0.531658, 6, -0.132614, -0.374802, 0.25, 0 ),
+"times": PoolRealArray( 0, 0.5, 4 )
+}
+
+[node name="Test" type="Spatial"]
+script = ExtResource( 2 )
+
+[node name="LabelBodyType" type="Label" parent="."]
+margin_left = 14.0
+margin_top = 78.0
+margin_right = 171.0
+margin_bottom = 92.0
+text = "Body Type: "
+__meta__ = {
+"_edit_use_anchors_": false
+}
+
+[node name="Options" parent="." instance=ExtResource( 3 )]
+
+[node name="Bodies" type="Spatial" parent="."]
+
+[node name="KinematicBody" type="KinematicBody" parent="Bodies"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -7, -1.95, 0 )
+collision_layer = 2
+script = ExtResource( 4 )
+_stop_on_slopes = true
+_use_snap = true
+
+[node name="CollisionShape" type="CollisionShape" parent="Bodies/KinematicBody"]
+transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0.8, 0 )
+shape = SubResource( 1 )
+
+[node name="RigidBody" type="RigidBody" parent="Bodies"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -7, -1.95, 0 )
+collision_layer = 4
+physics_material_override = SubResource( 2 )
+axis_lock_angular_x = true
+axis_lock_angular_y = true
+axis_lock_angular_z = true
+
+[node name="CollisionShape" type="CollisionShape" parent="Bodies/RigidBody"]
+transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0.8, 0 )
+shape = SubResource( 1 )
+
+[node name="Platforms" type="Spatial" parent="."]
+
+[node name="KinematicPlatform" type="KinematicBody" parent="Platforms"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -7, -2, 0 )
+
+[node name="CollisionShape" type="CollisionShape" parent="Platforms/KinematicPlatform"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.2, 0 )
+shape = SubResource( 3 )
+
+[node name="AnimationPlayer" type="AnimationPlayer" parent="Platforms/KinematicPlatform"]
+anims/Move = SubResource( 4 )
+
+[node name="Camera" type="Camera" parent="."]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10 )
+script = ExtResource( 1 )
+
+[node name="OmniLight" type="OmniLight" parent="Camera"]
+omni_range = 50.0

+ 23 - 0
3d/physics_tests/utils/kinematicbody_physics.gd

@@ -0,0 +1,23 @@
+extends KinematicBody
+
+
+export(bool) var _gravity_on_floor = true
+export(bool) var _stop_on_slopes = false
+export(bool) var _use_snap = false
+
+var _gravity = 20.0
+var _velocity = Vector3.ZERO
+
+
+func _physics_process(delta):
+	var snap = Vector3.DOWN * 0.2
+	if is_on_floor() and _gravity_on_floor:
+		_velocity += Vector3.DOWN * _gravity * delta
+	else:
+		_velocity += Vector3.DOWN * _gravity * delta
+		snap = Vector3.ZERO
+
+	if _use_snap:
+		_velocity = move_and_slide_with_snap(_velocity, snap, Vector3.UP, _stop_on_slopes)
+	else:
+		_velocity = move_and_slide(_velocity, Vector3.UP, _stop_on_slopes)