I’ve found a few threads and “Unity Answers” posts that seem to be related to this, but nothing that I’ve found therein has helped.
I’m sure this is a familiar problem to many of you though: I have a space ship that, when you hold down the right mouse button, shoots a laser sight. I’m just using a plain red line renderer to visualize it for now. I was pretty happy with how my whole “scope” idea was coming out until I started using it while moving. Doing so revealed that the raycast seems to lag behind the ship, causing it to hit the ship itself. The ship has a child object positioned in front of the ship (outside of its collider) which is used to set the origin of the raycast.
It’s probably worth mentioning that the ships’ forward movement is handled by the physics engine, but rotation is applied directly to the transform. I tried to use physics for rotation with a number of settings, and it never felt right. Anyways, the lag issue happens even if you’re just moving straight, so I don’t think that’s the source of the problem anyways.
Any ideas? I’ve heard that raycasts should be done through FixedUpdate, but I’m not entirely sure my flag set-up is accomplishing that properly. Also, I saw one person say something about multiplying the ray length by Time.deltaTime. I did that in lines 70, 72, and both, but it didn’t solve the problem.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScopeScript : MonoBehaviour
{
public LayerMask layerMask;
[Tooltip("A reference to the GO from which the laser will fire.")]
public GameObject origin;
private float defaultPrecisionModeSpeed;
private float scopePrecisionModeSpeed = 1;
private float laserLengthMax = 1000;
private float laserWidth = 0.5f;
private LineRenderer lineRenderer;
private ShipController ship;
private GameObject scopeCam;
private bool fireLaser = false;
private void Start()
{
lineRenderer = GetComponent<LineRenderer>();
lineRenderer.startWidth = laserWidth;
lineRenderer.endWidth = laserWidth;
ship = GetComponent<ShipController>();
defaultPrecisionModeSpeed = ship.precisionRotationSpeed;
scopeCam = ship.gameManager.scopeCamera;
}
// Update is called once per frame
void Update()
{
if (ship.GetIsSelectedShip() && ship.canAct && !ship.gameManager.cycleMode && ship.isAlive)
{
if ((Input.GetKey(KeyCode.LeftShift) || Input.GetMouseButton(1) && !ship.GetIsShutDown()))
{
fireLaser = true;
ship.precisionRotationSpeed = scopePrecisionModeSpeed;
}
else if (Input.GetKeyUp(KeyCode.LeftShift) || Input.GetMouseButtonUp(1))
{
fireLaser = false;
lineRenderer.enabled = false;
ship.precisionRotationSpeed = defaultPrecisionModeSpeed;
}
}
else
{
fireLaser = false;
lineRenderer.enabled = false;
}
}
private void FixedUpdate()
{
if (fireLaser)
FireRaycast();
}
private void FireRaycast()
{
Vector2 dir = origin.transform.position - ship.transform.position;
dir = ship.transform.up;
Ray2D ray = new Ray2D(origin.transform.position, dir);
RaycastHit2D raycastHit;
Vector3 endPosition = ray.origin + (laserLengthMax * ray.direction);
raycastHit = Physics2D.Raycast(ray.origin, ray.direction, laserLengthMax, layerMask);
if (raycastHit)
{
if (!(raycastHit.collider.GetComponent<StealthShipController>() && raycastHit.collider.GetComponent<StealthShipController>().cloakingController.IsCloaked()))
endPosition = raycastHit.point;
}
if (raycastHit && raycastHit.collider.gameObject == ship.gameObject)
Debug.Log("stop hitting yourself");
lineRenderer.SetPosition(0, ray.origin);
lineRenderer.SetPosition(1, endPosition);
lineRenderer.enabled = true;
scopeCam.transform.position = new Vector3(endPosition.x, endPosition.y, scopeCam.transform.position.z);
}
}