如何让2D箭头朝向3D物体?COD风格伤害指示器旋转偏移问题
解决伤害指示器旋转偏移(玩家转向后90度偏差)问题
问题描述
我正在制作类似《使命召唤》(Call of Duty)的伤害指示器:玩家受到攻击时,屏幕中央的箭头会指向攻击来源。目前遇到的问题是:当玩家朝向正前方(-Z轴)时,指示器旋转正常,左右移动也没问题,但玩家自身旋转后,指示器就会出现90度偏差,旋转逻辑失效。
原代码
func _physics_process(delta): if target_position == Vector3.ZERO: return rotate_to_target(target_position) func set_target(target : Vector3) -> void: target_position = target func rotate_to_target(target : Vector3) -> void: var player_position = PlayerProperties.player.global_position # Get the direction for the rotation var direction = (player_position - target).normalized() # Get the players rotation to influience the indicator direction = PlayerProperties.player.global_transform.basis * direction # Convert the direction into a angle that can be used # And offset the angle to follow the correct oritation var angle = atan2(direction.z,direction.x) - PI * 0.5 # Apply rotation to the damage indicator damage_indicator.rotation = angle
问题分析与修正
问题出在三个核心逻辑上:
- 方向向量搞反了:你计算的
player_position - target是玩家指向攻击来源的反方向,指示器应该指向攻击来源,所以要改成target - player_position。 - 空间转换方向错误:用
global_transform.basis * direction是把局部空间方向转成世界空间,但我们需要把世界空间的攻击方向转成玩家局部空间,所以得用basis.inverse()来做反向转换。 - 角度计算参数不匹配:原代码的atan2参数和偏移量对应错误,导致玩家旋转后角度偏差。
修正后的代码
func _physics_process(delta): if target_position == Vector3.ZERO: return rotate_to_target(target_position) func set_target(target : Vector3) -> void: target_position = target func rotate_to_target(target : Vector3) -> void: var player_position = PlayerProperties.player.global_position # 获取攻击来源相对于玩家的世界空间方向 var direction = (target - player_position).normalized() # 将世界方向转换为玩家局部空间,适配玩家自身旋转 direction = PlayerProperties.player.global_transform.basis.inverse() * direction # 计算局部空间下的旋转角度(适配-Z为正前方的设定) var angle = atan2(direction.x, direction.z) # 应用旋转到伤害指示器 damage_indicator.rotation = angle
关键修正点说明
- 方向向量修正:
target - player_position直接得到攻击来源在世界空间中相对于玩家的位置方向,确保指示器指向正确的来源。 - 空间转换:
basis.inverse()把世界空间的方向转换成玩家局部空间的方向,这样玩家无论怎么旋转,局部空间的正前方始终是玩家当前朝向,角度计算会以玩家自身为基准。 - 角度计算:用
atan2(direction.x, direction.z)计算局部空间内的角度,刚好匹配玩家-Z为正前方的设定,不需要额外的PI偏移。如果你的指示器初始朝向不对,可以根据UI布局微调偏移(比如加PI或PI/2)。
内容的提问来源于stack exchange,提问作者Dragon20C
相关产品推荐
相关产品推荐

