简体   繁体   English

如何让多个游戏 object 出现同一个代码?

[英]How to make more than one game object appear with the same code?

I'm newbie trying to build a game.我是新手试图建立一个游戏。 I have an ant when you click on it it disappears and appears again somewhere else.我有一个 ant 当你点击它时它会消失并再次出现在其他地方。

I want to make more than one ant appear at the same time and they get destroyed when you click on them.我想让不止一个 ant 同时出现,当你点击它们时它们会被破坏。 Also I want all of them move randomly from the top of the screen to the bottom of the screen.另外我希望它们都从屏幕顶部随机移动到屏幕底部。 How to do so?怎么做?

var ant : GameObject;
var scoreText : GameObject;
var livesText : GameObject;
var walkingSpeed : double;
var livesNumber : int;
var scoreNumber : int;

function Start () {
    ant = GameObject.Find("Ant");
    scoreText = GameObject.Find("Score");
    livesText = GameObject.Find("Lives");

    //Initialize the values of walking speed
    walkingSpeed = 0.0;
    livesNumber = 3;
    scoreNumber = 0;

    //Initialize the GUI components
    livesText.GetComponent(UI.Text).text = "Lives Remaining: " + livesNumber;
    scoreText.GetComponent(UI.Text).text = "Score: " + scoreNumber;

    //Place the ant in a random position on start of the game
    ant.transform.position.x = generateX();
    ant.transform.position.y = generateY();
}

function Update () {    

    if(ant.transform.position.y < -4.35 && livesNumber > 0){    

        livesNumber -= 1;
        livesText.GetComponent(UI.Text).text = "Lives Remaining: " + livesNumber;
        generateCoordinates();

    }else if(ant.transform.position.y < -4.35 && livesNumber == 0){
        Destroy(GameObject.Find("Ant"));
        gameOver();

    }else{

        ant.transform.position.y -= walkingSpeed;
    }
}

function gameOver(){    
    Application.LoadLevel("GameOver");
}


//Generates random x
function generateX(){
    var x = Random.Range(-2.54,2.54);
    return x;
}

//Generates random y
function generateY(){
    var y = Random.Range(-4.0,3.8);
    return y;
}

//Move the "Ant" to the new coordiantess
function generateCoordinates(){
    //You clicked it!
    scoreNumber += 1;

    //Update the score display
    scoreText.GetComponent(UI.Text).text = "Score: " + scoreNumber;
    ant.transform.position.x = generateX();
    ant.transform.position.y = generateY();
}

//If tapped or clicked
function OnMouseDown(){
    //Place the ant at another point
    generateCoordinates();

    //Increase the walking speed by 0.01
    walkingSpeed += 0.01;
}

First of all, UnityScript is now deprecated for a while, so I think a good practice should be to update your Unity version and code in C# as now it's the main language used.首先,UnityScript 现在被弃用了一段时间,所以我认为一个好的做法应该是更新你的 Unity 版本和 C# 中的代码,因为它现在是使用的主要语言。

Try to avoid Game.Find() which is not a good way to reference GameObject.尽量避免Game.Find()这不是引用 GameObject 的好方法。 Instead you could create a prefab of your 'ant' and instantiate it as many time you want in random positions like that:相反,您可以创建“蚂蚁”的预制件,并在随机位置多次实例化它:

public GameObject antPrefab;

void GenerateAnt()
{
  //create a new position from random X and Y
  Vector2 position = new Vector2(generateX(), generateY());

  //Instantiate a new ant gameobject from the prefab and set position and rotation
  GameObject newAnt = Instantiate(antPrefab, position, Quaternion.identity)
}

Now if you have multiple ants, you need to loop for each ant to update the position of each ant.现在,如果您有多个蚂蚁,则需要为每个 ant 循环以更新每个 ant 的 position。

Don't forget to link your prefab in your public field in the editor;不要忘记在编辑器的公共字段中链接您的预制件; ;) ;)

Your code is made around having only one specific ant.您的代码只有一个特定的 ant。 You need to make the code agnostic to specific ants.您需要使代码与特定的蚂蚁无关。

But before going into specifics;但在详细说明之前;

  • Please consider moving to C#, it'll make your life a lot easier.请考虑迁移到 C#,它会让您的生活更轻松。

  • I will assume this is 2D.我会假设这是二维的。 If 3d, simply change the Vector2s to Vector3 and remove 2d from trigger method.如果 3d,只需将 Vector2s 更改为 Vector3 并从触发方法中删除 2d。

  • I'll write the example code in C#我将在 C# 中编写示例代码

So basically, what you have today is:所以基本上,你今天拥有的是:

  • Spawn an ant.生成一个 ant。
  • If user clicks the ant, move it to start.如果用户点击 ant,移动它开始。
  • If ant goes too far, you lose a life & remove it.如果 ant 走得太远,您将失去生命并将其移除。

What you want it你想要什么

  • Spawn any number of ants in random position.在随机 position 中生成任意数量的蚂蚁。
  • If user clicks an ant, remove it(?).如果用户单击 ant,请将其删除(?)。
  • If ant reaches goal, you lose a life & remove it.如果 ant 达到目标,您将失去生命并将其移除。

So let's address every single one of these steps, and how I'd implement them:因此,让我们解决这些步骤中的每一个,以及我将如何实现它们:

Spawn any number of ants, in random position随机生成任意数量的蚂蚁 position

Spawning requires 2 things:产卵需要两件事:

  1. A prefab一个预制件
  2. Usage of Instantiate() Instantiate()的用法

If you don't know how to create a prefab, or what it is, I suggest googling around until you understand.如果您不知道如何创建预制件或它是什么,我建议您在谷歌上搜索直到您理解为止。 In short, it's an instance of a GameObject saved to disk.简而言之,它是一个保存到磁盘的 GameObject 实例。 You do this by simply dragging a GameObject to a folder in the inspector's project view. 您只需将 GameObject 拖到检查器项目视图中的文件夹即可。

public GameObject antPrefab;
GameObject SpawnAnt(Vector2 position) {
    return Instantiate<GameObject>(antPrefab, position, Quaternion.identity);
}

Random position随机 position

How I like doing spawn positions is by declaring a spawn area GameObject, which you can move around in the editor, and specifying the size as a serialized field:我喜欢生成生成位置的方式是声明生成区域 GameObject,您可以在编辑器中移动它,并将大小指定为序列化字段:

[Range(1f, 10f)] // Gives you a slider to drag between 1 and 10 for this variable
public float spawnAreaRadius;

public Transform spawnArea;
void Vector2 GetRandomSpawnPosition() {
    var spawnAreaCenter = spawnArea.position;
    var spawnRandomX = Random.Range(-spawnAreaRadius, spawnAreaRadius);
    var spawnRandomY = Random.Range(-spawnAreaRadius, spawnAreaRadius);
    return new Vector2(spawnRandomX, spawnRandomY);
}

And regarding spawning multiple, you'd probably want to put up some event/timer to spawn and increase the ants to make it progressively harder:关于生成多个,您可能需要设置一些事件/计时器来生成并增加蚂蚁以使其越来越难:

Call this when you want to spawn a certain amount of ants in a random pattern around your spawn position:当你想在你的生成 position 周围以随机模式生成一定数量的蚂蚁时调用这个:

void SpawnAnts(int num) {
    for (int i = 0; i < num; i++) {
         var pos = GetRandomSpawnPosition();
         SpawnAnt(pos);
    }

}

Ant movement & lifecycle Ant 机芯和生命周期

Instead of looping over all ants and moving them with an overhead controller, which may be the optimal solution, for the sake of simplicity I'd add a script to the antPrefab that contains the ants:为了简单起见,我将在包含蚂蚁的 antPrefab 中添加一个脚本,而不是循环遍历所有蚂蚁并使用开销 controller 移动它们,这可能是最佳解决方案:

(This component requires a rigidbody & collider) (这个组件需要一个刚体和碰撞器)

void Update() {
    // Move ant towards goal
}

void OnMouseDown() {
    Destroy();
}

This will also give you a chance to easily give different ants different speeds, etc. Make each ant's AI a bit unique with far less effort than if they were grouped together.这也将使您有机会轻松地为不同的蚂蚁提供不同的速度等。使每只蚂蚁的 AI 有点独特,而且比将它们组合在一起的努力要少得多。

Colliding with goal与目标相撞

Define an area which is the ant's goal by placing a Trigger Collider in your world.通过在您的世界中放置一个触发对撞机来定义一个作为蚂蚁目标的区域。 Add your existing script to it and add a method for detecting collisions:将现有脚本添加到其中并添加检测碰撞的方法:

void OnTriggerEnter2D(Collider2D col) {
     if (col.tag == "ant") {
           lives--;
           Destroy(col.gameObject);    
     }

}

Summary概括

Some of these things you already solved in your way (such as generateX()), I wanted to give you some insight in how I'd personally tackle your code.您已经以您的方式解决了其中的一些问题(例如 generateX()),我想让您了解我将如何亲自处理您的代码。 You should evaluate which parts you'd want to use.您应该评估要使用的部分。


Disclaimer: This achieves your requirements, but leaves you with some other limitations, such as adding points when clicking an ant requires you to, probably, call some singleton point manager from the ant, rather than just detecting it in the same controller, which also would handle points. Disclaimer: This achieves your requirements, but leaves you with some other limitations, such as adding points when clicking an ant requires you to, probably, call some singleton point manager from the ant, rather than just detecting it in the same controller, which also会处理积分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM