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开发技巧,觉得有用记得一键三连哦。么么哒!