|
通过这一点你应该明白预设在一个基本水平。他们是一组预定义的游戏对象 & 组件这是在游戏中重复使用。如果你不知道一个预设是什么,我们建议你阅读预设一个更基本的介绍页面。
问题就在手边的时候要复杂对象在运行时实例化。实例化预设可选择创建游戏对象从零开始使用代码。实例化预设在替代方法的优点:
你可以实例化预设一行代码,功能完备。创建等效对象的代码以平均有五行代码,但可能更多。
你可以设置,测试,和修改预置的迅速和容易地在现场督察。
你可以改变被实例化的预置物体不改变实例化代码。一个简单的火箭可能改变成一个超级火箭,没有代码所做的更改。
常见的场景
为了说明问题的力量,让我们考虑一些基本的情况,他们将派上用场:
建筑墙体的一个单一的“砖”,创造了几次不同位置的预制。
一个火箭发射器实例一个飞行的火箭预置发射时。预置物体包含一个网格,刚体,对撞机,和自己的孩子游戏对象跟踪粒子系统。
一个机器人爆炸成许多碎片。完整的、操作的机器人被破坏和更换一个毁坏的机器人预制。这个预置包含机器人分成很多部分,都建立了它们自己的刚体和粒子系统。这种技术允许你炸毁一个机器人成许多碎片,只有一行代码,一个预制更换一个对象。
建一堵墙
这个例子说明使用预制VS代码创建对象的优势。
首先,使用代码创建一堵砖墙:
// JavaScript
function Start () {
for (var y = 0; y < 5; y++) {
for (var x = 0; x < 5; x++) {
var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.AddComponent.<Rigidbody>();
cube.transform.position = Vector3 (x, y, 0);
}
}
}
// C#
public class Instantiation : MonoBehaviour {
void Start() {
for (int y = 0; y < 5; y++) {
for (int x = 0; x < 5; x++) {
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.AddComponent<Rigidbody>();
cube.transform.position = new Vector3(x, y, 0);
}
}
}
}
使用上面的脚本,我们只需保存脚本并将其拖到一个空的游戏对象。
创建一个空的游戏对象GameObject->Create Empty。
如果你执行的代码,你将看到创建的整个砖墙当你进入播放模式。有两对每一块砖的功能的相关线路:createprimitive线,和addcomponent线。不太坏的现在,但我们的每一砖不变形。每一个额外的行动要对砖进行,如改变纹理,摩擦,或刚体群众,是一个额外的线。
如果你创建一个预设,在执行前你所有的设置,你用一行代码来执行创建和设置每一块砖。这可以让你保持和改变了很多代码,当你决定你想要做出改变。用预制件,你只是让你的变化和玩。无需修改代码。
如果你使用一个预设为每一块砖,这是你需要创建墙的代码。
// JavaScript
var brick : Transform;
function Start () {
for (var y = 0; y < 5; y++) {
for (var x = 0; x < 5; x++) {
Instantiate(brick, Vector3 (x, y, 0), Quaternion.identity);
}
}
}
// C#
public Transform brick;
void Start() {
for (int y = 0; y < 5; y++) {
for (int x = 0; x < 5; x++) {
Instantiate(brick, new Vector3(x, y, 0), Quaternion.identity);
}
}
}
这不仅是很干净也很可。没有什么说我们实例化一个立方体,它必须包含刚体。所有的这一切都是在预制定义,可以快速在编辑器修改。
现在我们只需要创建的预设,我们的编辑做的。这里的如何:
选择GameObject > 3D Object > Cube
选择Component > Physics > Rigidbody
选择Assets > Create > Prefab
在项目视图,改变你的新的预置名称“砖”
把你创建的立方体等级制度我们的“砖”在预置物体项目视图
与预制的创建,你可以安全地从层次结构中删除立方体(删除在Windows,命令键MAC)
我们创建了砖的预制件,所以我们必须重视它的砖在我们的脚本变量。当你选择包含脚本的空的游戏对象,砖变会在检查可见。
现在将“砖”活动从项目视图上砖在检查变量。按下播放键,你会看到墙采用预制。
这是一个工作流模式,可以一次次在统一使用。在开始的时候,你可能不知道为什么这么好,因为脚本代码创建多维数据集只有2线更长。
但因为你使用的是预制的现在,你可以在几秒钟内调节预置。想改变所有实例的质量?调整刚体在预置只有一次。想使用一个不同的材料对于所有的情况吗?拖动材料到预置的唯一一次。想改变摩擦?使用不同的物理材质在预置的对撞机。要添加一个粒子系统,所有这些盒子吗?对预制添加子只有一次。
Instantiating rockets & explosions
这里的如何融入这个场景分类:
火箭发射器实例一个火箭预制当用户按下开火。预置物体包含一个网格,刚体,碰撞,和一个子游戏物体包含尾粒子系统。
火箭撞击并实例化一个爆炸预置。爆炸预置包含一个粒子系统,光消失了一段时间,和一个脚本,适用于周围物体的伤害。
而这将有可能建立一个火箭游戏对象完全从代码,手工添加组件并设置属性,它是实例化预设更容易。您可以实例化火箭仅仅一行代码,不管火箭的组合是多么复杂。在实例化预设还可以修改任何属性的实例化的对象(例如,你可以设置火箭刚体的速度)。
除了更容易使用,你可以更新预制后。所以,如果你正在建设一个火箭,你不马上要添加一个粒子跟踪它。你可以稍后。当你添加TRAIL作为一个孩子的游戏对象的预设,所有实例的火箭将粒子轨迹。最后,你可以快速调整在检查火箭预置的属性,使它更容易调整你的游戏。
这个脚本显示了如何发射火箭的使用instantiate()功能。
// JavaScript
// Require the rocket to be a rigidbody.
// This way we the user can not assign a prefab without rigidbody
var rocket : Rigidbody;
var speed = 10.0;
function FireRocket () {
var rocketClone : Rigidbody = Instantiate(rocket, transform.position, transform.rotation);
rocketClone.velocity = transform.forward * speed;
// You can also acccess other components / scripts of the clone
rocketClone.GetComponent.<MyRocketScript>().DoSomething();
}
// Calls the fire method when holding down ctrl or mouse
function Update () {
if (Input.GetButtonDown("Fire1")) {
FireRocket();
}
}
// C#
// Require the rocket to be a rigidbody.
// This way we the user can not assign a prefab without rigidbody
public Rigidbody rocket;
public float speed = 10f;
void FireRocket () {
Rigidbody rocketClone = (Rigidbody) Instantiate(rocket, transform.position, transform.rotation);
rocketClone.velocity = transform.forward * speed;
// You can also acccess other components / scripts of the clone
rocketClone.GetComponent<MyRocketScript>().DoSomething();
}
// Calls the fire method when holding down ctrl or mouse
void Update () {
if (Input.GetButtonDown("Fire1")) {
FireRocket();
}
}
一个布娃娃或沉船替换字符
让我们说你有一个完全操纵敌人的角色谁死。你可以在角色扮演的死亡动画和禁用所有脚本通常应付敌人的逻辑。你需要小心的删除一些脚本,添加一些自定义的逻辑来确保没有人会继续攻击敌人的死了,和其他清理工作。
更好的方法是立即删除整个角色和取代它的一个实例化了预制。这给你一个很大的灵活性。你可以使用不同的材料为死字,附加完全不同的脚本,创建的预置包含物体破碎成许多碎片来模拟消灭的敌人,或简单的实例一个预置包含一个版本的特性。
这些选项的任何可以实现的一个电话instantiate(),你只需要将它连接到正确的预制和你!
要记住的最重要的部分是你的残骸instantiate()可以由完全不同的对象比原来。例如,如果你有一架飞机,要准备两个版本的模型。其中一个飞机由一个单一的游戏对象网格渲染器和飞机物理脚本。通过保持模型只是一个游戏,你的游戏将运行的更快,因为你将能以更少的三角形,使模型因为它包含较少的对象,它将比使用许多小部分快。当你的飞机也高兴地飞来飞去,没有理由将其分开的部分。
创建一个破坏的飞机预置,一般步骤是:
把飞机模型在您最喜爱的模型有很多不同的地方
创建一个空的场景
拖动模型到空场景
添加刚体的所有部件,通过选择各零件和选择Component->Physics->Rigidbody
加框碰撞所有部件通过选择各零件和选择Component->Physics->Box Collider
一个额外的特殊效果,添加一个烟雾状粒子系统作为一个孩子的游戏对象的每一部分
现在你有一个飞机具有多个爆炸的部分,它们通过物理地将创建一个粒子轨迹由于连接的粒子系统。点击播放预览模型的反映,并做一些必要的调整。
选择Assets->Create Prefab
将含有所有飞机部件到预置的根对象
下面的例子说明了这些步骤是仿照代码。
// JavaScript
var wreck : GameObject;
// As an example, we turn the game object into a wreck after 3 seconds automatically
function Start () {
yield WaitForSeconds(3);
KillSelf();
}
// Calls the fire method when holding down ctrl or mouse
function KillSelf () {
// Instantiate the wreck game object at the same position we are at
var wreckClone = Instantiate(wreck, transform.position, transform.rotation);
// Sometimes we need to carry over some variables from this object
// to the wreck
wreckClone.GetComponent.<MyScript>().someVariable = GetComponent.<MyScript>().someVariable;
// Kill ourselves
Destroy(gameObject);
// C#
public GameObject wreck;
// As an example, we turn the game object into a wreck after 3 seconds automatically
IEnumerator Start() {
yield return new WaitForSeconds(3);
KillSelf();
}
// Calls the fire method when holding down ctrl or mouse
void KillSelf () {
// Instantiate the wreck game object at the same position we are at
GameObject wreckClone = (GameObject) Instantiate(wreck, transform.position, transform.rotation);
// Sometimes we need to carry over some variables from this object
// to the wreck
wreckClone.GetComponent<MyScript>().someVariable = GetComponent<MyScript>().someVariable;
// Kill ourselves
Destroy(gameObject);
}
}
将一组对象在一个特定的模式
比如说你想把一组对象在一个方形或圆形图案。通常这会做的:
建筑完全从代码的对象。这是乏味的!从脚本的输入值是缓慢的,直观的和不值得的麻烦。
使完全操纵的对象,它并把它复制多次在现场。这是乏味的,配售对象在网格中是很难准确。
所以使用instantiate()用预制件代替!我们认为你的问题是为什么在这些情况下非常有用的想法。这里的这些场景的必要的代码:
// JavaScript
// Instantiates a prefab in a circle
var prefab : GameObject;
var numberOfObjects = 20;
var radius = 5;
function Start () {
for (var i = 0; i < numberOfObjects; i++) {
var angle = i * Mathf.PI * 2 / numberOfObjects;
var pos = Vector3 (Mathf.Cos(angle), 0, Mathf.Sin(angle)) * radius;
Instantiate(prefab, pos, Quaternion.identity);
}
}
// C#
// Instantiates a prefab in a circle
public GameObject prefab;
public int numberOfObjects = 20;
public float radius = 5f;
void Start() {
for (int i = 0; i < numberOfObjects; i++) {
float angle = i * Mathf.PI * 2 / numberOfObjects;
Vector3 pos = new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * radius;
Instantiate(prefab, pos, Quaternion.identity);
}
}
// JavaScript
// Instantiates a prefab in a grid
var prefab : GameObject;
var gridX = 5;
var gridY = 5;
var spacing = 2.0;
function Start () {
for (var y = 0; y < gridY; y++) {
for (var x=0;x<gridX;x++) {
var pos = Vector3 (x, 0, y) * spacing;
Instantiate(prefab, pos, Quaternion.identity);
}
}
}
// C#
// Instantiates a prefab in a grid
public GameObject prefab;
public float gridX = 5f;
public float gridY = 5f;
public float spacing = 2f;
void Start() {
for (int y = 0; y < gridY; y++) {
for (int x = 0; x < gridX; x++) {
Vector3 pos = new Vector3(x, 0, y) * spacing;
Instantiate(prefab, pos, Quaternion.identity);
}
}
}
|
|