Search Unity

Question 2D laser mirror puzzle 2021.3.11 f1

Discussion in '2D' started by unity_94E4DF39DA73609CA9FD, Apr 2, 2023.

  1. unity_94E4DF39DA73609CA9FD

    unity_94E4DF39DA73609CA9FD

    Joined:
    Apr 2, 2023
    Posts:
    3
    I am making a 2D unity game for school and wanted to create a laser-mirror puzzle where the player rotates mirrors to aim a laser around obstacles to get to an end point. I have used a line renderer to create the laser and used this code for the laser:
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Laser : MonoBehaviour
    4. {
    5.     public Transform laserOrigin;
    6.     public LineRenderer lineRenderer;
    7.     public float maxLaserDistance = 100f;
    8.  
    9.     private int solidObjectsLayer;
    10.     private Vector3 upDirection;
    11.     private bool isReflecting = false;
    12.     private Vector3 reflectionPoint;
    13.  
    14.     private void Start()
    15.     {
    16.         lineRenderer.positionCount = 2;
    17.         lineRenderer.SetPosition(0, laserOrigin.position);
    18.  
    19.         solidObjectsLayer = LayerMask.NameToLayer("SolidObjects");
    20.         upDirection = transform.up;
    21.     }
    22.  
    23.     private void Update()
    24.     {
    25.         if (!isReflecting)
    26.         {
    27.             RaycastHit2D hit = Physics2D.Raycast(laserOrigin.position, upDirection, maxLaserDistance);
    28.  
    29.             if (hit.collider)
    30.             {
    31.                 lineRenderer.SetPosition(1, hit.point);
    32.  
    33.                 if (hit.collider.gameObject.layer == solidObjectsLayer)
    34.                 {
    35.                     isReflecting = true;
    36.                     reflectionPoint = hit.point;
    37.                 }
    38.             }
    39.             else
    40.             {
    41.                 lineRenderer.SetPosition(1, laserOrigin.position + (upDirection * maxLaserDistance));
    42.             }
    43.         }
    44.         else
    45.         {
    46.             lineRenderer.SetPosition(1, reflectionPoint);
    47.  
    48.             if (Vector3.Distance(laserOrigin.position, reflectionPoint) >= 0.01f)
    49.             {
    50.                 laserOrigin.position = Vector3.MoveTowards(laserOrigin.position, reflectionPoint, Time.deltaTime * maxLaserDistance);
    51.             }
    52.             else
    53.             {
    54.                 Vector3 reflectionDirection = Vector3.Reflect(upDirection, (reflectionPoint - laserOrigin.position).normalized);
    55.                 upDirection = reflectionDirection;
    56.                 isReflecting = false;
    57.             }
    58.         }
    59.     }
    60.  
    61.     private void OnTriggerEnter2D(Collider2D other)
    62.     {
    63.         if (other.gameObject.layer == solidObjectsLayer)
    64.         {
    65.             lineRenderer.enabled = false;
    66.         }
    67.     }
    68.  
    69.     private void OnTriggerExit2D(Collider2D other)
    70.     {
    71.         if (other.gameObject.layer == solidObjectsLayer)
    72.         {
    73.             lineRenderer.enabled = true;
    74.         }
    75.     }
    76. }
    77.  
    I cannot figure out a way for the line renderer/laser to reflect of these 'mirrors'. The way that I want them to reflect is the laser coming out of a specific point of the mirror, and not like a normal reflection where the angle at which the laser hits the mirror effects it. I also want to make it so if one mirror loses connection with the laser, the following lasers will be destroyed. I've tried making a script that means when the original laser touches the 'mirror' it creates another line renderer coming from the mirror, but it never works properly. I am also not sure if this is the place to post this question so if this is not the right spot, could you please direct me to a better place to post this. Thanks. upload_2023-4-2_10-7-6.png upload_2023-4-2_10-7-0.png
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    I think you're misusing
    Vector3.Reflect()
    .

    For one, you could probably just use
    Vector2.Reflect()
    instead if you're all in 2D.

    And as to the usage...

    The first argument should be the vector of the incoming laser, but you're just providing the "up" vector of whatever Transform this script is on.

    The second argument should be the normal to the reflecting surface, which in the 2D example above for the mirror near the bottom should be something like
    new Vector2( 1, 1).normalized;
    , or the unit vector 45 degrees up and right.

    If you want to see it for yourself, just test-run this code:

    Code (csharp):
    1. Vector2 inbound = new Vector2( 0, -1);   // straight down
    2.  
    3. Vector2 normal = new Vector2( 1, 1).normalized;   // normal up-right
    4.  
    5. // I prefer to name my arguments when they are identical types, in order to keep me honest
    6. Vector2 outbound = Vector2.Reflect( inDirection: inbound, inNormal: normal);
    7.  
    8. Debug.Log( outbound);
    As written above it should produce (1.0,0.0) as output.

    If you change the reflection normal to point 45 degrees up and to the left:

    Code (csharp):
    1. Vector2 normal = new Vector2( -1, 1).normalized;   // normal up-left
    you'll get this output instead (-1.0, 0.0)