Porte à charnière

Une porte tenue par une charnière avec limite d'angle. Cliquez pour la pousser et voir où la limite arrête le battant.

L'éditeur ci-dessus fait tourner ce projet. Changez une ligne et il se recharge.

Classes Godot utilisées

HingeJoint3DRigidBody3DStaticBody3D

Le code

scripts/main.gd
extends Node

const DOOR_SIZE: Vector3 = Vector3(2.2, 3.2, 0.14)

var door: RigidBody3D


func _ready() -> void:
	_add_environment()
	_add_light()
	_add_ground()

	# the door hangs above the floor, resting on it would jam the hinge
	var post: StaticBody3D = _add_post(Vector3(-1.3, 2.1, 0))
	door = _add_door(Vector3(0.1, 2.1, 0))

	# HingeJoint3D turns on its own Z, so it lies down to stand the hinge upright
	var joint: HingeJoint3D = HingeJoint3D.new()
	joint.position = Vector3(-1.1, 2.1, 0)
	joint.rotation_degrees = Vector3(90, 0, 0)
	joint.set_param(HingeJoint3D.PARAM_LIMIT_LOWER, -PI * 0.6)
	joint.set_param(HingeJoint3D.PARAM_LIMIT_UPPER, PI * 0.6)
	joint.set_flag(HingeJoint3D.FLAG_USE_LIMIT, true)
	add_child(joint)

	joint.node_a = post.get_path()
	joint.node_b = door.get_path()

	var camera: Camera3D = Camera3D.new()
	camera.position = Vector3(2.5, 3.2, 6)
	add_child(camera)
	camera.look_at(Vector3(0, 1.8, 0), Vector3.UP)
	camera.current = true

	print('click to push the door, the hinge holds it and the limit stops it')


func _unhandled_input(event: InputEvent) -> void:
	if event is InputEventMouseButton and event.pressed and is_instance_valid(door):
		door.apply_impulse(Vector3(0, 0, -6), Vector3(1.0, 0, 0))


func _add_door(at: Vector3) -> RigidBody3D:
	var mesh: BoxMesh = BoxMesh.new()
	mesh.size = DOOR_SIZE

	var material: StandardMaterial3D = StandardMaterial3D.new()
	material.albedo_color = Color('#8da5f3')
	material.roughness = 0.5

	var visual: MeshInstance3D = MeshInstance3D.new()
	visual.mesh = mesh
	visual.material_override = material

	var shape: BoxShape3D = BoxShape3D.new()
	shape.size = DOOR_SIZE

	var collision: CollisionShape3D = CollisionShape3D.new()
	collision.shape = shape

	var body: RigidBody3D = RigidBody3D.new()
	body.position = at
	body.mass = 4.0
	body.add_child(visual)
	body.add_child(collision)
	add_child(body)

	return body


func _add_post(at: Vector3) -> StaticBody3D:
	var size: Vector3 = Vector3(0.3, 3.6, 0.3)

	var mesh: BoxMesh = BoxMesh.new()
	mesh.size = size

	var material: StandardMaterial3D = StandardMaterial3D.new()
	material.albedo_color = Color('#fc7f7f')

	var visual: MeshInstance3D = MeshInstance3D.new()
	visual.mesh = mesh
	visual.material_override = material

	var shape: BoxShape3D = BoxShape3D.new()
	shape.size = size

	var collision: CollisionShape3D = CollisionShape3D.new()
	collision.shape = shape

	var post: StaticBody3D = StaticBody3D.new()
	post.position = at
	post.add_child(visual)
	post.add_child(collision)
	add_child(post)

	return post


func _add_ground() -> void:
	var size: Vector3 = Vector3(20, 1, 20)

	var mesh: BoxMesh = BoxMesh.new()
	mesh.size = size

	var material: StandardMaterial3D = StandardMaterial3D.new()
	material.albedo_color = Color('#2a2f3d')

	var visual: MeshInstance3D = MeshInstance3D.new()
	visual.mesh = mesh
	visual.material_override = material

	var shape: BoxShape3D = BoxShape3D.new()
	shape.size = size

	var collision: CollisionShape3D = CollisionShape3D.new()
	collision.shape = shape

	var ground: StaticBody3D = StaticBody3D.new()
	ground.position = Vector3(0, -0.5, 0)
	ground.add_child(visual)
	ground.add_child(collision)
	add_child(ground)


func _add_environment() -> void:
	var sky_material: ProceduralSkyMaterial = ProceduralSkyMaterial.new()
	sky_material.sky_top_color = Color(0.05, 0.06, 0.12)
	sky_material.sky_horizon_color = Color(0.14, 0.16, 0.24)
	sky_material.ground_bottom_color = Color(0.02, 0.02, 0.04)
	sky_material.ground_horizon_color = Color(0.1, 0.11, 0.16)

	var sky: Sky = Sky.new()
	sky.sky_material = sky_material

	var env: Environment = Environment.new()
	env.background_mode = Environment.BG_SKY
	env.sky = sky
	env.ambient_light_source = Environment.AMBIENT_SOURCE_SKY
	env.ambient_light_energy = 0.8

	var world: WorldEnvironment = WorldEnvironment.new()
	world.environment = env
	add_child(world)


func _add_light() -> void:
	var light: DirectionalLight3D = DirectionalLight3D.new()
	light.rotation_degrees = Vector3(-50, -30, 0)
	light.light_energy = 1.2
	light.shadow_enabled = true
	add_child(light)

Plus d'exemples de Physique