2016-05-04 16:55:33 wangxiong_zh 阅读数 1726
Unity3d Webplayer 屏蔽缓存机制

  前言:   

  在最近的项目中,出现了一个问题就是:使用unity3d webplayer的时候,当用户首次进入游戏的时候,

  如果下载AssetBundle文件失败的话,就会出现后续无法登陆的情况。这个时候客户端需要的操作就

  是删除本地的缓存文件,或者是登陆Unity3d提供的缓存服务器进行删除。这些操作对开发者来说是很

  简单的事情,但是对没有多少计算机操作知识的用户来说就显得很心烦了。

  原因如下:

  1.对于webplayer本地的缓存文件是被隐藏 了,需要进过一系列的操作去找到。这样用户基本是不愿意

  做的事,这样我们的用户就少了很多了。

  2.对于登陆缓存服务器去进行删除的操作,也是同样的道理。同时还是E文的,用户可能看都不看了。

  现在都是流行一条龙的服务,你的服务不好,那就只好下一位了。

  虽然我们现在还没有找到很好的实现方式,但是我们只要屏蔽有关数据的缓存了。缓存这个东西好处是多

  但是坏处也是不少的!

  好了。我们现在谈谈今天的主题:屏蔽缓存机制。

  方式很是简单的:

  在我们发布的html代码中加入一个<meta >标签就可以了。

  我们先看看效果:

    添加标签前的效果:

  979x486

  我们添加标签:

  853x409

  添加标签:

  855x427

  最后的效果:

  997x475

  这样webplayer缓存机制就失去效果了。很简单的操作 呵呵

  结束语:

  对于这样的方式是不好的,正在寻找有关的实现方式。看了看完美世界的页游,在处理这一块的时候做的挺不错的。希望各位大神提供和交流相应的解决方案,在此先谢谢啦!

2017-01-09 18:14:58 net_guy 阅读数 2611

Unity3D虽然是强大的游戏工具,但没有优化,也会做得不好,下有个简单的实验可以说明为什么需要优化。
这里的方法之一只是简单地将对象缓存起来,但缓存与否性能还真是天壤之别。

场景里面只下面的基本物件

Main Camera
Directional light

我们要做的事情是设置Directional light属性1000次,下面分别做了3次实验:No Cache,Partial Cache,Full Cache,我们把脚本分别挂在Main Camera上面。

No Cache

using UnityEngine;
public class NoCaching : MonoBehaviour
{
    void Start()
    {
    }

    void Update()
    {
        for(int i = 0;i<1000;i++)
        {
            GameObject.Find("Directional light").GetComponent<Light>().intensity = 1;
        }
    }
}

Partial Cache

using UnityEngine;

public class PartialCaching : MonoBehaviour
{

    private GameObject directionalLight;

    void Start()
    {
        directionalLight = GameObject.Find("Directional light");
    }

    void Update()
    {
        for (int i = 0; i < 1000; i++)
        {
            directionalLight.GetComponent<Light>().intensity = 1;
        }
    }
}

Full Cache

using UnityEngine;
public class FullCaching : MonoBehaviour {

    private Light directionalLight;

    void Start()
    {
        directionalLight = GameObject.Find("Directional light").GetComponent<Light>();
    }

    void Update()
    {
        for (int i = 0; i < 1000; i++)
        {
            directionalLight.intensity = 1;
        }
    }
}

总结

缓存方式 CPU
No Cache 30.5%
Partial Cache 1.3%
Full Cache 1.0%
2013-10-28 11:11:58 braveyoung123 阅读数 1474

前言:   

在最近的项目中,出现了一个问题就是:使用unity3d webplayer的时候,当用户首次进入游戏的时候,

如果下载AssetBundle文件失败的话,就会出现后续无法登陆的情况。这个时候客户端需要的操作就

是删除本地的缓存文件,或者是登陆Unity3d提供的缓存服务器进行删除。这些操作对开发者来说是很

简单的事情,但是对没有多少计算机操作知识的用户来说就显得很心烦了。

原因如下

1.对于webplayer本地的缓存文件是被隐藏 了,需要进过一系列的操作去找到。这样用户基本是不愿意

做的事,这样我们的用户就少了很多了。

2.对于登陆缓存服务器去进行删除的操作,也是同样的道理。同时还是E文的,用户可能看都不看了。

现在都是流行一条龙的服务,你的服务不好,那就只好下一位了。

虽然我们现在还没有找到很好的实现方式,但是我们只要屏蔽有关数据的缓存了。缓存这个东西好处是多

但是坏处也是不少的!

好了。我们现在谈谈今天的主题:屏蔽缓存机制。

方式很是简单的:

在我们发布的html代码中加入一个<meta >标签就可以了。

我们先看看效果:

  添加标签前的效果:


