2
votes

In Unity, I'm trying to make my sprite go offscreen to the left and have it appear offscreen on the right or vice versa. I have my sprite move left or right (depending on user input) constantly for my gameplay by the way.

I take into account that the sprite needs to be fully offscreen before having it appear on the right side.

Here's my current code:

void Start () 
{
    minXValueWorld = Camera.main.ScreenToWorldPoint(new Vector3(0,0,0)).x;
    maxXValueWorld = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, 0, 0)).x;

    playerSize = this.GetComponent<Renderer>().bounds.size;
}

void Move()
{
    if (inputLeft)
    {
        this.transform.position -= new Vector3(speed * Time.deltaTime, 0, 0);
    }
    else
    {
        this.transform.position += new Vector3(speed * Time.deltaTime, 0, 0);
    }
}

void OffscreenCheck()
{

    Vector3 screenPos = Camera.main.WorldToScreenPoint(this.transform.position);
    Vector3 maxWorldXWithPlayerSize = Camera.main.WorldToScreenPoint(new Vector3(maxXValueWorld,0,0) + playerSize/2);
    Vector3 minWorldWithPlayerSize = Camera.main.WorldToScreenPoint(new Vector3(minXValueWorld,0,0) - playerSize/2);

    if (screenPos.x < minWorldWithPlayerSize.x)
    {
        this.transform.position = new Vector3(maxWorldXWithPlayerSize.x, this.transform.position.y, this.transform.position.z);
    }

    if (screenPos.x > maxWorldXWithPlayerSize.x)
    {
        this.transform.position = new Vector3(minWorldWithPlayerSize.x, this.transform.position.y, this.transform.position.z);
    }

}

Then the Move and OffscreenCheck are called in the Update function in order.

The problem with this code is that once my sprite goes fully offscreen on the left, it appears on the right offscreen, but it does not move left anymore.

Instead, it just teleports to the left or right offscreen positions. I do not see it move left or right across the screen anymore because of this.

I'm pretty sure that my code logic is just off. Does anyone know how to fix this issue?

Thanks

1
Without a good, minimal, complete code example that clearly shows the behavior, it's hard to know for sure what the problem might be. However, one thing in your code looks suspicious to me: new Vector3(maxXValueWorld,0,0) + playerSize/2. I would think that would make more sense as new Vector3(maxXValueWorld + playerSize/2,0,0). The way you have it, I can imagine some strangeness going on transforming to screen coordinates, in which the x value doesn't wind up where you thought it should be.Peter Duniho
Thanks for the reply. I have fixed my code with your advice but my object's behavior remains the same. Basically what happens is that when the object goes offscreen, the x-position of the object becomes -19 and 424 (based on my screen aspect ratio, at least). It just switches between those x-positions which is the problem because those are offscreen positions already. I'm not sure but I think the problem is with my logic in my if statements.aresz
Inside my if blocks, when I change the maxWorldXWithPlayerSize.x to simply maxXValueWorld, and minWorldWithPlayerSize.x to minXValueWorld, the object appears on the other side of the screen successfully. But what I want is to have it appear from the offscreen so that the object doesn't just appear out of nowhere with its half showing (since the pivot point of the sprite is on the center)aresz

1 Answers

0
votes

I think the following should work:

void OffscreenCheck()
{

    Vector3 screenPos = Camera.main.WorldToScreenPoint(this.transform.position);
    Vector3 maxWorldWithPlayerSize = new Vector3(maxXValueWorld + playerSize/2,0,0);
    Vector3 minWorldWithPlayerSize = new Vector3(minXValueWorld - playerSize/2,0,0);
    Vector3 maxScreenWithPlayerSize = Camera.main.WorldToScreenPoint(maxWorldWithPlayerSize);
    Vector3 minScreenWithPlayerSize = Camera.main.WorldToScreenPoint(minWorldWithPlayerSize);

    if (screenPos.x < minScreenWithPlayerSize.x)
    {
        this.transform.position = new Vector3(
            maxWorldWithPlayerSize.x,
            this.transform.position.y,
            this.transform.position.z);
    }

    if (screenPos.x > maxScreenWithPlayerSize.x)
    {
        this.transform.position = new Vector3(
            minWorldWithPlayerSize.x,
            this.transform.position.y,
            this.transform.position.z);
    }

}

The above is a good illustration of why to be careful about how you name your variables. When I first looked at your code, I failed to connect the fact that while the variables had the word "World" in them, they were actually in screen coordinates. So I didn't notice the faulty assignment of the position, in which you used screen coordinates to assign an X coordinate in world coordinates.

In the above, I have separated the world and screen coordinate vectors into individual local variables. The screen coordinates are used for the off-screen comparison itself, while the world coordinates are used for actually moving the sprite to where you want.

Again, lacking a complete code example I'm not able to actually test the above and verify that it solves your problem. But I think it will.