【问题标题】:Shooting laser continuously in Unity在 Unity 中连续发射激光
【发布时间】:2018-06-08 05:35:12
【问题描述】:

我正在尝试创建像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);
}

有人可以看看代码并告诉我哪里出错了。

【问题讨论】:

    标签: c# unity3d logic


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      这是使用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);
          }
      }
      

      解释一下代码:

      Laser prefab 有自己的脚本,用于向单词移动,一旦它存在并且将目标传递给它,它就会向活动单词移动。

      在场景的其他地方,您有一个游戏对象来保存第二个脚本。让我们称之为“控制器游戏对象”。根据早期的设计,它会检查单词是否“活跃”。当一个词处于活动状态时,此脚本会创建一个激光,并告诉它以活动词为目标。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-10
        • 1970-01-01
        • 2021-05-14
        • 1970-01-01
        相关资源
        最近更新 更多