ForceMode解析

http://www.manew.com/thread-42925-1-1.html


一直搞不明白四种力模式的区别,百度下了下,觉得分析的很透彻,分享给大家

ForceMode为枚举类型,用来控制力的作用方式,有4个枚举成员,在以下举例中均设刚体质量为m=2.0f,力向量为f=(10.0f,0.0f,0.0f)。

(1)ForceMode.Force:默认方式,使用刚体的质量计算,以每帧间隔时间为单位计算动量。设FixedUpdate()的执行频率采用系统默认值(即0.02s),,则由动量定理

f•t=m•v

可得:10*0.02=2*v1,从而可得v1=0.1,即每帧刚体在X轴上值增加0.1米,从而可计算得刚体的每秒移动速度为v2=(1/0.02)*v1=5m/s。

(2)ForceMode.Acceleration:在此种作用方式下会忽略刚体的实际质量而采用默认值1.0f,时间间隔以系统帧频间隔计算(默认值为0.02s),即

f•t=1.0•v

即可得v1= f•t=10*0.02=0.2,即刚体每帧增加0.2米,从而可得刚体的每秒移动速度为v2=(1/0.02)*v1=10m/s。

(3)ForceMode.Impulse:此种方式采用瞬间力作用方式,即把t的值默认为1,不再采用系统的帧频间隔,即

f•1.0=m•v

即可得v1=f/m=10.0/2.0=5.0,即刚体每帧增加5.0米,从而可得刚体每秒的速度为v2=(1/0.02)*5.0=250m/s。

(4)ForceMode.VelocityChange:此种作用方式下将忽略刚体的实际质量,采用默认质量1.0,同时也忽略系统的实际帧频间隔,采用默认间隔1.0,即

f•1.0=1.0•v

即可得v1=f=10.0,即刚体每帧沿X轴移动距离为10米,从而可得刚体每秒的速度为v2=(1/0.02)*v1=500m/s










using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using SimpleJson;


