What's wrong with parallax calculation?

PLEASE IGNORE HERE AND GO DOWN

I’m working on a parallax background and wrote this code. but the code I commented “this loop” loops always. I controlled variables for multiple times and here a set of them when I paused game
changePos[0] = -1919
changePos[1] = -1897
transform.position.x = -1905
for this values loop must not loop but it’s. I’m working on this for 1 day and couldn’t find the problem


using UnityEngine;
public class Parallax_Cont : MonoBehaviour
{
    public SpriteRenderer spriteRenderer;
    public Transform camTrans;
    public float spriteWidth;
    public float parallaxAmount = 0.5f;
    public float camInitialPosX;
    float spriteInitialX;
    public float[] changePos = new float[2];
    void Start()
    {
        camTrans = Camera.main.transform;
        spriteRenderer = GetComponent<SpriteRenderer>();
        spriteWidth = spriteRenderer.bounds.size.x;
        spriteInitialX = transform.position.x;
        camInitialPosX = Camera.main.transform.position.x;
    }
    void FixedUpdate()
    {
        CheckForBound();
        MoveParallax();
    }
    void CheckForBound()
    {
        if(transform.position.x > changePos[1])
        {
            transform.position = new Vector3(changePos[1] + spriteWidth/2, transform.position.y, transform.position.z);
            spriteInitialX = changePos[1];
            Debug.Log("Upper Limit Reached");
            ChangeBounds();
        }
        if(transform.position.x < changePos[0]) //THIS LOOP
        {
            transform.position = new Vector3(changePos[0] - spriteWidth/2, transform.position.y, transform.position.z);
            spriteInitialX = changePos[0];
            Debug.Log("Bottom Limit Reached");
            ChangeBounds();
        }
    }
    void MoveParallax()
    {
        float moveAmount = camTrans.position.x - camInitialPosX;
        transform.Translate(new Vector3(camTrans.position.x - camInitialPosX, 0, 0 )  * (1-parallaxAmount));
        camInitialPosX = camTrans.position.x;
    }
    void ChangeBounds()
    {
        changePos[0] = spriteInitialX - spriteWidth * parallaxAmount;
        changePos[1] = spriteInitialX + spriteWidth * parallaxAmount;
    }
}

Have you tried using a break point in the line with “//THIS LOOP”?
Just pausing the game does not define, where it is paused exactly, a break point does.

There is no loop to break outside, I tried :frowning_face:

With the values you shown both if statements are true so both will run at the same time. Other than that this is a little to advance for me atm.

I mean a break point in your debugger. Which IDE do you use?

(I have not yet checked the values in detail, just want to rule out possible basic errors)

-1897 > -1905 so they cannot be both true, and game doesn’t runs like they’re both true. I’m using visual studio code on macOS. Here are ss from the trial.

I have no experience with macOS but I am sure it also provides a debugging-function for your Unity-Editor.
I found a Youtube-Video demonstrating how to start the debugger in VS for macOS (go to 6:00):

https://www.youtube.com/watch?v=vykg4x4HFx4

I also shows how to set break points, so that the program stops at a precise point in your code, which allows you to check all variables that currently are in the scope of the program.

So what you should do is:

  • Start the debugger
  • Start your Unity player
  • Bring the application to the state where you think it fails
  • Set the break point in your code as shown in the video (do not set it beforehand, or it will stop the program during each frame)
  • Check the values of the two variables in the condition of your if-statement

Alternatively, if you don’t want to use the debugger (I also only use it since it has integrated support for Unity) you should add some “Debug.Log” calls in your code, for example:

        Debug.Log("My two values are: " + transform.position.x.ToString() + " and " + changePos[0].ToString());
        if(transform.position.x < changePos[0]) //THIS LOOP
        {
            transform.position = new Vector3(changePos[0] - spriteWidth/2, transform.position.y, transform.position.z);
            spriteInitialX = changePos[0];
            Debug.Log("Bottom Limit Reached");
            ChangeBounds();
        }

This prints the two values of your variables to the console right before the if-statement is reached.

This is the very last stage of the code. This code makes parallax exactly how I think but here’s the issue. I’m applying parallax these 3 game objects. they’re children are just 2 copies of it so they behave like images but with three times of width (one left, one right) like -child-parent-child- . This code changes position of grass when it’s over but clouds moving early. so there’s an error how I’m calculating. here is my calculation algorithm:

    *float distance = spriteWidth / (1-parallaxAmount);*
  •    boundsForSprite[0] = camInitialPosX -  distance;*
    
  •    boundsForSprite[1] = camInitialPosX + distance;*
    
  •    camInitialPosX = camTrans.position.x;*
    

sprite always goes the opposite direction through cam with a rate of (1-parallax) so if parallax is 1 sprite moves with cam like a normal child of cam object. I do not tell again my formulation is above and in code. What are your thoughts?

using UnityEngine;
public class Parallax_Cont : MonoBehaviour
{
    public SpriteRenderer spriteRenderer;
    public Transform camTrans;
    public float spriteWidth;
    public float parallaxAmount = 0.5f;
    public float camInitialPosX;
    float spriteInitialX;
    public float[] boundsForSprite; //zeroth element is left side bound -- first element is right side bound
    void Start()
    {
        boundsForSprite = new float[2];
        camTrans = Camera.main.transform;
        spriteRenderer = GetComponent<SpriteRenderer>();
        spriteWidth = spriteRenderer.bounds.size.x;
        spriteInitialX = transform.position.x;
        camInitialPosX = Camera.main.transform.position.x;
        CalculateBounds();
    }
    void FixedUpdate()
    {
        CheckForBound();
        MoveParallax();
    }
    void CheckForBound()
    {
        if(camTrans.position.x > boundsForSprite[1])
        {
            Debug.Log("You gone too forward on x axis");
            CalculateBounds();
            transform.position = new Vector3(camInitialPosX, transform.position.y, transform.position.z);
        }
        if(camTrans.position.x < boundsForSprite[0])
        {
            Debug.Log("You gone too backward on x axis");
            CalculateBounds();
            transform.position = new Vector3(camInitialPosX, transform.position.y, transform.position.z);
        }
        
    }
    void MoveParallax()
    {
        float moveAmount = camTrans.position.x - camInitialPosX;
        transform.Translate(new Vector3((camTrans.position.x - camInitialPosX) *-1f, 0, 0 )  * (1-parallaxAmount));
        camInitialPosX = camTrans.position.x;
    }
    void CalculateBounds()
    {
        float distance = spriteWidth / (1-parallaxAmount);
        boundsForSprite[0] = camInitialPosX -  distance;
        boundsForSprite[1] = camInitialPosX + distance;
        camInitialPosX = camTrans.position.x;
    }

}

I do not understand the problem (and the code) exactly.

Your bounds become large if the sprite moves slowly (i.e. the parallaxAmount approaches 1).

If the parallaxAmount is smaller the bounds are smaller and the sprite moves faster.

If the pA is 1, the sprite does not move, because the translation is multiplied with 0 (and the bounds are infinity).

Why do the bounds scale with the speed?
What exactly is the purpose of the CheckForBound()-method? (Documentation i.e. commentary helps a lot) From what I see, you check if the camera is inside the calculated bounds, and if not, new bounds are calculated based on the new camera position and the sprites position is set to the one of the camera.