I’m trying to make a laser gun, when a certain button is pressed, a beam is fired, the beam can only fly where the gun is looking, the gun itself is on the machine. Accordingly, the shot can only be in a straight line, that is, along the z axis. I cast a ray along the given axis with respect to the empty object, the starting point. The problem is that the beam does not always fly straight, with the nearest values of rotation of the machine equal to 0 and 180 degrees, that is, the pure z-axis, the beam is directed to the origin of the scene. At the same time, with other values of rotation, the beam flies exactly straight relative to the car. What is the problem?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Gun : MonoBehaviour
{
public float range = 100f;
public float laserDuration = 0.05f;
public GameObject shootPoint;
public LineRenderer laserLine;
void Start()
{
laserLine.enabled = true;
}
void Update()
{
// if (Input.GetKeyDown(KeyCode.Q))
Shoot();
}
void Shoot()
{
RaycastHit hit;
Physics.Raycast(shootPoint.transform.position, shootPoint.transform.forward, out hit, range);
Debug.DrawLine(shootPoint.transform.position, hit.point);
laserLine.SetPosition(0, transform.position);
laserLine.SetPosition(1, hit.point);
}
}
First, you should test the result of Physics.Raycast() to see if you’re even hitting anything.
Currently line 28 and 30 blindly use the hit.point whether it is valid or not, which probably accounts for being directed at the origin.
Second, use Debug.Log() to find the name of the collider you hit, IF you hit a collider. You might be surprised by what you’re hitting, such as your own car or something.
Finally, use Physics.Raycast() always with named arguments because it contains many poorly-designed overloads:
If that doesn’t do it, start figuring out hard numbers.
You must find a way to get the information you need in order to reason about what the problem is.
What is often happening in these cases is one of the following:
the code you think is executing is not actually executing at all
the code is executing far EARLIER or LATER than you think
the code is executing far LESS OFTEN than you think
the code is executing far MORE OFTEN than you think
the code is executing on another GameObject than you think it is
you’re getting an error or warning and you haven’t noticed it in the console window
To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.
Doing this should help you answer these types of questions:
is this code even running? which parts are running? how often does it run? what order does it run in?
what are the values of the variables involved? Are they initialized? Are the values reasonable?
are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)
Knowing this information will help you reason about the behavior you are seeing.
If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.
You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.
You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.
You could also just display various important quantities in UI Text elements to watch them change as you play the game.
Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.
Here’s an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:
I tried to fix this problem and wrote a test script, added it to the cube and to my car, and on the cube, with any rotation, the beam flies straight and on the car flies to the origin. I correctly understand that the problem is in the machine and not in the script, because it’s strange.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class test : MonoBehaviour
{
public float fireRate = 0.25f;
public float range = 100f;
public float hitForce = 100f;
public Transform gunEnd;
private WaitForSeconds shotDuration = new WaitForSeconds(0.07f);
private LineRenderer laserLine;
private float nextFire;
void Start()
{
laserLine = GetComponent<LineRenderer>();
}
void Update()
{
if(Input.GetButtonDown("Fire1") && Time.time > nextFire){
nextFire = Time.time + fireRate;
StartCoroutine(ShotEffect());
Vector3 rayOrigin = gunEnd.position;
RaycastHit hit;
laserLine.SetPosition(0, gunEnd.position);
// if(Physics.Raycast(rayOrigin, gunEnd.forward, out hit, range))
laserLine.SetPosition(1, gunEnd.forward*range);
}
}
IEnumerator ShotEffect(){
laserLine.enabled = true;
yield return shotDuration;
laserLine.enabled = false;
}
}
I can’t figure out how it works! Why is the beam now flying somewhere to the side! I did nothing with the cube, what kind of nonsense is this. He doesn’t even have spin, how can he throw at an angle, it’s just nonsense.