unity3d入门教程六
15.1预制体
火神山10天建成,使用了预制体技术
一个个小房间都是事先建造好的,最后吊车装配
Unity也有预制体技术
模拟这样一个游戏背景
飞机发射子弹,子弹很多,所以在游戏中动态的创建游戏对象,子弹对象,此时就需要预制体技术
15.2编辑预制体
![](https://i-blog.csdnimg.cn/direct/5f22caf74e2949b69d93ab5e7e1b77a6.png)
![](https://i-blog.csdnimg.cn/direct/708b9e6711af4f78b530081c530e72bb.png)
![](https://i-blog.csdnimg.cn/direct/07119c63aaf14c04b2927adc05a65bcf.png)
![](https://i-blog.csdnimg.cn/direct/d74c74bdf3754e73aee7595cecd0a6d5.png)
![](https://i-blog.csdnimg.cn/direct/13c4222704ed44f7a5447b5dabbf7812.png)
然后退出预制体的编辑状态进行其他的操作
void Update()
{
//另其向上移动
float step = 1.8f * Time.deltaTime;
transform.Translate(0, step, 0, Space.Self);
}
预制体相当于模板,可以创建更多的相同的实例
15.3在场景中编辑
![](https://i-blog.csdnimg.cn/direct/1dd13137b5d2489ea0f554ddc20c68f1.png)
![](https://i-blog.csdnimg.cn/direct/64d59954c6f44a5e9f11bc2c7bc10754.png)
![](https://i-blog.csdnimg.cn/direct/6f5ef790387848819c8fedda917a0322.png)
断开联系后,就可以单独更改一个实例不影响其他的
15.4动态创建实例
如飞机射子弹,要发出非常多的子弹,不能全放进去,而是游戏运行时自动创建出来的
![](https://i-blog.csdnimg.cn/direct/8995fe32679f41beba702573eecf956a.png)
1 添加 MyJet.cs ,挂载到 '飞机' 节点
2 添加公共变量
public GameObject myPrefab;
3 在 Inspector 中引用资源
4 当点击鼠标时,创建一个子弹的实例
GameObject bullet = Instantiate(myPrefab);
bullet.transform.position = transform.position + new Vector3(0, 1f, 0);
其中,Instantiate() 方法根据一个 Prefab ,来创建一个实例,返回值就是创建出来的GameObject 。
5 运行游戏
在 Hierarchy 窗口中,观察新创建的实例
Instantiate() 重载了很多版本,常用的如下:
bullet = Instantiate(myPrefab)
创建一个实例,position与rotation与当前游戏对象相当,挂载场景根节点下
bullet = Instantiate(myPrefab, Transform parent )
创建一个实例,position与rotation与当前游戏对象相当,同时指定父节点
bullet = Instantiate(myPrefab, position, rotation)
创建一个实例,挂载场景根节点下,同时指定 position与rotation
例如,
bullet = Instantiate(myPrefab, transform.position, transform.rotation)
bullet = Instantiate(myPrefab, position, rotation, Transform parent)
创建一个实例,挂载 parent 节点下,同时指定 position与rotation
![](https://i-blog.csdnimg.cn/direct/d42926ce49b74e4eaefbee26af2b1e8f.png)
![](https://i-blog.csdnimg.cn/direct/23aeec0837d54a0aa2034fef313a0272.png)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class myjet2 : MonoBehaviour
{
public GameObject myPrefab;
// Start is called before the first frame update
void Start()
{
Application.targetFrameRate = 60;
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Fire();
}
}
private void Fire()
{
//Instantiate方法可以将预制体资源创建为一个object
GameObject bullet = Instantiate(myPrefab);
bullet.transform.position = transform.position + new Vector3(0, 1f, 0);//创建位置放在飞机的上方
bullet.name = "bullet";//更改创建的实例的名称
}
}
15.5实例的销毁
![](https://i-blog.csdnimg.cn/direct/3bf5b185263b4754843e8058ca81c9f1.png)
之前点击一次创建一次子弹,创建的子弹会越来越多,需要将其销毁在合适的时机,即在消失在视野后进行销毁
将此脚本挂载到子弹的对象下,而不是飞机下,这样子弹自动被销毁
This指向的是当前组件,而实际要销毁的是游戏对象。
![](https://i-blog.csdnimg.cn/direct/bc9da2fb859c4ccf906bfe3472543c7c.png)
16.1(练习)子弹发射
![](https://i-blog.csdnimg.cn/direct/84e9a6cead3c444b810ccafcdfb82887.png)
使用键盘的左右键盘进行移动(键盘事件),并且自动不断发射子弹(需要定时器机制,如1秒2个子弹)
16.2定时器
子弹预制体对象上挂载的代码mybullet不用变,有自动向上移动和自我销毁功能
只需改变挂载到飞机上的代码即可,如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class myjet2 : MonoBehaviour
{
//预制体资源 '子弹'
public GameObject myPrefab;
//定时
private float interval = 0.4f;//计时,每个0.4秒发射一颗子弹
private float count = 0;
// Start is called before the first frame update
void Start()
{
Application.targetFrameRate = 60;
}
// Update is called once per frame
void Update()
{
如果鼠标按下就发射
//if (Input.GetMouseButtonDown(0))
//{
// Fire();
//}
//计时,每个0.4秒发射一颗子弹
count += Time.deltaTime;
if (count >= interval)
{
count = 0;
Fire();
}
}
//发射开火子弹
private void Fire()
{
//Instantiate方法可以将预制体资源创建为一个object
GameObject bullet = Instantiate(myPrefab);
bullet.transform.position = transform.position + new Vector3(0, 1f, 0);//创建位置放在飞机的上方
bullet.name = "bullet";//更改创建的实例的名称
}
}
16.3键盘事件
![](https://i-blog.csdnimg.cn/direct/e4cc823f807046e7b1d9e0418104437b.png)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class myjet2 : MonoBehaviour
{
//预制体资源 '子弹'
public GameObject myPrefab;
//定时
private float interval = 0.4f;//计时,每个0.4秒发射一颗子弹
private float count = 0;
// Start is called before the first frame update
void Start()
{
Application.targetFrameRate = 60;
}
// Update is called once per frame
void Update()
{
如果鼠标按下就发射
//if (Input.GetMouseButtonDown(0))
//{
// Fire();
//}
//计时,每个0.4秒发射一颗子弹
count += Time.deltaTime;
if (count >= interval)
{
count = 0;
Fire();
}
//按键响应
float step = 2.5f * Time.deltaTime;
//若左键被按下(按下的状态是一直按着的,不是按下一次)
if (Input.GetKey(KeyCode.LeftArrow))
{
transform.Translate(-step, 0, 0);
}
if (Input.GetKey(KeyCode.RightArrow))
{
transform.Translate(step, 0, 0);
}
}
//发射开火子弹
private void Fire()
{
//Instantiate方法可以将预制体资源创建为一个object
GameObject bullet = Instantiate(myPrefab);
bullet.transform.position = transform.position + new Vector3(0, 1f, 0);//创建位置放在飞机的上方
bullet.name = "bullet";//更改创建的实例的名称
}
}