//using System;
/// <summary>
/// 1、加载Document目录中的资源,
/// 分为dll代码和一个prefab的assetBundle
/// code通过getComponent累进行动态获取,
/// 更新的prefab通过从assetBundle中加载
/// </summary>
public class LocalResourceManager : MonoBehaviour
{


private static LocalResourceManager instance;
 
//需要更新的资源直接是一行一个需要更新的资源,格式为:资源名#资源大小#资源名称|资源名称|资源名称
public static readonly string UPDATE_RES_LIST = "updateResList.txt";
//需要更新的所有的dll
public static readonly string Dll_VERSION_FLIE = "lxxc_dll.unity3d";
//更新的prefab
public static readonly string AB_VERSION_FLIE = "updatePrefab.unity3d";
//protobuff 加密协议
public static readonly string PROTO_BUFF = "protobuff.txt";


public static readonly string BATTLE_MONST_DATA = "BattleDemoMonsterData.txt";
public static readonly string BATTLE_DATA = "BattleDemoBattleData.txt";
public static readonly string BATTLE_PLAYER_DATA = "BattleDemoPlayerData.txt";




public delegate void HandleFinishDownload (WWW www);


private static string LOCAL_RES_PATH = "";


public DownLoadMananger.DownLoadResProgress downloadProgress;
 
public DownLoadMananger.DownFinish updateFinish;


//已经加载好的数据库数据
[HideInInspector]
public byte[] dbBytes;
public byte[] dbCompressBytes;
private List<string> loadResource;
//更新的assembly
private  static Assembly assembly;


private AssetBundle prefabAb;


private List<string> bundleList;


private static bool isFinish = false;


/// <summary>
/// 获取ResourceUpdate单例对象
/// </summary>
/// <returns>The instance.</returns>
public static LocalResourceManager GetInstance ()
{
return instance;
}


// Use this for initialization
void Awake ()
{
instance = this;
}


// Update is called once per frame
void Update ()
{


}


//下载更新资源
public void LoadedDocumentRes ()
{
if (isFinish) {
if (updateFinish != null) {
updateFinish ();
}
return;
}
//加载bundle的配置文件
DownLoadMananger.GetInstance ().InitParam ();
string filePath = GameUtils.GetAssetPath () + BundleManager.BundleConfigFileName;

DownLoadMananger.GetInstance ().downLoadOneFinish = loadBundleCfgOneFinish;
DownLoadMananger.GetInstance ().downFinish = LoadBundleCfgFinish;


List<string> list = new List<string> ();
list.Add (filePath);
DownLoadMananger.GetInstance ().StartDownLoad (list);
}


void loadBundleCfgOneFinish (string fileName, WWW wwwData)
{
BundleManager.GetInstance ().SetConfigData (wwwData.text);
}


void LoadBundleCfgFinish ()
{
LOCAL_RES_PATH = GameUtils.GetDocumentsPath () + "/";
string result = GetOldUpdateList ();
bundleList = BundleManager.GetInstance ().GetBundleUrlList ();
if (loadResource == null) {
loadResource = new List<string> ();
}
loadResource.AddRange (bundleList);
if (result != "") {
string[] items = result.Split (new char[] { '\n' });
for (int i = 0; i < items.Length; i++) {
if (items [i] != "") {
loadResource.Add (LOCAL_RES_PATH + items [i]);
}
}
}  
loadResource.AddRange (InitBattleDemoData());
DownLoadMananger.GetInstance ().InitParam ();
DownLoadMananger.GetInstance ().downFinish = LoadFinish;
DownLoadMananger.GetInstance ().downLoadOneFinish = DownLoadOneFinish;
DownLoadMananger.GetInstance ().downLoadProgress = downloadProgress;
DownLoadMananger.GetInstance ().StartDownLoad (loadResource);
}




List<string> InitBattleDemoData(){
List<string> path = new List<string> ();
path.Add (GameUtils.getPersistentPath() + "BattleDemo/" + BATTLE_MONST_DATA);
path.Add (GameUtils.getPersistentPath() + "BattleDemo/" + BATTLE_DATA);
path.Add (GameUtils.getPersistentPath() + "BattleDemo/" + BATTLE_PLAYER_DATA);
return path;
}


void LoadFinish ()
{
isFinish = true;
SQLiteDataManager.GetInstance ().finishCallback = updateFinish;
LoginLoadingView.GetInstance ().SetLoadText ("正在解压配置,请稍等....");
SQLiteDataInit.GetInstance ().InitSQLiteData ();
}


void DownLoadOneFinish (string fileName, WWW wwwData)
{
//将下载的资源替换本地就的资源
if (fileName.IndexOf (Dll_VERSION_FLIE) >= 0) {
LoadAssembly (wwwData);
return;
}
if (fileName.IndexOf (SQLiteDataInit.DBEncodeFileName) >= 0) {
dbBytes = wwwData.bytes;
} else if (fileName.IndexOf (SQLiteDataInit.DBCompressFileName) >= 0) {
dbCompressBytes = wwwData.bytes;
} else if (fileName.IndexOf (AB_VERSION_FLIE) >= 0) {
prefabAb = wwwData.assetBundle;
} else if (fileName.IndexOf (PROTO_BUFF) >= 0) {
Pomelo.DotNetClient.Protocol.protoBuffJson = (JsonObject)SimpleJson.SimpleJson.DeserializeObject (wwwData.text);
} else if (fileName.IndexOf (BATTLE_DATA) >= 0) {
GLogger.Log (wwwData.text);
BattleDemoManager.battleData = wwwData.text;
} else if (fileName.IndexOf (BATTLE_MONST_DATA) >= 0) {
BattleDemoManager.battleMonstData = wwwData.text;
} else if (fileName.IndexOf (BATTLE_PLAYER_DATA) >= 0) {
GLogger.Log (wwwData.text);
BattleDemoManager.battlePlayerData = wwwData.text;
}


//设置boundle
for (int i = 0; i < bundleList.Count; i++) {
if (bundleList [i].IndexOf (fileName) >= 0) {
BundleManager.GetInstance ().SetBoundle (fileName, wwwData);
}
}
}




string GetOldUpdateList ()
{
string path = LOCAL_RES_PATH.Replace ("file://", "") + UPDATE_RES_LIST;
CreateDic (path);
return GetFileContent (path);
}


//创建路径
void CreateDic (string filePath)
{
int index = filePath.LastIndexOf ('/');
string dir = filePath.Substring (0, index + 1);
if (!Directory.Exists (dir)) {
Directory.CreateDirectory (dir);
}
}
 
//给物体上挂在脚本
public void AddComponentToResource (string className, GameObject gb)
{
System.Type type = assembly.GetType (className);
if (type == null) {
Assembly assembly2 = Assembly.GetAssembly (typeof(ResourceUpdate));
type = assembly2.GetType (className);
}
// GLogger.Log (type  + "***************额额额额额***************************************************" + className);
if (gb != null && type != null && gb.GetComponent (type) == null) {
gb.AddComponent (type);
}
}


//加载并存储code
private void LoadAssembly (WWW assemblyBytes)
{
if (assemblyBytes == null) {
return;
}
//iphone 
#if UNITY_IPHONE || UNITY_IOS || UNITY_IPHONE_API
Assembly[] array = System.AppDomain.CurrentDomain.GetAssemblies ();
for (int i = 0; i < array.Length; i++) {
if(array[i].FullName.IndexOf("lxxc_dll") >= 0){
assembly = array[i];
break;
}
}
#endif


#if UNITY_ANDROID
AssetBundle bundle = assemblyBytes.assetBundle;
string loadName = Dll_VERSION_FLIE.Substring (0, Dll_VERSION_FLIE.LastIndexOf ('.'));
TextAsset asset = bundle.Load (loadName, typeof(TextAsset)) as TextAsset;
assembly = System.Reflection.Assembly.Load (asset.bytes);
#endif


// //使用当前程序集中的类
// #if UNITY_EDITOR
// assembly = Assembly.GetAssembly (typeof(ResourceUpdate));
// #endif




//使用其他加载进来的dll中的类
#if UNITY_EDITOR
string sapath = Application.streamingAssetsPath;
string BinPath = sapath.Substring (0, sapath.IndexOf ("lxxc"));
assembly = Assembly.LoadFile (BinPath + "lxxc_dll/obj/Debug/lxxc_dll.dll");
#endif


// System.Type[] types = assembly.GetExportedTypes();
// for (int i = 0; i < types.Length; i++) {
// GLogger.Log(types[i].Name + "**************");
//
// }
assemblyBytes.Dispose ();


}


//
public AssetBundle HasInNewPrefab (string assetName)
{
if (prefabAb == null) {
return null;
}
if (prefabAb.Contains (assetName)) {
return prefabAb;
}
return null;
}


 


string GetFileContent (string path)
{
if (!File.Exists (path)) {
return "";
}
StringBuilder sb = new StringBuilder ();
StreamReader sr = new StreamReader (path, Encoding.Default);
string line;
while ((line = sr.ReadLine ()) != null) {
sb.Append (line + "\n");
}
sr.Close ();
return sb.ToString ();
}


}


