0
\$\begingroup\$

I am making a 2D platformer in Unity and I programmed one of the enemies to move back and forth with the ping pong function.

I would like to change the local scale depending on which direction the character is moving.

I have tried using two if statements where if the x value of the transform is below or above a certain number it will change the local scale accordingly, but that did not work.

Here is the code for the enemy:

public class Bunny: MonoBehaviour  {

    float min;
    float max;
    [SerializeField] float movmentSpeed = 0.5f;
    float movementDistance;
    public bool isHit = false;
      
    void Start() {
        min = transform.position.x;
        max = transform.position.x + 3;
        movementDistance = max - min;
    }
    
    void Update()  {
        if(isHit == false) {             
            transform.position = new Vector3(
                Mathf.PingPong(Time.time * movmentSpeed, movementDistance) + min, 
                transform.position.y, 
                transform.position.z
            );
        } 
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ Have you considered getting the distance between max and transform.position and then dividing it by movementDistance and use this value for x factor of local scale? \$\endgroup\$
    – Arian_ki
    Jun 29 at 4:54

3 Answers 3

0
\$\begingroup\$

You can do this without an extra member variable, and without overshooting past min/max. "Moving left" just means your new x is less than your old x. So, compare to see which one is bigger.

float newX = Mathf.PingPong(Time.time * movmentSpeed, movementDistance) + min;

transform.localScale = new Vector3(
    newX < transform.position.x ? -1 : 1,
    1,
    1
);

transform.position = new Vector3(
    newX,
    transform.position.y, 
    transform.position.z
);
\$\endgroup\$
2
  • \$\begingroup\$ This is going to sound pretty bad but i don't understand this part of ur code transform.localScale = new Vector3( newX < transform.position.x ? -1 : 1, 1, 1 ); Is this a shorthand for something I am unaware of? Unity is the only time I have done anything with c# \$\endgroup\$
    – SebstaBro7
    Jun 29 at 15:15
  • \$\begingroup\$ That's called the ternary operator. It chooses one of two values based on a condition: booleanTest ? valueIfTrue : valueIfFalse. When you're wondering about core programming syntax, be sure to search StackOverflow first - it's probably already answered there. \$\endgroup\$
    – DMGregory
    Jun 29 at 16:37
0
\$\begingroup\$

The problem with the Mathf.PingPong function is that it doesn't tell you if the returned value is from the "Ping" or the "Pong" phase. When you need that information, for example because you need it to decide in which direction the sprite is supposed to face, then it is not going to be of much use. So we are going to need to use a different solution here.

One simple solution is to have a variable which states if the bunny is currently moving left or right. I would prefer to use an enum for that purpose, but when you don't know how to use enumerations yet, then you can just use a flag bool isMovingLeft.

Then you implement the Update function to behave differently depending on the state of that variable:

if (isMovingLeft) {
    transform.Translate(-movementSpeed * Time.deltaTime, 0f, 0f);
} else {
    transform.Translate(movementSpeed * Time.deltaTime, 0f, 0f);
}

Then you need to detect if an event occurred which would cause the bunny to turn around, and then do everything that entails. In that case this event would be to exceed the "max" or "min" value:

if (transform.position.x > max) {
    isMovingLeft = true; // move left from now on       
    transform.scale.x = -1f;  // flip the sprite to mirrored
}
if (transform.position.x < min) {
    isMovingLeft = false; // move right again from now on
    transform.scale.x = 1f; // flip the sprite back to normal
}
\$\endgroup\$
0
\$\begingroup\$

Try it, simple and easy way to flip in a specific range. It worked for me.

if (transform.position.x > max)
            transform.Rotate(0f, 180f, 0f);
else if (transform.position.x < min)
            transform.Rotate(0f, -180f, 0f);
\$\endgroup\$
1
  • \$\begingroup\$ With the method they used in this question, the position will never be larger than max or smaller than min. \$\endgroup\$
    – Philipp
    Jun 29 at 11:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .