在Unity中连续拍摄激光

时间:2018-06-08 05:35:12

标签: c# unity3d logic

我正在尝试制作像z-type这样的堕落文字游戏。游戏开始后,屏幕上会显示几个单词。当用户键入一个字母并且与所显示的任何单词的第一个字母匹配时,会在该单词中添加activeWord标记。我还创建了一个激光脚本,用于检查标签是否处于活动状态,当发生这种情况时,它会拍摄激光。

现在正在发生的事情是激光仅被拍摄一次,即第一个字母匹配但在输入剩余的单词时不会拍摄激光。

这是激光脚本:

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
        } 
    }
}

我还在显示/ UI字段中添加了我使用的代码。

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);
}

有人可以查看代码并告诉我我在哪里犯了错误。

2 个答案:

答案 0 :(得分:2)

我认为如果激光到达目标,你必须重置激光的位置:

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;
        }
    } 
}

答案 1 :(得分:1)

以下是使用Instantiate()和预制件执行此操作的一种方法。这种方法的好处是可扩展。您可以创建多个激光器,只需最少的调整。请注意,要使用多个激光,您必须删除WaitForThisLaserDestroyed;

要实现这一点,您必须首先将激光游戏对象更改为预制件并将此脚本添加到其中:

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);  
    }               
}

然后在一些任意的其他对象上。例如,同一场景中的空游戏对象:

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);
    }
}

解释代码:

激光预制件有自己的脚本移动到单词,一旦它存在并将目标传递给它,它将移动到活动单词。

在场景中的其他地方,您有一个游戏对象,用于存放第二个脚本。让我们称之为“控制器游戏对象”。它按照早期的设计检查单词是否“活动”。当一个单词处于活动状态时,该脚本只会创建一个激光,并告诉它定位活动单词。

你有另一个游戏对象(这可能与控制器游戏对象相同),它标志着激光的起源。您可以通过其他方式执行此操作,但我认为使用游戏对象标记起点对初学者来说是一种简单的方法。