欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 培训 > Unity3D运行设置物体为预制体

Unity3D运行设置物体为预制体

2025/5/22 20:05:42 来源:https://blog.csdn.net/qq_42603590/article/details/144242837  浏览:    关键词:Unity3D运行设置物体为预制体

系列文章目录

unity知识点


文章目录

  • 系列文章目录
  • 👉前言
  • 👉一、效果展示
  • 👉二、使用方法
  • 👉三、对象池使用
    • 👉3-1、效果展示
    • 👉3-2、制作prefab
    • 👉3-3、核心代码
    • 👉3-4、对象池使用
  • 👉壁纸分享
  • 👉总结


👉前言

有时候需要做摆放场景物体的时候会重复使用一些物体,这时候把物体做成预制体是最好用的,有时候需要用到很多的预制体,需要手动全部拖到Project面板的Assets文件夹下面(自己创建新的文件夹名称,按自己喜欢的名称就好)

博客将会介绍制作的方法。希望这篇博客对Unity的开发者有所帮助。
大家好,我是心疼你的一切,不定时更新Unity开发技巧,觉得有用记得一键三连哦。
欢迎点赞评论哦.下面就让我们进入正文吧 !


提示:以下是本篇文章正文内容,下面案例可供参考

👉一、效果展示

项目运行时制作预制体

👉二、使用方法

1.如图所示的代码挂载到一个空物体上即可
在这里插入图片描述
2.场景如下图所示在这里插入图片描述
3.完整代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 引擎运行可以使用,打包出来不能用切记
/// </summary>
public class GameObjToPrefabs : MonoBehaviour
{public GameObject prefabHolder;//制作单个的物体预制体public void ConvertToPrefab(string name_){
#if UNITY_EDITOR       // 将场景物体设为预制体UnityEditor.PrefabUtility.SaveAsPrefabAsset(prefabHolder, "Assets/Scripts/一键生成预制体/Prefabs/"+ name_ + ".prefab");
#endif}//制作物体下面子物体的预制体public void ConvertToPrefab(List <GameObject> name_s){foreach (var item in name_s){
#if UNITY_EDITOR// 将场景物体设为预制体UnityEditor.PrefabUtility.SaveAsPrefabAsset(item, "Assets/Scripts/一键生成预制体/Prefabs/" + item.name + ".prefab");
#endif}}private void Update(){if (Input.GetKeyDown(KeyCode.P)){ConvertToPrefab(prefabHolder.name);}if (Input.GetKeyDown(KeyCode.O)){List<GameObject> lists = new List<GameObject>();for (int i = 0; i < prefabHolder.transform.childCount; i++){lists.Add(prefabHolder.transform.GetChild(i).gameObject);}ConvertToPrefab(lists);}}}

运行自己测试即可,
最后在加点其他的吧!!

对象池的原理:
Unity对象池的基本原理是通过预先实例化一定数量的对象并将它们放入对象池中,当需要使用对象时,从池中获取一个未使用的对象,使用完毕后,再将对象归还到池中,以便重用。这样可以减少对象的创建与销毁,提高性能,特别是在创建与销毁数量较多的对象时,如子弹、敌人等。

👉三、对象池使用

👉3-1、效果展示

对象池应用

👉3-2、制作prefab

1.先创建一个Resources文件夹,然后制作预制体
预制体如下图所示:
在这里插入图片描述
2.预制体上面的组件如下图所示:
在这里插入图片描述
3.预制体上面的代码组件如下:
代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class DelPush : MonoBehaviour
{public Rigidbody rigidbody;private float speed = 50;private void Start(){rigidbody.AddRelativeForce(new Vector3 (0,0,speed), ForceMode.Impulse );}void OnEnable(){speed =50;this.transform.position = Vector3.zero;rigidbody.AddRelativeForce(new Vector3(0, 0, speed), ForceMode.Impulse);//unity自带的延迟方法 在time秒后,延迟调用方法methodNameInvoke("Push", 2);}//放回去 void Push(){ObjectTool.instance.PushObj(transform.name, this.gameObject);speed = 0;}
}

👉3-3、核心代码

代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class ObjectTool : MonoBehaviour
{public static ObjectTool instance;void Awake(){instance = this;}//这里是缓存池模块//创建字段存储容器public Dictionary<string, List<GameObject>> pool1Dic = new Dictionary<string, List<GameObject>>();private GameObject poolObj;//取得游戏物体public GameObject GetObj(string name){GameObject obj = null;//ContainsKey判断是否包含指定的“键名”//.count 获得符合条件的个数if (pool1Dic.ContainsKey(name) && pool1Dic[name].Count > 0){//取得List中的第一个obj = pool1Dic[name][0];//移除第零个(这样才能允许同时创建多个物体)//这样才是真正的“拿出来”pool1Dic[name].RemoveAt(0);}else{//缓存池中没有该物体,我们去目录中加载//外面传一个预设体的路径和名字,我内部就去加载它//Resources类允许你从指定的路径查找或访问资源(api)obj = GameObject.Instantiate(Resources.Load<GameObject>(name));//创建对象后,将对象的名字与池中名字相符obj.name = name;}//让物体显示出来obj.SetActive(true);obj.transform.parent = null;return obj;}//外界返还游戏物体public void PushObj(string name, GameObject obj){if (poolObj == null){poolObj = new GameObject("Pool");}//将这个物体设置父亲为空物体obj.transform.parent = poolObj.transform;//让物体失活也就是让物体隐藏起来不在屏幕上显示了,也就是在缓存池中了obj.SetActive(false);//里面有记录这个键(有这个抽屉)就加进去if (pool1Dic.ContainsKey(name)){pool1Dic[name].Add(obj);}//未曾记录这个键(没有这个抽屉)就创建一个新的键值对象else{pool1Dic.Add(name, new List<GameObject>() { obj });}}
}

👉3-4、对象池使用

新建脚本:CeShiDXC.cs
代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class CeShiDXC : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){if (Input.GetMouseButtonDown(0)){//向缓存池中拿东西ObjectTool.instance.GetObj("Cube");}if (Input.GetMouseButtonDown(1)){ObjectTool.instance.GetObj("Sphere");}}
}

最后运行测试即可,如果需要其他功能,请自行扩展

👉壁纸分享

请添加图片描述
请添加图片描述


👉总结

本次总结的就是运行生成预制体的代码和对象池代码的使用 有需要会继续增加功能
如能帮助到你,就帮忙点个赞吧,三连更好哦,谢谢
你的点赞就是对博主的支持,有问题记得留言评论哦!
不定时更新Unity开发技巧,觉得有用记得一键三连哦。么么哒!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词