我们添加标签:


添加标签:



最后的效果:



这样webplayer缓存机制就失去效果了。很简单的操作 呵呵

结束语:

对于这样的方式是不好的,正在寻找有关的实现方式。看了看完美世界的页游,在处理这一块的时候做的挺不错的。希望各位大神提供和交流相应的解决方案,在此先谢谢啦!

enjoy



2014-11-16 16:13:32 CWHISME 阅读数 310

这次虽然由于时间以及复杂度的问题,自己做游戏的笔记写了一部分就没写了。不过如果什么都不留下的话,想想也觉得不对,所以决定还是偶尔记一记比较必要点的问题吧(话说这好像是第一次写博客.....)。

在Unity3D中,据说是用Instantiate实例化一个物体的话,将会异常消耗性能,如果在游戏过程中,经常使用到这个方式创建对象,那么将对性能造成很大的影响。

我查看了下自己的代码,对于实现方式,有几个地方貌似都是这样用的。。。比如实例化NPC、实例化在游戏世界中的物品实体,还比如NPC头顶的血条、名字等等。为此,必须得改造下了,毕竟或许一个两个地方倒没什么,如果数量达到一定程度,那对性能的影响就比较大了。

这儿我先新建一个名为“ObjTempManager”的脚本,用于存放所有的缓存对象的实例。这儿先慢慢来,最开始我就只定义一个用于存放物品实体的List,代码如下:

//**********************************************************

//Copyright (c) 2014 wangjiaying. All Rights Reserved.

//类名:ObjTempManager.cs

//UnityVersion:4.5.4f1

//作者:CWH

//日期:

//联系方式:cwhisme@gmail.com

//cwhisme@qq.com

//功能:

//**********************************************************

using UnityEngine;

using System.Collections;

using System.Collections.Generic;

/// <summary>

/// 用于存放游戏中所有的需要缓存对象

/// 避免过多的Instaniate、Destroy等等,优化游戏性能

/// </summary>

public class ObjTempManager : MonoBehaviour {

 

    private List<GameObject> m_itemEntityList = new List<GameObject>();//在游戏世界中的物品的缓存list   

}

因为我将游戏世界中所有的物品实例都统一表现为一个相同的模型,决定于它们不同的只是其上存放的一个“Item”对象而已。(如果每个物品都是使用符合该物品特征的不同的模型,其非常花费时间的,现在毕业之际,最差的就是时间了,为此我还是决定使用同样的模型),就是一个宝箱的样子:


决定其内在的,主要是其上的“ItemInstanceEntity”脚本,这这个脚本暂时无关,就先不提。
我原本使用的方式是:
当玩家或者NPC触碰到这个宝箱时,玩家或者NPC就会获得该物品,而这个用于存放物品对象的宝箱实体也就会随之“Destroy”掉。
不过,如果窒息想一想的话,玩家杀死敌人大多情况下都会掉落物品,以及场景中随时可能放置的一些“彩蛋(隐藏物品)”都是属于这个模型,如果一直Instantiate然后Destroy,这个可不是一个小的消耗!
原本我再“ItemManager”类中,对外提供实例化宝箱的时候使用的方法是这样的:

    /// <summary>

    /// 在游戏世界中实例化一个物品的实体

    /// </summary>

    /// <param name="position">位置</param>

    /// <param name="item">物品</param>

    public static void ItemInstanceAEntity(Vector3 position, ItemCore item)

    {

        GameObject obj = Instantiate(ObjManager.GetInstance.GetItemEntity, position, Quaternion.Euler(0,Random.Range(0,360),0)) as GameObject;

        obj.GetComponent<ItemInstanceEntity>().SetItem = item;

        obj.transform.Translate(Vector3.forward,Space.Self);

    } 

它通过实例化一个宝箱模型,然后再设置改模型身上的“ItemInstanceEntity”脚本。

这儿稍稍变通一下,方法名之类的可以不变,只需要将这个方法中实例化模型的操作,改为向适才创建的“ObjTempManager ”中获取相应的模型即可,如果模型不够,再由“ObjTempManager ”负责创建,缓存即可。

而作为缓存游戏对象的这个“ObjTempManager ”,应当是一个单例类,以使得该类全局可用,按照惯例,首先定义单例类的方法:

    private static ObjTempManager m_instance = null;

    public static ObjTempManager GetInstance

    {

        get

        {

            if (m_instance == null)

            {

                GameObject obj = new GameObject();

                obj.name = "_TempManager";

                DontDestroyOnLoad(obj);

                m_instance = obj.AddComponent<ObjTempManager>();

            }

            return m_instance;

        }

    }

接着,可以定义个方法,这个方法的主要作用是:返回缓存中可用的对象,如果缓存的所有对象都不可用,那么才创建一个对象返回。

