Unity3D运行设置物体为预制体

系列文章目录

unity知识点



👉前言

有时候需要做摆放场景物体的时候会重复使用一些物体,这时候把物体做成预制体是最好用的,有时候需要用到很多的预制体,需要手动全部拖到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");
        }
      
    }
}

最后运行测试即可,如果需要其他功能,请自行扩展
补充:
底层原理分析

  1. 序列化机制
    Unity使用YAML或二进制格式序列化预制体文件。
    序列化内容包括:
    物体的Transform、组件及其属性。
    子物体递归序列化。
    对其他资源的引用(通过GUID和Local Identifier管理)。

  2. 依赖关系处理
    若物体引用了材质、贴图等资源,Unity会:
    检查资源是否已存在于项目中。
    若为运行时生成的新资源(如动态材质),需先保存为独立资源再引用。

  3. 实例与预制体的链接
    预制体实例通过PrefabInstance组件记录源预制体的GUID和文件ID。
    修改实例属性时,Unity会标记为覆盖(Override),与源预制体差异通过蓝线显示。

限制与替代方案

  1. 运行时生成预制体的限制
    仅限编辑器模式:无法在构建后的应用中使用。
    性能开销:频繁保存预制体会触发资源数据库刷新,导致卡顿。
    资源引用风险:动态生成资源需手动管理依赖。

  2. 替代方案
    ScriptableObject
    存储配置数据,运行时动态生成物体。
    AssetBundle
    打包预设资源,支持运行时动态加载。
    JSON/二进制序列化
    保存物体状态,重启时重新构造。

应用场景

  1. 快速原型开发:在Play Mode中调试后直接保存为预制体。

  2. 动态内容生成工具:编辑器扩展工具中批量生成预制体。

  3. 关卡编辑器:允许用户在运行时设计关卡并保存为预制体模板。

👉壁纸分享

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


👉总结

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

Unity烟花预设体资源是在Unity引擎中使用的预设体资源,用于创建和呈现烟花效果。在Unity中,预设体是一种带有已经设置好的组件、材质、粒子效果、动画等属性的游戏对象。烟花预设体资源就是事先制作好的烟花效果,并将其保存为预设体,供用户在游戏中直接使用。 使用Unity的烟花预设体资源,可以轻松地在游戏中添加各种炫丽的烟花效果。预设体资源中通常包含了烟花爆炸的特效、烟花形状、颜色、音效等相关属性。用户只需将预设体资源拖放到场景中的相应位置,或者通过脚本实例化预设体,就能够在游戏中看到炫丽的烟花效果。 烟花预设体资源的优点在于其易用性和灵活性。用户不需要从头开始制作和调整烟花的特效和动画,而是直接使用现成的资源,大大节省了开发时间和精力。同时,通过调整预设体资源的属性,用户可以根据需要自定义烟花的形状、大小、颜色等,使其更符合游戏的主题和风格。 除了供开发者使用,Unity烟花预设体资源也可以用于教学和学习。学生和初学者可以通过研究和修改现有的烟花预设体资源,来探索烟花特效的实现原理,提高他们的建模、动画和粒子特效制作能力。 综上所述,Unity烟花预设体资源是一种方便易用的资源,能够帮助开发者在游戏中添加华丽炫目的烟花效果,并且有助于学者和初学者深入学习和理解烟花特效的实现原理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心疼你的一切

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
OSZAR »