unity3d 销毁克隆物体为什么不能销毁物体?

Unity3D:按键生成物件,Instantiate克隆的使用和销毁对象
在按下按键之后,可以在画面中生成之前定义好了的物体,这里使用了Instantiate函数来生成
1.先在游戏中定一个空物件GameObject
创建空物件快捷键:ctrl+shift+n
2.在视图中放置
3.编写脚本
脚本:SpaceCheck.cs
using UnityE
using System.C
public class SapceCheck : MonoBehaviour {
& & public GameObject
// Use this for initialization
void Start () {
// Update is called once per frame
void Update () {
& if (Input.GetKey(KeyCode.Space))&//按空格键时候开始克隆
if(Time.frameCount %5 ==0)//按照第几帧来限定每秒生成物件的数量
GameObject.Instantiate(Instcube, gameObject.transform.position,
gameObject.transform.rotation);
4.将脚本拖放到刚才创建的空物件上面
5.创建一个Cube预置
在文件夹中右键----Create-----Prefab(预置),将一个Cube拖入到该文件中
6.将这个Cube预置拖入到GameObject的脚本中
7.完成,检查效果
8.销毁对象
这里用鼠标单击来完成
创建一个c#脚本
void OnMouseUp()
GameObject.Destroy(gameObject);
然后拖放c#文件到刚才创建的预置文件中
测试可以发现在点击后方块消失
这里为了增强效果,增加了一个音效,最终脚本如下:
脚本:cube01.cs
using UnityE
using System.C
public class cube01 : MonoBehaviour {
&&& public
AudioClip BoomS//声音音效
&// Use this for initialization
&void Start () {
&// Update is called once per frame
&void Update () {
OnMouseUp()
GameObject.Destroy(gameObject);//摧毁物件
AudioSource.PlayClipAtPoint(BoomSound,
transform.localPosition);//点击鼠标时候播放音效
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。5576人阅读
&&&&&&&& 要在手机上玩转u3d,一定会做的一个就是对象池,在这里我不打算讨论对象池本身,基本思路大同小异。我这里想讨论的是切换场景引发的对象池中对象的问题。
&&&&&&& 首先如果你什么都不处理,那么一旦你切换场景,你会发现你对象池中所有GameObject本身或者变量全部都变成了null。你下次使用这个对象就会抛出指针异常,所以你肯定会去研究怎么切场景不销毁,ok,你马上就能找到DontDestroyOnLoad方法,只要声明之后,这个物体就不会被销毁。
&&&&&& 然后你发现有那么多对象都需要声明,会很麻烦,所以你可以新建一个物体,挂上不销毁的脚本,然后把不需要销毁的物体全部放到它里面,那么所有的物体切换场景就不会销毁了。
&&&&& 然后这样做的第一个问题,就是重复加载同样的场景,你会发现这个不销毁的新建的总物体每次都多复制了一个。因为上一次的保存下来,而这一次的还在,这个也不难解决,你可以直接判断场景中是否已经有这个物体,如果有就添加,没有就不用添加了,当然你可以参考雨凇MOMO的做法:/archives/2938(他说他的做法更好。。。虽然我觉得没有他说的那么夸张)
&&&& 接下来似乎不会有什么问题,但其实如果你真的在项目中这么做,你会发现还有很大的两个问题。
&&&& 1.我们放对象的时候,经常会把对象设置成不同层,比如默认是default, 可能会有UI层,& effect层。ok,当你把不同层的东西都放在一个obj下面的时候,下次再次加载场景时,它的父亲突然就变了。莫名其妙的把这个非销毁的所有物体挂在了UI层下(这是我碰到的情况,也许可能会挂在别的层,总之就是父亲变了)。这样问题就大了,因为如果父亲不是销毁的,那么儿子标记销毁是无效的,而且改变父亲这种行为也不是我们想看到的。也许你觉得只要重新设置一下父亲就好了。。。但所有儿子的Layer也会全被改掉。。。。你得全部重新设置,蛋碎。。。所以不建议这么做。
要解决也不难,只要注意不同层都应该要有自己的一个非销毁obj,比如default有一个,UI也要有一个,这样就不会乱了。
&&&& 2.第二个问题才是大问题。切换场景后,现在出现了三种情况,直接被销毁的物体,包括大部分脚本和GameObject. 不被销毁的静态变量和全局数据。& 最后就是挂了不销毁脚本的一堆GameObject.让我们一种一种看。
&&&& 第一种是最简单的,既然被销毁了,那么下次重新构造一个就好了,也是问题最少的做法,当然性能最差。
&&&& 第二种最常见的就是事件,你给物体挂上了事件一般都是存在一个事件管理器里的,当然正常的做法肯定是在销毁流程的时候会把所有的事件移除,但是切换场景可能是中途退出,所以不一定会把流程走完,所以建议在OnDestroy函数中处理这些问题。因为不论是否走正常流程,被销毁的物体肯定会进入OnDestroy函数,你只要在里面移除事件即可。
&&& 第三种最复杂,首先由于你已经标记为不销毁GameObject,所以你必须在场景切换前自己把所有的物体打回对象池。你可以用代理或者消息实现。这里要注意如果物体已经在对象池中,务必将所有的事件先移除,不然会重复调用。最后将物体移入对象池后,仍然需要注意下次取出的时候,有些东西可能已经不是正常的了。特别是你是对象池中的物体,而你的有些变量是被销毁的物体的引用,这个就需要你自己写逻辑维护了。
&&& 总之对象池虽好,但碰到这种蛋疼问题还是要早发现早处理。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:228611次
积分:3307
积分:3307
排名:第10485名
原创:88篇
转载:19篇
评论:91条
文章:54篇
阅读:99308
(1)(1)(1)(3)(2)(2)(4)(2)(2)(4)(5)(1)(2)(4)(2)(3)(10)(5)(7)(10)(4)(2)(3)(3)(5)(10)(3)(2)(2)(1)(1)Unity3D开发常用API之实例化与销毁(六) - 简书
Unity3D开发常用API之实例化与销毁(六)
1.实例化游戏物体
1.游戏中的案例介绍
在很多 MMORPG 类的游戏中都有类似于“金钱副本”的副本关卡。在这类副
本中通常都是限定一个时间,在这个时间内玩家可以尽情的破坏,然后收集金钱。
分析游戏截图讲解场景元素:[见图]
①场景中所有的坛子,模型都是一样的,坛子是预制体。
②坛子是从“天上”掉下来的,所以坛子模型身上有刚体组件。
③如果玩家在一段时间内没有打碎坛子,这些坛子会消失。
2.案例场景制作
①创建地面模型;
②创建“坛子”模型,并制作成预制体;
3.实例化生成 1 个坛子
GameObject.Instantiate(Object, Vector3, Quaternion);
参数说明:
Object:用于实例化的预制体;
Vector3:实例化后生成的物体所在的位置;
Quaternion[四元数]:实例化后生成的物体的旋转状态;
Quaternion.identity:无旋转;
4.构造随机位置
位置是用 Vector3 类型进行表示的。
X,Y,Z 三个值确定了物体在三维世界中的位置。
Random.Range(min, max):生成随机数。
在 min 和 max 直接随机生成一个随机数。
演示:按下键盘的一个键,就在随机位置实例化一个物体。
2.销毁游戏物体
GameObject.Destroy(Object, float);定时销毁某个游戏物体。
参数说明:
Object:要销毁的游戏物体;
float:时间,多少秒后销毁;
CreateBoxs
public class CreateBoxs : MonoBehaviour {
//定义公开变量 并通过拖曳 把相关预置体拖至相关属性下
public GameObject goP
void Start () {
//实例化对象关键语句(静态方法)
// GameObject.Instantiate(goPrefab,Vector3.up,Quaternion.identity);//参数1:预置体,就是要实例化的对象;参数2:0位置上方1米,参数3:4元数无旋转
//自己定义随机范围(位置)
// Vector3 position = new Vector3(1,1,1);
//Vector3 position = new Vector3(Random.Range(-9.0f,9.0f),10,Random.Range(-9.0f,9.0f));//参数1:X轴的范围 Y固定下高度,Z轴的范围
//GameObject.Instantiate(goPrefab,position,Quaternion.identity);
//通过按下空格键随机实例化box;
void Update () {
//通过按下空格键随机实例化box;
if (Input.GetKeyDown(KeyCode.Space))
Vector3 position = new Vector3(Random.Range(-9.0f,9.0f),10,Random.Range(-9.0f,9.0f));
GameObject.Instantiate(goPrefab,position,Quaternion.identity);
DestroyBox
public class DestroyBox : MonoBehaviour {
// Use this for initialization
void Start () {
//出现段时候后,销毁物体
关键语句 gameobject静态类方法
GameObject.Destroy(gameObject,Random.Range(5.0f,10.0f));//参数1:销毁物体的对象(就是本身) 参数2:销毁的时间
//以上方法只能写在start方法里,不能写在其他update方法中;
//// Update is called once per frame
//void Update () {
Unity API.png
一个无聊的人,经常做些无聊的事儿,撸代码,喂马,劈柴,周游世界......更喜欢看妹子~哈哈哈...AR/VR技术交流群:程序写累了,就来玩玩酷跑小游戏吧,嘿嘿。
雨松MOMO送你一首歌曲,嘿嘿。
Unity3D研究院之DontDestroyOnLoad的坑
Unity3D研究院之DontDestroyOnLoad的坑
围观51195次
编辑日期: 字体:
Unity中的一个方法DontDestroyOnLoad可以让某些游戏对象在切换场景的时候不是施放,听起来是一个非常好的方法,但是其实如果没用好那么可能就是有问题了。
举个例子:
在场景1中某一个脚本的Start方法中,DontDestroyOnLoad(A)
接着切换到场景2中,理所当然A对象被保留了下来
如果在从2场景再次回到1场景,那么又执行了一遍DontDestroyOnLoad(A)然而之前你的A对象却没有被施放,这样就会无线循环下去了。
当然我们可以去做逻辑判断是否DontDestroyOnLoad,判断A是否等于Null做一些判断。但是我觉得这其实是下策。DontDestroyOnLoad方法其实更多的是去保存一个全局的游戏脚本,比如一些第三方的SDK你需要用这个脚本来做中间件的支持。
我目前的做法是,我做了一个初始化场景。在初始化场景里面我只做两件事,第一在初始化场景里面的某个游戏对象的全局脚本中,Start方法里我把这个场景里面的所有游戏对象全部设置成DontDestroyOnLoad,也就是切换场景时不销毁,比如NGUI的Root梳妆结构。
Object[] initsObjects = GameObject.FindObjectsOfType(typeof(GameObject));
foreach (Object go in initsObjects) {
DontDestroyOnLoad(go);
第二,接着我在进入我的第一个游戏场景,也就是说我的逻辑永远不会在回返我的初始化场景。所以我也不会出现来回切场景DontDestroyOnLoad没有删除的问题。
还有一个巧妙的办法就是利用static 初始化方法,如下代码所示,当代码在调用Global类的时候
首先程序会进入static Global方法中,这个方法永远只会走一遍,所以我在这里创建一个GameObjcet,然后把Global这条脚本绑定上去,我在DontDestroyOnLoad这个对象。
12345678910111213141516171819202122232425
using UnityEngine;using System.Collections;&public class Global :MonoBehaviour{ public static Global instance;& static Global() {
GameObject go = new GameObject("Globa");
DontDestroyOnLoad(go);
instance = go.AddComponent&Global&(); }& public void DoSomeThings() {
Debug.Log("DoSomeThings"); }& void Start ()
Debug.Log("Start"); }&}
这样这条脚本就类似一个静态脚本了,而且这个游戏对象也永远不会因为切换场景而被销毁。而且用起来非常方便。在需要调用它的地方直接调用就行了。
Global.instance.DoSomeThings();
本文固定链接:
转载请注明:
雨松MOMO提醒您:亲,如果您觉得本文不错,快快将这篇文章分享出去吧 。另外请点击网站顶部彩色广告或者捐赠支持本站发展,谢谢!
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
如果您愿意花10块钱请我喝一杯咖啡的话,请用手机扫描二维码即可通过支付宝直接向我捐款哦。
您可能还会对这些文章感兴趣!29624人阅读
Unity 3D(145)
gameObject.renderer.enabled
//是控制一个物体是否在屏幕上渲染或显示
而物体实际还是存在的 只是想当于隐身 而物体本身的碰撞体还依然存在的
GameObject.Destroy()
//表示移除物体或物体上的组件 代表销毁该物体
实际上该物体的内存并没有立即释放 而是在你下下个场景中槽释放内存资源,就是你a场景中Destroy了 一般是在c场景中才真正释放该物体的内存资源(这是我的体会 不知道理解错误没)
gameObject.active
//是否在场景中停用该物体
在你gameObject.active =false中 则你在场景中用find找不到该物体
//如果该物体有子物体 你要用SetActiveRecursively(false) 来控制是否在场景中停用该物体(递归的)
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
互动教程列表
访问:944239次
积分:11549
积分:11549
排名:第1367名
原创:202篇
转载:323篇
评论:83条

我要回帖

更多关于 unity 怎么销毁子物体 的文章

 

随机推荐