using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System;


//using System;
/// <summary>
/// 1、从服务器获取版本号,和当前客户端存储的版本号进行对比,
///    a、如果相同则不更新
///    b、如果不同,则从服务器获取需要更新的资源列表文件version.txt,再没有进行大版本更新的时候,这个列表是进行累加的。;
///    c、文件更新后,修改客户端本地的版本号存储到version.txt文件中。
/// </summary>
/// /// <summary>
/// 1.在vs中新建一个代码库工程,命名为test
//2.添加几个类Scirpt,Scirpt2,Data
//3.将这个项目生成DLL,test.dll
//4.新建一个unity项目,将DLL倒入到Asset,改名为test.bytes,不然可能会报错
//5.利用我们之前实现过的打包脚本,将test.bytes打包成test.assetbundle。
//6.创建CodeUpdate.cs脚本,用于加载代码资源,反射调用。
//7.为了验证代码更新后,可以直接加载使用,我们可以更改一下Data.cs的代码,重复以上过程,可以看到,更新了代码打包后,我们重新运行游戏,就可以看到效果
/// </summary>
public class ResourceUpdate : MonoBehaviour
{


private static ResourceUpdate instance;
//需要更新的资源直接是一行一个需要更新的资源,格式为:资源名#资源大小#资源名称|资源名称|资源名称
public static readonly string UPDATE_RES_LIST = "updateResList.txt";
//本地存储版本号
public static readonly string LOCAL_VERSION = "version.txt";
//需要更新的所有的dll
public static readonly string Dll_VERSION_FLIE = "lxxc_dll.unity3d";
//格式为:资源名(为更新的资源名)#GameObject.name_c#clssName_GameObject.name_c#clssName
public static readonly string Dll_TO_RES_VERSION_FLIE = "dynamicRes.txt";
public static string LOCAL_RES_URL = "";
public static string SERVER_RES_URL = "";
public static string LOCAL_RES_PATH = "";


public delegate void HandleFinishDownload (WWW www);


private static List<string> localResVersion;


private static List<string> totalUpdateResList;


//格式为:资源名, GameObject.name_c#clssName_GameObject.name_c#clssName;
private Dictionary<string, string> dll2Res;
private System.Reflection.Assembly assembly;


public DownLoadMananger.DownFinish updateFinish;
public DownLoadMananger.DownLoadResProgress downloadProgress;


//下载版本文件,解析成功后回调
public delegate void ParseUpdateListCallback ();


public ParseUpdateListCallback parseFinishCallBack;


//本次更新资源总大小
public static float updateTotalSize;
//是否需要更新db
public static bool isUpdateDB = false;
//是否下载完成
public static bool isDownloaded = true;
//当前下载的文件进度
public static float currentDownNum = 0f;
private int totalNum = 1;
public static  WWW currentWWW;


/// <summary>
/// 获取ResourceUpdate单例对象
/// </summary>
/// <returns>The instance.</returns>
public static ResourceUpdate GetInstance ()
{
return instance;
}






// Use this for initialization
void Awake ()
{
LOCAL_RES_PATH = GameUtils.GetDocumentsPath () + "/";
LOCAL_RES_URL = GameUtils.GetDocumentsPath () + "/";
instance = this;
localResVersion = new List<string> ();
totalUpdateResList = new List<string> ();
GLogger.Log (Application.dataPath + "==========" + LOCAL_RES_URL);
}


void InitUpdateList ()
{
if (SERVER_RES_URL != "") {
return;
}
ResetServerPath ();
string result = GetOldUpdateList ();
if (result != "") {
string[] items = result.Split (new char[] { '\n' });
totalUpdateResList = new List<string> (items);
}
}


void ResetServerPath ()
{
SERVER_RES_URL = GlobalConfig.ResUrl;
#if UNITY_EDITOR
SERVER_RES_URL += "android/";
#elif UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX
SERVER_RES_URL += "pc/";
#elif UNITY_IPHONE || UNITY_IOS || UNITY_IPHONE_API
SERVER_RES_URL += "ios/";
#elif UNITY_ANDROID
SERVER_RES_URL += "android/";
#endif
}




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


//下载更新资源
public void DownloadServerVersionTxt ()
{
NetDataRequestTip.showLoading ();
isDownloaded = false;
InitUpdateList ();
updateTotalSize = 0;
//先下载资源更新的列表文件
DownLoadMananger.GetInstance ().InitParam ();
DownLoadMananger.GetInstance ().downLoadOneFinish = DownLoadUplistFinish;
DownLoadMananger.GetInstance ().downFinish = DownUpdateListFinish;
List<string> list = new List<string> ();
list.Add (SERVER_RES_URL + UPDATE_RES_LIST + "?time=" + System.DateTime.Now.Ticks);
DownLoadMananger.GetInstance ().StartDownLoad (list);
}


void DownLoadUplistFinish (string file, WWW wwwData)
{
NetDataRequestTip.removeLoading ();
ParseVersionFile (wwwData.text, localResVersion);
}


void DownUpdateListFinish ()
{
if (parseFinishCallBack != null) {
parseFinishCallBack ();
}
}


public int GetTotalDownNum ()
{
return totalNum;
}






//依次加载需要更新的资源
public void DownLoadRes ()
{
InitUpdateList ();
DownLoadMananger.GetInstance ().InitParam ();
DownLoadMananger.GetInstance ().downFinish = DownLoadFinish;
DownLoadMananger.GetInstance ().downLoadOneFinish = ReplaceLocalRes;
DownLoadMananger.GetInstance ().downLoadProgress = downloadProgress;
List<string> urlList = new List<string> ();
for (int i = 0; i < localResVersion.Count; i++) {
urlList.Add (SERVER_RES_URL + localResVersion [i] + "?time=" + System.DateTime.Now.Ticks);
}
DownLoadMananger.GetInstance ().StartDownLoad (urlList);
}


//下载完成回调
void DownLoadFinish ()
{
UpdateLocalVersion (GlobalConfig.version);
if (updateFinish != null) {
GLogger.Log ("=====DownLoadRes==finish=====" + GlobalConfig.version);
updateFinish ();
}
}


public bool isNeedDownloadRes ()
{
return totalUpdateResList.Count > 0;
}


private void ReplaceLocalRes (string fileName, WWW wwwData)
{
byte[] data = wwwData.bytes;
string path = LOCAL_RES_PATH.Replace ("file://", "");
 
GLogger.Log (path + "      replace");
string filePath = path + fileName;
FileStream stream;
if (File.Exists (filePath)) {
stream = new FileStream (filePath, FileMode.Create);
} else {
CreateDic (filePath);
stream = File.Create (filePath);
}
stream.Write (data, 0, data.Length);
stream.Flush ();
stream.Close ();
 
}


 


public bool isHasNewRes (string assetName)
{
int index = totalUpdateResList.IndexOf (assetName);
// GLogger.Log (LitJson.JsonMapper.ToJson (totalUpdateResList) + "   " + assetName + " " + index);
return index >= 0;
}


//解析更新的资源,并计算更新的总大小
private void ParseVersionFile (string content, List<string> dict)
{
if (content == null || content.Trim ().Length == 0) {
isDownloaded = true;
// if (parseFinishCallBack != null) {
// parseFinishCallBack ();
// }
return;
}
string appendRes = "";
string[] items = content.Split ('\n');
string[] res;
isUpdateDB = false;
foreach (string item in items) {
if (item != null && item.Trim ().Length > 0) {
res = item.Split ('#');
if (res.Length >= 2) {
updateTotalSize += (float)System.Convert.ToDouble (res [1]);
dict.Add (res [0]);
if (res [0] == SQLiteDataInit.DBFileName) {
isUpdateDB = true;
}
if (totalUpdateResList.IndexOf (res [0]) < 0) {
totalUpdateResList.Add (res [0]);
appendRes += res [0] + "\n";
}
if (res.Length >= 3 && res [2] != "") {
string[] resNames = res [2].Split ('|');
for (int i = 0; i < resNames.Length; i++) {
totalUpdateResList.Add (resNames [i]);
appendRes += resNames [i] + "\n";
}
}
}
}
}
if (appendRes != "") {
string path = LOCAL_RES_PATH.Replace ("file://", "") + UPDATE_RES_LIST;
CreateDic (path);
FileStream fs;
if (!File.Exists (path)) {
fs = new FileStream (path, FileMode.Create);
} else {
fs = new FileStream (path, FileMode.Append);
}
byte[] bytes = Encoding.UTF8.GetBytes (appendRes);
fs.Write (bytes, 0, bytes.Length);
fs.Flush ();
fs.Close ();
}
// updateTotalSize = updateTotalSize;
// if (parseFinishCallBack != null) {
// parseFinishCallBack ();
// }
}


//创建路径
void CreateDic (string filePath)
{
int index = filePath.LastIndexOf ('/');
string dir = filePath.Substring (0, index + 1);
if (!Directory.Exists (dir)) {
Directory.CreateDirectory (dir);
}
}


string GetOldUpdateList ()
{
string path = LOCAL_RES_PATH.Replace ("file://", "") + UPDATE_RES_LIST;
CreateDic (path);
return GetFileContent (path);
}




//更新本地文件的版本号
public void UpdateLocalVersion (string version)
{
string path = LOCAL_RES_PATH.Replace ("file://", "") + LOCAL_VERSION;
CreateDic (path);
if (File.Exists (path)) {
File.Delete (path);
}
FileStream fs = new FileStream (path, FileMode.Create);
byte[] bytes = Encoding.UTF8.GetBytes (version.ToString ());
fs.Write (bytes, 0, bytes.Length);
fs.Flush ();
fs.Close ();
}




//更新本地文件的版本号
public void SaveDll (string version)
{
string path = LOCAL_RES_PATH.Replace ("file://", "") + LOCAL_VERSION;
CreateDic (path);
if (File.Exists (path)) {
File.Delete (path);
}
FileStream fs = new FileStream (path, FileMode.Create);
byte[] bytes = Encoding.UTF8.GetBytes (version.ToString ());
fs.Write (bytes, 0, bytes.Length);
fs.Flush ();
fs.Close ();
}




//获取本地文件的版本号
public string GetLocalVersion ()
{
//Open the stream and read it back.
string path = LOCAL_RES_PATH.Replace ("file://", "") + LOCAL_VERSION;
GLogger.Log (path);
string version = GetFileContent (path);
if (version == "") {
return GlobalConfig.version;
} else {
// int txtIndex = version.LastIndexOf (".");
// int txtVersion = Convert.ToInt32 (version.Substring (0, txtIndex).Replace (".", ""));
//
// int cfgIndex = version.LastIndexOf (".");
// int cfgVersion = Convert.ToInt32 (GlobalConfig.version.Substring (0, cfgIndex).Replace (".", ""));
//改为比较整个版本号,取两个中较大的,避免version版本同时低于资源版本和GlobalConfig版本时会更新资源而不是解压资源
int txtVersion = GameUtils.ConvertVersionInt(version);
int cfgVersion = GameUtils.ConvertVersionInt(GlobalConfig.version);

return  txtVersion >= cfgVersion ? version : GlobalConfig.version;
}

// return version.Replace ("\n", "");
}




string GetFileContent (string path)
{
if (!File.Exists (path)) {
return "";
}
StringBuilder sb = new StringBuilder ();
StreamReader sr = new StreamReader (path, Encoding.Default);
string line;
while ((line = sr.ReadLine ()) != null) {
sb.Append (line + "\n");
}
sr.Close ();
return sb.ToString ();
}


}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System;


