当前位置: 首页 > article >正文

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秒后,延迟调用方法methodName
        Invoke("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 update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            //向缓存池中拿东西
            ObjectTool.instance.GetObj("Cube");
        }
        if (Input.GetMouseButtonDown(1))
        {
            ObjectTool.instance.GetObj("Sphere");
        }
      
    }
}

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

👉壁纸分享

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


👉总结

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


http://www.kler.cn/a/428153.html

相关文章:

  • C++:多继承习题5
  • 【Linux】线程互斥与同步
  • 解码,蓝桥杯2020G
  • .NET MAUI 入门学习指南
  • [STM32 - 野火] - - - 固件库学习笔记 - - -十三.高级定时器
  • HarmonyOS DevEco Studio模拟器点击运行没有反应的解决方法
  • 福昕PDF低代码平台
  • Oracle EBS FA 如何打开关闭的资产会计期间?
  • CTF-WEB: 目录穿越与伪协议 [第一届国城杯 signal] 赛后学习笔记
  • 现代C++ 7 初始化
  • 高效开发 Python Web 应用:FastAPI 数据验证与响应体设计
  • 在vue3里使用scss实现简单的换肤功能
  • 3D 生成重建018-LangSplat用文本在3DGS内搜寻你的真爱
  • CCF-GESP 等级考试 2024年12月认证C++三级真题解析
  • MATLAB 直线插点重采样(98)
  • C 语言进阶:突破基础,探索更强大的编程世界
  • 常见面试题之JAVA集合
  • 光伏组件的度电成本如何降低?
  • 解决 Maven 部署中的 Artifact 覆盖问题:实战经验分享20241204
  • Docker--Docker Container(容器)
  • Android显示系统(03)- OpenGL ES - GLSurfaceView的使用
  • Android 调用手机相册,相机功能实现
  • 零基础学安全--Burp Suite验证码识别以及爆破
  • 记一次由docker容器使得服务器cpu占满密码和密钥无法访问bug
  • 基于 NXP S32K312+FS23 的汽车通用评估板方案
  • ADBC 查询语法介绍:EXECUTE_QUERY