代码如下:

    /// <summary>

    /// 在缓存列表中获取一个游戏世界中的物品实体(如无,将创建该物体)

    /// </summary>

    public ItemInstanceEntity GetItemEntityModel

    {

        get

        {

            for (int i = 0; i < m_itemEntityList.Count; i++)

            {

                if (m_itemEntityList[i].gameObject.activeSelf)//如果该对象是激活的,那么表示该对象是在使用中的,那么跳过

                {

                    print(m_itemEntityList[i].gameObject.activeSelf);

                    continue;

                }

                m_itemEntityList[i].SetActive(true);//激活

                return m_itemEntityList[i].GetComponent<ItemInstanceEntity>();//返回对象

            }

            //如果代码能执行到这儿的话,就说明当前所有的对象都在使用,那么就重新创建一个吧

            GameObject obj = Instantiate(ObjManager.GetInstance.GetItemEntity) as GameObject;

            obj.transform.parent = m_instance.transform;//将该对象设置为自身子物体

            m_itemEntityList.Add(obj);//添加对象至缓存

            return obj.GetComponent<ItemInstanceEntity>();//创建一个物品实体,并返回

        }

    }

这样的话,只要战斗不是太过于激烈,一般被实例化的就几个物体而已。

然后修改下上文中提到的“ItemManager”中对外提供创建宝箱的方法“ItemInstanceAEntity”:

    /// <summary>

    /// 在游戏世界中实例化一个物品的实体

    /// </summary>

    /// <param name="position">位置</param>

    /// <param name="item">物品</param>

    public static void ItemInstanceAEntity(Vector3 position, ItemCore item)

    {

        //GameObject obj = Instantiate(ObjManager.GetInstance.GetItemEntity, position, Quaternion.Euler(0,Random.Range(0,360),0)) as GameObject;

        ItemInstanceEntity it = ObjTempManager.GetInstance.GetItemEntityModel;

        //obj.GetComponent<ItemInstanceEntity>().SetItem = item;

        it.SetItem = item;

        it.transform.position = position;//设置坐标

        it.transform.Rotate(0,Random.Range(0,360),0);//随机旋转移动,造成随机的位置

        it.transform.Translate(Vector3.forward,Space.Self);

    } 

注释掉原本的那些直接Instantiate创建宝箱的代码,改为直接向“ObjTempManager”类中获取,然后操作。

最后,还有一个需要注意的地方就是宝箱本身的那个类“ItemInstanceEntity”,里边原本的代码就是直接摧毁自身,现在也应该改一改,变成将自身Active属性设置为false即可:

主要代码如下:

    void OnTriggerEnter(Collider other)

    {

        if (item == null)

        {

            gameObject.SetActive(false);

            return;

        }  

       if (ItemManager.AddItem(other.GetComponent<AICreature>(), item))//如果玩家成功获得物品,就禁用该物品

            {

                gameObject.SetActive(false);

            }

    }

就这样,关于宝箱的缓存就做好了。

运行游戏,效果如下:


基本上这个被实例化的物品很少了,除非特殊情况,总共也就实例化一两个,却可以在有需要的情况下重复利用。

其它的一些对象优化方式也差不多,这儿就不多赘述了。










2013-01-21 14:53:57 jeksonal 阅读数 16702

unity3D 用3DMax 做的模型时需要注意几点

1:方向问题
2:模型尺寸问题

3:模型所占资源大小问题

 

3DMax 做的东西导入到 Unity3D 中,在 Unity3D 引擎中 X 会被反向旋转 90 度();个人处理方式是建模时先将模型 X 轴旋转 90;再调节模型;

3DMax 做的东西导入到 Unity3D 中,由于 3DMax 默认的单位处理机制与 Unity3D 不一样,而导致显示过小的问题;所以,在制作模型前先调节好 3DMax 中的系统单位设置

具体操作:

 菜单栏: 选择 “自定义”  ,

再选择 “单位设置”-- >

 接着点选 “系统单位设置 ”  --->   将系统单位比例设置成:  ;再点击 “ 确定” 保存!

在模型的制作过程当中,为了使物体的坐标在物体的中心点,要记得冻结物体的坐标属性

当模型制作完成时,导出为 FBX 格式时还需注意:

在导出的 设置面板中 :

点击高级选项,然后出现:

确保 “ 场景单位转化为:”的设置为 "Meters"


模型导出后,模型资源可能很大,原因有以下几个:

1: 检测一下材质贴图的格式是否为:.png 的,不是请改过来 ;

2:看模型当中是否有过多的独立存在的物体,将不需要单独 存在给它合并在一块!


要是模型导入到Unity3D 中后,引擎运行变卡,就得看看模型的面是不是太多了!


Unity3D 5.1烘培

阅读数 29273

没有更多推荐了,返回首页