美文网首页真实
unity 射线检测与对象池

unity 射线检测与对象池

作者: 穿AJ的火烈鸟 | 来源:发表于2017-08-06 15:48 被阅读0次

真正学懂一个知识的时候是要传授给别人这个知识的时候让对方也能轻而易举的理解。

遇到需要频繁加载和销毁的游戏对象(例如子弹,特效,贴图),使用对象池可以节约内存的开销,尤其对于移动设备尤为显著。

所以,研究了一天的对象池。 其中有半天没找到对象,徘徊在找对象的路上。最后发现是把对象的名字找错了。

首先 得有个对象池。其实本质就是一个列表(ArrayList)(还有很多,堆栈 队列呀  你玩的花咋样都行,能存东西就行)  在程序运行开始把prefebs加载进去,但是active为false,用的时候拿出来激活就好, 。要销毁prefebs的时候 就把prefebs的active设置成false 再把它弄回列表里。

using System.Collections;using System.Collections.Generic;using UnityEngine;

public class Pool : MonoBehaviour {        private static Dictionarydic = new Dictionary();

//  字典 key等于要存的预制体的名字  value是一个Arraylist列表

// Use this for initialization

void Start () {

}

// Update is called once per frame

void Update () {

}

public static GameObject Get(string key, Vector3 position, Quaternion rotation)

{

print(key);    //用于测试的标志位

GameObject go;    //临时变量

string GameObiectName = key + "(Clone)";  //key获取的是prefebs的名字 但实例化的时候会加上(Clone);

print(GameObiectName);//测试标志

if (dic.ContainsKey(GameObiectName)&& dic[GameObiectName].Count>0)  //如果能取到pefebs的Key 并且 value的list数据大于0

{

print("第一位");

ArrayList list = dic[GameObiectName];        // 获取列表

go = list[0] as GameObject;

list.RemoveAt(0);                          //将预制体移出列表

go.SetActive(true);                  //设置预制体为激活状态

go.transform.position = position;

go.transform.rotation = rotation;

}

else

{

print("第二位");

go = Instantiate(Resources.Load("Sphere"), position, rotation) as GameObject;  //池中没有东西时候会执行这一句来创建预制体

}

return go;

}

public static void Return(GameObject g) {

string key = g.name;

print(key);

if (dic.ContainsKey(key))            //如果有这个Key  就把这个物体放进这个Value(List)里

{

print("已经有列表,添加进去");

dic[key].Add(g);

}

else {

print("创建一个列表");

dic[key] = new ArrayList() { g };          //创建这个键值。(第一次调用)

}

g.SetActive(false);

}

}

有了对象池就可以在别处使用了。就是执行对象池的get方法就可以拿出来一个对象 return方法就可以把对象放回去。代替了load和destroy

public class Main : MonoBehaviour {

RaycastHit Hit;                //射线碰撞监测到的点

public GameObject sphere;    //预制体是一个sphere

// Use this for initialization

void Start () {

}

// Update is called once per frame

void Update () {

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);    //将鼠标点击的屏幕坐标空间转换为射线

Debug.DrawLine(ray.origin, Hit.point, Color.red);              //绘制射线

if (Input.GetMouseButtonDown(0))

{

if (Physics.Raycast(ray, out Hit, 1000f))

{

Pool.Get(sphere.name, Hit.point, Hit.transform.rotation);        //调用对象池中的Get方法获取返回。返回是将prefebs的active设置成true

//传入位置参数和旋转角度。

//  print(Hit.transform.name);

}

}

}

}

return方法写在预制体上面,根据具体需求到点了就执行就可以了

private float time;

// Use this for initialization

void Start()

{

}

// Update is called once per frame

void Update()

{

time += Time.deltaTime;                //计时器

if (time > 3)

{

Pool.Return(this.gameObject);  //调用对象池中的Return方法 将预制体设置为false;

time= 0;

}

// StartCoroutine(dest());

}

//IEnumerator dest() {

//    yield return new WaitForSeconds(3f);

//    Pool.Return(this.transform.gameObject);

//}

}

相关文章

  • unity 射线检测与对象池

    真正学懂一个知识的时候是要传授给别人这个知识的时候让对方也能轻而易举的理解。 遇到需要频繁加载和销毁的游戏对象(例...

  • 射线检测-unity

    与最近物体碰撞取得位置: 与指定层的物体碰撞: 另外collider相当于游戏物体了

  • Unity射线检测

    Physics.RayCast方法发射射线,射线碰撞的信息存在RaycastHit中。 Camera.main.S...

  • Unity Physics.Raycast

    参考Unity - 射线检测[https://www.cnblogs.com/SouthBegonia/p/117...

  • API

    Plane.Raycast Plane 的介绍参考例子 Unity 之 plane.Raycast 射线检测 拷贝...

  • Unity 基础 - 射线

    Unity 中虚拟射线能够检测所碰撞到物体,使用 Physics 类的 Raycast 方法实现色心啊碰撞检测功能。

  • Unity 学习笔记

    Unity 对象池实现方案:

  • unity3dUGUI空对象实现射线检测

  • 内存优化记录1

    1:概念熟知与工具使用 profiler的使用,数据类型的区别,对象池的艺术.unity管理内存,A)unity引...

  • Unity 3D的角色移动

    在Unity控制角色移动时,要注意两大点: 鼠标点击地面,检测射线以及人物面朝移动方向。 控制人物的移动与速度首先...

网友评论

    本文标题:unity 射线检测与对象池

    本文链接:https://www.haomeiwen.com/subject/gczglxtx.html