0

I am making an endlesss car driving game and I want to call one of the switchLane functions by random whenever the player car is close to one of the enemy cars. The point is to make some other cars switch to a random lane when you get close. The main thing I am looking for is a way to call one of these 4 switchLane functions by random everytime you get close.


public class EnemyScript : MonoBehaviour
{
 public float speed;
 private GameObject playerTransform;
 private GameObject enemyCarPrefab;
 private float distanceToNextCar;
 public float distance;

 private float roadWidth;
 private float lane1 = 7.25f;
 private float lane2 = 2.45f;
 private float lane3 = 2.4f;
 private float lane4 = 7.3f;

 // Start is called before the first frame update
 void Start()
 {
    
 }

 // Update is called once per frame
 void Update()
 {
     playerTransform = GameObject.FindGameObjectWithTag("Player");
     enemyCarPrefab = GameObject.FindGameObjectWithTag("BaseCar");

     distanceToNextCar = enemyCarPrefab.transform.position.z - distance;
     if (playerTransform.transform.position.z > distanceToNextCar)
     {
         switchLane1();
         switchLane2();
         switchLane3();
         switchLane4();
     }
 }


 private void switchLane1()
 {
     Vector3 targetPos1 = new Vector3(-lane1, 0, 0);
     transform.position += (targetPos1 * speed * Time.deltaTime);



     if (transform.position.x <= -lane1)
     {
         Vector3 newPositionLeft = new Vector3(-lane1, transform.position.y, transform.position.z);
         transform.position = newPositionLeft;
     }
     if (transform.position.x >= lane1)
     {
         Vector3 newPositionRight = new Vector3(lane1, transform.position.y, transform.position.z);
         transform.position = newPositionRight;
     }

 }

 private void switchLane2()
 {
     Vector3 targetPos2 = new Vector3(-lane2, 0, 0);
     transform.position += (targetPos2 * speed * Time.deltaTime);



     if (transform.position.x <= -lane2)
     {
         Vector3 newPositionLeft = new Vector3(-lane2, transform.position.y, transform.position.z);
         transform.position = newPositionLeft;
     }
     if (transform.position.x >= lane2)
     {
         Vector3 newPositionRight = new Vector3(lane2, transform.position.y, transform.position.z);
         transform.position = newPositionRight;
     }

 }

 private void switchLane3()
 {
     Vector3 targetPos3 = new Vector3(lane3, 0, 0);
     transform.position += (targetPos3 * speed * Time.deltaTime);



     if (transform.position.x <= -lane3)
     {
         Vector3 newPositionLeft = new Vector3(-lane3, transform.position.y, transform.position.z);
         transform.position = newPositionLeft;
     }
     if (transform.position.x >= lane3)
     {
         Vector3 newPositionRight = new Vector3(lane3, transform.position.y, transform.position.z);
         transform.position = newPositionRight;
     }

 }

 private void switchLane4()
 {
     Vector3 targetPos4 = new Vector3(lane4, 0, 0);
     transform.position += (targetPos4 * speed * Time.deltaTime);



     if (transform.position.x <= -lane4)
     {
         Vector3 newPositionLeft = new Vector3(-lane4, transform.position.y, transform.position.z);
         transform.position = newPositionLeft;
     }
     if (transform.position.x >= lane4)
     {
         Vector3 newPositionRight = new Vector3(lane4, transform.position.y, transform.position.z);
         transform.position = newPositionRight;
     }

 }
}
derHugo
  • 83,094
  • 9
  • 75
  • 115
Lukaas
  • 19
  • 5

2 Answers2

1

What about e.g.

// for more flexibility rather use an array
// You should also add the ability to change it via the Inspector
[SerializeField]
private float[] lanes = new []
{
    7.25f,
    2.45f,
    2.4f,
    7.3f
};

// pass the index of the lane to your method
// this way you can handle all lanes with a single method
private void SwitchToLane(int index)
{
    Debug.Log($"Switching to lane {index}", this);

    // Get the float at given index in lanes
    var x = lanes[index];

    var targetPos = new Vector3(x, 0, 0);
    transform.position += (targetPos * speed * Time.deltaTime);

    if (transform.position.x <= -x)
    {
       var newPositionLeft = new Vector3(-x, transform.position.y, transform.position.z);
       transform.position = newPositionLeft;
    }
    // Rather use 'else if' when it is already clear that only one case can be true at the same time
    else if (transform.position.x >= x)
    {
       var newPositionRight = new Vector3(x, transform.position.y, transform.position.z);
       transform.position = newPositionRight;
    }
}

and then call

// Call this to switch to any random lane
private void SwitchToRandomLane()
{
    // generate a random int between 0 and lanes.Length - 1
    // second parameter is EXCLUSIVE!
    var random = Random.Range(0, lanes.Length); 

    SwitchToLane(random);
}
        

Further notes:

  1. You would also need to somehow change your condition check in Update. Currently as soon as the player goes once below the distance threshold you switch lane every frame!

  2. You would probably want to somewhere store the current lane index so when SwitchToRandomLane is called the current index is excluded from the options and you can only definitely switch to a different lane then the one you are already on.

Both points I leave to you.

derHugo
  • 83,094
  • 9
  • 75
  • 115
0

You can make a random number

int randomNum = Random.Range(0, 4);

And use it on a switch with the four functions, something like this

switch(randomNum){
case 0:
  switchLane1();
break;
case 1:
  switchLane2();
break;
case 2:
  switchLane3();
break;
case 3:
  switchLane4();
break;
}

But I am sure there is a better solution for this, I see so much repeated code, maybe you can make one function with a parameter for the four cases and simply send a parameter with a direction or a number.

Eric Valero
  • 540
  • 5
  • 8
  • This is somewhat what I am looking for but then to make it work everytime I come close to a car this code only works one time... and about removing repeated code, I am a complete beginner so I don't really know what I should do otherwise so this is the solution I came up with :) (the game runs in infinite loop so you pass the cars multiple times) – Lukaas Sep 08 '20 at 16:21
  • @Lukaas The reason why is only happening one time is that "enemyCarPrefab" is always the same and the "if" is true only in one place. I think you should research more and train following basic tutorials, you have Unity courses with small games to do with all explained. https://learn.unity.com/ – Eric Valero Sep 09 '20 at 06:15