将 UI RectTransform 移动到世界位置 [英] Move UI RectTransform to world position
问题描述
我有一个名为 Player 的游戏对象和一个画布.HealthBar GameObject 是 Canvas (Canvas>HealthBar) 的子元素.我有一个脚本跟随播放器的 HP 栏.它应该在玩家上方的固定位置跟随玩家,因此它位于精灵顶部附近.这是 HP Follow Script 的follow"部分.
I have a GameObject named Player, and a Canvas. The HealthBar GameObject is a child of the Canvas (Canvas>HealthBar). I have the HP bar following the player with a script. It is supposed to follow the player at a fixed position above it, so it sits near the top of the sprite. Here is the 'follow' part of the HP Follow Script.
void Update ()
{
Vector3 currentPos = transform.position;
Vector3 playerPos = Camera.main.WorldToViewportPoint (Player.transform.position);
transform.position = playerPos;
问题在于 HP 条会随着角色移动,但只是玩家移动速度的一小部分.例如,如果玩家移动 1 个单位,则横条移动 0.1 个单位.
The problem is that the HP bar moves with the character, but at a very small fraction of the speed of which the player is moving. For example, if the player moves one unit, the bar moves 0.1 units.
错误视频:https://streamable.com/vaz7h
推荐答案
你想让一个 UI 对象(图像)跟随一个游戏对象是一个 SpriteRenderer 或 MeshRenderer.
You want to make a UI Object(Image) follow a GameObject is a SpriteRenderer or MeshRenderer.
换句话说,这可以描述为将世界点转换为 UI 点.
In another way, this can be described as converting world point to UI point.
下面这个简单的函数将世界位置转换为 UI 空间.它将 UI 的 Canvas
作为参数,然后是您要转换为 UI 位置的位置,在您的情况下是 Player.transform.position
变量.
This simple function below converts world position to UI space. It takes a the Canvas
of the UI as parameter then the position you want to convert to UI position which in your case is the Player.transform.position
variable.
移动 UI 对象的关键是 RectTransformUtility.ScreenPointToLocalPointInRectangle
将屏幕点转换为ui矩形局部点的函数.
The key for moving a UI object is the RectTransformUtility.ScreenPointToLocalPointInRectangle
function which converts the screen point to ui rectangle local point.
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 定位到它应该在的位置,并且您现在希望它跟随另一个对象(播放器),您需要使用上面的代码实现一个简单的偏移.这真的很容易.下面是它应该是什么样子:
Now, let's say that you have already positioned the UI to be where it is supposed to be and you now want it to follow another Object(Player), you need to implement a simple offset with the code above. This is really easy. Below is what it is supposed to look like:
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);
}
这篇关于将 UI RectTransform 移动到世界位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!