0
\$\begingroup\$

I have created a GUI that floats over an object. However, when I reload the scene, the ScreenPointToLocalPointInRectangle() function does not work and acts as if I used WorldToScreenPoint() instead. Here is a video showing the problem I'm facing.

This is my current code:

using UnityEngine;
using UnityEngine.UI;
using System;

public class GUI : MonoBehaviour
{
  public GameObject pressgui;
  public Image image;
  public float Radius;
  float x1,x2,y1,y2,ex,ey,vx,vy,cx,cy,tx,ty;
  float offset;
  int reverse;
  Vector3 reverseR;

  void Awake() {
      offset = 20f;
      x1 = Screen.width/2*-1+offset;
      x2 = Screen.width/2-offset;
      y1 = Screen.height/2*-1+offset;
      y2 = Screen.height/2-offset;
  }
  
  void Update() {
    pressgui.active = false;
    image.enabled = true;
    Vector3 loc = transform.position;
    var screenPosition = Camera.main.WorldToScreenPoint(transform.position + new Vector3(0.5f,2,0));
    
    Collider[] colliders = Physics.OverlapSphere(loc,Radius);
    RectTransformUtility.ScreenPointToLocalPointInRectangle(
        (RectTransform)pressgui.transform.parent, // pressgui's container
        screenPosition ,          // position measured in pixels
        null,                    // use this for Screen Space - Overlay canvas
        out Vector2 uiPosition // local UI space position
    ); 
    foreach (Collider hit in colliders){
        if(hit.gameObject.tag == "Player"){
            image.enabled = false;
            pressgui.active = true;
            pressgui.transform.localPosition = uiPosition;
        }
    }
  
    reverse = 180;
    reverseR = -Vector3.forward;
    vx = uiPosition.x;
    vy = uiPosition.y;
    if (vx > 0 )ex = x2; else ex = x1;
    if (vy > 0 ){ey = y2;} else {ey = y1;}
    if (vx == 0 )cx = 0;cy = ey;
    if (vy == 0 )cx = ex;cy = 0;
    tx = (ex - 0) / vx;
    ty = (ey - 0) / vy;
    if (tx <= ty ){ cx = ex; cy = 0 + tx * vy; }else{ cx = 0 + ty * vx;  cy = ey;}
    image.transform.localPosition = new Vector2(cx,cy);
  
    if(screenPosition.z<0){
        image.transform.localPosition = new Vector2(image.transform.localPosition.x*-1, image.transform.localPosition.y*-1);
        reverse = 0;
        gyakuu = Vector3.forward;
    }
    var dir = new Vector2(0,0) - new Vector2(image.transform.localPosition.x,image.transform.localPosition.y);
    var angle = Mathf.Atan2(dir.x,dir.y) * Mathf.Rad2Deg - reverse;  
    image.transform.rotation = Quaternion.AngleAxis(angle,reverseR);
  }
}

Here's my Image setup:

1

Canvas setup:

2

And the object to which the script is attached:

3

\$\endgroup\$
9
  • \$\begingroup\$ Usually this is a symptom of one of the objects you were referencing getting unloaded. Check whether pressgui is null here. (In general: always check for null when something mysteriously stops working - it rarely has anything to do with the code attempting to use the null, and everything to do with the code that made the reference null, or failed to repopulate it) \$\endgroup\$
    – DMGregory
    Commented Jan 23, 2023 at 2:41
  • \$\begingroup\$ @DMGregory: I debugged it, both before and after reloading. guican (UnityEngine.RectTransform) Debug:Log (object) was displayed. \$\endgroup\$
    – kunokouki
    Commented Jan 23, 2023 at 2:51
  • \$\begingroup\$ I notice you no longer have an if check skipping this unless the player is close. Is it possible that multiple objects are running this script after a reload and fighting over where tp place pressgui? We'll need you to update the question to include a Minimal Complete Verifiable Example of the problem: every line of code and every step of scene setup needed to reproduce the problem in a new, empty project. Strip out anything not required, to keep this as lean as possible. Once we can reproduce the problem, we can test solutions to be sure they'll work for your situation. \$\endgroup\$
    – DMGregory
    Commented Jan 23, 2023 at 2:54
  • \$\begingroup\$ @DMGregory: I used "Find Reference In Scene" to find conflicts, but it only attaches to one object. \$\endgroup\$
    – kunokouki
    Commented Jan 23, 2023 at 3:30
  • \$\begingroup\$ When I say every line of code and every step of scene setup, the every is very important. The code above will not compile because we don't have the declaration of checkpoint, image, loc, radius, etc. To ensure you are sharing a Minimal Complete Verifiable Example, create a new, empty project. Add to the project only the content that is explicitly described in your question. If that project does not compile, run, and demonstrate the problem, you have not finished making your MCVE yet. \$\endgroup\$
    – DMGregory
    Commented Jan 23, 2023 at 3:52

0

You must log in to answer this question.

Browse other questions tagged .