Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question using multiple raycasts to detect obstacles?

Discussion in 'Scripting' started by ChaosEaterY, Jul 4, 2023.

  1. ChaosEaterY

    ChaosEaterY

    Joined:
    Jun 3, 2018
    Posts:
    3
    I wish to make a script where the player sprite moves around and when it touches specific objects it stops while when it touches others it moves past them. this can be done with oncollisionenter or ontriggerenter but this is a something I want to do with purely scripting and no other components other than colliders.
    my current way of doing this is casting 5 rays in the direction the sprite is moving and act according to what is in front. my problem is that I cannot calculate the way to make 5 rays appear in every direction (8 directions including the diagonals because that is how my game works). this is the basic idea that I have:
    Code (CSharp):
    1.  
    2.     public float Speed;
    3.     public Transform PlayerTransform;
    4.     public Sprite PlayerCharacter;
    5.  
    6.     LayerMask lm = new LayerMask();
    7.     RaycastHit2D[] ForwardRay = new RaycastHit2D[5];
    8.     Vector2 dir;
    9.  
    10.     int verticalMov = 1;
    11.     int horizontalMov = 0;
    12.  
    13.     void Update()
    14.     {
    15.         if (Input.GetKey(Up)) verticalMov++; // keys pressed
    16.         if (Input.GetKey(Down)) verticalMov--;
    17.         if (Input.GetKey(Left)) horizontalMov--;
    18.         if (Input.GetKey(Right)) horizontalMov++;
    19.  
    20.         dir = new Vector2(horizontalMov, verticalMov); // calculate direction of movement
    21.  
    22.         ForwardRay = new RaycastHit2D[5];
    23.  
    24.         int j = 0;
    25.  
    26.         for (int i = ForwardRay.Length / -2; i < ForwardRay.Length / 2 + 0.5; i++)
    27.         {
    28.             ForwardRay[j] = Physics2D.Raycast(new Vector2(PlayerTransform.position.x + (PlayerCharacter.bounds.size.x / (ForwardRay.Length - 1) * i * dir.x), PlayerTransform.position.y + (PlayerCharacter.bounds.size.y / (ForwardRay.Length - 1) * i * dir.y)), dir, 0.5f, lm); // calculation that does not work
    29.  
    30.             Debug.DrawRay(new Vector2(PlayerTransform.position.x + (PlayerCharacter.bounds.size.x / (ForwardRay.Length - 1) * i), PlayerTransform.position.y + (PlayerCharacter.bounds.size.y / (ForwardRay.Length - 1) * i)), dir, Color.red, Mathf.Infinity); // debugging
    31.  
    32.             if (ForwardRay[j] && ForwardRay[j].collider)
    33.             {
    34.                 if (ForwardRay[j].collider.gameObject.layer == 7)
    35.                 {
    36.                     dir = Vector2.zero; // stop moving if hit an obstacle
    37.                 }
    38.             }
    39.             j++;
    40.         }
    41.  
    42.         PlayerTransform.Translate(dir.normalized * Speed * Time.deltaTime); // calculate movement
    43.     }
    44.  
    my problem is that I cannot find a way to calculate and cast the 5 rays in all 8 directions the player can point to. if anyone has any ideas or answers please help.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    Any Vector3 can be rotated by a Quaternion.

    For instance, if you have a Quaternion:

    Code (csharp):
    1. Quaternion myRotation = Quaternion.Euler( 0, 45, 0);
    You can rotate any Vector3 by 45 degrees around the y:

    Code (csharp):
    1. Vector3 originalVector =  ... however you get this
    2.  
    3. Vector3 rotatedBy45Vector = myRotation * originalVector;
     
    ChaosEaterY likes this.
  3. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    510
    Code (CSharp):
    1.         float angle=-20;
    2.         for (int i=0; i<5; i++)
    3.         {
    4.             Vector2 forwardRay=dir;
    5.             forwardRay=Quaternion.AngleAxis(angle, Vector3.forward) * forwardRay;   // rotate forwardRay
    6.             if (Physics2D.Raycast(playerTransform.position, forwardRay, 0.5f, lm)
    7.             {
    8.                 dir = Vector2.zero; // stop moving if hit an obstacle
    9.                 break;  // exit this loop. no need to waste time checking the remaining directions
    10.             }
    11.             angle+=10; // add 10 degrees to angle
    12.         }
    13.         PlayerTransform.Translate(dir.normalized * Speed * Time.deltaTime);
     
    ChaosEaterY likes this.
  4. ChaosEaterY

    ChaosEaterY

    Joined:
    Jun 3, 2018
    Posts:
    3
    thank you very much!
    it seems I was in a completely wrong thought process.