0
\$\begingroup\$

Basically, I was attempting to write a piece of code that alters the position of an object dynamically, so, I think moving anchors around would also be necessary. If I move them around dynamically, it would be great if I could preview them moving in the unity editor dynamically. Is there a way to enable them in gameplay mode?

Below is the screenshot of gameplay vs. scene mode: enter image description here

As you can see, the anchor is not visible in gameplay mode. I'd like to make it visible, so, I can see the results in real-time when I'm programmatically altering the anchors.

\$\endgroup\$
5
  • \$\begingroup\$ You need to be more clear about what you are trying to do. What anchors are we talking about? What are the types of objects you are moving? What do you mean by "moving dynamically"? What do you mean by "gameplay mode" and what exactly are you trying to enable in it? \$\endgroup\$ Aug 22 at 16:03
  • \$\begingroup\$ @S.TarıkÇetin , I've edited above. Thanks for the comment \$\endgroup\$
    – juztcode
    Aug 22 at 18:00
  • 2
    \$\begingroup\$ If you simply want to see the position of anchor (without widget interaction) you can draw a box gizmo or point gizmos in place of anchors. \$\endgroup\$
    – Tooster
    Aug 22 at 21:59
  • 2
    \$\begingroup\$ @Tooster that might be worth demonstrating in an Answer for a shot at the bounty. 😉 \$\endgroup\$
    – DMGregory
    Aug 22 at 23:19
  • \$\begingroup\$ > As you can see, the anchor is not visible in gameplay mode. < actually it's not visible in the "Game window", not in "gameplay mode" \$\endgroup\$
    – Sergey
    Aug 23 at 11:43
4
+50
\$\begingroup\$

Is there a way to enable them in gameplay mode?

The purpose of anchors is that they can be edited in the Scene window. You can't edit them in the Game window (like many other editable stuff), so there is no need for them to be visible there. But you can use Gizmos to visualize their positions in the Game window even when the game is not running. To do this add either OnDrawGizmos() or OnDrawGizmosSelected() methods to your MonoBehaviour class. There are various forms of Gizmos visualization available: enter image description here

Example:

/// <summary>
/// Draw wired cube at `transform.position` of the current object.
/// </summary>
private void OnDrawGizmos()
{
    float cubeSize = 0.1f;
    Gizmos.color = Color.white;
    Gizmos.DrawWireCube(transform.position, Vector3.one * cubeSize);
}

In your case, you should add Gizmos.* drawing for each anchor position you want to be visible and replace transform.position with their actual positions. Keep in mind that Gizmos methods accept position and size parameters in world coordinates.

Here is an example of a component class that shows (visualizes with Gizmos) its anchors both in Game and Scene windows:

[DisallowMultipleComponent]
public class ShowAnchors : MonoBehaviour
{
#pragma warning disable CS0649

    [SerializeField]
    private float _gizmosSize = 5f;

    [SerializeField]
    private Color _color = Color.white;

#pragma warning restore CS0649

    private void OnDrawGizmos()
    {
        RectTransform rt = transform as RectTransform;

        if (!rt)
            return; // the object is not an UI element

        if (!rt.parent)
            return; // the object doesn't have a parent 

        Gizmos.color = _color;
        RectTransform parent = rt.parent as RectTransform;
        Rect parentRect = parent.rect;
        Matrix4x4 mat = parent.localToWorldMatrix;
        Vector2 minPos = parentRect.min + new Vector2(rt.anchorMin.x * parentRect.size.x, rt.anchorMin.y * parentRect.size.y);
        Vector2 maxPos = parentRect.min + new Vector2(rt.anchorMax.x * parentRect.size.x, rt.anchorMax.y * parentRect.size.y);

        // Anchor positions in screen coordinates.
        Vector2[] anchors = new Vector2[4]
        {
            minPos,
            new Vector2(minPos.x, maxPos.y),
            maxPos,
            new Vector2(maxPos.x, minPos.y)
        };

        for (int i = 0; i < anchors.Length; i++)
        {
            Vector3 anchor = anchors[i];
            // convert anchor position from screen to world coordinates
            Vector3 worldPos = mat.MultiplyPoint(anchor);
            // make gizmos look the same size for different camera projections & sizes
            float size = constGizmoSize(worldPos);
            // draw point
            Gizmos.DrawSphere(worldPos, size);
            // draw line
            Vector3 dir = Vector3.ClampMagnitude(_dirs[i], size * 2);
            Gizmos.DrawLine(worldPos, worldPos + dir);
        }
    }

    private static readonly Vector3[] _dirs = new Vector3[4]
    {
        Vector2.left + Vector2.down,
        Vector2.left + Vector2.up,
        Vector2.right + Vector2.up,
        Vector2.right + Vector2.down,
    };

    private float constGizmoSize(Vector3 position)
    {
        Camera camera = Camera.current;

        if (!camera)
            return _gizmosSize;

        position = Gizmos.matrix.MultiplyPoint(position);
        Transform transform = camera.transform;
        Vector3 position2 = transform.position;
        float z = Vector3.Dot(position - position2, transform.TransformDirection(new Vector3(0f, 0f, 1f)));
        Vector3 a = camera.WorldToScreenPoint(position2 + transform.TransformDirection(new Vector3(0f, 0f, z)));
        Vector3 b = camera.WorldToScreenPoint(position2 + transform.TransformDirection(new Vector3(1f, 0f, z)));
        float magnitude = (a - b).magnitude;
        float size = _gizmosSize / Mathf.Max(magnitude, 0.0001f);
        return size;
    }
}

Add it to the UI elements and you'll get a picture in the editor like this:

enter image description here (added to the Button(red) and its child Text(green))


If I move them around dynamically, it would be great if I could preview them moving in the unity editor dynamically.

Could you explain this more clearly?

\$\endgroup\$
2
  • \$\begingroup\$ thanks for the answer. The last statement meant, if I programmatically alter the values of the anchors dynamically, then, they should update in the game window. Which is what you've done above, right? \$\endgroup\$
    – juztcode
    Aug 23 at 16:19
  • 1
    \$\begingroup\$ @juztcode right \$\endgroup\$
    – Sergey
    Aug 24 at 5:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.