2015-11-19 21:30:03 u014716849 阅读数 5258
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4645 人正在学习 去看看 张刚

虽然unity3d有自带的navigation避开障碍物,但有一次做项目时发现:当场景大而且人物变多时这个navigation计算不是很灵敏,于是心想能否自己想出另外一个检测障碍物并避开的方法。话不多说,上代码:

using UnityEngine;
using System.Collections;

public class ObstacleDetection : MonoBehaviour {

public float MoveSpeed = 2; //避开时的移动速度
public float ColliderDistance = 2; //检测距离

public string[] ObstacleTags; //障碍物的标签,就是要避开的障碍物
public  bool IsObstacle{get{return _IsObstacle;}} //是否有障碍物,用来给外部的接口

private Vector3 pos; //记录避开障碍物前的的旋转坐标

private bool IsForward = false; //前方是否有障碍物
private bool IsInLeft  = false; //左方是否有障碍物
private bool IsInRight = false; //右方是否有障碍物
private bool _IsObstacle = false; //是否有障碍物

private float timer = 0; //避开障碍物后返回原先状态的缓冲计时

private Transform m_transform;
// Use this for initialization
void Start () {
m_transform = this.transform;

}
// Update is called once per frame
void Update () {
MoveForward ();
Detection();

}
//当侧面有障碍物而前方没有时向前移动
void MoveForward()
{
if(_IsObstacle)
{
if(!IsForward)
{
pos = m_transform.localEulerAngles;
m_transform.Translate(Vector3.forward*Time.deltaTime*MoveSpeed);
}
}
}
//障碍物检测
#region Detection
void Detection()
{
IsForward = DirectionForward ();
IsInLeft = DirectionLeft ();
IsInRight = DirectionRight ();

if (IsForward) {
if (IsInLeft && !IsInRight) 
{
float rotateAnglesY = RotateAngles (pos.y + 90);
m_transform.localEulerAngles = new Vector3 (m_transform.localEulerAngles.x,
                                           rotateAnglesY,
                                           m_transform.localEulerAngles.z);
else if (!IsInLeft && IsInRight) 
{
float rotateAnglesY = RotateAngles (pos.y - 90);
m_transform.localEulerAngles = new Vector3 (m_transform.localEulerAngles.x,
                                           rotateAnglesY,
                                           m_transform.localEulerAngles.z);
else if (IsInLeft && IsInRight) 
{
float rotateAnglesY = RotateAngles (pos.y + 180);
m_transform.localEulerAngles = new Vector3 (m_transform.localEulerAngles.x,
                                           rotateAnglesY,
                                           m_transform.localEulerAngles.z);
}
else 
{
float rotateAnglesY = RotateAngles (pos.y + Random_1_1 () * 90);
m_transform.localEulerAngles = new Vector3 (m_transform.localEulerAngles.x,
                                           rotateAnglesY,
                                           m_transform.localEulerAngles.z);
}
else 
{
if(!IsInLeft && !IsInRight)
{
if(IsObstacle)
{
//避开障碍物到返回原先状态的缓冲时间
timer += Time.deltaTime;
if(timer > 0.8f)
{
timer = 0;
_IsObstacle = false;
}
}
}
}
}
//检测前方
bool DirectionForward()
{
bool check = false;
RaycastHit hitForward;
Vector3 LocalForward = m_transform.TransformPoint(Vector3.forward)-m_transform.position;
if (Physics.Raycast (m_transform.position, 
                     LocalForward, 
                     out hitForward, ColliderDistance/2))
{
if(CompareTags(hitForward.transform.gameObject.tag))
{
_IsObstacle =true;
check = true;
}
}
return check;
}
//检测右方
bool DirectionRight()
{
bool check = false;
RaycastHit hitRight;
Vector3 LocalRight = m_transform.TransformPoint(Vector3.right)-m_transform.position;
if (Physics.Raycast (m_transform.position, 
                     LocalRight, 
                     out hitRight, ColliderDistance)) 
{
if(CompareTags(hitRight.transform.gameObject.tag))
{
_IsObstacle =true;
check = true;
}
}
return check;
}
//检测左方
bool DirectionLeft()
{
bool check = false;
RaycastHit hitLeft;
Vector3 LocalLeft = m_transform.TransformPoint(-Vector3.right)-m_transform.position;
if (Physics.Raycast (m_transform.position, 
                     LocalLeft, 
                     out hitLeft, ColliderDistance)) 
{
if(CompareTags(hitLeft.transform.gameObject.tag))
{
_IsObstacle =true;
check = true;
}
}
return check;
}
#endregion
//自己写的一些小功能
#region MyFunction
//遍历ObstacleTags数组,是否与其中的一个值相符
bool CompareTags(string name)
{
bool isSame = false;
for(int i = 0; i <  ObstacleTags.Length;i++)
{
if(ObstacleTags[i].Equals(name))
{
isSame = true;
break;
}
}
return isSame;
}
//将角度规范,变为0~360之间
float RotateAngles(float Angles)
{
float angles = 0;
if (Angles >= 0) {
angles = Angles - ((int)(Angles / 360)) * 360;
else 
{
angles = (((int)(Angles / 360))+1) * 360 - Angles;
}
return angles;
}
//产生-1~1的随机数,不包括0
float Random_1_1()
{
float index = Random.Range (-1,1);
if(index == 0)
{
index = Random_1_1();
}
return index;
}
#endregion
void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawLine (transform.position, transform.TransformPoint(Vector3.forward*ColliderDistance/2));
Gizmos.DrawLine (transform.position, transform.TransformPoint(Vector3.right*ColliderDistance));
Gizmos.DrawLine (transform.position, transform.TransformPoint(Vector3.left*ColliderDistance));
}

}


2017-02-23 15:04:10 xiaomage1987 阅读数 1791
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4645 人正在学习 去看看 张刚

常用的Unity3D网址:

Unity3D官网: 没什么好解释的.
http://unity3d.com/

Unity3D离线安装包地址: 官方的,但是很多人不知道.新版本还支持bt下载
https://unity3d.com/cn/get-unity/download/archive

Unity3D补丁: 官方的.
https://unity3d.com/cn/unity/qa/patch-releases

Unity3D破解版: 个人版已经免费了,希望大家不要破解,给Unity3D流一个开始画面而已,赚钱了的更不应该破解,以备不时之需吧.
http://www.ceeger.com/forum/read.php?tid=23396&page=1

Unity3D学习资源:  很多,慢慢补充吧.
http://www.manew.com/forum.php
http://www.woxueyuan.com/

2015-02-08 17:24:04 u014678046 阅读数 1633
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4645 人正在学习 去看看 张刚

对于Unity3d的资源管理已经研究了很久,大概是从大学毕业到现在,依然在不断的探索着,这期间不断的在网上查看各位大神们的讲解,然后自己就研究,也做部分实验,发现其实要很好地管理起来是很容易的,资源更新,加载,卸载对于一款游戏来说是十分重要的,首先我从资源更新说起。

一、资源更新现在有很多的办法,Unity3d提供了很多种资源管理方式。1、你可以将资源存放在工程目录的Resource文件夹下面,这个文件夹下面的资源会随着你导出平台安装包的时候加密到你的安装包里面,unity程序在运行的时候会根据自己的资源加载思路将场景里面用到的资源进行加载,但是这部分资源是不能够及时更新的,也就是说,资源跟新不能考虑这个文件夹;2、unity工程下面还有一个特殊的文件夹,就是StreamingAssets文件夹,这个文件夹会在你导出的时候原封不动的考到安装包里面,在释放到平台上面,注意一点,他是原封不动的,这就需要你采用自己的加密方式,要不会很容易被破解的,这部分资源在各个平台上是可以访问到,安卓手机上面用WWW类进行读取,PC,以及iPhone可以用File类进行读取,很方便。上述两个文件夹是unity提供给我们的,很方便,哈哈。
我自己在研究了那么久之后,决定将大部分用到的,可能需要经常更新的资源存放到了StreamingAssets目录下面,有用到的ngui的图集,以及预设等等,由于iPhone不支持代码更新,我们就在脚本中运用了lua代码,我们采用的是ulua,这都是跟着群里面的大神学习的,首先游戏安装到设备上头一回运行的时候,会将StreamingAssets下面的资源进行复制,释放到平台上面我们自己指定的目录,需要获得读写权限,这个路径Application.streamingAssetsPath就是平台上面的StreamingAssets所在的位置,然后在安卓手机上面访问内置sd卡或sd卡1的路径为/mnt/sdcard,在4.1以后也可用路径/storage/sdcard0这个路径,最后在这个历经下面建立文件夹,存放自己的资源。在iPhone以及PC上面完全可以使用Application.persistentDataPath这个目录进行资源的存放。资源存放好了就可以准备更新了,www可以访问你自己的资源服务器,游戏资源存放得当之后便可以调用new WWW(地址);来进行下载,我们的做法是资源释放到了本地,然后会从服务器上面下载最新的资源配置文件,lua太伟大了,既可以写程序也可以作为配置文件,哈哈,我就将资源的名称以及他们的md5值存放在lua的table里面,然后就是表的遍历了,方法很多,ulua在这方面已经完全可以胜任,支持安卓PC以及iPhone,wp推荐用nlua,nlua我不会,哈哈,怎样打assetbundle类型的资源包网上教程很多,也很详细,如果资源包过大,也可以考虑一下采用压缩,有7z,网上有宣雨松的例子,很好。遍历配置表格,进行md5比对,不同的就进行下载,最终进入游戏。建议是资源尽量分的细一些,这样既方便局部资源的整体替换,同时也有利于团队分工开发,后期的更新维护也会很简单,你可以参考一下别人的安装包,解压看看里面的资源是怎么布置的,看看就好呀,哈哈。共同学习。
二、下面就是资源的加载了,建议大家对Resource类进行适当的利用然后写出一个自己能够方便使用的资源加载类,首先可以从Resource目录下面方便的加载,然后还要很方便的从assetbundle里面进行加载,assetbundle里面的资源你想要用的时候要提前加载,建议做在loading界面里面,这样用户体验会好一些,因为此时用户的耐心是最大的,你一卡一卡的,老板都会揍你,哈哈,这个加载类可以加载assetbundle里面的东西,并将加载的assetbundle交给全局的加载对象管理器,以便进行及时的释放,关于assetbundle的完全释放,网上讲的很多,也很好,我这里面总结一下整体的过程,仅供参考:
1.首先记录下已经加载的assetbundle,以便你好释放;
2.将预设或者图集,图片从里面加载出来,记录;
3.将在第2步里面加载的东西放到场景的某个对象上面,或者直接实例化预设,将这个放到场景里面的这个对象记录下来,因为它上面有对asser的引用;
4.在一个assetbundlle里面所有的用到的资源都加在出来之后,执行语句Resources.UnloadUnusedAssets();会将不用了的asset占用的内存释放出来;
5.场景中通过某一个assetbundle创建的对象或者依附的对象没什么用处的时候,将对象进行Destroy(对象);这个方法,这样对象会从场景里面消失,同时它所引用的资源就没有存在的意义了;
6.将销毁的对象所用的assetbundle执行assetbundle.Unload(false);,这样就会将已经记录的资源包所占用的内存镜像会完全卸载;
7.Resources.UnloadUnusedAssets();卸载没有用到的资源;
8.将记录的加载过的预设,等资源设置为null;
9.Resources.UnloadUnusedAssets();释放资源,
10.调用系统的垃圾回收站清理函数GC.Collect();
通过上面十个步骤,就可以将引用的assetbundle进行彻底的释放,由于在代码里面我与用到了lua脚本,就可能会存在lua的引用,这时需要在第8个步骤里面调用一下lua自身的垃圾回收函数collectgarbage();然后再进行第9步,实验证明是可以的。
我在实际的过程中就是采用的如此的资源更新,加载,以及释放的过程,很方便,没有提到的就是工程里面要有一个对象管理器,就是对象池,需要你对对象进行比较明确的管理,时刻明白场景里面哪些是有用的,哪些是可以释放卸载掉的,这样,unity3d的游戏在平台上才不会内存一直飙高,可能引起的游戏闪退等现象,卡顿也会避免。
最后,大家加油呀!快过年了,程序员还没放假,哈哈
下面是我自己的部分代码,很简单的,只供参考,嘿嘿

--关闭面板(Lua脚本),将场景里面的已将创建的面板进行销毁--GameObjectMgr是我自己写的一个很简单的管理器
function CloseWindow(args)
    if(args==nil)then
        print('ERROR    变量未正确赋值');
        return;
    end

    local   _iswindestory       =args['_iswindestory']
    local   _winname            =args['_winname']
    local   _isassetdestory =args['_isassetdestory']
    local   _assetname          =args['_assetname']
    local   _ispbdestory        =args['_ispbdestory']
    local   _prefabname         =args['_prefabname']

    if(GameObjectMgr.IsObjCreated(_winname)==false)then
        print("指定窗口不存在,不需要关闭 :",_winname);
        return;
    end

    args =nil;

    if(_ispbdestory)then
        GameObjectMgr.AdddestoryPerfabList (_prefabname);
    end
    if(_iswindestory)then
        print('销毁窗口');
        GameObjectMgr.AdddestoryObjNameList (_winname);
    else
        print('窗口隐藏');
        GameObjectMgr.SetObjActivePority(_winname,false);
    end
    if(_isassetdestory)then
        GameObjectMgr.AdddestoryABList (_assetname);
    end
    collectgarbage();
    --下面将会进行对象销毁,内存释放内存释放
    GameObjectMgr.FreeMemory ();

end

改日把我的GameObjectMgr也加进来,供大家参考,周末愉快,下周末我也就放假啦,哈哈哈,开心的等待着

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

public class GameObjectMgr{

    public static       Dictionary<string,GameObject>           loadedPerfabList        =null;      //存放已经加载的预设资源
    public static       Dictionary<string,AssetBundle>          loadedAssetList         =null;      //存放AB包
    public static       Dictionary<string,GameObject>           createdObjList          =null;      //存放创建的对象

    public static       string[]                                destoryPerfabList       =null;      //销毁的预设
    public static       string[]                                destoryAssetList            =null;      //销毁的AB包,unload(false);
    public static       string[]                                destoryObjNameList      =null;      //销毁的对象;
    //设置是否显示
    public static void SetObjActivePority(string _name,bool _active){
        if (createdObjList == null) {
        } else {
            foreach(string key in createdObjList.Keys){
                if(key==_name){
                    if(createdObjList[key]!=null){
                        createdObjList[key].SetActive(_active);
                    }else{
                        createdObjList.Remove(_name);
                    }
                }               
            }   
        }

    }
    //获得一个已经创建的对象
    public static GameObject GetGameObjectByName(string _name){    
        if (createdObjList == null) {
            return null;
        } else {
            foreach(string key in createdObjList.Keys){
                if(key==_name){
                    if(createdObjList[key]!=null){
                        return createdObjList[key];
                    }else{
                        createdObjList.Remove(_name);
                        return null;
                    }
                }               
            }   
        }
        return null;
    }
    //获得一个已经加载的预设
    public static GameObject GetPrefabByName(string _name){    
        if (loadedPerfabList == null) {
            return null;
        } else {
            foreach(string key in loadedPerfabList.Keys){
                if(key==_name){
                    if(loadedPerfabList[key]!=null){
                        return loadedPerfabList[key];
                    }else{
                        loadedPerfabList.Remove(_name);
                        return null;
                    }
                }               
            }   
        }
        return null;
    }

    //查看预设是否加载
    public static bool IsPerfabLoaded(string _name){
        if (loadedPerfabList == null) {
            return false;
        } else {
            foreach(string key in loadedPerfabList.Keys){
                if(key==_name){
                    if(loadedPerfabList[key]!=null)
                        return true;
                    else{
                        loadedPerfabList.Remove(_name);
                        return false;
                    }
                }               
            }   
        }
        return false;
    }
    //对象是否已经被创建
    public static bool IsObjCreated(string _name){
        if (createdObjList == null) {
            return false;
        } else {
            foreach(string key in createdObjList.Keys){
                if(key==_name){
                    if(createdObjList[key]!=null){
                        return true;
                    }else{
                        createdObjList.Remove(_name);
                        return false;
                    }
                }               
            }   
        }
        return false;
    }

    //添加已经创建
    public static void AddCreatedObjList(string _name, GameObject _obj){
        if (createdObjList == null) {
            createdObjList = new Dictionary<string, GameObject>();  
        }
        if(createdObjList.ContainsKey(_name)){
            return ;
        }
        createdObjList.Add (_name,_obj);
    }
    //添加已经加载的assetbundle
    public static void AddloadedAssetList(string _name, AssetBundle _obj){
        if (loadedAssetList == null) {
            loadedAssetList = new Dictionary<string, AssetBundle>();    
        }
        if(loadedAssetList.ContainsKey(_name)){
            return ;
        }
        loadedAssetList.Add (_name,_obj);
    }

    //添加已经加载的预设
    public static void AddloadedPerfabList(string _name, GameObject _obj){
        if (loadedPerfabList == null) {
            loadedPerfabList = new Dictionary<string, GameObject>();    
        }
        if(loadedPerfabList.ContainsKey(_name)){
            return ;
        }
        loadedPerfabList.Add (_name,_obj);
    }

    //添加预设名字
    public static void AdddestoryPerfabList(string _name){
        if (destoryPerfabList == null) {
            destoryPerfabList = new string[1];
            destoryPerfabList[0] = _name;
            return;
        } else {
            int j = destoryPerfabList.Length;
            destoryPerfabList[j] = _name;
            return;
        }
    }

    //添加对象名字
    public static void AdddestoryObjNameList(string _name){
        if (destoryObjNameList == null) {
            destoryObjNameList = new string[1];
            destoryObjNameList[0] = _name;
            return;
        } else {
            int i=destoryObjNameList.Length;
            destoryObjNameList[i] = _name;
            return;
        }
    }
    //添加assetbundle名字
    public static void AdddestoryABList(string _name){
        if (destoryAssetList == null) {
            destoryAssetList = new string[1];
            destoryAssetList[0] =_name;
            return;
        } else {
            int j = destoryAssetList.Length;
            destoryAssetList[j] = _name;
            return;
        }
    }
    //清理内存
    public static void FreeMemory(){
        if (destoryObjNameList == null&&destoryPerfabList.Length== null&&destoryAssetList== null) {
            Debug.Log("不需要释放资源");   
            return;
        }
        int i = 0;
        if (destoryObjNameList != null) {
            i = destoryObjNameList.Length;
            for(int j = i-1;j>=0;j--){
                if(destoryObjNameList[j]!=null)
                if(createdObjList.ContainsKey(destoryObjNameList[j])){
                    GameObject obj=createdObjList[destoryObjNameList[j]];
                    createdObjList.Remove(destoryObjNameList[j]);
                    GameObject.Destroy(obj);
                }
                destoryObjNameList[j]=null;
            }   
        }

        destoryObjNameList = null;
        if (destoryPerfabList != null) {
            i = destoryPerfabList.Length;
            for(int j = i-1;j>=0;j--){
                if(destoryPerfabList[j]!=null)
                if(loadedPerfabList.ContainsKey(destoryPerfabList[j])){
                    loadedPerfabList[destoryPerfabList[j]]=null;
                    loadedPerfabList.Remove(destoryPerfabList[j]);
                }
                destoryPerfabList[j]=null;
            }   
        }

        destoryPerfabList = null;

        if (destoryAssetList == null || destoryAssetList.Length == 0) {
        } else {
            i = destoryAssetList.Length;
            for(int j =i-1;j>=0;j--){
                if(destoryAssetList[j]!=null)
                    if(loadedAssetList.ContainsKey(destoryAssetList[j]))
                        AssetBundle asset = loadedAssetList[destoryAssetList[j]];
                        loadedAssetList.Remove(destoryAssetList[j]);
                        asset.Unload(false);
                    }
                destoryAssetList[j]=null;
            }
        }

        destoryAssetList = null;
        Resources.UnloadUnusedAssets ();
        System.GC.Collect ();
    }
}
2015-10-31 11:01:59 hoxily 阅读数 478
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4645 人正在学习 去看看 张刚

由于某种原因,unity3d官方教程的视频无法播放,造成不便。

通过百度搜索引擎的搜索,找到一些相关的资源。一般为热心楼主通过某种方式下载后重新上传的版本。整理如下,方便后来人的使用。

unity3d官方教程资源整理
类型 名称 更新时间 资源url
Project Space Shooter tutorial 2014年 http://www.youku.com/playlist_show/id_22170217.html
Project Survival Shooter tutorial 2014-12-11 http://pan.baidu.com/s/1jGmT3tO
Project Survival Shooter tutorial英文字幕 2015-10-31 http://subhd.com/a/330981

2015-04-11 18:27:33 wlj613613 阅读数 1098
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4645 人正在学习 去看看 张刚

书籍比较杂,有些不一定写的很好,
全部是英文的(中文书一般是不会有清晰电子版,你肯定知道的),
所以大家酌情下载喜欢的那几本看完就好了。都是别人的劳动成果,
学习有收获就好,希望仅供学习交流之用。


Apress.Learn.Unity.4.for.iOS.Game.Development.Jun.2013

Unity3D 4.x Cookbook

Unity Shaders and Effects Cookbook

Unity 3D Game Development by Example Beginner

Unity 2D Game Development

Pro.Unity.Game.Development.with.CSharp-2014

C# Game Programming Cookbook for Unity 3D - CRC Press (2014)

Practical Game Design with Unity and Playmaker

NGUI for Unity

Learning C# by Developing Games with Unity 3D Beginner’s Guide

Unity.Multiplayer.Games

Unity4.x Game AI Programming
Unity.Android.Game.Development.by.Example.Beginners.Guide

Creating E-Learning Games with Unity

Apress.Learn.Unity.for.2D.Game.Development.Oct.2013

Getting.Started.with.Unity.Aug.2013

Unity AI Programming Essentials

Unity Game Development Scripting

Unity 3D UI Essentials (介绍unity 新GUI内容)

EBOOK ALL

VIDEO:

Creating Mobile Games with Unity

祝学习愉快!

Unity3D - 资源管理

阅读数 6807

Unity3D的资源管理总结

博文 来自: ynnmnm
没有更多推荐了,返回首页