//using System;
/// <summary>
/// 1、从服务器获取版本号,和当前客户端存储的版本号进行对比,
///    a、如果相同则不更新
///    b、如果不同,则从服务器获取需要更新的资源列表文件version.txt,再没有进行大版本更新的时候,这个列表是进行累加的。;
///    c、文件更新后,修改客户端本地的版本号存储到version.txt文件中。
/// </summary>
/// /// <summary>
/// 1.在vs中新建一个代码库工程,命名为test
//2.添加几个类Scirpt,Scirpt2,Data
//3.将这个项目生成DLL,test.dll
//4.新建一个unity项目,将DLL倒入到Asset,改名为test.bytes,不然可能会报错
//5.利用我们之前实现过的打包脚本,将test.bytes打包成test.assetbundle。
//6.创建CodeUpdate.cs脚本,用于加载代码资源,反射调用。
//7.为了验证代码更新后,可以直接加载使用,我们可以更改一下Data.cs的代码,重复以上过程,可以看到,更新了代码打包后,我们重新运行游戏,就可以看到效果
/// </summary>
public class ResourceUpdateFromLocal : MonoBehaviour
{


private static ResourceUpdateFromLocal instance;
//需要更新的资源直接是一行一个需要更新的资源,格式为:资源名#资源大小#资源名称|资源名称|资源名称
public static readonly string UPDATE_RES_LIST = "updateResList.txt";
//本地存储版本号
public static readonly string LOCAL_VERSION = "version.txt";
//需要更新的所有的dll
public static readonly string Dll_VERSION_FLIE = "lxxc_dll.unity3d";
//格式为:资源名(为更新的资源名)#GameObject.name_c#clssName_GameObject.name_c#clssName
public static readonly string Dll_TO_RES_VERSION_FLIE = "dynamicRes.txt";
public static string LOCAL_RES_URL = "";
public static string SERVER_RES_URL = "";
public static string LOCAL_RES_PATH = "";


public delegate void HandleFinishDownload (WWW www);


private static List<string> localResVersion;


private static List<string> totalUpdateResList;


//格式为:资源名, GameObject.name_c#clssName_GameObject.name_c#clssName;
private Dictionary<string, string> dll2Res;
private System.Reflection.Assembly assembly;


public DownLoadMananger.DownFinish updateFinish;
public DownLoadMananger.DownLoadResProgress downloadProgress;


//下载版本文件,解析成功后回调
public delegate void ParseUpdateListCallback();
public ParseUpdateListCallback parseFinishCallBack;


//本次更新资源总大小
public static float updateTotalSize;
//是否需要更新db
public static bool isUpdateDB = false;
//是否下载完成
public static bool isDownloaded = true;
//当前下载的文件进度
public static float currentDownNum = 0f;
private int totalNum = 1;
public static  WWW currentWWW ;


/// <summary>
/// 获取ResourceUpdate单例对象
/// </summary>
/// <returns>The instance.</returns>
public static ResourceUpdateFromLocal GetInstance ()
{
return instance;
}






// Use this for initialization
void Awake ()
{
LOCAL_RES_PATH = GameUtils.GetDocumentsPath() + "/";
LOCAL_RES_URL = GameUtils.GetDocumentsPath () + "/";
instance = this;
localResVersion = new List<string> ();
GLogger.Log (Application.dataPath + "==========" + LOCAL_RES_URL);
}


void InitUpdateList(){
if (SERVER_RES_URL != "") {
return;
}
ResetServerPath ();
string result = GetOldUpdateList ();
GLogger.Log (Application.dataPath + "=====3333=====" + result);
if (result != "") {
string[] items = result.Split (new char[] { '\n' });
totalUpdateResList = new List<string> (items);
} else {
totalUpdateResList = new List<string> ();
}
}


void ResetServerPath(){
#if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX
SERVER_RES_URL = "file://" + Application.streamingAssetsPath + "/";
#elif UNITY_WEBPLAYER
SERVER_RES_URL = "StreamingAssets/";
#elif UNITY_IPHONE || UNITY_IOS || UNITY_IPHONE_API
SERVER_RES_URL = "file://" + Application.dataPath + "/Raw/";
#elif UNITY_ANDROID
SERVER_RES_URL = Application.streamingAssetsPath + "/";
#endif
}




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


//下载更新资源
public void DownloadServerVersionTxt ()
{
NetDataRequestTip.showLoading ();
isDownloaded = false;
InitUpdateList ();
updateTotalSize = 0;
//先下载资源更新的列表文件
DownLoadMananger.GetInstance ().InitParam ();
DownLoadMananger.GetInstance ().downLoadOneFinish = DownLoadUplistFinish;
DownLoadMananger.GetInstance ().downFinish = DownUpdateListFinish;
List<string> list = new List<string> ();
list.Add (SERVER_RES_URL + UPDATE_RES_LIST);
DownLoadMananger.GetInstance ().StartDownLoad (list);
}


void DownLoadUplistFinish(string file, WWW wwwData){
NetDataRequestTip.removeLoading();
ParseVersionFile (wwwData.text, localResVersion);
}


void DownUpdateListFinish(){
if (parseFinishCallBack != null) {
parseFinishCallBack ();
}
}


public int GetTotalDownNum(){
return totalNum;
}






//依次加载需要更新的资源
public void DownLoadRes ()
{
InitUpdateList ();
DownLoadMananger.GetInstance ().InitParam ();
DownLoadMananger.GetInstance ().downFinish = DownLoadFinish;
DownLoadMananger.GetInstance ().downLoadOneFinish = ReplaceLocalRes;
DownLoadMananger.GetInstance ().downLoadProgress = downloadProgress;
List<string> urlList = new List<string>();
for (int i = 0; i < localResVersion.Count; i++) {
urlList.Add (SERVER_RES_URL + localResVersion[i]);
}
DownLoadMananger.GetInstance ().StartDownLoad (urlList);
}


//下载完成回调
void DownLoadFinish(){
UpdateLocalVersion (GlobalConfig.version);
if (updateFinish != null) {
GLogger.Log ( "=====DownLoadRes==finish=====" + GlobalConfig.version);
updateFinish ();
}
}




private void ReplaceLocalRes (string fileName, WWW wwwData)
{
byte[] data = wwwData.bytes;
string path = LOCAL_RES_PATH.Replace ("file://", "");
 
GLogger.Log (path + "      replace");
string filePath = path + fileName;
FileStream stream;
if (File.Exists (filePath)) {
stream = new FileStream (filePath, FileMode.Create);
} else {
CreateDic (filePath);
stream = File.Create (filePath);
}
stream.Write (data, 0, data.Length);
stream.Flush ();
stream.Close ();
 
}


 


public bool isHasNewRes(string assetName){
int index = totalUpdateResList.IndexOf (assetName);
// GLogger.Log (LitJson.JsonMapper.ToJson (totalUpdateResList) + "   " + assetName + " " + index);
return index  >= 0;
}


//解析更新的资源,并计算更新的总大小
private void ParseVersionFile (string content, List<string> dict)
{
if (content == null || content.Trim().Length == 0) {
isDownloaded = true;
// if (parseFinishCallBack != null) {
// parseFinishCallBack ();
// }
return;
}
string appendRes = "";
string[] items = content.Split ('\n');
string[] res;
isUpdateDB = false;
foreach (string item in items) {
if (item != null && item.Trim().Length > 0) {
res = item.Split ('#');
if (res.Length >= 2) {
updateTotalSize += (float)System.Convert.ToDouble (res [1]);
dict.Add (res[0]);
if (res [0] == SQLiteDataInit.DBFileName) {
isUpdateDB = true;
}
if (totalUpdateResList.IndexOf (res [0]) < 0) {
totalUpdateResList.Add (res [0]);
appendRes += res [0] + "\n";
}
if (res.Length >= 3 && res [2] != "") {
string[] resNames = res [2].Split ('|');
for (int i = 0; i < resNames.Length; i++) {
totalUpdateResList.Add (resNames [i]);
appendRes += resNames [i] + "\n";
}
}
}
}
}
if (appendRes != "") {
string path = LOCAL_RES_PATH.Replace ("file://", "") + UPDATE_RES_LIST;
CreateDic (path);
FileStream fs;
if (!File.Exists (path)) {
fs = new FileStream (path, FileMode.Create);
} else {
fs = new FileStream (path, FileMode.Append);
}
byte[] bytes = Encoding.UTF8.GetBytes (appendRes);
fs.Write (bytes, 0, bytes.Length);
fs.Flush ();
fs.Close ();
}
// updateTotalSize = updateTotalSize;
// if (parseFinishCallBack != null) {
// parseFinishCallBack ();
// }
}


//创建路径
void CreateDic(string filePath){
int index = filePath.LastIndexOf ('/');
string dir = filePath.Substring (0, index + 1);
if (!Directory.Exists (dir)) {
Directory.CreateDirectory (dir);
}
}


string GetOldUpdateList(){
string path = LOCAL_RES_PATH.Replace ("file://", "") + UPDATE_RES_LIST;
CreateDic (path);
return GetFileContent(path);
}




public bool isNeedUnZipLocalRes(){
string dbDecompressPath = GameUtils.GetDocumentsPath().Replace("file://", "") + "/" + LOCAL_VERSION;
if (File.Exists(dbDecompressPath))
{
string version = GetFileContent (dbDecompressPath);
if(GameUtils.ConvertVersionInt(version) >= GameUtils.ConvertVersionInt(GlobalConfig.version))
return false;
}
return true;
}


//更新本地文件的版本号
public void UpdateLocalVersion (string version)
{
string path = LOCAL_RES_PATH.Replace ("file://", "") + LOCAL_VERSION;
CreateDic (path);
if (File.Exists (path)) {
File.Delete (path);
}
FileStream fs = new FileStream (path, FileMode.Create);
byte[] bytes = Encoding.UTF8.GetBytes (version.ToString ());
fs.Write (bytes, 0, bytes.Length);
fs.Flush ();
fs.Close ();
}




//更新本地文件的版本号
public void SaveDll (string version)
{
string path = LOCAL_RES_PATH.Replace ("file://", "") + LOCAL_VERSION;
CreateDic (path);
if (File.Exists (path)) {
File.Delete (path);
}
FileStream fs = new FileStream (path, FileMode.Create);
byte[] bytes = Encoding.UTF8.GetBytes (version.ToString ());
fs.Write (bytes, 0, bytes.Length);
fs.Flush ();
fs.Close ();
}




//获取本地文件的版本号
public string GetLocalVersion ()
{
//Open the stream and read it back.
string path = LOCAL_RES_PATH.Replace ("file://", "") + LOCAL_VERSION;
GLogger.Log (path);
string version = GetFileContent(path);
if (version == "") {
return GlobalConfig.version;
}else{
// int txtIndex = version.LastIndexOf (".");
// int txtVersion = Convert.ToInt32 (version.Substring (0, txtIndex).Replace (".", ""));
//
// int cfgIndex = version.LastIndexOf (".");
// int cfgVersion = Convert.ToInt32 (GlobalConfig.version.Substring (0, cfgIndex).Replace (".", ""));


//改为比较整个版本号,取两个中较大的,避免version版本同时低于资源版本和GlobalConfig版本时会更新资源而不是解压资源
int txtVersion = GameUtils.ConvertVersionInt(version);
int cfgVersion = GameUtils.ConvertVersionInt(GlobalConfig.version);


return  txtVersion >= cfgVersion ? version : GlobalConfig.version;
}



// return version.Replace("\n", "");
}




string GetFileContent(string path){
if (!File.Exists (path)) {
return "";
}
StringBuilder sb = new StringBuilder ();
StreamReader sr = new StreamReader(path,Encoding.Default);
string line;
while ((line = sr.ReadLine()) != null) 
{
sb.Append(line + "\n");
}
sr.Close ();
return sb.ToString ();
}


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


public class DownLoadMananger : MonoBehaviour {




private static DownLoadMananger instance;
public delegate void HandleFinishDownload (WWW www);
private List<string> localResVersion;


private  WWW currentWWW ;


//下载完成事件
public delegate void DownFinish();
public DownFinish downFinish;


//下载过程事件
public delegate void DownLoadResProgress(float progress);
public DownLoadResProgress downLoadProgress;


//下载过程事件
public delegate void DownLoadOneFinish(string fileName, WWW wwwData);
public DownLoadOneFinish downLoadOneFinish;


//当前正在下载的文件
private int currentDownNum = 0;


private float totalNum = 0;
//下载的所有文件的总进度
private float totalProgress = 0.0f;


public static DownLoadMananger GetInstance ()
{
return instance;
}




// Use this for initialization
void Awake () {
instance = this;
}

// Update is called once per frame
void Update () {

if (currentWWW != null) {
totalProgress = (currentDownNum + currentWWW.progress) / totalNum;
if (downLoadProgress != null) {
downLoadProgress (totalProgress);
}
// GLogger.Log (downLoadProgress + "=====DownLoadRes=======" + totalProgress +  "  " + totalNum);
}




}


public void InitParam(){
downFinish = null;
downLoadProgress = null;
downLoadOneFinish = null;
currentDownNum = 0;
totalNum = 0;
totalProgress = 0f;
}


//依次加载需要更新的资源
public void StartDownLoad (List<string> resList)
{
//如果下载列表为null,直接回调结束
if (resList == null || resList.Count <= 0) {
FinishCallback ();
return;
}
localResVersion = resList;
totalNum = (float)localResVersion.Count;
DownLoadFile ();
}


void FinishCallback(){
if (downFinish != null) {
downFinish ();

}


void DownLoadFile(){
if (localResVersion == null || (localResVersion != null && localResVersion.Count <= 0)) {
FinishCallback ();
return;
}


string file = localResVersion [0];
if (file == null || file.Trim ().Length == 0) {
localResVersion.RemoveAt (0);
currentDownNum++;
currentWWW = null;
DownLoadFile();
return;
}
GLogger.LogWarning("__________"+localResVersion[0]);

StartCoroutine (this.DownLoad (file, delegate(WWW w) {
GLogger.LogWarning("__________"+localResVersion[0]);
//将下载的资源替换本地就的资源
if(downLoadOneFinish != null){
int end = file.Length - (file.LastIndexOf('/') + 1);
int index = file.IndexOf("?");
if(index >= 0){
end = index - 1 - file.LastIndexOf('/');
}
// GLogger.LogError(file + "  " + end);
downLoadOneFinish(file.Substring((file.LastIndexOf('/') + 1),end), w);
}
localResVersion.RemoveAt (0);
currentDownNum++;
if(localResVersion.Count > 0){
}
currentWWW = null;
DownLoadFile ();
}));
}




//下载文件
private IEnumerator DownLoad (string url, HandleFinishDownload finishFun)
{
WWW www = new WWW (url);
GLogger.Log (url + "----------");
currentWWW =www;
yield return www;
bool hasError = false;
if (www.error != null) {
hasError = true;
}


if (www.isDone) {
if (www.bytesDownloaded > 0 && !hasError) {
if (finishFun != null) {
GLogger.LogWarning (url + "---------------------------");
finishFun (www);
}
} else {
GLogger.Log (url + " ***load error **www.bytesDownloaded is *****" + www.bytesDownloaded + " error is" + www.error.ToString() );
currentWWW = null;
www.Dispose ();
NetDataRequestTip.removeLoading ();
AlertConfirmController.GetInstance ().pushAlertMsg (CNString.DOWN_RES_ERROR, delegate(bool isConfirm){
if(isConfirm){
GLogger.LogWarning(url);

StartCoroutine(DownLoad(url, finishFun));
}
else{
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit ();
#endif
}
});
}
} else {
currentWWW = null;
}


www.Dispose ();
www = null;
System.GC.Collect ();
}




}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值