68 lines
1.7 KiB
GDScript
68 lines
1.7 KiB
GDScript
class_name StaticObjectNode
|
|
extends Node3D
|
|
## A visual representation of a static world object within a chunk.
|
|
##
|
|
## This node is instantiated by [ChunkScene] for each static (non-dynamic)
|
|
## [WorldObject]. It renders the object's mesh (referenced by `asset_id`) at
|
|
## the object's transform. If the asset is not yet loaded, a placeholder mesh
|
|
## is shown.
|
|
##
|
|
## ## Structure
|
|
##
|
|
## ```
|
|
## StaticObjectNode (Node3D)
|
|
## └── MeshInstance3D # the object's visual mesh
|
|
## ```
|
|
|
|
## The world object data this node represents.
|
|
var world_object: WorldObject = null
|
|
|
|
## The loaded mesh instance (or placeholder).
|
|
var _mesh_instance: MeshInstance3D = null
|
|
|
|
|
|
func _ready() -> void:
|
|
if world_object == null:
|
|
return
|
|
_load_mesh()
|
|
|
|
|
|
## Load and attach the object's mesh.
|
|
func _load_mesh() -> void:
|
|
_mesh_instance = MeshInstance3D.new()
|
|
_mesh_instance.name = "mesh"
|
|
|
|
# Try to load the asset by its id (path). Fall back to a placeholder.
|
|
var mesh := _load_asset_mesh(world_object.asset_id)
|
|
if mesh == null:
|
|
mesh = _make_placeholder_mesh()
|
|
|
|
_mesh_instance.mesh = mesh
|
|
add_child(_mesh_instance)
|
|
|
|
|
|
## Attempt to load a mesh from the asset path.
|
|
func _load_asset_mesh(asset_id: String) -> Mesh:
|
|
if asset_id.is_empty():
|
|
return null
|
|
var path := "res://assets/%s" % asset_id
|
|
if ResourceLoader.exists(path):
|
|
var res := load(path)
|
|
if res is Mesh:
|
|
return res
|
|
return null
|
|
|
|
|
|
## Create a simple placeholder box mesh when the real asset is unavailable.
|
|
func _make_placeholder_mesh() -> Mesh:
|
|
var mesh := BoxMesh.new()
|
|
mesh.size = Vector3(1.0, 1.0, 1.0)
|
|
return mesh
|
|
|
|
|
|
## Get the world object's display name.
|
|
func get_display_name() -> String:
|
|
if world_object == null:
|
|
return ""
|
|
return world_object.get_display_name()
|