adi pat
adi pat

Reputation: 11

Shooting laser continuously in Unity

I'm trying to create a falling word game like z-type. Once the game starts a few words are displayed on the screen. When the user types a letter and if that matches with the first letter of any of the words displayed, an activeWord tag is added to the word. I have also created a laser script that checks if the tag is active and when that happens, it shoots the laser.

What's happening right now is that the laser is shot only once i.e when the first letter matches but doesn't shoot a laser when the remaining words are typed.

This is the laser script:

using UnityEngine;
using UnityEngine.UI;

public class Laser : MonoBehaviour {
    public float speed = 10.0f;  
    private Vector3 laserTarget;

    private void Update () {
        GameObject activeWord = GameObject.FindGameObjectWithTag("activeWord");

        if (activeWord && activeWord.GetComponent<Text>().text.Length > 0) {
            laserTarget = activeWord.transform.position; // find position of word
            transform.Translate(laserTarget * speed * Time.deltaTime); // shoot the laser
        } 
    }
}

I'm also adding the code that I use in the display/UI field.

public void RemoveLetter() {
/* remove the first letter if its correct and so 
on for the remaining letters. change the color of the word to red and add 
the "activeddWord" tag.*/
    text.text = text.text.Remove(0, 1);    
    text.color = Color.red;
    text.gameObject.tag = "activeWord";        
}

public void RemoveWord() { // destroy the word once all the letters match 
    Destroy(gameObject);
}

Can someone please have a look at the code and tell me where I'm making a mistake.

Upvotes: 1

Views: 1219

Answers (2)

Tyler S. Loeper
Tyler S. Loeper

Reputation: 836

Here is one way you can do this using Instantiate() and prefabs. The benefit of this method is that it is scalable. You can create multiple lasers with minimal tweaking. Please note that to use multiple lasers you will have to remove WaitForThisLaserDestroyed;.

To get this to work you will have to start by changing your laser gameObject into a prefab and adding this script onto it:

https://docs.unity3d.com/Manual/Prefabs.html

public class Laser : MonoBehaviour 
{
    public float speed = 10.0f;  
    public Vector3 laserTarget;
    public float destroyLaserAfterTime = 3f;

    private void Update () 
    {    
         transform.Translate(laserTarget * speed * Time.deltaTime);  
    }               
}

And then on some arbitrary other object. For example an empty game object in the same scene:

public class LaserInitializer : MonoBehaviour 
{
    public GameObject laserPrefab;
    public GameObject laserOrigin;
    private GameObject WaitForThisLaserDestroyed;

    private void Update () 
    {    
         GameObject activeWord = GameObject.FindGameObjectWithTag("activeWord");            
         if (WaitForThisLaserDestroyed == null && activeWord && activeWord.GetComponent<Text>().text.Length > 0)
         {        
             CreateLaser(activeWord);
         }     
    }        

    private void CreateLaser(GameObject activeWord)
    {
         GameObject activeLaser = Instantiate(laserPrefab, laserOrigin.Transform.Position, Quaternion.identity) as GameObject;
         Laser laserScript = activeLaser.GetComponent<Laser>();
         laserScript.laserTarget = activeWord.transform.position;
         WaitForLaserDestroyed = activeLaser;
         Destroy(activeLaser, destroyLaserAfterTime);
    }
}

To explain the code:

The Laser prefab has its own script for moving towards the word, and as soon as it exists and has the target passed to it, it will move towards the active word.

Somewhere else in the scene you have a game object that exists to hold the second script. Lets call it the "controller game object". It checks to see if the words are "active", as per the earlier design. When a word is active this script creates exactly one laser, and tells it to target the active word.

You have another gameobject (this can be the same one as the controller game object), that marks the origin of the laser. You can do this in other ways, but I thought that using a game object to mark the start point would be an easy way for beginners.

Upvotes: 1

dome12b
dome12b

Reputation: 623

I think you have to reset the position of your laser if it reaches the target:

public float speed = 10.0f;  
private Vector3 laserTarget;
private Vector3 laserOrigin;

private void Start () {
    // save laser's origin position
    laserOrigin = transform.position;
}


private void Update () { 
    GameObject activeWord = GameObject.FindGameObjectWithTag("activeWord");

    if (activeWord && activeWord.GetComponent<Text>().text.Length > 0)
    {        
        laserTarget = activeWord.transform.position; // find position of word
        transform.Translate(laserTarget * speed * Time.deltaTime); // shoot the laser

        float distance = Vector3.Distance(laserTarget , transform.position);
        if(distance < 0.05f){ // I don't know your scaling, perhaps change the limit here!
            transform.position = laserOrigin;
        }
    } 
}

Upvotes: 2

Related Questions