我有一个名为 Player 的GameObject和一个Canvas。 HealthBar GameObject是Canvas (Canvas> HealthBar)的子项。我有一个HP栏跟随玩家的脚本。它应该跟随玩家在其上方的固定位置,因此它位于精灵的顶部附近。 这是'关注' HP Follow Script的一部分。
void Update ()
{
Vector3 currentPos = transform.position;
Vector3 playerPos = Camera.main.WorldToViewportPoint (Player.transform.position);
transform.position = playerPos;
问题在于HP栏随着角色一起移动,但只是玩家移动速度的一小部分。例如,如果玩家移动一个单位,则该栏移动0.1个单位。
答案 0 :(得分:5)
你想让一个UI对象(Image)跟随一个GameObject是SpriteRenderer或MeshRenderer。
另一方面,这可以描述为将世界点转换为UI点。
下面这个简单的函数将世界位置转换为UI空间。它需要将Canvas
UI作为参数,然后将您要转换为UI位置的位置(在您的情况下为Player.transform.position
变量。
移动UI对象的关键是RectTransformUtility.ScreenPointToLocalPointInRectangle
函数,它将屏幕点转换为ui矩形本地点。
public Vector3 worldToUISpace(Canvas parentCanvas, Vector3 worldPos)
{
//Convert the world for screen point so that it can be used with ScreenPointToLocalPointInRectangle function
Vector3 screenPos = Camera.main.WorldToScreenPoint(worldPos);
Vector2 movePos;
//Convert the screenpoint to ui rectangle local point
RectTransformUtility.ScreenPointToLocalPointInRectangle(parentCanvas.transform as RectTransform, screenPos, parentCanvas.worldCamera, out movePos);
//Convert the local point to world point
return parentCanvas.transform.TransformPoint(movePos);
}
<强>用法强>:
public GameObject Player;
public Canvas canvas;
void Update()
{
//Convert the player's position to the UI space then apply the offset
transform.position = worldToUISpace(canvas, Player.transform.position);
}
现在,让我们说你已经将UI定位在它应该的位置,你现在希望它跟随另一个Object(Player),你需要用上面的代码实现一个简单的偏移。这真的很容易。以下是它应该是什么样子:
public GameObject Player;
public Canvas canvas;
Vector3 Offset = Vector3.zero;
void Start()
{
Offset = transform.position - worldToUISpace(canvas, Player.transform.position);
}
void Update()
{
//Convert the player's position to the UI space then apply the offset
transform.position = worldToUISpace(canvas, Player.transform.position) + Offset;
}
public Vector3 worldToUISpace(Canvas parentCanvas, Vector3 worldPos)
{
//Convert the world for screen point so that it can be used with ScreenPointToLocalPointInRectangle function
Vector3 screenPos = Camera.main.WorldToScreenPoint(worldPos);
Vector2 movePos;
//Convert the screenpoint to ui rectangle local point
RectTransformUtility.ScreenPointToLocalPointInRectangle(parentCanvas.transform as RectTransform, screenPos, parentCanvas.worldCamera, out movePos);
//Convert the local point to world point
return parentCanvas.transform.TransformPoint(movePos);
}
答案 1 :(得分:1)
如果画布是ScreenSpace,您可以使用:
healthbarTransform.position = camera.WorldToScreenPoint(playerTransform.position);
(如果是屏幕空间,只要你每帧设置位置,它可以是玩家的孩子或其他什么)
....关于您的问题,有一些因素可以解决问题: 您正在更新功能中设置健康栏位置,让玩家知道在玩家移动之后执行此代码,您需要在脚本执行顺序中将HPFollow脚本添加到默认时间以下(如果您要使用更新)。 或者您可以使用lateUpdate来设置ui位置。我强烈推荐。
如果你的问题只是闪烁ui,它应该是关于ui rect转换量表......
答案 2 :(得分:0)
以下是解决方案:
void Start () {
Canvas.willRenderCanvases += canvasUpdate;
}
void canvasUpdate () {
var screenPoint = RectTransformUtility.WorldToScreenPoint( canvas.worldCamera, worldPoint );
Vector2 localPoint;
RectTransformUtility.ScreenPointToLocalPointInRectangle( canvas.GetComponent<RectTransform>(), screenPoint, canvas.worldCamera, out localPoint );
transform.localPosition = localPoint;
}