Walking through a portal (buggy)
This commit is contained in:
parent
7efb6d3e84
commit
11f61d62f4
@ -1,10 +1,10 @@
|
|||||||
"""
|
"""
|
||||||
Asset: Godot Simple Portal System
|
Asset: Godot Simple Portal System
|
||||||
File: collision_disable_area.gd
|
File: collision_disable_area.gd
|
||||||
Description: An area in which collisions are disabled for physics bodies based on the "disabled_collision_masks" metadata array.
|
Description: An area in which collisions are disabled for physics bodies based on the "disabled_collision_masks" metadata array.
|
||||||
Instructions: For detailed documentation, see the README or visit: https://github.com/Donitzo/godot-simple-portal-system
|
Instructions: For detailed documentation, see the README or visit: https://github.com/Donitzo/godot-simple-portal-system
|
||||||
Repository: https://github.com/Donitzo/godot-simple-portal-system
|
Repository: https://github.com/Donitzo/godot-simple-portal-system
|
||||||
License: CC0 License
|
License: CC0 License
|
||||||
"""
|
"""
|
||||||
|
|
||||||
extends Area3D
|
extends Area3D
|
||||||
@ -17,79 +17,79 @@ class_name CollisionDisableArea
|
|||||||
var _disables:Array = []
|
var _disables:Array = []
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
connect("body_entered", _on_body_entered)
|
connect("body_entered", _on_body_entered)
|
||||||
connect("body_exited", _on_body_exited)
|
connect("body_exited", _on_body_exited)
|
||||||
|
|
||||||
func _process(delta:float) -> void:
|
func _process(delta:float) -> void:
|
||||||
for i in range(_disables.size() - 1, -1, -1):
|
for i in range(_disables.size() - 1, -1, -1):
|
||||||
var disable_info:Dictionary = _disables[i]
|
var disable_info:Dictionary = _disables[i]
|
||||||
|
|
||||||
if not is_instance_valid(disable_info.body):
|
if not is_instance_valid(disable_info.body):
|
||||||
# Body has been freed, remove disable info
|
# Body has been freed, remove disable info
|
||||||
_disables.remove_at(i)
|
_disables.remove_at(i)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not disable_info.left:
|
if not disable_info.left:
|
||||||
# The body has yet to leave the area
|
# The body has yet to leave the area
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# The body left the area, so reduce its timeout before removal
|
# The body left the area, so reduce its timeout before removal
|
||||||
disable_info.seconds_until_enable -= delta
|
disable_info.seconds_until_enable -= delta
|
||||||
if disable_info.seconds_until_enable > 0:
|
if disable_info.seconds_until_enable > 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
_disables.remove_at(i)
|
_disables.remove_at(i)
|
||||||
|
|
||||||
# Re-enable collision masks
|
# Re-enable collision masks
|
||||||
for layer_number in disable_info.disabled_layers:
|
for layer_number in disable_info.disabled_layers:
|
||||||
# Only consider layers which were enabled to begin with
|
# Only consider layers which were enabled to begin with
|
||||||
if disable_info.disable_count.has(layer_number):
|
if disable_info.disable_count.has(layer_number):
|
||||||
# Decrement disables so only the final area actually disables the mask
|
# Decrement disables so only the final area actually disables the mask
|
||||||
disable_info.disable_count[layer_number] -= 1
|
disable_info.disable_count[layer_number] -= 1
|
||||||
if disable_info.disable_count[layer_number] == 0:
|
if disable_info.disable_count[layer_number] == 0:
|
||||||
# Final disable, so re-enable the collision mask
|
# Final disable, so re-enable the collision mask
|
||||||
disable_info.body.set_collision_mask_value(layer_number, true)
|
disable_info.body.set_collision_mask_value(layer_number, true)
|
||||||
|
|
||||||
func _on_body_entered(body:PhysicsBody3D) -> void:
|
func _on_body_entered(body:PhysicsBody3D) -> void:
|
||||||
if not body.has_meta("disabled_collision_masks"):
|
if not body.has_meta("disabled_collision_masks"):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Is the body already disabled by this area?
|
# Is the body already disabled by this area?
|
||||||
for disable_info in _disables:
|
for disable_info in _disables:
|
||||||
if disable_info.body == body:
|
if disable_info.body == body:
|
||||||
# Reset left and timeout
|
# Reset left and timeout
|
||||||
disable_info.left = false
|
disable_info.left = false
|
||||||
disable_info.seconds_until_enable = re_enable_delay_seconds
|
disable_info.seconds_until_enable = re_enable_delay_seconds
|
||||||
return
|
return
|
||||||
|
|
||||||
# Keep track of the number of times each collision mask is disabled in a meta field
|
# Keep track of the number of times each collision mask is disabled in a meta field
|
||||||
if not body.has_meta("collision_disable_count"):
|
if not body.has_meta("collision_disable_count"):
|
||||||
body.set_meta("collision_disable_count", {})
|
body.set_meta("collision_disable_count", {})
|
||||||
var disable_count:Dictionary = body.get_meta("collision_disable_count")
|
var disable_count:Dictionary = body.get_meta("collision_disable_count")
|
||||||
|
|
||||||
# Disable the collision masks specified in the "disabled_collision_masks" metadata array
|
# Disable the collision masks specified in the "disabled_collision_masks" metadata array
|
||||||
var disabled_layers:Array = body.get_meta("disabled_collision_masks")
|
var disabled_layers:Array = body.get_meta("disabled_collision_masks")
|
||||||
for layer_number in disabled_layers:
|
for layer_number in disabled_layers:
|
||||||
# Only consider layers which were enabled to begin with
|
# Only consider layers which were enabled to begin with
|
||||||
if disable_count.has(layer_number) or body.get_collision_mask_value(layer_number):
|
if disable_count.has(layer_number) or body.get_collision_mask_value(layer_number):
|
||||||
# Increment disables so only the first area actually disables the mask
|
# Increment disables so only the first area actually disables the mask
|
||||||
disable_count[layer_number] = 1 if not disable_count.has(layer_number) else disable_count[layer_number] + 1
|
disable_count[layer_number] = 1 if not disable_count.has(layer_number) else disable_count[layer_number] + 1
|
||||||
if disable_count[layer_number] == 1:
|
if disable_count[layer_number] == 1:
|
||||||
# First disable, so disable the collision mask
|
# First disable, so disable the collision mask
|
||||||
body.set_collision_mask_value(layer_number, false)
|
body.set_collision_mask_value(layer_number, false)
|
||||||
|
|
||||||
# Keep a reference to all current disables in the area
|
# Keep a reference to all current disables in the area
|
||||||
_disables.push_back({
|
_disables.push_back({
|
||||||
"body": body,
|
"body": body,
|
||||||
"disabled_layers": disabled_layers,
|
"disabled_layers": disabled_layers,
|
||||||
"disable_count": disable_count,
|
"disable_count": disable_count,
|
||||||
"seconds_until_enable": re_enable_delay_seconds,
|
"seconds_until_enable": re_enable_delay_seconds,
|
||||||
"left": false,
|
"left": false,
|
||||||
})
|
})
|
||||||
|
|
||||||
func _on_body_exited(body:PhysicsBody3D) -> void:
|
func _on_body_exited(body:PhysicsBody3D) -> void:
|
||||||
if body.has_meta("disabled_collision_masks"):
|
if body.has_meta("disabled_collision_masks"):
|
||||||
for disable_info in _disables:
|
for disable_info in _disables:
|
||||||
if disable_info.body == body:
|
if disable_info.body == body:
|
||||||
# Mark the body as having left the area
|
# Mark the body as having left the area
|
||||||
disable_info.left = true
|
disable_info.left = true
|
||||||
|
@ -10,16 +10,21 @@
|
|||||||
extends Area3D
|
extends Area3D
|
||||||
class_name SimplePortalTeleport
|
class_name SimplePortalTeleport
|
||||||
|
|
||||||
var _parent_portal:Portal
|
var _parent_portal: Portal
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
_parent_portal = get_parent() as Portal
|
_parent_portal = get_parent() as Portal
|
||||||
if _parent_portal == null:
|
if _parent_portal == null:
|
||||||
push_error("The PortalTeleport \"%s\" is not a child of a Portal instance" % name)
|
push_error("The PortalTeleport \"%s\" is not a child of a Portal instance" % name)
|
||||||
|
|
||||||
connect("area_entered", _on_area_entered)
|
area_entered.connect(_on_area_entered)
|
||||||
|
body_entered.connect(_on_body_entered)
|
||||||
|
|
||||||
func _on_area_entered(area:Area3D):
|
func _on_area_entered(area: Area3D) -> void:
|
||||||
if area.has_meta("teleportable_root"):
|
if area.has_meta("teleportable_root"):
|
||||||
var root:Node3D = area.get_node(area.get_meta("teleportable_root"))
|
var root:Node3D = area.get_node(area.get_meta("teleportable_root"))
|
||||||
root.global_transform = _parent_portal.real_to_exit_transform(root.global_transform)
|
root.global_transform = _parent_portal.real_to_exit_transform(root.global_transform)
|
||||||
|
|
||||||
|
func _on_body_entered(body: Node3D) -> void:
|
||||||
|
if body.has_meta("teleportable"):
|
||||||
|
body.global_transform = _parent_portal.real_to_exit_transform(body.global_transform)
|
||||||
|
44
main.tscn
44
main.tscn
@ -1,7 +1,10 @@
|
|||||||
[gd_scene load_steps=7 format=3 uid="uid://dpatwnepecl8r"]
|
[gd_scene load_steps=13 format=3 uid="uid://dpatwnepecl8r"]
|
||||||
|
|
||||||
[ext_resource type="MeshLibrary" uid="uid://bedqgubx1g1uf" path="res://prototypes.tres" id="1_ig7tw"]
|
[ext_resource type="MeshLibrary" uid="uid://bedqgubx1g1uf" path="res://prototypes.tres" id="1_ig7tw"]
|
||||||
[ext_resource type="Script" uid="uid://bp1bo57yqtv65" path="res://player.gd" id="2_0xm2m"]
|
[ext_resource type="Script" uid="uid://bp1bo57yqtv65" path="res://player.gd" id="2_0xm2m"]
|
||||||
|
[ext_resource type="ArrayMesh" uid="uid://bqilnvlfws6xh" path="res://portal-mesh.tres" id="3_1bvp3"]
|
||||||
|
[ext_resource type="Script" uid="uid://d2bvvjsibau8c" path="res://addons/simple-portal-system/scripts/portal.gd" id="4_lquwl"]
|
||||||
|
[ext_resource type="Script" uid="uid://bkv7t4hw21byg" path="res://addons/simple-portal-system/scripts/simple_portal_teleport.gd" id="5_lquwl"]
|
||||||
|
|
||||||
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_ig7tw"]
|
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_ig7tw"]
|
||||||
sky_horizon_color = Color(0.662243, 0.671743, 0.686743, 1)
|
sky_horizon_color = Color(0.662243, 0.671743, 0.686743, 1)
|
||||||
@ -13,13 +16,19 @@ sky_material = SubResource("ProceduralSkyMaterial_ig7tw")
|
|||||||
[sub_resource type="Environment" id="Environment_h2yge"]
|
[sub_resource type="Environment" id="Environment_h2yge"]
|
||||||
background_mode = 2
|
background_mode = 2
|
||||||
sky = SubResource("Sky_0xm2m")
|
sky = SubResource("Sky_0xm2m")
|
||||||
tonemap_mode = 2
|
|
||||||
glow_enabled = true
|
glow_enabled = true
|
||||||
|
|
||||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_0xm2m"]
|
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_0xm2m"]
|
||||||
radius = 0.4
|
radius = 0.05
|
||||||
height = 1.75
|
height = 1.75
|
||||||
|
|
||||||
|
[sub_resource type="Environment" id="Environment_lquwl"]
|
||||||
|
|
||||||
|
[sub_resource type="BoxShape3D" id="BoxShape3D_1bvp3"]
|
||||||
|
size = Vector3(2, 2.5, 0.2)
|
||||||
|
|
||||||
|
[sub_resource type="Environment" id="Environment_7mycd"]
|
||||||
|
|
||||||
[node name="Main" type="Node3D"]
|
[node name="Main" type="Node3D"]
|
||||||
|
|
||||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||||
@ -60,6 +69,7 @@ omni_range = 4.0
|
|||||||
[node name="Player" type="CharacterBody3D" parent="."]
|
[node name="Player" type="CharacterBody3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.28597, -3)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.28597, -3)
|
||||||
script = ExtResource("2_0xm2m")
|
script = ExtResource("2_0xm2m")
|
||||||
|
metadata/teleportable = true
|
||||||
|
|
||||||
[node name="Camera3D" type="Camera3D" parent="Player"]
|
[node name="Camera3D" type="Camera3D" parent="Player"]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.32153, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.32153, 0)
|
||||||
@ -67,3 +77,31 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.32153, 0)
|
|||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Player"]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="Player"]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.875, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.875, 0)
|
||||||
shape = SubResource("CapsuleShape3D_0xm2m")
|
shape = SubResource("CapsuleShape3D_0xm2m")
|
||||||
|
|
||||||
|
[node name="P_white_wide" type="MeshInstance3D" parent="." node_paths=PackedStringArray("exit_portal")]
|
||||||
|
transform = Transform3D(1.1, 0, 0, 0, 1.1, 0, 0, 0, 1.1, 0, 2, -6.5)
|
||||||
|
mesh = ExtResource("3_1bvp3")
|
||||||
|
script = ExtResource("4_lquwl")
|
||||||
|
exit_environment = SubResource("Environment_lquwl")
|
||||||
|
exit_portal = NodePath("../P_green_wide")
|
||||||
|
|
||||||
|
[node name="Teleport" type="Area3D" parent="P_white_wide"]
|
||||||
|
script = ExtResource("5_lquwl")
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="P_white_wide/Teleport"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.1)
|
||||||
|
shape = SubResource("BoxShape3D_1bvp3")
|
||||||
|
|
||||||
|
[node name="P_green_wide" type="MeshInstance3D" parent="." node_paths=PackedStringArray("exit_portal")]
|
||||||
|
transform = Transform3D(1.1, 0, 0, 0, 1.1, 0, 0, 0, 1.1, 16, 2, -6.5)
|
||||||
|
mesh = ExtResource("3_1bvp3")
|
||||||
|
script = ExtResource("4_lquwl")
|
||||||
|
exit_environment = SubResource("Environment_7mycd")
|
||||||
|
exit_portal = NodePath("../P_white_wide")
|
||||||
|
|
||||||
|
[node name="Teleport" type="Area3D" parent="P_green_wide"]
|
||||||
|
script = ExtResource("5_lquwl")
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="P_green_wide/Teleport"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.1)
|
||||||
|
shape = SubResource("BoxShape3D_1bvp3")
|
||||||
|
Loading…
Reference in New Issue
Block a user