将UI RectTransform移动到世界位置

Dav*_*ios 3 c# canvas unity-game-engine

我有一个名为Player的GameObject 和一个Canvas。该HealthBar游戏对象是画布的孩子(画布> HealthBar) 。在播放器后面有脚本的HP酒吧。它应该跟随玩家在其上方的固定位置,因此它位于精灵顶部附近。这是HP Follow Script的“关注”部分。

        void Update () 
{
    Vector3 currentPos = transform.position;
    Vector3 playerPos = Camera.main.WorldToViewportPoint (Player.transform.position);
    transform.position = playerPos;
Run Code Online (Sandbox Code Playgroud)

问题是HP条随角色移动,但移动速度却很小。例如,如果玩家移动一个单位,则小节移动0.1个单位。

错误视频:https//streamable.com/vaz7h

Pro*_*mer 6

您要使UI Object(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);
}
Run Code Online (Sandbox Code Playgroud)

用法

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);
}
Run Code Online (Sandbox Code Playgroud)

现在,假设您已经将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);
}
Run Code Online (Sandbox Code Playgroud)