- Home /
[C#] Line Renderer beam not going straight
Hello!
I need help.
I'm making a Wave Motion Gun from Space Battleship Yamato. The script shoots a straight beam if nothing is in front of it, and if there is, end position of the line renderer would be the RaycastHit point.
Picture of it working firing straight into space: PICTURE
Picture of hitting a target: PICTURE2
Picture after target was destroyed, the beam isn't shooting straight anymore: PICTURE3
This is the code:
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(LineRenderer))]
public class WaveCannon : MonoBehaviour
{
public float Damage = 1.0f;
public AudioSource audioSource;
public Transform LaserFiringPoint;
public float LaserMaxDistance = 10.0f;
LineRenderer linerenderer;
public AudioClip WaveGunCharge;
public AudioClip WaveGunPrefire;
public AudioClip WaveGunLaser;
public ParticleSystem ChargingObject;
public ParticleSystem PrefireObject;
public ParticleSystem FiringObject;
public GameObject FiringEndObject;
public float LaserReachSpeed;
bool Firing = false;
private float beginTime;
Vector3 HitPoint;
private bool canDamage = false;
GameObject hitThing;
void Start()
{
linerenderer = GetComponent<LineRenderer>();
linerenderer.GetComponent<Renderer>().enabled = false;
Firing = false;
ChargingObject.Stop();
PrefireObject.Stop();
FiringObject.Stop();
}
void Update()
{
if (Firing)
{
RaycastHit hit;
float smoothMove = (Time.time - beginTime) * LaserReachSpeed;
linerenderer.SetPosition(0, LaserFiringPoint.position);
Vector3 fwd = LaserFiringPoint.TransformDirection(Vector3.forward);
if (Physics.Raycast(LaserFiringPoint.position, fwd, out hit, LaserMaxDistance))
{
linerenderer.SetPosition(1, Vector3.Lerp(LaserFiringPoint.position, hit.point, smoothMove));
Debug.DrawLine(LaserFiringPoint.position, hit.point);
HitPoint = hit.point;
canDamage = true;
hitThing = hit.transform.gameObject;
}
else
{
linerenderer.SetPosition(1, Vector3.Lerp(LaserFiringPoint.position, fwd * LaserMaxDistance, smoothMove));
canDamage = false;
hitThing = null;
}
}
else
{
if (Input.GetKeyDown("g"))
{
Charging();
}
}
}
void Charging()
{
ChargingObject.Play();
audioSource.PlayOneShot(WaveGunCharge);
Invoke("Prefire", WaveGunCharge.length);
}
void Prefire()
{
PrefireObject.Play();
ChargingObject.Stop();
audioSource.PlayOneShot(WaveGunPrefire);
Invoke("Fire", WaveGunPrefire.length);
}
void Fire()
{
beginTime = Time.time;
Firing = true;
FiringObject.Play();
PrefireObject.Stop();
linerenderer.GetComponent<Renderer>().enabled = true;
audioSource.PlayOneShot(WaveGunLaser);
Invoke("AfterFire", WaveGunLaser.length);
InvokeRepeating("DamageEffect", 0.0f, 0.05f);
}
void DamageEffect()
{
if (canDamage)
{
Instantiate(FiringEndObject, HitPoint, transform.rotation);
hitThing.SendMessage("Damage", Damage, SendMessageOptions.DontRequireReceiver);
}
}
void AfterFire()
{
CancelInvoke("DamageEffect");
FiringObject.Stop();
linerenderer.GetComponent<Renderer>().enabled = false;
Firing = false;
}
}
While I took the pictures, I did not move it. But it does the it while moving too.
Answer by Bunny83 · Oct 16, 2015 at 09:57 PM
Well your problem is that in the case where you don't hit anything you set the second point to:
Vector3.Lerp(LaserFiringPoint.position, fwd * LaserMaxDistance, smoothMove)
The problem here is that "LaserFiringPoint.position" is a world space point but "fwd * LaserMaxDistance" is just a world space direction and not a point. So the resulting positiob will be around the world origin.
You might want to use this instead:
linerenderer.SetPosition(1, LaserFiringPoint.position + fwd * LaserMaxDistance * Mathf.Clamp01(smoothMove));
That did it! Thanks for helping with the problem! That will actually help with couple other projects too, that had the problem. Thank you.