Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bi-directional door animations #16

Closed
pcbeard opened this issue Jan 7, 2024 · 5 comments
Closed

Bi-directional door animations #16

pcbeard opened this issue Jan 7, 2024 · 5 comments
Assignees
Labels
enhancement New feature or request

Comments

@pcbeard
Copy link
Contributor

pcbeard commented Jan 7, 2024

I've been working with these house assets and realized that the default animations it uses which open a door when a player character is nearby are a bit awkward to use when the doors open toward the character. Toward that end, I've prototyped a solution that I would love to see incorporated into Cogito, if possible. You can see what it looks like in this mastodon post.

The main idea would be to have the door swing inward if approached from one side, and outward from the other. I implemented this by adding another Area3D to determine which side the of the door the player is approaching from, and managing a simple state machine to run the animations.

@pcbeard
Copy link
Contributor Author

pcbeard commented Jan 7, 2024

Here's the GDScript code I wrote to implement this logic:

extends Node3D

@onready var animation = $AnimationPlayer

enum { CLOSED, CLOSING, OPENING, OPEN }
var door_state = CLOSED
var in_outside_area = false
var in_inside_area = false
var closing_animation = ""

func check_door_state():
	match door_state:
		CLOSED:
			if in_outside_area:
				door_state = OPENING
				animation.play("open_inward")
				closing_animation = "open_inward"
			elif in_inside_area:
				door_state = OPENING
				animation.play("open_outward")
				closing_animation = "open_outward"
		OPENING:
			pass
		CLOSING:
			pass
		OPEN:
			if !in_outside_area and !in_inside_area:
				door_state = CLOSING
				animation.play_backwards(closing_animation)

func _on_animation_player_animation_finished(anim_name):
	match door_state:
		OPENING:
			door_state = OPEN
		CLOSING:
			door_state = CLOSED
	check_door_state()

func _on_outside_area_3d_body_entered(body):
	if body is CharacterBody3D:
		in_outside_area = true
		check_door_state()

func _on_outside_area_3d_body_exited(body):
	if body is CharacterBody3D:
		in_outside_area = false
		check_door_state()

func _on_inside_area_3d_body_entered(body):
	if body is CharacterBody3D:
		in_inside_area = true
		check_door_state()
		
func _on_inside_area_3d_body_exited(body):
	if body is CharacterBody3D:
		in_inside_area = false
		check_door_state()

@Phazorknight
Copy link
Owner

Thanks for this.
Your script is based on how the doors work within that asset pack and the included script. As this is a different approach on how COGITO is set up, I'm not going to include it in the repo.

That being said: I understand the request was able to add this functionality to COGITO in a different way.
I've created a "door setter zone" script, that when attached to a zone can override a door's settings when the player enters said zone.
Putting on of these on each side of a door can create the behaviour you described.

You can see how it works here:

2024-01-07.09-04-13.mp4

I'll include this script in the next update, but if you want to give it a try earlier, here it is (with automatic signal hookup):

door_setter_zone.gd

extends Area3D

## Reference to the door that will get upated
@export var door_to_set : NodePath
## Setting the new open rotation position in degrees.
@export var new_open_rotation_deg : float
## Check this is the door is changing transform position instead of rotation
@export var is_sliding : bool
## The new open position transform coordinates
@export var new_open_pos : Vector3
## Check this is the door is animation based
@export var is_using_animations : bool
## Name of the new opening animation. This has to exist in the door's animation player to work.
@export var new_opening_animation : String

func _ready():
	body_entered.connect(_on_body_entered)
	
	
func _on_body_entered(body: Node3D):
	if !body.is_in_group("Player"):
		return
		
	if door_to_set != null:
		var door = get_node(door_to_set)
		if is_sliding:
			door.open_position = new_open_pos
		elif is_using_animations:
			door.opening_animation = new_opening_animation
		else:
			door.open_rotation_deg = new_open_rotation_deg
	

@Phazorknight Phazorknight added the enhancement New feature or request label Jan 7, 2024
@Phazorknight Phazorknight self-assigned this Jan 7, 2024
@pcbeard
Copy link
Contributor Author

pcbeard commented Jan 7, 2024

Looks great. I do like the option to have automatic doors too.

@Phazorknight
Copy link
Owner

I've added a quick update to door_setter_zone.gd which enables it to be used to set up automatic doors in experimental / BETA 202401.7

Ideally this script would be used to either update doors and their directions OR be used to create the automatic behaviour, due to how the zone signals get fired.

If you want to create a door that is automatic but also changes directions, I'd handle this in separate door_setter_zones that overlap:

  • door_setter_zone 1 would cover the whole area around the door and only handles opening and closing.
  • door_setter_zone 2 A and B are set up to each side of the door and override the door direction/etc.

Considering this issue as resolved.

@pcbeard
Copy link
Contributor Author

pcbeard commented Jan 29, 2024

Thanks for making this happen!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants