C# 如何以编程方式随机生成游戏对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16183457/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to randomly generate GameObjects programmatically?
提问by Ange
I'd like some help with the following issue. I'm making a simple game where you have a character running and he has to jump over obstacles coming at him.
我想要一些关于以下问题的帮助。我正在制作一个简单的游戏,你有一个角色在奔跑,他必须跳过向他袭来的障碍物。
And I'm currently stuck when it comes to creating GameObjects and randomly generating them within the game scene at run time.
在创建游戏对象并在运行时在游戏场景中随机生成它们时,我目前陷入困境。
I've written a class to help accomplish this:
我写了一个类来帮助实现这一点:
using UnityEngine;
using System.Collections;
public class randomObstacles : MonoBehaviour {
public GameObject myCube;
public Vector3 spawnLocation = new Vector3(0,2,0);
// Use this for initialization
void Start () {
GameObject SpawnLocation = (GameObject)Instantiate(myCube, spawnLocation, Quaternion.identity);
}
// Update is called once per frame
void Update () {
}
}
The above code is what I wrote to simply create Objects, one after the other. But when I run the game, it comes up empty -_- !
上面的代码是我为了简单地一个接一个地创建对象而编写的。但是当我运行游戏时,它出现空 -_- !
Can anyone please tell me where am going wrong, and from the look of it my code doesn't seem to do what I am hoping to achieve :(
谁能告诉我哪里出了问题,从它的外观来看,我的代码似乎没有达到我希望实现的目标:(
I've attached the above script into an empty GameObject as I saw in a tutorial from the Unity Community forum, but that did not help either. (I've looked around and it seems like no one has come across such an issue - I could bee wrong)
正如我在 Unity 社区论坛的教程中看到的那样,我已将上述脚本附加到一个空的 GameObject 中,但这也无济于事。(我环顾四周,似乎没有人遇到过这样的问题 - 我可能错了)
采纳答案by daniel-cheng
It would seem that your myCubevariable is the root of your problems, having tested it in a scene of my own. By subsituting
似乎您的myCube变量是问题的根源,在我自己的场景中对其进行了测试。通过代入
(GameObject)Instantiate(myCube, ...
with
和
(GameObject)Instantiate(GameObject.CreatePrimitive(PrimitiveType.Cube), ...
I was able to produce a cube at (0,2,0) with no qualms. Perhaps your myCubeGameObject is missing a Mesh Renderer, in which case it would appear in the Hierarchy during runtime even though it would not appear visible in Game View. Perhaps you are not assigning it in the Inspector before you run the game, in which case the myCubevariable would refer to nulland thus not be created. Additionally, though you may be assigning the GameObject you instantiate to SpawnLocation, it is an unused local variable (something MonoDevelop or your code editor should notify you of). Make sure you either provide a reference to a myCubeGameObject in the Inspector before runtime or through script referencing to a loaded prefab/GameObject during runtime. It would also be helpful to provide a fallback (say, to PrimitiveType.Cube perhaps?), which will make your code more robust and able to handle errors in referencing should they arise.
我能够毫无顾虑地在 (0,2,0) 处生成一个立方体。也许您的myCube游戏对象缺少网格渲染器,在这种情况下,它会在运行时出现在层次结构中,即使它在游戏视图中不可见。也许您在运行游戏之前没有在 Inspector 中分配它,在这种情况下,myCube变量将引用null并因此不会被创建。此外,尽管您可能将您实例化的 GameObject 分配给 SpawnLocation,但它是一个未使用的局部变量(MonoDevelop 或您的代码编辑器应该通知您)。确保您提供对myCube运行时之前检查器中的游戏对象或通过脚本在运行时引用加载的预制件/游戏对象。提供回退(比如,可能是 PrimitiveType.Cube?)也会很有帮助,这将使您的代码更加健壮,并且能够处理引用中出现的错误。
Regardless, in order to achieve the functionality you have described, first make sure yo have properly prepared whatever you would desire myCubeto be. Also, for future posterity, you may want to initialize your spawnLocationin the Startroutine, and assign the variable coordinates by substituting Random.value * yourValueCeilingin for each random coordinate you would like myCubeto spawn on. You could even go as far to make a helper method externalized and thus independent from the start routine, such that you will not have to have a hundred instances of a single script to create a hundred instances of what you need; rather, you can call the method through a single script, and save yourself trouble in this way. If you would so appreciate it, here is my implementation of your objective, hope this helps!
无论如何,为了实现您所描述的功能,首先要确保您已经准备好您想要的任何东西myCube。此外,对于未来的后代,您可能希望spawnLocation在Start例程中初始化您的,并通过替换Random.value * yourValueCeiling您myCube想要生成的每个随机坐标来分配变量坐标。您甚至可以将辅助方法外部化,从而独立于启动例程,这样您就不必拥有单个脚本的一百个实例来创建您需要的一百个实例;相反,您可以通过单个脚本调用该方法,这样可以省去麻烦。如果您愿意的话,这是我对您的目标的实现,希望对您有所帮助!
using UnityEngine;
using System.Collections;
public class randomObstacles : MonoBehaviour {
public Vector3 spawnLocation;
public GameObject myCube;
// Use this for initialization
void Start () {
if (myCube != true) {
Debug.Log("myCube not set");
myCube = GameObject.CreatePrimitive(PrimitiveType.Cube);
}
if (myCube.renderer.enabled == false) {
Debug.Log("myCube not rendered");
myCube = GameObject.CreatePrimitive(PrimitiveType.Cube);
}
CreateCube();
}
// Update is called once per frame
void Update () {
}
void CreateCube() {
spawnLocation = new Vector3(0, Random.value * 10, 0);
Instantiate(myCube, spawnLocation, Quaternion.identity);
}
}
回答by LightStriker
Taken from my own code in a game that auto generate mazes:
取自我自己在自动生成迷宫的游戏中的代码:
public class Cell
{
private GameObject instance;
public void CreateVisual()
{
// Load a GameObject that exist inside the "Resources" folder.
GameObject prefab = (GameObject)Resources.Load("Models/Walls/3W1");
// Create an instance of the prefab
instance = (GameObject)GameObject.Instantiate(prefab);
instance.transform.position = myPosition;
}
}
I think the part you are missing is the Resources.Load()method.
我认为您缺少的部分是Resources.Load()方法。
回答by Dan Puzey
It may be worth pointing out that you're creating your object in the Startmethod, which means your code will only run once: from the name of your class, I'd assume you want to create more than one object using this code.
值得指出的是,您正在方法中创建对象Start,这意味着您的代码只会运行一次:根据您的类的名称,我假设您想使用此代码创建多个对象。
If you move the code into Updateyou'll create one object per frame, which is most likely too many. My guess would be that you want something like a coroutine that will run on a random interval, and then spawn cubes repeatedly over time, something like this:
如果您将代码移入,Update您将每帧创建一个对象,这很可能太多了。我的猜测是你想要一个像协程这样的东西,它会以随机间隔运行,然后随着时间的推移重复生成立方体,就像这样:
void Start () {
StartCoroutine("SpawnObjects");
}
IEnumerator SpawnObjects()
{
while (keepAddingObjects) // a boolean - could just be "true" or could be controlled elsewhere
{
GameObject SpawnLocation = (GameObject)Instantiate(myCube, spawnLocation, Quaternion.identity);
float delay = Random.Range(1f, 5f); // adjust this to set frequency of obstacles
yield return new WaitForSeconds(delay);
}
}

