Godot 3D 人物血条实现

原理其实很简单,将3D模型的坐标转为屏幕坐标,然后实时更新UI(血条)即可,直接上关键代码:

func updateUI(delta):
	#Update for UI
	#人物的全局坐标
	var world_pos = global_transform.origin
	#这里的uiSize即为血条的UI控件大小
	#camera = get_viewport().get_camera() 即为当前视图的摄像头
	#通过unproject_position将3D坐标转为屏幕坐标,这里由于人物坐标位于中心,所以需要做一定的偏移
	var pos = camera.unproject_position(world_pos) - 0.5 * uiSize
	pos.y -= 20 + uiSize.y 
	#更新UI坐标
	$Node2D/UnitView.position = pos
	#$Node2D/UnitView.updateStatus(currentHP, currentMala)
	pass

=======================================更新====================================================

上述方法有一定局限性,最大的问题在于本质上是2D形式来切合3D模型,如果模型不再屏幕之内就会比较麻烦,可以换个一个思路,通过ViewPort在3D模型上显示2D UI,直接上代码,将视图显示在mesh上(mesh与viewport同级,2D视图挂在viewport下):

#Viewport脚本
extends Viewport


# Called when the node enters the scene tree for the first time.
func _ready():
	var mesh : MeshInstance = get_node_or_null("../MeshInstance")
	mesh.material_override.params_billboard_mode = true
	mesh.material_override.albedo_texture = get_texture()
	pass # Replace with function body.


#MeshInstance脚本
extends MeshInstance

func _ready():
	pass # Replace with function body.

func _physics_process(delta):
    #旋转camera,测试
	get_node("../CameraHub").rotation_degrees.y += delta * 60
	pass


或则直接作为一个texture显示在Sprite3D中(viewport作为字节点挂在Sprite3D下,2D视图挂在viewport下):

extends Sprite3D

# Called when the node enters the scene tree for the first time.
func _ready():
	billboard = SpatialMaterial.BILLBOARD_ENABLED
	texture = $Viewport.get_texture()
#	$Viewport.usage = Viewport.USAGE_2D
	$Viewport.transparent_bg = true
#	$Viewport.render_target_v_flip = true
	pass # Replace with function body.

参考:https://blog.csdn.net/ttm2d/article/details/100179747

你可能感兴趣的:(Godot,游戏开发)