我正在尝试创建一个像z-type这样的坠落单词游戏。一旦游戏开始,屏幕上就会显示几个单词。当用户键入一个字母时,如果该字母与所显示的任何单词的第一个字母相匹配,则会向该单词添加一个activeWord标记。我还创建了一个激光脚本来检查标签是否处于活动状态,当发生这种情况时,它会发射激光。
现在发生的情况是,激光只发射一次,即当第一个字母匹配时,而不是在键入其余单词时发射激光。
这是laser脚本:
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
}
}
}我还添加了在display/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);
}有没有人可以看一下代码,告诉我哪里出了错。
发布于 2018-06-08 14:56:30
我认为如果激光到达目标,你必须重新设置激光的位置:
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;
}
}
}发布于 2018-06-08 22:07:25
这里有一种方法,你可以使用Instantiate()和预制来做这件事。这种方法的好处是它是可伸缩的。您可以创建多个激光与最小的调整。请注意,要使用多个激光器,您必须移除WaitForThisLaserDestroyed;。
要让这项工作,你将不得不改变你的激光gameObject到一个预制,并添加以下脚本到它:
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);
}
}要解释代码,请执行以下操作:
激光预制有它自己的脚本,一旦它存在并将目标传递给它,它就会移动到活动的单词。
在场景中的其他地方,您有一个游戏对象,该对象用于保存第二个脚本。让我们称它为“控制器游戏对象”。它检查单词是否按照早期的设计是“活动的”。当一个词被激活时,这个脚本只创建一个激光,并告诉它指向激活的词。
你有另一个游戏对象(这可以是与控制器游戏对象相同的对象),它标记了激光的起源。你也可以用其他的方式来实现,但是我认为对于初学者来说,使用一个游戏对象来标记起点是一种简单的方式。
https://stackoverflow.com/questions/50753973
复制相似问题