├── .gitignore
├── Assets
├── AssetBundlePatch.meta
├── AssetBundlePatch
│ ├── AssetBundlePatch.cs
│ └── AssetBundlePatch.cs.meta
├── Level1.unity
├── Level1.unity.meta
├── Level2.unity
├── Level2.unity.meta
├── Plane1.mat
├── Plane1.mat.meta
├── Plane2.mat
├── Plane2.mat.meta
├── Plugins.meta
├── Plugins
│ ├── Android.meta
│ ├── Android
│ │ ├── libAssetBundleParser.so
│ │ └── libAssetBundleParser.so.meta
│ ├── AssetBundleParser.bundle.meta
│ ├── AssetBundleParser.bundle
│ │ ├── Contents.meta
│ │ └── Contents
│ │ │ ├── Info.plist
│ │ │ ├── Info.plist.meta
│ │ │ ├── MacOS.meta
│ │ │ ├── MacOS
│ │ │ ├── AssetBundleParser
│ │ │ └── AssetBundleParser.meta
│ │ │ ├── Resources.meta
│ │ │ └── Resources
│ │ │ ├── en.lproj.meta
│ │ │ └── en.lproj
│ │ │ ├── InfoPlist.strings
│ │ │ └── InfoPlist.strings.meta
│ ├── iOS.meta
│ ├── iOS
│ │ ├── libAssetBundleParser.a
│ │ └── libAssetBundleParser.a.meta
│ ├── x86.meta
│ ├── x86
│ │ ├── AssetBundleParser.dll
│ │ └── AssetBundleParser.dll.meta
│ ├── x86_64.meta
│ └── x86_64
│ │ ├── AssetBundleParser.dll
│ │ └── AssetBundleParser.dll.meta
├── Standard Assets.meta
├── Standard Assets
│ ├── Character Controllers.meta
│ └── Character Controllers
│ │ ├── 3rd Person Controller.prefab
│ │ ├── 3rd Person Controller.prefab.meta
│ │ ├── First Person Controller.prefab
│ │ ├── First Person Controller.prefab.meta
│ │ ├── Sources.meta
│ │ └── Sources
│ │ ├── PrototypeCharacter.meta
│ │ ├── PrototypeCharacter
│ │ ├── Constructor.FBX
│ │ ├── Constructor.FBX.meta
│ │ ├── Materials.meta
│ │ ├── Materials
│ │ │ ├── constructor_done.mat
│ │ │ └── constructor_done.mat.meta
│ │ ├── Textures.meta
│ │ └── Textures
│ │ │ ├── constructor_diffuse.png
│ │ │ ├── constructor_diffuse.png.meta
│ │ │ ├── constructor_normals.png
│ │ │ └── constructor_normals.png.meta
│ │ ├── Scripts.meta
│ │ └── Scripts
│ │ ├── CharacterMotor.js
│ │ ├── CharacterMotor.js.meta
│ │ ├── FPSInputController.js
│ │ ├── FPSInputController.js.meta
│ │ ├── MouseLook.cs
│ │ ├── MouseLook.cs.meta
│ │ ├── PlatformInputController.js
│ │ ├── PlatformInputController.js.meta
│ │ ├── ThirdPersonCamera.js
│ │ ├── ThirdPersonCamera.js.meta
│ │ ├── ThirdPersonController.js
│ │ └── ThirdPersonController.js.meta
├── StreamingAssets.meta
├── StreamingAssets
│ ├── diff.rtttl
│ └── diff.rtttl.meta
├── Test.meta
├── Test
│ ├── Editor.meta
│ ├── Editor
│ │ ├── OneBuilderEditor.cs
│ │ └── OneBuilderEditor.cs.meta
│ ├── Progress.cs
│ ├── Progress.cs.meta
│ ├── UnzipProgress.cs
│ ├── UnzipProgress.cs.meta
│ ├── Updater.cs
│ ├── Updater.cs.meta
│ ├── ZipFile.cs
│ └── ZipFile.cs.meta
├── Thirdparty.meta
└── Thirdparty
│ ├── SharpZip.dll
│ ├── SharpZip.dll.meta
│ ├── UnityUtils.meta
│ └── UnityUtils
│ ├── AndroidAssetStream.cs
│ ├── AndroidAssetStream.cs.meta
│ ├── DynamicObject.cs
│ ├── DynamicObject.cs.meta
│ ├── Editor.meta
│ ├── Editor
│ ├── AssetDatabase.cs
│ ├── AssetDatabase.cs.meta
│ ├── CodeFormat.cs
│ ├── CodeFormat.cs.meta
│ ├── CommandLine.cs
│ ├── CommandLine.cs.meta
│ ├── EditorGUITools.cs
│ ├── EditorGUITools.cs.meta
│ ├── UIAdapterEditor.cs
│ └── UIAdapterEditor.cs.meta
│ ├── EventHelper.cs
│ ├── EventHelper.cs.meta
│ ├── IO.cs
│ ├── IO.cs.meta
│ ├── Log.cs
│ ├── Log.cs.meta
│ ├── README.md
│ ├── README.md.meta
│ ├── SimpleJson.cs
│ ├── SimpleJson.cs.meta
│ ├── Util.cs
│ └── Util.cs.meta
├── LICENSE
├── ProjectSettings
├── AudioManager.asset
├── DynamicsManager.asset
├── EditorBuildSettings.asset
├── EditorSettings.asset
├── GraphicsSettings.asset
├── InputManager.asset
├── NavMeshLayers.asset
├── NetworkManager.asset
├── Physics2DSettings.asset
├── ProjectSettings.asset
├── QualitySettings.asset
├── TagManager.asset
└── TimeManager.asset
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | Temp/
2 | Library
3 | *.csproj
4 |
--------------------------------------------------------------------------------
/Assets/AssetBundlePatch.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 45baf8a5af6e9433eb867191405a1e53
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/AssetBundlePatch/AssetBundlePatch.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections;
3 | using System.Runtime.InteropServices;
4 | using System;
5 | using System.IO;
6 |
7 | namespace dpull
8 | {
9 | public enum AssetBundlePatchResult
10 | {
11 | Failed = -1,
12 | Succeed = 0,
13 |
14 | FromAssetBundleLoadFailed,
15 | DiffFileSaveFailed,
16 | DiffFileLoadFailed,
17 | ToAssetBundleSaveFailed,
18 | }
19 |
20 | public class AssetBundlePatch
21 | {
22 | public static bool IsSupport(string file)
23 | {
24 | var bundle = assetbundle_load(file);
25 | if (bundle == IntPtr.Zero)
26 | return false;
27 |
28 | var ret = assetbundle_check(bundle);
29 | assetbundle_destroy(bundle);
30 | return ret;
31 | }
32 |
33 | public static AssetBundlePatchResult Diff(string appDataDir, string fromAssetbundle, string toAssetbundle, string diff)
34 | {
35 | if (string.IsNullOrEmpty(appDataDir))
36 | appDataDir = null;
37 |
38 | if (string.IsNullOrEmpty(fromAssetbundle))
39 | fromAssetbundle = null;
40 |
41 | if (string.IsNullOrEmpty(toAssetbundle))
42 | throw new System.ArgumentNullException("toAssetbundle");
43 |
44 | if (string.IsNullOrEmpty(diff))
45 | throw new System.ArgumentNullException("diff");
46 |
47 | return (AssetBundlePatchResult)assetbundle_diff(appDataDir, fromAssetbundle, toAssetbundle, diff);
48 | }
49 |
50 | public static AssetBundlePatchResult Merge(string appDataDir, string fromAssetbundle, string toAssetbundle, string diff)
51 | {
52 | if (string.IsNullOrEmpty(appDataDir))
53 | appDataDir = string.Empty;
54 |
55 | if (string.IsNullOrEmpty(fromAssetbundle))
56 | fromAssetbundle = null;
57 |
58 | if (string.IsNullOrEmpty(toAssetbundle))
59 | throw new System.ArgumentNullException("toAssetbundle");
60 |
61 | if (string.IsNullOrEmpty(diff))
62 | throw new System.ArgumentNullException("diff");
63 |
64 | AppDataDir = appDataDir;
65 | return (AssetBundlePatchResult)assetbundle_merge(ReadFile, IntPtr.Zero, fromAssetbundle, toAssetbundle, diff);
66 | }
67 |
68 | public static void Print(string diff, string output)
69 | {
70 | if (string.IsNullOrEmpty(diff))
71 | throw new System.ArgumentNullException("diff");
72 |
73 | if (string.IsNullOrEmpty(output))
74 | output = null;
75 |
76 | assetbundle_diff_print(diff, output);
77 | }
78 |
79 | public static bool SetFileSize(string file, uint length)
80 | {
81 | return filemapping_truncate(file, length);
82 | }
83 |
84 | public static string GetAppDataDir()
85 | {
86 | switch (Application.platform)
87 | {
88 | case RuntimePlatform.IPhonePlayer:
89 | return Directory.GetParent(Application.streamingAssetsPath).FullName;
90 |
91 | case RuntimePlatform.Android:
92 | return Path.Combine(Application.streamingAssetsPath, "bin/Data");
93 |
94 | default:
95 | throw new UnityException("Not support:" + Application.platform.ToString());
96 | }
97 | }
98 |
99 | #if UNITY_EDITOR
100 | public static string GetEditorAppDataDir(string clientPath, UnityEditor.BuildTarget target)
101 | {
102 | switch (target)
103 | {
104 | case UnityEditor.BuildTarget.iPhone:
105 | return Path.Combine(clientPath, "Payload/hero.app/Data");
106 |
107 | case UnityEditor.BuildTarget.Android:
108 | return Path.Combine(clientPath, "assets/bin/Data");
109 |
110 | default:
111 | throw new UnityException("Not support:" + Application.platform.ToString());
112 | }
113 | }
114 | #endif
115 |
116 | static bool TrySplitPath(string fullPath, ref string splitFileName, ref int splitIndex)
117 | {
118 | var match = ".split";
119 | var findIndex = fullPath.LastIndexOf(match);
120 | if (findIndex == -1)
121 | return false;
122 |
123 | var subPath = fullPath.Substring(0, findIndex);
124 | var indexStr = fullPath.Substring(findIndex + match.Length);
125 | var index = 0;
126 | if (!int.TryParse(indexStr, out index))
127 | return false;
128 |
129 | splitFileName = subPath;
130 | splitIndex = index;
131 | return true;
132 | }
133 |
134 | static string GetNextSplitPath(string splitFileName, ref int splitIndex)
135 | {
136 | splitIndex++;
137 | return string.Format("{0}.split{1}", splitFileName, splitIndex);
138 | }
139 |
140 | [AOT.MonoPInvokeCallback(typeof(ReadFileCallback))]
141 | static bool ReadFile(IntPtr buffer, string fileName, uint fileOffset, uint length, IntPtr userdata)
142 | {
143 | try
144 | {
145 | var fullPath = Path.Combine(AppDataDir, fileName);
146 | var offset = (int)fileOffset;
147 | var left = (int)length;
148 | var data = new byte[length];
149 | var splitFileName = string.Empty;
150 | var splitIndex = 0;
151 |
152 | while (left > 0)
153 | {
154 | Debug.Log("Merge from file:" + fullPath);
155 |
156 | using (var stream = FileEx.OpenRead(fullPath))
157 | {
158 | if (stream == null)
159 | {
160 | Debug.LogError("File not exist:" + fullPath);
161 | return false;
162 | }
163 |
164 | stream.Seek(offset, SeekOrigin.Begin);
165 | while (left > 0)
166 | {
167 | var ret = stream.Read(data, (int)length - left, left);
168 | if (ret <= 0)
169 | {
170 | if (string.IsNullOrEmpty(splitFileName))
171 | TrySplitPath(fullPath, ref splitFileName, ref splitIndex);
172 |
173 | if (string.IsNullOrEmpty(splitFileName))
174 | {
175 | Debug.LogError(string.Format("stream read failed. {0}, offset:{1}, length{2}, left:{3}", fileName, offset, length, left));
176 | return false;
177 | }
178 |
179 | fullPath = GetNextSplitPath(splitFileName, ref splitIndex);
180 | offset = 0;
181 | break;
182 | }
183 | left -= ret;
184 | }
185 | }
186 | }
187 |
188 | Marshal.Copy(data, 0, buffer, data.Length);
189 | return true;
190 | }
191 | catch(System.Exception e)
192 | {
193 | Debug.LogException(e);
194 | return false;
195 | }
196 | }
197 |
198 | static string AppDataDir;
199 |
200 | #if UNITY_IPHONE
201 | internal const string LIBNAME = "__Internal";
202 | #else
203 | internal const string LIBNAME = "AssetBundleParser";
204 | #endif
205 |
206 | [DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "assetbundle_load")]
207 | static extern IntPtr assetbundle_load(string file);
208 |
209 | [DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl, EntryPoint = "assetbundle_check")]
210 | static extern bool assetbundle_check(IntPtr bundle);
211 |
212 | [DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl, EntryPoint = "assetbundle_destroy")]
213 | static extern void assetbundle_destroy(IntPtr bundle);
214 |
215 | [DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "assetbundle_diff")]
216 | static extern int assetbundle_diff(string appDataDir, string fromAssetbundle, string toAssetbundle, string diff);
217 |
218 | delegate bool ReadFileCallback(IntPtr buffer, string fileName, uint offset, uint length, IntPtr userdata);
219 |
220 | [DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "assetbundle_merge")]
221 | static extern int assetbundle_merge(ReadFileCallback callback, IntPtr userdata, string fromAssetbundle, string toAssetbundle, string diff);
222 |
223 | [DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "assetbundle_diff_print")]
224 | static extern void assetbundle_diff_print(string filename, string output);
225 |
226 | [DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "filemapping_truncate")]
227 | static extern bool filemapping_truncate(string filename, uint length);
228 | }
229 | }
230 |
--------------------------------------------------------------------------------
/Assets/AssetBundlePatch/AssetBundlePatch.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c50e787b870c049c5a87ee1725e6a2f5
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Level1.unity:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/Assets/Level1.unity
--------------------------------------------------------------------------------
/Assets/Level1.unity.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 300cc774bd455470cba1303ae216b9eb
3 | DefaultImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/Assets/Level2.unity:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/Assets/Level2.unity
--------------------------------------------------------------------------------
/Assets/Level2.unity.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5459faf1402e842269af21598972ff1c
3 | DefaultImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/Assets/Plane1.mat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/Assets/Plane1.mat
--------------------------------------------------------------------------------
/Assets/Plane1.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ee5e25bacf97945bdb67cfd82c0d967c
3 | NativeFormatImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/Assets/Plane2.mat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/Assets/Plane2.mat
--------------------------------------------------------------------------------
/Assets/Plane2.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0e1f8588e459140acaac309e88fcfd42
3 | NativeFormatImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/Assets/Plugins.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c92a22cd038ab412d9d114f27240a1ae
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Plugins/Android.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0004c0a5ad641d4468ebb65779ee48b2
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Plugins/Android/libAssetBundleParser.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/Assets/Plugins/Android/libAssetBundleParser.so
--------------------------------------------------------------------------------
/Assets/Plugins/Android/libAssetBundleParser.so.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 3c88edaa3cfee4c4fa904ff79c3c7e8f
3 | DefaultImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/Assets/Plugins/AssetBundleParser.bundle.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 6214b14be0029470a9fe9105b6013267
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Plugins/AssetBundleParser.bundle/Contents.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 42a37ca4118c14c29855fcbd2d06384e
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Plugins/AssetBundleParser.bundle/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildMachineOSBuild
6 | 14C109
7 | CFBundleDevelopmentRegion
8 | English
9 | CFBundleExecutable
10 | AssetBundleParser
11 | CFBundleIdentifier
12 | lua.dpull.com
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | AssetBundleParser
17 | CFBundlePackageType
18 | BNDL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | CFPlugInDynamicRegisterFunction
26 |
27 | CFPlugInDynamicRegistration
28 | NO
29 | CFPlugInFactories
30 |
31 | 00000000-0000-0000-0000-000000000000
32 | MyFactoryFunction
33 |
34 | CFPlugInTypes
35 |
36 | 00000000-0000-0000-0000-000000000000
37 |
38 | 00000000-0000-0000-0000-000000000000
39 |
40 |
41 | CFPlugInUnloadFunction
42 |
43 | DTCompiler
44 | com.apple.compilers.llvm.clang.1_0
45 | DTPlatformBuild
46 | 6C131e
47 | DTPlatformVersion
48 | GM
49 | DTSDKBuild
50 | 14A383
51 | DTSDKName
52 | macosx10.10
53 | DTXcode
54 | 0620
55 | DTXcodeBuild
56 | 6C131e
57 | NSHumanReadableCopyright
58 | Copyright © 2014年 dpull. All rights reserved.
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Assets/Plugins/AssetBundleParser.bundle/Contents/Info.plist.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 89753a4000ee5452d8cd76eb79dce4bb
3 | DefaultImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/Assets/Plugins/AssetBundleParser.bundle/Contents/MacOS.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 82f2dc4a1a58342579676d8ced5f81de
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Plugins/AssetBundleParser.bundle/Contents/MacOS/AssetBundleParser:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/Assets/Plugins/AssetBundleParser.bundle/Contents/MacOS/AssetBundleParser
--------------------------------------------------------------------------------
/Assets/Plugins/AssetBundleParser.bundle/Contents/MacOS/AssetBundleParser.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 98f718bc01ad24cc6aa047a0f5714796
3 | DefaultImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/Assets/Plugins/AssetBundleParser.bundle/Contents/Resources.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4276ad4fbe4e64229b0f89ad138d2bb0
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Plugins/AssetBundleParser.bundle/Contents/Resources/en.lproj.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: bedaf6fb2711f4254a4abc5de0e94e1c
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Plugins/AssetBundleParser.bundle/Contents/Resources/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/Assets/Plugins/AssetBundleParser.bundle/Contents/Resources/en.lproj/InfoPlist.strings
--------------------------------------------------------------------------------
/Assets/Plugins/AssetBundleParser.bundle/Contents/Resources/en.lproj/InfoPlist.strings.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c66eb7b89cddf4b0f992fe56e53ecfd3
3 | DefaultImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/Assets/Plugins/iOS.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 3fe8320f4ef77a6419bcdffeb8a68556
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Plugins/iOS/libAssetBundleParser.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/Assets/Plugins/iOS/libAssetBundleParser.a
--------------------------------------------------------------------------------
/Assets/Plugins/iOS/libAssetBundleParser.a.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 964d63d0d926b4c0784052ae105470a6
3 | DefaultImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/Assets/Plugins/x86.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8b0b0c4ffe67d2f4292c5211de91e55f
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Plugins/x86/AssetBundleParser.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/Assets/Plugins/x86/AssetBundleParser.dll
--------------------------------------------------------------------------------
/Assets/Plugins/x86/AssetBundleParser.dll.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8035ebec9c8dd48eb912ec05d7973cb7
3 | DefaultImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/Assets/Plugins/x86_64.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7ea0a8e1f899b1148badb9e92b431566
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Plugins/x86_64/AssetBundleParser.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/Assets/Plugins/x86_64/AssetBundleParser.dll
--------------------------------------------------------------------------------
/Assets/Plugins/x86_64/AssetBundleParser.dll.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 43482e9e733214852adb6206de5ef9d6
3 | DefaultImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/Assets/Standard Assets.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 28a81280068924e63b40ae4748ddb321
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 54216e9ed42974e30967824b7f0b2806
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/3rd Person Controller.prefab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/Assets/Standard Assets/Character Controllers/3rd Person Controller.prefab
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/3rd Person Controller.prefab.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2314ce3a3eecf4816bad3c9eca4de2e1
3 | NativeFormatImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/First Person Controller.prefab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/Assets/Standard Assets/Character Controllers/First Person Controller.prefab
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/First Person Controller.prefab.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9d4133d5d30b644bd87802a347eaccbe
3 | NativeFormatImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7e0b0a994d8934541a387e092630b5db
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/PrototypeCharacter.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c81df2918c80c054ca3d436e62090893
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/PrototypeCharacter/Constructor.FBX:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/Assets/Standard Assets/Character Controllers/Sources/PrototypeCharacter/Constructor.FBX
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/PrototypeCharacter/Constructor.FBX.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 449b48f7eb5d87a4baaa5fb73f875a59
3 | ModelImporter:
4 | serializedVersion: 16
5 | fileIDToRecycleName:
6 | 100000: Bip001 R Finger1
7 | 100002: Bip001 R Finger21
8 | 100004: Bip001 R Finger11
9 | 100006: Bip001 R Finger02
10 | 100010: Bip001 R Finger12
11 | 100012: Bip001 R Finger41
12 | 100014: Bip001 R Finger4
13 | 100018: Bip001 R Finger32
14 | 100020: Bip001 R Finger31
15 | 100022: Bip001 R Finger3
16 | 100026: hip_adjustment_bone_right
17 | 100028: Bip001 R Finger42
18 | 100032: hip_adjustment_bone_left
19 | 100034: Bip001 R Finger2
20 | 100036: Bip001 R Finger22
21 | 100040: Bip001 R UpperArm
22 | 100042: Bip001 R Forearm
23 | 100044: Bip001 R Finger0
24 | 100046: Bip001 R Finger01
25 | 100052: //RootNode
26 | 100054: Bip001 R Clavicle
27 | 100058: Bip001 L Finger3
28 | 100060: Bip001 L Finger31
29 | 100062: Bip001 L Finger32
30 | 100066: Bip001 L Finger4
31 | 100068: Bip001 L Finger41
32 | 100070: Bip001 L Finger42
33 | 100074: Bip001 L Finger22
34 | 100076: Bip001 L Finger02
35 | 100080: Bip001 L Finger1
36 | 100082: Bip001 L Finger11
37 | 100084: Bip001 L Finger12
38 | 100088: Bip001 L Finger2
39 | 100090: Bip001 L Finger21
40 | 100092: Bip001 L Finger0
41 | 100094: Bip001 L Finger01
42 | 100096: Bip001 L Forearm
43 | 100098: Bip001 L UpperArm
44 | 100100: Bip001 L Clavicle
45 | 100102: construction_worker
46 | 100104: Bip001 R Toe0
47 | 100106: Bip001 R Foot
48 | 100108: Bip001 R Calf
49 | 100110: Bip001 R Thigh
50 | 100112: Bip001 L Toe0
51 | 100114: Bip001 L Foot
52 | 100116: Bip001 L Calf
53 | 100118: Bip001 L Thigh
54 | 100120: helmet_bone
55 | 100124: Bip001 Head
56 | 100126: wrench
57 | 100128: Bip001 R Hand
58 | 100130: Bip001 L Hand
59 | 100132: Bip001 Neck
60 | 100134: Bip001 Spine1
61 | 100136: Bip001 Spine
62 | 100138: Bip001 Pelvis
63 | 100140: Bip001
64 | 400000: Bip001 R Finger1
65 | 400002: Bip001 R Finger21
66 | 400004: Bip001 R Finger11
67 | 400006: Bip001 R Finger02
68 | 400010: Bip001 R Finger12
69 | 400012: Bip001 R Finger41
70 | 400014: Bip001 R Finger4
71 | 400018: Bip001 R Finger32
72 | 400020: Bip001 R Finger31
73 | 400022: Bip001 R Finger3
74 | 400026: hip_adjustment_bone_right
75 | 400028: Bip001 R Finger42
76 | 400032: hip_adjustment_bone_left
77 | 400034: Bip001 R Finger2
78 | 400036: Bip001 R Finger22
79 | 400040: Bip001 R UpperArm
80 | 400042: Bip001 R Forearm
81 | 400044: Bip001 R Finger0
82 | 400046: Bip001 R Finger01
83 | 400052: //RootNode
84 | 400054: Bip001 R Clavicle
85 | 400058: Bip001 L Finger3
86 | 400060: Bip001 L Finger31
87 | 400062: Bip001 L Finger32
88 | 400066: Bip001 L Finger4
89 | 400068: Bip001 L Finger41
90 | 400070: Bip001 L Finger42
91 | 400074: Bip001 L Finger22
92 | 400076: Bip001 L Finger02
93 | 400080: Bip001 L Finger1
94 | 400082: Bip001 L Finger11
95 | 400084: Bip001 L Finger12
96 | 400088: Bip001 L Finger2
97 | 400090: Bip001 L Finger21
98 | 400092: Bip001 L Finger0
99 | 400094: Bip001 L Finger01
100 | 400096: Bip001 L Forearm
101 | 400098: Bip001 L UpperArm
102 | 400100: Bip001 L Clavicle
103 | 400102: construction_worker
104 | 400104: Bip001 R Toe0
105 | 400106: Bip001 R Foot
106 | 400108: Bip001 R Calf
107 | 400110: Bip001 R Thigh
108 | 400112: Bip001 L Toe0
109 | 400114: Bip001 L Foot
110 | 400116: Bip001 L Calf
111 | 400118: Bip001 L Thigh
112 | 400120: helmet_bone
113 | 400124: Bip001 Head
114 | 400126: wrench
115 | 400128: Bip001 R Hand
116 | 400130: Bip001 L Hand
117 | 400132: Bip001 Neck
118 | 400134: Bip001 Spine1
119 | 400136: Bip001 Spine
120 | 400138: Bip001 Pelvis
121 | 400140: Bip001
122 | 2300000: wrench
123 | 3300000: wrench
124 | 4300000: construction_worker
125 | 4300002: wrench
126 | 7400012: idle
127 | 7400014: run
128 | 7400016: walk
129 | 7400018: jump_pose
130 | 11100000: //RootNode
131 | 13700000: Bip001 Pelvis
132 | materials:
133 | importMaterials: 1
134 | materialName: 3
135 | materialSearch: 1
136 | animations:
137 | legacyGenerateAnimations: 3
138 | bakeSimulation: 0
139 | optimizeGameObjects: 0
140 | motionNodeName:
141 | animationCompression: 0
142 | animationRotationError: .5
143 | animationPositionError: .5
144 | animationScaleError: .5
145 | animationWrapMode: 0
146 | extraExposedTransformPaths: []
147 | clipAnimations:
148 | - serializedVersion: 16
149 | name: idle
150 | takeName:
151 | firstFrame: 2
152 | lastFrame: 62
153 | wrapMode: 2
154 | orientationOffsetY: 0
155 | level: 0
156 | cycleOffset: 0
157 | loop: 0
158 | loopTime: 0
159 | loopBlend: 0
160 | loopBlendOrientation: 0
161 | loopBlendPositionY: 0
162 | loopBlendPositionXZ: 0
163 | keepOriginalOrientation: 0
164 | keepOriginalPositionY: 1
165 | keepOriginalPositionXZ: 0
166 | heightFromFeet: 0
167 | mirror: 0
168 | bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000
169 | curves: []
170 | events: []
171 | transformMask: []
172 | maskType: 0
173 | maskSource: {instanceID: 0}
174 | - serializedVersion: 16
175 | name: run
176 | takeName:
177 | firstFrame: 65
178 | lastFrame: 81
179 | wrapMode: 2
180 | orientationOffsetY: 0
181 | level: 0
182 | cycleOffset: 0
183 | loop: 0
184 | loopTime: 0
185 | loopBlend: 0
186 | loopBlendOrientation: 0
187 | loopBlendPositionY: 0
188 | loopBlendPositionXZ: 0
189 | keepOriginalOrientation: 0
190 | keepOriginalPositionY: 1
191 | keepOriginalPositionXZ: 0
192 | heightFromFeet: 0
193 | mirror: 0
194 | bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000
195 | curves: []
196 | events: []
197 | transformMask: []
198 | maskType: 0
199 | maskSource: {instanceID: 0}
200 | - serializedVersion: 16
201 | name: walk
202 | takeName:
203 | firstFrame: 84
204 | lastFrame: 116
205 | wrapMode: 2
206 | orientationOffsetY: 0
207 | level: 0
208 | cycleOffset: 0
209 | loop: 0
210 | loopTime: 0
211 | loopBlend: 0
212 | loopBlendOrientation: 0
213 | loopBlendPositionY: 0
214 | loopBlendPositionXZ: 0
215 | keepOriginalOrientation: 0
216 | keepOriginalPositionY: 1
217 | keepOriginalPositionXZ: 0
218 | heightFromFeet: 0
219 | mirror: 0
220 | bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000
221 | curves: []
222 | events: []
223 | transformMask: []
224 | maskType: 0
225 | maskSource: {instanceID: 0}
226 | - serializedVersion: 16
227 | name: jump_pose
228 | takeName:
229 | firstFrame: 118
230 | lastFrame: 123
231 | wrapMode: 0
232 | orientationOffsetY: 0
233 | level: 0
234 | cycleOffset: 0
235 | loop: 0
236 | loopTime: 0
237 | loopBlend: 0
238 | loopBlendOrientation: 0
239 | loopBlendPositionY: 0
240 | loopBlendPositionXZ: 0
241 | keepOriginalOrientation: 0
242 | keepOriginalPositionY: 1
243 | keepOriginalPositionXZ: 0
244 | heightFromFeet: 0
245 | mirror: 0
246 | bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000
247 | curves: []
248 | events: []
249 | transformMask: []
250 | maskType: 0
251 | maskSource: {instanceID: 0}
252 | isReadable: 1
253 | meshes:
254 | lODScreenPercentages: []
255 | globalScale: .00999999978
256 | meshCompression: 0
257 | addColliders: 0
258 | importBlendShapes: 1
259 | swapUVChannels: 0
260 | generateSecondaryUV: 0
261 | useFileUnits: 1
262 | optimizeMeshForGPU: 1
263 | weldVertices: 1
264 | secondaryUVAngleDistortion: 8
265 | secondaryUVAreaDistortion: 15.000001
266 | secondaryUVHardAngle: 88
267 | secondaryUVPackMargin: 4
268 | tangentSpace:
269 | normalSmoothAngle: 60
270 | splitTangentsAcrossUV: 1
271 | normalImportMode: 0
272 | tangentImportMode: 1
273 | importAnimation: 1
274 | copyAvatar: 0
275 | humanDescription:
276 | human: []
277 | skeleton: []
278 | armTwist: .5
279 | foreArmTwist: .5
280 | upperLegTwist: .5
281 | legTwist: .5
282 | armStretch: .0500000007
283 | legStretch: .0500000007
284 | feetSpacing: 0
285 | rootMotionBoneName:
286 | lastHumanDescriptionAvatarSource: {instanceID: 0}
287 | animationType: 1
288 | additionalBone: 0
289 | userData:
290 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/PrototypeCharacter/Materials.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e53c8c3dcc4ff59438bc9e86cb45c3f6
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/PrototypeCharacter/Materials/constructor_done.mat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/Assets/Standard Assets/Character Controllers/Sources/PrototypeCharacter/Materials/constructor_done.mat
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/PrototypeCharacter/Materials/constructor_done.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ca49380a71a2bb64c830d06bd421b9d1
3 | NativeFormatImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/PrototypeCharacter/Textures.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b365e6042890d4b1987423ed6bb8a08c
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/PrototypeCharacter/Textures/constructor_diffuse.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/Assets/Standard Assets/Character Controllers/Sources/PrototypeCharacter/Textures/constructor_diffuse.png
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/PrototypeCharacter/Textures/constructor_diffuse.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 97b050d43ac7c4d2b9f6cbb587650761
3 | TextureImporter:
4 | fileIDToRecycleName: {}
5 | serializedVersion: 2
6 | mipmaps:
7 | mipMapMode: 0
8 | enableMipMap: 1
9 | linearTexture: 0
10 | correctGamma: 0
11 | fadeOut: 0
12 | borderMipMap: 0
13 | mipMapFadeDistanceStart: 1
14 | mipMapFadeDistanceEnd: 3
15 | bumpmap:
16 | convertToNormalMap: 0
17 | externalNormalMap: 0
18 | heightScale: .25
19 | normalMapFilter: 0
20 | isReadable: 0
21 | grayScaleToAlpha: 0
22 | generateCubemap: 0
23 | seamlessCubemap: 0
24 | textureFormat: -1
25 | maxTextureSize: 1024
26 | textureSettings:
27 | filterMode: -1
28 | aniso: -1
29 | mipBias: -1
30 | wrapMode: -1
31 | nPOTScale: 1
32 | lightmap: 0
33 | compressionQuality: 50
34 | spriteMode: 0
35 | spriteExtrude: 1
36 | spriteMeshType: 1
37 | alignment: 0
38 | spritePivot: {x: .5, y: .5}
39 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
40 | spritePixelsToUnits: 100
41 | alphaIsTransparency: 0
42 | textureType: -1
43 | buildTargetSettings: []
44 | spriteSheet:
45 | sprites: []
46 | spritePackingTag:
47 | userData:
48 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/PrototypeCharacter/Textures/constructor_normals.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/Assets/Standard Assets/Character Controllers/Sources/PrototypeCharacter/Textures/constructor_normals.png
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/PrototypeCharacter/Textures/constructor_normals.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 531c14f8d5cdc4e5baa83ee6e16f783a
3 | TextureImporter:
4 | fileIDToRecycleName: {}
5 | serializedVersion: 2
6 | mipmaps:
7 | mipMapMode: 0
8 | enableMipMap: 1
9 | linearTexture: 1
10 | correctGamma: 0
11 | fadeOut: 0
12 | borderMipMap: 0
13 | mipMapFadeDistanceStart: 1
14 | mipMapFadeDistanceEnd: 3
15 | bumpmap:
16 | convertToNormalMap: 0
17 | externalNormalMap: 1
18 | heightScale: .25
19 | normalMapFilter: 0
20 | isReadable: 0
21 | grayScaleToAlpha: 0
22 | generateCubemap: 0
23 | seamlessCubemap: 0
24 | textureFormat: -1
25 | maxTextureSize: 1024
26 | textureSettings:
27 | filterMode: 1
28 | aniso: -1
29 | mipBias: -1
30 | wrapMode: -1
31 | nPOTScale: 1
32 | lightmap: 0
33 | compressionQuality: 50
34 | spriteMode: 0
35 | spriteExtrude: 1
36 | spriteMeshType: 1
37 | alignment: 0
38 | spritePivot: {x: .5, y: .5}
39 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
40 | spritePixelsToUnits: 100
41 | alphaIsTransparency: 0
42 | textureType: 1
43 | buildTargetSettings: []
44 | spriteSheet:
45 | sprites: []
46 | spritePackingTag:
47 | userData:
48 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/Scripts.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f781c091d1c8647c380d5230adfaee54
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/Scripts/CharacterMotor.js:
--------------------------------------------------------------------------------
1 | #pragma strict
2 | #pragma implicit
3 | #pragma downcast
4 |
5 | // Does this script currently respond to input?
6 | var canControl : boolean = true;
7 |
8 | var useFixedUpdate : boolean = true;
9 |
10 | // For the next variables, @System.NonSerialized tells Unity to not serialize the variable or show it in the inspector view.
11 | // Very handy for organization!
12 |
13 | // The current global direction we want the character to move in.
14 | @System.NonSerialized
15 | var inputMoveDirection : Vector3 = Vector3.zero;
16 |
17 | // Is the jump button held down? We use this interface instead of checking
18 | // for the jump button directly so this script can also be used by AIs.
19 | @System.NonSerialized
20 | var inputJump : boolean = false;
21 |
22 | class CharacterMotorMovement {
23 | // The maximum horizontal speed when moving
24 | var maxForwardSpeed : float = 10.0;
25 | var maxSidewaysSpeed : float = 10.0;
26 | var maxBackwardsSpeed : float = 10.0;
27 |
28 | // Curve for multiplying speed based on slope (negative = downwards)
29 | var slopeSpeedMultiplier : AnimationCurve = AnimationCurve(Keyframe(-90, 1), Keyframe(0, 1), Keyframe(90, 0));
30 |
31 | // How fast does the character change speeds? Higher is faster.
32 | var maxGroundAcceleration : float = 30.0;
33 | var maxAirAcceleration : float = 20.0;
34 |
35 | // The gravity for the character
36 | var gravity : float = 10.0;
37 | var maxFallSpeed : float = 20.0;
38 |
39 | // For the next variables, @System.NonSerialized tells Unity to not serialize the variable or show it in the inspector view.
40 | // Very handy for organization!
41 |
42 | // The last collision flags returned from controller.Move
43 | @System.NonSerialized
44 | var collisionFlags : CollisionFlags;
45 |
46 | // We will keep track of the character's current velocity,
47 | @System.NonSerialized
48 | var velocity : Vector3;
49 |
50 | // This keeps track of our current velocity while we're not grounded
51 | @System.NonSerialized
52 | var frameVelocity : Vector3 = Vector3.zero;
53 |
54 | @System.NonSerialized
55 | var hitPoint : Vector3 = Vector3.zero;
56 |
57 | @System.NonSerialized
58 | var lastHitPoint : Vector3 = Vector3(Mathf.Infinity, 0, 0);
59 | }
60 |
61 | var movement : CharacterMotorMovement = CharacterMotorMovement();
62 |
63 | enum MovementTransferOnJump {
64 | None, // The jump is not affected by velocity of floor at all.
65 | InitTransfer, // Jump gets its initial velocity from the floor, then gradualy comes to a stop.
66 | PermaTransfer, // Jump gets its initial velocity from the floor, and keeps that velocity until landing.
67 | PermaLocked // Jump is relative to the movement of the last touched floor and will move together with that floor.
68 | }
69 |
70 | // We will contain all the jumping related variables in one helper class for clarity.
71 | class CharacterMotorJumping {
72 | // Can the character jump?
73 | var enabled : boolean = true;
74 |
75 | // How high do we jump when pressing jump and letting go immediately
76 | var baseHeight : float = 1.0;
77 |
78 | // We add extraHeight units (meters) on top when holding the button down longer while jumping
79 | var extraHeight : float = 4.1;
80 |
81 | // How much does the character jump out perpendicular to the surface on walkable surfaces?
82 | // 0 means a fully vertical jump and 1 means fully perpendicular.
83 | var perpAmount : float = 0.0;
84 |
85 | // How much does the character jump out perpendicular to the surface on too steep surfaces?
86 | // 0 means a fully vertical jump and 1 means fully perpendicular.
87 | var steepPerpAmount : float = 0.5;
88 |
89 | // For the next variables, @System.NonSerialized tells Unity to not serialize the variable or show it in the inspector view.
90 | // Very handy for organization!
91 |
92 | // Are we jumping? (Initiated with jump button and not grounded yet)
93 | // To see if we are just in the air (initiated by jumping OR falling) see the grounded variable.
94 | @System.NonSerialized
95 | var jumping : boolean = false;
96 |
97 | @System.NonSerialized
98 | var holdingJumpButton : boolean = false;
99 |
100 | // the time we jumped at (Used to determine for how long to apply extra jump power after jumping.)
101 | @System.NonSerialized
102 | var lastStartTime : float = 0.0;
103 |
104 | @System.NonSerialized
105 | var lastButtonDownTime : float = -100;
106 |
107 | @System.NonSerialized
108 | var jumpDir : Vector3 = Vector3.up;
109 | }
110 |
111 | var jumping : CharacterMotorJumping = CharacterMotorJumping();
112 |
113 | class CharacterMotorMovingPlatform {
114 | var enabled : boolean = true;
115 |
116 | var movementTransfer : MovementTransferOnJump = MovementTransferOnJump.PermaTransfer;
117 |
118 | @System.NonSerialized
119 | var hitPlatform : Transform;
120 |
121 | @System.NonSerialized
122 | var activePlatform : Transform;
123 |
124 | @System.NonSerialized
125 | var activeLocalPoint : Vector3;
126 |
127 | @System.NonSerialized
128 | var activeGlobalPoint : Vector3;
129 |
130 | @System.NonSerialized
131 | var activeLocalRotation : Quaternion;
132 |
133 | @System.NonSerialized
134 | var activeGlobalRotation : Quaternion;
135 |
136 | @System.NonSerialized
137 | var lastMatrix : Matrix4x4;
138 |
139 | @System.NonSerialized
140 | var platformVelocity : Vector3;
141 |
142 | @System.NonSerialized
143 | var newPlatform : boolean;
144 | }
145 |
146 | var movingPlatform : CharacterMotorMovingPlatform = CharacterMotorMovingPlatform();
147 |
148 | class CharacterMotorSliding {
149 | // Does the character slide on too steep surfaces?
150 | var enabled : boolean = true;
151 |
152 | // How fast does the character slide on steep surfaces?
153 | var slidingSpeed : float = 15;
154 |
155 | // How much can the player control the sliding direction?
156 | // If the value is 0.5 the player can slide sideways with half the speed of the downwards sliding speed.
157 | var sidewaysControl : float = 1.0;
158 |
159 | // How much can the player influence the sliding speed?
160 | // If the value is 0.5 the player can speed the sliding up to 150% or slow it down to 50%.
161 | var speedControl : float = 0.4;
162 | }
163 |
164 | var sliding : CharacterMotorSliding = CharacterMotorSliding();
165 |
166 | @System.NonSerialized
167 | var grounded : boolean = true;
168 |
169 | @System.NonSerialized
170 | var groundNormal : Vector3 = Vector3.zero;
171 |
172 | private var lastGroundNormal : Vector3 = Vector3.zero;
173 |
174 | private var tr : Transform;
175 |
176 | private var controller : CharacterController;
177 |
178 | function Awake () {
179 | controller = GetComponent (CharacterController);
180 | tr = transform;
181 | }
182 |
183 | private function UpdateFunction () {
184 | // We copy the actual velocity into a temporary variable that we can manipulate.
185 | var velocity : Vector3 = movement.velocity;
186 |
187 | // Update velocity based on input
188 | velocity = ApplyInputVelocityChange(velocity);
189 |
190 | // Apply gravity and jumping force
191 | velocity = ApplyGravityAndJumping (velocity);
192 |
193 | // Moving platform support
194 | var moveDistance : Vector3 = Vector3.zero;
195 | if (MoveWithPlatform()) {
196 | var newGlobalPoint : Vector3 = movingPlatform.activePlatform.TransformPoint(movingPlatform.activeLocalPoint);
197 | moveDistance = (newGlobalPoint - movingPlatform.activeGlobalPoint);
198 | if (moveDistance != Vector3.zero)
199 | controller.Move(moveDistance);
200 |
201 | // Support moving platform rotation as well:
202 | var newGlobalRotation : Quaternion = movingPlatform.activePlatform.rotation * movingPlatform.activeLocalRotation;
203 | var rotationDiff : Quaternion = newGlobalRotation * Quaternion.Inverse(movingPlatform.activeGlobalRotation);
204 |
205 | var yRotation = rotationDiff.eulerAngles.y;
206 | if (yRotation != 0) {
207 | // Prevent rotation of the local up vector
208 | tr.Rotate(0, yRotation, 0);
209 | }
210 | }
211 |
212 | // Save lastPosition for velocity calculation.
213 | var lastPosition : Vector3 = tr.position;
214 |
215 | // We always want the movement to be framerate independent. Multiplying by Time.deltaTime does this.
216 | var currentMovementOffset : Vector3 = velocity * Time.deltaTime;
217 |
218 | // Find out how much we need to push towards the ground to avoid loosing grouning
219 | // when walking down a step or over a sharp change in slope.
220 | var pushDownOffset : float = Mathf.Max(controller.stepOffset, Vector3(currentMovementOffset.x, 0, currentMovementOffset.z).magnitude);
221 | if (grounded)
222 | currentMovementOffset -= pushDownOffset * Vector3.up;
223 |
224 | // Reset variables that will be set by collision function
225 | movingPlatform.hitPlatform = null;
226 | groundNormal = Vector3.zero;
227 |
228 | // Move our character!
229 | movement.collisionFlags = controller.Move (currentMovementOffset);
230 |
231 | movement.lastHitPoint = movement.hitPoint;
232 | lastGroundNormal = groundNormal;
233 |
234 | if (movingPlatform.enabled && movingPlatform.activePlatform != movingPlatform.hitPlatform) {
235 | if (movingPlatform.hitPlatform != null) {
236 | movingPlatform.activePlatform = movingPlatform.hitPlatform;
237 | movingPlatform.lastMatrix = movingPlatform.hitPlatform.localToWorldMatrix;
238 | movingPlatform.newPlatform = true;
239 | }
240 | }
241 |
242 | // Calculate the velocity based on the current and previous position.
243 | // This means our velocity will only be the amount the character actually moved as a result of collisions.
244 | var oldHVelocity : Vector3 = new Vector3(velocity.x, 0, velocity.z);
245 | movement.velocity = (tr.position - lastPosition) / Time.deltaTime;
246 | var newHVelocity : Vector3 = new Vector3(movement.velocity.x, 0, movement.velocity.z);
247 |
248 | // The CharacterController can be moved in unwanted directions when colliding with things.
249 | // We want to prevent this from influencing the recorded velocity.
250 | if (oldHVelocity == Vector3.zero) {
251 | movement.velocity = new Vector3(0, movement.velocity.y, 0);
252 | }
253 | else {
254 | var projectedNewVelocity : float = Vector3.Dot(newHVelocity, oldHVelocity) / oldHVelocity.sqrMagnitude;
255 | movement.velocity = oldHVelocity * Mathf.Clamp01(projectedNewVelocity) + movement.velocity.y * Vector3.up;
256 | }
257 |
258 | if (movement.velocity.y < velocity.y - 0.001) {
259 | if (movement.velocity.y < 0) {
260 | // Something is forcing the CharacterController down faster than it should.
261 | // Ignore this
262 | movement.velocity.y = velocity.y;
263 | }
264 | else {
265 | // The upwards movement of the CharacterController has been blocked.
266 | // This is treated like a ceiling collision - stop further jumping here.
267 | jumping.holdingJumpButton = false;
268 | }
269 | }
270 |
271 | // We were grounded but just loosed grounding
272 | if (grounded && !IsGroundedTest()) {
273 | grounded = false;
274 |
275 | // Apply inertia from platform
276 | if (movingPlatform.enabled &&
277 | (movingPlatform.movementTransfer == MovementTransferOnJump.InitTransfer ||
278 | movingPlatform.movementTransfer == MovementTransferOnJump.PermaTransfer)
279 | ) {
280 | movement.frameVelocity = movingPlatform.platformVelocity;
281 | movement.velocity += movingPlatform.platformVelocity;
282 | }
283 |
284 | SendMessage("OnFall", SendMessageOptions.DontRequireReceiver);
285 | // We pushed the character down to ensure it would stay on the ground if there was any.
286 | // But there wasn't so now we cancel the downwards offset to make the fall smoother.
287 | tr.position += pushDownOffset * Vector3.up;
288 | }
289 | // We were not grounded but just landed on something
290 | else if (!grounded && IsGroundedTest()) {
291 | grounded = true;
292 | jumping.jumping = false;
293 | SubtractNewPlatformVelocity();
294 |
295 | SendMessage("OnLand", SendMessageOptions.DontRequireReceiver);
296 | }
297 |
298 | // Moving platforms support
299 | if (MoveWithPlatform()) {
300 | // Use the center of the lower half sphere of the capsule as reference point.
301 | // This works best when the character is standing on moving tilting platforms.
302 | movingPlatform.activeGlobalPoint = tr.position + Vector3.up * (controller.center.y - controller.height*0.5 + controller.radius);
303 | movingPlatform.activeLocalPoint = movingPlatform.activePlatform.InverseTransformPoint(movingPlatform.activeGlobalPoint);
304 |
305 | // Support moving platform rotation as well:
306 | movingPlatform.activeGlobalRotation = tr.rotation;
307 | movingPlatform.activeLocalRotation = Quaternion.Inverse(movingPlatform.activePlatform.rotation) * movingPlatform.activeGlobalRotation;
308 | }
309 | }
310 |
311 | function FixedUpdate () {
312 | if (movingPlatform.enabled) {
313 | if (movingPlatform.activePlatform != null) {
314 | if (!movingPlatform.newPlatform) {
315 | var lastVelocity : Vector3 = movingPlatform.platformVelocity;
316 |
317 | movingPlatform.platformVelocity = (
318 | movingPlatform.activePlatform.localToWorldMatrix.MultiplyPoint3x4(movingPlatform.activeLocalPoint)
319 | - movingPlatform.lastMatrix.MultiplyPoint3x4(movingPlatform.activeLocalPoint)
320 | ) / Time.deltaTime;
321 | }
322 | movingPlatform.lastMatrix = movingPlatform.activePlatform.localToWorldMatrix;
323 | movingPlatform.newPlatform = false;
324 | }
325 | else {
326 | movingPlatform.platformVelocity = Vector3.zero;
327 | }
328 | }
329 |
330 | if (useFixedUpdate)
331 | UpdateFunction();
332 | }
333 |
334 | function Update () {
335 | if (!useFixedUpdate)
336 | UpdateFunction();
337 | }
338 |
339 | private function ApplyInputVelocityChange (velocity : Vector3) {
340 | if (!canControl)
341 | inputMoveDirection = Vector3.zero;
342 |
343 | // Find desired velocity
344 | var desiredVelocity : Vector3;
345 | if (grounded && TooSteep()) {
346 | // The direction we're sliding in
347 | desiredVelocity = Vector3(groundNormal.x, 0, groundNormal.z).normalized;
348 | // Find the input movement direction projected onto the sliding direction
349 | var projectedMoveDir = Vector3.Project(inputMoveDirection, desiredVelocity);
350 | // Add the sliding direction, the spped control, and the sideways control vectors
351 | desiredVelocity = desiredVelocity + projectedMoveDir * sliding.speedControl + (inputMoveDirection - projectedMoveDir) * sliding.sidewaysControl;
352 | // Multiply with the sliding speed
353 | desiredVelocity *= sliding.slidingSpeed;
354 | }
355 | else
356 | desiredVelocity = GetDesiredHorizontalVelocity();
357 |
358 | if (movingPlatform.enabled && movingPlatform.movementTransfer == MovementTransferOnJump.PermaTransfer) {
359 | desiredVelocity += movement.frameVelocity;
360 | desiredVelocity.y = 0;
361 | }
362 |
363 | if (grounded)
364 | desiredVelocity = AdjustGroundVelocityToNormal(desiredVelocity, groundNormal);
365 | else
366 | velocity.y = 0;
367 |
368 | // Enforce max velocity change
369 | var maxVelocityChange : float = GetMaxAcceleration(grounded) * Time.deltaTime;
370 | var velocityChangeVector : Vector3 = (desiredVelocity - velocity);
371 | if (velocityChangeVector.sqrMagnitude > maxVelocityChange * maxVelocityChange) {
372 | velocityChangeVector = velocityChangeVector.normalized * maxVelocityChange;
373 | }
374 | // If we're in the air and don't have control, don't apply any velocity change at all.
375 | // If we're on the ground and don't have control we do apply it - it will correspond to friction.
376 | if (grounded || canControl)
377 | velocity += velocityChangeVector;
378 |
379 | if (grounded) {
380 | // When going uphill, the CharacterController will automatically move up by the needed amount.
381 | // Not moving it upwards manually prevent risk of lifting off from the ground.
382 | // When going downhill, DO move down manually, as gravity is not enough on steep hills.
383 | velocity.y = Mathf.Min(velocity.y, 0);
384 | }
385 |
386 | return velocity;
387 | }
388 |
389 | private function ApplyGravityAndJumping (velocity : Vector3) {
390 |
391 | if (!inputJump || !canControl) {
392 | jumping.holdingJumpButton = false;
393 | jumping.lastButtonDownTime = -100;
394 | }
395 |
396 | if (inputJump && jumping.lastButtonDownTime < 0 && canControl)
397 | jumping.lastButtonDownTime = Time.time;
398 |
399 | if (grounded)
400 | velocity.y = Mathf.Min(0, velocity.y) - movement.gravity * Time.deltaTime;
401 | else {
402 | velocity.y = movement.velocity.y - movement.gravity * Time.deltaTime;
403 |
404 | // When jumping up we don't apply gravity for some time when the user is holding the jump button.
405 | // This gives more control over jump height by pressing the button longer.
406 | if (jumping.jumping && jumping.holdingJumpButton) {
407 | // Calculate the duration that the extra jump force should have effect.
408 | // If we're still less than that duration after the jumping time, apply the force.
409 | if (Time.time < jumping.lastStartTime + jumping.extraHeight / CalculateJumpVerticalSpeed(jumping.baseHeight)) {
410 | // Negate the gravity we just applied, except we push in jumpDir rather than jump upwards.
411 | velocity += jumping.jumpDir * movement.gravity * Time.deltaTime;
412 | }
413 | }
414 |
415 | // Make sure we don't fall any faster than maxFallSpeed. This gives our character a terminal velocity.
416 | velocity.y = Mathf.Max (velocity.y, -movement.maxFallSpeed);
417 | }
418 |
419 | if (grounded) {
420 | // Jump only if the jump button was pressed down in the last 0.2 seconds.
421 | // We use this check instead of checking if it's pressed down right now
422 | // because players will often try to jump in the exact moment when hitting the ground after a jump
423 | // and if they hit the button a fraction of a second too soon and no new jump happens as a consequence,
424 | // it's confusing and it feels like the game is buggy.
425 | if (jumping.enabled && canControl && (Time.time - jumping.lastButtonDownTime < 0.2)) {
426 | grounded = false;
427 | jumping.jumping = true;
428 | jumping.lastStartTime = Time.time;
429 | jumping.lastButtonDownTime = -100;
430 | jumping.holdingJumpButton = true;
431 |
432 | // Calculate the jumping direction
433 | if (TooSteep())
434 | jumping.jumpDir = Vector3.Slerp(Vector3.up, groundNormal, jumping.steepPerpAmount);
435 | else
436 | jumping.jumpDir = Vector3.Slerp(Vector3.up, groundNormal, jumping.perpAmount);
437 |
438 | // Apply the jumping force to the velocity. Cancel any vertical velocity first.
439 | velocity.y = 0;
440 | velocity += jumping.jumpDir * CalculateJumpVerticalSpeed (jumping.baseHeight);
441 |
442 | // Apply inertia from platform
443 | if (movingPlatform.enabled &&
444 | (movingPlatform.movementTransfer == MovementTransferOnJump.InitTransfer ||
445 | movingPlatform.movementTransfer == MovementTransferOnJump.PermaTransfer)
446 | ) {
447 | movement.frameVelocity = movingPlatform.platformVelocity;
448 | velocity += movingPlatform.platformVelocity;
449 | }
450 |
451 | SendMessage("OnJump", SendMessageOptions.DontRequireReceiver);
452 | }
453 | else {
454 | jumping.holdingJumpButton = false;
455 | }
456 | }
457 |
458 | return velocity;
459 | }
460 |
461 | function OnControllerColliderHit (hit : ControllerColliderHit) {
462 | if (hit.normal.y > 0 && hit.normal.y > groundNormal.y && hit.moveDirection.y < 0) {
463 | if ((hit.point - movement.lastHitPoint).sqrMagnitude > 0.001 || lastGroundNormal == Vector3.zero)
464 | groundNormal = hit.normal;
465 | else
466 | groundNormal = lastGroundNormal;
467 |
468 | movingPlatform.hitPlatform = hit.collider.transform;
469 | movement.hitPoint = hit.point;
470 | movement.frameVelocity = Vector3.zero;
471 | }
472 | }
473 |
474 | private function SubtractNewPlatformVelocity () {
475 | // When landing, subtract the velocity of the new ground from the character's velocity
476 | // since movement in ground is relative to the movement of the ground.
477 | if (movingPlatform.enabled &&
478 | (movingPlatform.movementTransfer == MovementTransferOnJump.InitTransfer ||
479 | movingPlatform.movementTransfer == MovementTransferOnJump.PermaTransfer)
480 | ) {
481 | // If we landed on a new platform, we have to wait for two FixedUpdates
482 | // before we know the velocity of the platform under the character
483 | if (movingPlatform.newPlatform) {
484 | var platform : Transform = movingPlatform.activePlatform;
485 | yield WaitForFixedUpdate();
486 | yield WaitForFixedUpdate();
487 | if (grounded && platform == movingPlatform.activePlatform)
488 | yield 1;
489 | }
490 | movement.velocity -= movingPlatform.platformVelocity;
491 | }
492 | }
493 |
494 | private function MoveWithPlatform () : boolean {
495 | return (
496 | movingPlatform.enabled
497 | && (grounded || movingPlatform.movementTransfer == MovementTransferOnJump.PermaLocked)
498 | && movingPlatform.activePlatform != null
499 | );
500 | }
501 |
502 | private function GetDesiredHorizontalVelocity () {
503 | // Find desired velocity
504 | var desiredLocalDirection : Vector3 = tr.InverseTransformDirection(inputMoveDirection);
505 | var maxSpeed : float = MaxSpeedInDirection(desiredLocalDirection);
506 | if (grounded) {
507 | // Modify max speed on slopes based on slope speed multiplier curve
508 | var movementSlopeAngle = Mathf.Asin(movement.velocity.normalized.y) * Mathf.Rad2Deg;
509 | maxSpeed *= movement.slopeSpeedMultiplier.Evaluate(movementSlopeAngle);
510 | }
511 | return tr.TransformDirection(desiredLocalDirection * maxSpeed);
512 | }
513 |
514 | private function AdjustGroundVelocityToNormal (hVelocity : Vector3, groundNormal : Vector3) : Vector3 {
515 | var sideways : Vector3 = Vector3.Cross(Vector3.up, hVelocity);
516 | return Vector3.Cross(sideways, groundNormal).normalized * hVelocity.magnitude;
517 | }
518 |
519 | private function IsGroundedTest () {
520 | return (groundNormal.y > 0.01);
521 | }
522 |
523 | function GetMaxAcceleration (grounded : boolean) : float {
524 | // Maximum acceleration on ground and in air
525 | if (grounded)
526 | return movement.maxGroundAcceleration;
527 | else
528 | return movement.maxAirAcceleration;
529 | }
530 |
531 | function CalculateJumpVerticalSpeed (targetJumpHeight : float) {
532 | // From the jump height and gravity we deduce the upwards speed
533 | // for the character to reach at the apex.
534 | return Mathf.Sqrt (2 * targetJumpHeight * movement.gravity);
535 | }
536 |
537 | function IsJumping () {
538 | return jumping.jumping;
539 | }
540 |
541 | function IsSliding () {
542 | return (grounded && sliding.enabled && TooSteep());
543 | }
544 |
545 | function IsTouchingCeiling () {
546 | return (movement.collisionFlags & CollisionFlags.CollidedAbove) != 0;
547 | }
548 |
549 | function IsGrounded () {
550 | return grounded;
551 | }
552 |
553 | function TooSteep () {
554 | return (groundNormal.y <= Mathf.Cos(controller.slopeLimit * Mathf.Deg2Rad));
555 | }
556 |
557 | function GetDirection () {
558 | return inputMoveDirection;
559 | }
560 |
561 | function SetControllable (controllable : boolean) {
562 | canControl = controllable;
563 | }
564 |
565 | // Project a direction onto elliptical quater segments based on forward, sideways, and backwards speed.
566 | // The function returns the length of the resulting vector.
567 | function MaxSpeedInDirection (desiredMovementDirection : Vector3) : float {
568 | if (desiredMovementDirection == Vector3.zero)
569 | return 0;
570 | else {
571 | var zAxisEllipseMultiplier : float = (desiredMovementDirection.z > 0 ? movement.maxForwardSpeed : movement.maxBackwardsSpeed) / movement.maxSidewaysSpeed;
572 | var temp : Vector3 = new Vector3(desiredMovementDirection.x, 0, desiredMovementDirection.z / zAxisEllipseMultiplier).normalized;
573 | var length : float = new Vector3(temp.x, 0, temp.z * zAxisEllipseMultiplier).magnitude * movement.maxSidewaysSpeed;
574 | return length;
575 | }
576 | }
577 |
578 | function SetVelocity (velocity : Vector3) {
579 | grounded = false;
580 | movement.velocity = velocity;
581 | movement.frameVelocity = Vector3.zero;
582 | SendMessage("OnExternalVelocity");
583 | }
584 |
585 | // Require a character controller to be attached to the same game object
586 | @script RequireComponent (CharacterController)
587 | @script AddComponentMenu ("Character/Character Motor")
588 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/Scripts/CharacterMotor.js.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0ab79d7f243824f5d9826bd83522c8df
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/Scripts/FPSInputController.js:
--------------------------------------------------------------------------------
1 | private var motor : CharacterMotor;
2 |
3 | // Use this for initialization
4 | function Awake () {
5 | motor = GetComponent(CharacterMotor);
6 | }
7 |
8 | // Update is called once per frame
9 | function Update () {
10 | // Get the input vector from keyboard or analog stick
11 | var directionVector = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
12 |
13 | if (directionVector != Vector3.zero) {
14 | // Get the length of the directon vector and then normalize it
15 | // Dividing by the length is cheaper than normalizing when we already have the length anyway
16 | var directionLength = directionVector.magnitude;
17 | directionVector = directionVector / directionLength;
18 |
19 | // Make sure the length is no bigger than 1
20 | directionLength = Mathf.Min(1, directionLength);
21 |
22 | // Make the input vector more sensitive towards the extremes and less sensitive in the middle
23 | // This makes it easier to control slow speeds when using analog sticks
24 | directionLength = directionLength * directionLength;
25 |
26 | // Multiply the normalized direction vector by the modified length
27 | directionVector = directionVector * directionLength;
28 | }
29 |
30 | // Apply the direction to the CharacterMotor
31 | motor.inputMoveDirection = transform.rotation * directionVector;
32 | motor.inputJump = Input.GetButton("Jump");
33 | }
34 |
35 | // Require a character controller to be attached to the same game object
36 | @script RequireComponent (CharacterMotor)
37 | @script AddComponentMenu ("Character/FPS Input Controller")
38 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/Scripts/FPSInputController.js.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 60bca8f58a0b8478e946e6e86658cb29
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/Scripts/MouseLook.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections;
3 |
4 | /// MouseLook rotates the transform based on the mouse delta.
5 | /// Minimum and Maximum values can be used to constrain the possible rotation
6 |
7 | /// To make an FPS style character:
8 | /// - Create a capsule.
9 | /// - Add the MouseLook script to the capsule.
10 | /// -> Set the mouse look to use LookX. (You want to only turn character but not tilt it)
11 | /// - Add FPSInputController script to the capsule
12 | /// -> A CharacterMotor and a CharacterController component will be automatically added.
13 |
14 | /// - Create a camera. Make the camera a child of the capsule. Reset it's transform.
15 | /// - Add a MouseLook script to the camera.
16 | /// -> Set the mouse look to use LookY. (You want the camera to tilt up and down like a head. The character already turns.)
17 | [AddComponentMenu("Camera-Control/Mouse Look")]
18 | public class MouseLook : MonoBehaviour {
19 |
20 | public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }
21 | public RotationAxes axes = RotationAxes.MouseXAndY;
22 | public float sensitivityX = 15F;
23 | public float sensitivityY = 15F;
24 |
25 | public float minimumX = -360F;
26 | public float maximumX = 360F;
27 |
28 | public float minimumY = -60F;
29 | public float maximumY = 60F;
30 |
31 | float rotationY = 0F;
32 |
33 | void Update ()
34 | {
35 | if (axes == RotationAxes.MouseXAndY)
36 | {
37 | float rotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivityX;
38 |
39 | rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
40 | rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);
41 |
42 | transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0);
43 | }
44 | else if (axes == RotationAxes.MouseX)
45 | {
46 | transform.Rotate(0, Input.GetAxis("Mouse X") * sensitivityX, 0);
47 | }
48 | else
49 | {
50 | rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
51 | rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);
52 |
53 | transform.localEulerAngles = new Vector3(-rotationY, transform.localEulerAngles.y, 0);
54 | }
55 | }
56 |
57 | void Start ()
58 | {
59 | // Make the rigid body not change rotation
60 | if (GetComponent())
61 | GetComponent().freezeRotation = true;
62 | }
63 | }
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/Scripts/MouseLook.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 68ec2fe99d1108b9d0006a298d76c639
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/Scripts/PlatformInputController.js:
--------------------------------------------------------------------------------
1 | // This makes the character turn to face the current movement speed per default.
2 | var autoRotate : boolean = true;
3 | var maxRotationSpeed : float = 360;
4 |
5 | private var motor : CharacterMotor;
6 |
7 | // Use this for initialization
8 | function Awake () {
9 | motor = GetComponent(CharacterMotor);
10 | }
11 |
12 | // Update is called once per frame
13 | function Update () {
14 | // Get the input vector from keyboard or analog stick
15 | var directionVector = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"), 0);
16 |
17 | if (directionVector != Vector3.zero) {
18 | // Get the length of the directon vector and then normalize it
19 | // Dividing by the length is cheaper than normalizing when we already have the length anyway
20 | var directionLength = directionVector.magnitude;
21 | directionVector = directionVector / directionLength;
22 |
23 | // Make sure the length is no bigger than 1
24 | directionLength = Mathf.Min(1, directionLength);
25 |
26 | // Make the input vector more sensitive towards the extremes and less sensitive in the middle
27 | // This makes it easier to control slow speeds when using analog sticks
28 | directionLength = directionLength * directionLength;
29 |
30 | // Multiply the normalized direction vector by the modified length
31 | directionVector = directionVector * directionLength;
32 | }
33 |
34 | // Rotate the input vector into camera space so up is camera's up and right is camera's right
35 | directionVector = Camera.main.transform.rotation * directionVector;
36 |
37 | // Rotate input vector to be perpendicular to character's up vector
38 | var camToCharacterSpace = Quaternion.FromToRotation(-Camera.main.transform.forward, transform.up);
39 | directionVector = (camToCharacterSpace * directionVector);
40 |
41 | // Apply the direction to the CharacterMotor
42 | motor.inputMoveDirection = directionVector;
43 | motor.inputJump = Input.GetButton("Jump");
44 |
45 | // Set rotation to the move direction
46 | if (autoRotate && directionVector.sqrMagnitude > 0.01) {
47 | var newForward : Vector3 = ConstantSlerp(
48 | transform.forward,
49 | directionVector,
50 | maxRotationSpeed * Time.deltaTime
51 | );
52 | newForward = ProjectOntoPlane(newForward, transform.up);
53 | transform.rotation = Quaternion.LookRotation(newForward, transform.up);
54 | }
55 | }
56 |
57 | function ProjectOntoPlane (v : Vector3, normal : Vector3) {
58 | return v - Vector3.Project(v, normal);
59 | }
60 |
61 | function ConstantSlerp (from : Vector3, to : Vector3, angle : float) {
62 | var value : float = Mathf.Min(1, angle / Vector3.Angle(from, to));
63 | return Vector3.Slerp(from, to, value);
64 | }
65 |
66 | // Require a character controller to be attached to the same game object
67 | @script RequireComponent (CharacterMotor)
68 | @script AddComponentMenu ("Character/Platform Input Controller")
69 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/Scripts/PlatformInputController.js.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: da93ddd6928094e24bb1f3f665f143d3
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/Scripts/ThirdPersonCamera.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | var cameraTransform : Transform;
4 | private var _target : Transform;
5 |
6 | // The distance in the x-z plane to the target
7 |
8 | var distance = 7.0;
9 |
10 | // the height we want the camera to be above the target
11 | var height = 3.0;
12 |
13 | var angularSmoothLag = 0.3;
14 | var angularMaxSpeed = 15.0;
15 |
16 | var heightSmoothLag = 0.3;
17 |
18 | var snapSmoothLag = 0.2;
19 | var snapMaxSpeed = 720.0;
20 |
21 | var clampHeadPositionScreenSpace = 0.75;
22 |
23 | var lockCameraTimeout = 0.2;
24 |
25 | private var headOffset = Vector3.zero;
26 | private var centerOffset = Vector3.zero;
27 |
28 | private var heightVelocity = 0.0;
29 | private var angleVelocity = 0.0;
30 | private var snap = false;
31 | private var controller : ThirdPersonController;
32 | private var targetHeight = 100000.0;
33 |
34 | function Awake ()
35 | {
36 | if(!cameraTransform && Camera.main)
37 | cameraTransform = Camera.main.transform;
38 | if(!cameraTransform) {
39 | Debug.Log("Please assign a camera to the ThirdPersonCamera script.");
40 | enabled = false;
41 | }
42 |
43 |
44 | _target = transform;
45 | if (_target)
46 | {
47 | controller = _target.GetComponent(ThirdPersonController);
48 | }
49 |
50 | if (controller)
51 | {
52 | var characterController : CharacterController = _target.GetComponent.();
53 | centerOffset = characterController.bounds.center - _target.position;
54 | headOffset = centerOffset;
55 | headOffset.y = characterController.bounds.max.y - _target.position.y;
56 | }
57 | else
58 | Debug.Log("Please assign a target to the camera that has a ThirdPersonController script attached.");
59 |
60 |
61 | Cut(_target, centerOffset);
62 | }
63 |
64 | function DebugDrawStuff ()
65 | {
66 | Debug.DrawLine(_target.position, _target.position + headOffset);
67 |
68 | }
69 |
70 | function AngleDistance (a : float, b : float)
71 | {
72 | a = Mathf.Repeat(a, 360);
73 | b = Mathf.Repeat(b, 360);
74 |
75 | return Mathf.Abs(b - a);
76 | }
77 |
78 | function Apply (dummyTarget : Transform, dummyCenter : Vector3)
79 | {
80 | // Early out if we don't have a target
81 | if (!controller)
82 | return;
83 |
84 | var targetCenter = _target.position + centerOffset;
85 | var targetHead = _target.position + headOffset;
86 |
87 | // DebugDrawStuff();
88 |
89 | // Calculate the current & target rotation angles
90 | var originalTargetAngle = _target.eulerAngles.y;
91 | var currentAngle = cameraTransform.eulerAngles.y;
92 |
93 | // Adjust real target angle when camera is locked
94 | var targetAngle = originalTargetAngle;
95 |
96 | // When pressing Fire2 (alt) the camera will snap to the target direction real quick.
97 | // It will stop snapping when it reaches the target
98 | if (Input.GetButton("Fire2"))
99 | snap = true;
100 |
101 | if (snap)
102 | {
103 | // We are close to the target, so we can stop snapping now!
104 | if (AngleDistance (currentAngle, originalTargetAngle) < 3.0)
105 | snap = false;
106 |
107 | currentAngle = Mathf.SmoothDampAngle(currentAngle, targetAngle, angleVelocity, snapSmoothLag, snapMaxSpeed);
108 | }
109 | // Normal camera motion
110 | else
111 | {
112 | if (controller.GetLockCameraTimer () < lockCameraTimeout)
113 | {
114 | targetAngle = currentAngle;
115 | }
116 |
117 | // Lock the camera when moving backwards!
118 | // * It is really confusing to do 180 degree spins when turning around.
119 | if (AngleDistance (currentAngle, targetAngle) > 160 && controller.IsMovingBackwards ())
120 | targetAngle += 180;
121 |
122 | currentAngle = Mathf.SmoothDampAngle(currentAngle, targetAngle, angleVelocity, angularSmoothLag, angularMaxSpeed);
123 | }
124 |
125 |
126 | // When jumping don't move camera upwards but only down!
127 | if (controller.IsJumping ())
128 | {
129 | // We'd be moving the camera upwards, do that only if it's really high
130 | var newTargetHeight = targetCenter.y + height;
131 | if (newTargetHeight < targetHeight || newTargetHeight - targetHeight > 5)
132 | targetHeight = targetCenter.y + height;
133 | }
134 | // When walking always update the target height
135 | else
136 | {
137 | targetHeight = targetCenter.y + height;
138 | }
139 |
140 | // Damp the height
141 | var currentHeight = cameraTransform.position.y;
142 | currentHeight = Mathf.SmoothDamp (currentHeight, targetHeight, heightVelocity, heightSmoothLag);
143 |
144 | // Convert the angle into a rotation, by which we then reposition the camera
145 | var currentRotation = Quaternion.Euler (0, currentAngle, 0);
146 |
147 | // Set the position of the camera on the x-z plane to:
148 | // distance meters behind the target
149 | cameraTransform.position = targetCenter;
150 | cameraTransform.position += currentRotation * Vector3.back * distance;
151 |
152 | // Set the height of the camera
153 | cameraTransform.position.y = currentHeight;
154 |
155 | // Always look at the target
156 | SetUpRotation(targetCenter, targetHead);
157 | }
158 |
159 | function LateUpdate () {
160 | Apply (transform, Vector3.zero);
161 | }
162 |
163 | function Cut (dummyTarget : Transform, dummyCenter : Vector3)
164 | {
165 | var oldHeightSmooth = heightSmoothLag;
166 | var oldSnapMaxSpeed = snapMaxSpeed;
167 | var oldSnapSmooth = snapSmoothLag;
168 |
169 | snapMaxSpeed = 10000;
170 | snapSmoothLag = 0.001;
171 | heightSmoothLag = 0.001;
172 |
173 | snap = true;
174 | Apply (transform, Vector3.zero);
175 |
176 | heightSmoothLag = oldHeightSmooth;
177 | snapMaxSpeed = oldSnapMaxSpeed;
178 | snapSmoothLag = oldSnapSmooth;
179 | }
180 |
181 | function SetUpRotation (centerPos : Vector3, headPos : Vector3)
182 | {
183 | // Now it's getting hairy. The devil is in the details here, the big issue is jumping of course.
184 | // * When jumping up and down we don't want to center the guy in screen space.
185 | // This is important to give a feel for how high you jump and avoiding large camera movements.
186 | //
187 | // * At the same time we dont want him to ever go out of screen and we want all rotations to be totally smooth.
188 | //
189 | // So here is what we will do:
190 | //
191 | // 1. We first find the rotation around the y axis. Thus he is always centered on the y-axis
192 | // 2. When grounded we make him be centered
193 | // 3. When jumping we keep the camera rotation but rotate the camera to get him back into view if his head is above some threshold
194 | // 4. When landing we smoothly interpolate towards centering him on screen
195 | var cameraPos = cameraTransform.position;
196 | var offsetToCenter = centerPos - cameraPos;
197 |
198 | // Generate base rotation only around y-axis
199 | var yRotation = Quaternion.LookRotation(Vector3(offsetToCenter.x, 0, offsetToCenter.z));
200 |
201 | var relativeOffset = Vector3.forward * distance + Vector3.down * height;
202 | cameraTransform.rotation = yRotation * Quaternion.LookRotation(relativeOffset);
203 |
204 | // Calculate the projected center position and top position in world space
205 | var centerRay = cameraTransform.GetComponent.().ViewportPointToRay(Vector3(.5, 0.5, 1));
206 | var topRay = cameraTransform.GetComponent.().ViewportPointToRay(Vector3(.5, clampHeadPositionScreenSpace, 1));
207 |
208 | var centerRayPos = centerRay.GetPoint(distance);
209 | var topRayPos = topRay.GetPoint(distance);
210 |
211 | var centerToTopAngle = Vector3.Angle(centerRay.direction, topRay.direction);
212 |
213 | var heightToAngle = centerToTopAngle / (centerRayPos.y - topRayPos.y);
214 |
215 | var extraLookAngle = heightToAngle * (centerRayPos.y - centerPos.y);
216 | if (extraLookAngle < centerToTopAngle)
217 | {
218 | extraLookAngle = 0;
219 | }
220 | else
221 | {
222 | extraLookAngle = extraLookAngle - centerToTopAngle;
223 | cameraTransform.rotation *= Quaternion.Euler(-extraLookAngle, 0, 0);
224 | }
225 | }
226 |
227 | function GetCenterOffset ()
228 | {
229 | return centerOffset;
230 | }
231 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/Scripts/ThirdPersonCamera.js.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0b167d00b3108411a8a963cba5ddde1b
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/Scripts/ThirdPersonController.js:
--------------------------------------------------------------------------------
1 |
2 | // Require a character controller to be attached to the same game object
3 | @script RequireComponent(CharacterController)
4 |
5 | public var idleAnimation : AnimationClip;
6 | public var walkAnimation : AnimationClip;
7 | public var runAnimation : AnimationClip;
8 | public var jumpPoseAnimation : AnimationClip;
9 |
10 | public var walkMaxAnimationSpeed : float = 0.75;
11 | public var trotMaxAnimationSpeed : float = 1.0;
12 | public var runMaxAnimationSpeed : float = 1.0;
13 | public var jumpAnimationSpeed : float = 1.15;
14 | public var landAnimationSpeed : float = 1.0;
15 |
16 | private var _animation : Animation;
17 |
18 | enum CharacterState {
19 | Idle = 0,
20 | Walking = 1,
21 | Trotting = 2,
22 | Running = 3,
23 | Jumping = 4,
24 | }
25 |
26 | private var _characterState : CharacterState;
27 |
28 | // The speed when walking
29 | var walkSpeed = 2.0;
30 | // after trotAfterSeconds of walking we trot with trotSpeed
31 | var trotSpeed = 4.0;
32 | // when pressing "Fire3" button (cmd) we start running
33 | var runSpeed = 6.0;
34 |
35 | var inAirControlAcceleration = 3.0;
36 |
37 | // How high do we jump when pressing jump and letting go immediately
38 | var jumpHeight = 0.5;
39 |
40 | // The gravity for the character
41 | var gravity = 20.0;
42 | // The gravity in controlled descent mode
43 | var speedSmoothing = 10.0;
44 | var rotateSpeed = 500.0;
45 | var trotAfterSeconds = 3.0;
46 |
47 | var canJump = true;
48 |
49 | private var jumpRepeatTime = 0.05;
50 | private var jumpTimeout = 0.15;
51 | private var groundedTimeout = 0.25;
52 |
53 | // The camera doesnt start following the target immediately but waits for a split second to avoid too much waving around.
54 | private var lockCameraTimer = 0.0;
55 |
56 | // The current move direction in x-z
57 | private var moveDirection = Vector3.zero;
58 | // The current vertical speed
59 | private var verticalSpeed = 0.0;
60 | // The current x-z move speed
61 | private var moveSpeed = 0.0;
62 |
63 | // The last collision flags returned from controller.Move
64 | private var collisionFlags : CollisionFlags;
65 |
66 | // Are we jumping? (Initiated with jump button and not grounded yet)
67 | private var jumping = false;
68 | private var jumpingReachedApex = false;
69 |
70 | // Are we moving backwards (This locks the camera to not do a 180 degree spin)
71 | private var movingBack = false;
72 | // Is the user pressing any keys?
73 | private var isMoving = false;
74 | // When did the user start walking (Used for going into trot after a while)
75 | private var walkTimeStart = 0.0;
76 | // Last time the jump button was clicked down
77 | private var lastJumpButtonTime = -10.0;
78 | // Last time we performed a jump
79 | private var lastJumpTime = -1.0;
80 |
81 |
82 | // the height we jumped from (Used to determine for how long to apply extra jump power after jumping.)
83 | private var lastJumpStartHeight = 0.0;
84 |
85 |
86 | private var inAirVelocity = Vector3.zero;
87 |
88 | private var lastGroundedTime = 0.0;
89 |
90 |
91 | private var isControllable = true;
92 |
93 | function Awake ()
94 | {
95 | moveDirection = transform.TransformDirection(Vector3.forward);
96 |
97 | _animation = GetComponent(Animation);
98 | if(!_animation)
99 | Debug.Log("The character you would like to control doesn't have animations. Moving her might look weird.");
100 |
101 | /*
102 | public var idleAnimation : AnimationClip;
103 | public var walkAnimation : AnimationClip;
104 | public var runAnimation : AnimationClip;
105 | public var jumpPoseAnimation : AnimationClip;
106 | */
107 | if(!idleAnimation) {
108 | _animation = null;
109 | Debug.Log("No idle animation found. Turning off animations.");
110 | }
111 | if(!walkAnimation) {
112 | _animation = null;
113 | Debug.Log("No walk animation found. Turning off animations.");
114 | }
115 | if(!runAnimation) {
116 | _animation = null;
117 | Debug.Log("No run animation found. Turning off animations.");
118 | }
119 | if(!jumpPoseAnimation && canJump) {
120 | _animation = null;
121 | Debug.Log("No jump animation found and the character has canJump enabled. Turning off animations.");
122 | }
123 |
124 | }
125 |
126 |
127 | function UpdateSmoothedMovementDirection ()
128 | {
129 | var cameraTransform = Camera.main.transform;
130 | var grounded = IsGrounded();
131 |
132 | // Forward vector relative to the camera along the x-z plane
133 | var forward = cameraTransform.TransformDirection(Vector3.forward);
134 | forward.y = 0;
135 | forward = forward.normalized;
136 |
137 | // Right vector relative to the camera
138 | // Always orthogonal to the forward vector
139 | var right = Vector3(forward.z, 0, -forward.x);
140 |
141 | var v = Input.GetAxisRaw("Vertical");
142 | var h = Input.GetAxisRaw("Horizontal");
143 |
144 | // Are we moving backwards or looking backwards
145 | if (v < -0.2)
146 | movingBack = true;
147 | else
148 | movingBack = false;
149 |
150 | var wasMoving = isMoving;
151 | isMoving = Mathf.Abs (h) > 0.1 || Mathf.Abs (v) > 0.1;
152 |
153 | // Target direction relative to the camera
154 | var targetDirection = h * right + v * forward;
155 |
156 | // Grounded controls
157 | if (grounded)
158 | {
159 | // Lock camera for short period when transitioning moving & standing still
160 | lockCameraTimer += Time.deltaTime;
161 | if (isMoving != wasMoving)
162 | lockCameraTimer = 0.0;
163 |
164 | // We store speed and direction seperately,
165 | // so that when the character stands still we still have a valid forward direction
166 | // moveDirection is always normalized, and we only update it if there is user input.
167 | if (targetDirection != Vector3.zero)
168 | {
169 | // If we are really slow, just snap to the target direction
170 | if (moveSpeed < walkSpeed * 0.9 && grounded)
171 | {
172 | moveDirection = targetDirection.normalized;
173 | }
174 | // Otherwise smoothly turn towards it
175 | else
176 | {
177 | moveDirection = Vector3.RotateTowards(moveDirection, targetDirection, rotateSpeed * Mathf.Deg2Rad * Time.deltaTime, 1000);
178 |
179 | moveDirection = moveDirection.normalized;
180 | }
181 | }
182 |
183 | // Smooth the speed based on the current target direction
184 | var curSmooth = speedSmoothing * Time.deltaTime;
185 |
186 | // Choose target speed
187 | //* We want to support analog input but make sure you cant walk faster diagonally than just forward or sideways
188 | var targetSpeed = Mathf.Min(targetDirection.magnitude, 1.0);
189 |
190 | _characterState = CharacterState.Idle;
191 |
192 | // Pick speed modifier
193 | if (Input.GetKey (KeyCode.LeftShift) || Input.GetKey (KeyCode.RightShift))
194 | {
195 | targetSpeed *= runSpeed;
196 | _characterState = CharacterState.Running;
197 | }
198 | else if (Time.time - trotAfterSeconds > walkTimeStart)
199 | {
200 | targetSpeed *= trotSpeed;
201 | _characterState = CharacterState.Trotting;
202 | }
203 | else
204 | {
205 | targetSpeed *= walkSpeed;
206 | _characterState = CharacterState.Walking;
207 | }
208 |
209 | moveSpeed = Mathf.Lerp(moveSpeed, targetSpeed, curSmooth);
210 |
211 | // Reset walk time start when we slow down
212 | if (moveSpeed < walkSpeed * 0.3)
213 | walkTimeStart = Time.time;
214 | }
215 | // In air controls
216 | else
217 | {
218 | // Lock camera while in air
219 | if (jumping)
220 | lockCameraTimer = 0.0;
221 |
222 | if (isMoving)
223 | inAirVelocity += targetDirection.normalized * Time.deltaTime * inAirControlAcceleration;
224 | }
225 |
226 |
227 |
228 | }
229 |
230 |
231 | function ApplyJumping ()
232 | {
233 | // Prevent jumping too fast after each other
234 | if (lastJumpTime + jumpRepeatTime > Time.time)
235 | return;
236 |
237 | if (IsGrounded()) {
238 | // Jump
239 | // - Only when pressing the button down
240 | // - With a timeout so you can press the button slightly before landing
241 | if (canJump && Time.time < lastJumpButtonTime + jumpTimeout) {
242 | verticalSpeed = CalculateJumpVerticalSpeed (jumpHeight);
243 | SendMessage("DidJump", SendMessageOptions.DontRequireReceiver);
244 | }
245 | }
246 | }
247 |
248 |
249 | function ApplyGravity ()
250 | {
251 | if (isControllable) // don't move player at all if not controllable.
252 | {
253 | // Apply gravity
254 | var jumpButton = Input.GetButton("Jump");
255 |
256 |
257 | // When we reach the apex of the jump we send out a message
258 | if (jumping && !jumpingReachedApex && verticalSpeed <= 0.0)
259 | {
260 | jumpingReachedApex = true;
261 | SendMessage("DidJumpReachApex", SendMessageOptions.DontRequireReceiver);
262 | }
263 |
264 | if (IsGrounded ())
265 | verticalSpeed = 0.0;
266 | else
267 | verticalSpeed -= gravity * Time.deltaTime;
268 | }
269 | }
270 |
271 | function CalculateJumpVerticalSpeed (targetJumpHeight : float)
272 | {
273 | // From the jump height and gravity we deduce the upwards speed
274 | // for the character to reach at the apex.
275 | return Mathf.Sqrt(2 * targetJumpHeight * gravity);
276 | }
277 |
278 | function DidJump ()
279 | {
280 | jumping = true;
281 | jumpingReachedApex = false;
282 | lastJumpTime = Time.time;
283 | lastJumpStartHeight = transform.position.y;
284 | lastJumpButtonTime = -10;
285 |
286 | _characterState = CharacterState.Jumping;
287 | }
288 |
289 | function Update() {
290 |
291 | if (!isControllable)
292 | {
293 | // kill all inputs if not controllable.
294 | Input.ResetInputAxes();
295 | }
296 |
297 | if (Input.GetButtonDown ("Jump"))
298 | {
299 | lastJumpButtonTime = Time.time;
300 | }
301 |
302 | UpdateSmoothedMovementDirection();
303 |
304 | // Apply gravity
305 | // - extra power jump modifies gravity
306 | // - controlledDescent mode modifies gravity
307 | ApplyGravity ();
308 |
309 | // Apply jumping logic
310 | ApplyJumping ();
311 |
312 | // Calculate actual motion
313 | var movement = moveDirection * moveSpeed + Vector3 (0, verticalSpeed, 0) + inAirVelocity;
314 | movement *= Time.deltaTime;
315 |
316 | // Move the controller
317 | var controller : CharacterController = GetComponent(CharacterController);
318 | collisionFlags = controller.Move(movement);
319 |
320 | // ANIMATION sector
321 | if(_animation) {
322 | if(_characterState == CharacterState.Jumping)
323 | {
324 | if(!jumpingReachedApex) {
325 | _animation[jumpPoseAnimation.name].speed = jumpAnimationSpeed;
326 | _animation[jumpPoseAnimation.name].wrapMode = WrapMode.ClampForever;
327 | _animation.CrossFade(jumpPoseAnimation.name);
328 | } else {
329 | _animation[jumpPoseAnimation.name].speed = -landAnimationSpeed;
330 | _animation[jumpPoseAnimation.name].wrapMode = WrapMode.ClampForever;
331 | _animation.CrossFade(jumpPoseAnimation.name);
332 | }
333 | }
334 | else
335 | {
336 | if(controller.velocity.sqrMagnitude < 0.1) {
337 | _animation.CrossFade(idleAnimation.name);
338 | }
339 | else
340 | {
341 | if(_characterState == CharacterState.Running) {
342 | _animation[runAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0, runMaxAnimationSpeed);
343 | _animation.CrossFade(runAnimation.name);
344 | }
345 | else if(_characterState == CharacterState.Trotting) {
346 | _animation[walkAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0, trotMaxAnimationSpeed);
347 | _animation.CrossFade(walkAnimation.name);
348 | }
349 | else if(_characterState == CharacterState.Walking) {
350 | _animation[walkAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0, walkMaxAnimationSpeed);
351 | _animation.CrossFade(walkAnimation.name);
352 | }
353 |
354 | }
355 | }
356 | }
357 | // ANIMATION sector
358 |
359 | // Set rotation to the move direction
360 | if (IsGrounded())
361 | {
362 |
363 | transform.rotation = Quaternion.LookRotation(moveDirection);
364 |
365 | }
366 | else
367 | {
368 | var xzMove = movement;
369 | xzMove.y = 0;
370 | if (xzMove.sqrMagnitude > 0.001)
371 | {
372 | transform.rotation = Quaternion.LookRotation(xzMove);
373 | }
374 | }
375 |
376 | // We are in jump mode but just became grounded
377 | if (IsGrounded())
378 | {
379 | lastGroundedTime = Time.time;
380 | inAirVelocity = Vector3.zero;
381 | if (jumping)
382 | {
383 | jumping = false;
384 | SendMessage("DidLand", SendMessageOptions.DontRequireReceiver);
385 | }
386 | }
387 | }
388 |
389 | function OnControllerColliderHit (hit : ControllerColliderHit )
390 | {
391 | // Debug.DrawRay(hit.point, hit.normal);
392 | if (hit.moveDirection.y > 0.01)
393 | return;
394 | }
395 |
396 | function GetSpeed () {
397 | return moveSpeed;
398 | }
399 |
400 | function IsJumping () {
401 | return jumping;
402 | }
403 |
404 | function IsGrounded () {
405 | return (collisionFlags & CollisionFlags.CollidedBelow) != 0;
406 | }
407 |
408 | function GetDirection () {
409 | return moveDirection;
410 | }
411 |
412 | function IsMovingBackwards () {
413 | return movingBack;
414 | }
415 |
416 | function GetLockCameraTimer ()
417 | {
418 | return lockCameraTimer;
419 | }
420 |
421 | function IsMoving () : boolean
422 | {
423 | return Mathf.Abs(Input.GetAxisRaw("Vertical")) + Mathf.Abs(Input.GetAxisRaw("Horizontal")) > 0.5;
424 | }
425 |
426 | function HasJumpReachedApex ()
427 | {
428 | return jumpingReachedApex;
429 | }
430 |
431 | function IsGroundedWithTimeout ()
432 | {
433 | return lastGroundedTime + groundedTimeout > Time.time;
434 | }
435 |
436 | function Reset ()
437 | {
438 | gameObject.tag = "Player";
439 | }
440 |
441 |
--------------------------------------------------------------------------------
/Assets/Standard Assets/Character Controllers/Sources/Scripts/ThirdPersonController.js.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1d5ac211a643e447ca78c2d794a16381
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/StreamingAssets.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e7b334c0ce61b4a1e86c3578e5bbaab4
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/StreamingAssets/diff.rtttl:
--------------------------------------------------------------------------------
1 | 占位文件
--------------------------------------------------------------------------------
/Assets/StreamingAssets/diff.rtttl.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 95895ab8633f34cbab2f1ecabd540a24
3 | DefaultImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/Assets/Test.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 881edbad5bca045f6808956b043c71fe
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Test/Editor.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7b5a2b499130d4073b5d9dc2c3d008f3
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Test/Editor/OneBuilderEditor.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using UnityEditor;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.IO;
6 | using System.Text;
7 |
8 | namespace dpull
9 | {
10 | class OneBuilderEditor : EditorWindow
11 | {
12 | string OutputDir = Path.Combine(Application.dataPath, "../Bin");
13 | string DebugInfo;
14 |
15 | [MenuItem("XStudio/Tools/One Builder")]
16 | public static void UIAdapter()
17 | {
18 | EditorWindow.GetWindow(false, "One Builder", true).Show();
19 | }
20 |
21 | string BuildPlayer(BuildTarget target, BuildOptions options, params string[] levels)
22 | {
23 | var output = Path.Combine(OutputDir, target.ToString());
24 | DirectoryEx.DeleteDirectory(output);
25 |
26 | BuildPipeline.BuildPlayer(levels, output, target, options);
27 | return output;
28 | }
29 |
30 | string BuildStreamedSceneAssetBundle(BuildTarget target, params string[] levels)
31 | {
32 | var output = Path.Combine(OutputDir, target.ToString() + ".asset");
33 | BuildPipeline.BuildStreamedSceneAssetBundle(levels, output, target, BuildOptions.UncompressedAssetBundle);
34 | return output;
35 | }
36 |
37 | long GetFileSize(string path)
38 | {
39 | var info = new FileInfo(path);
40 | return info.Length;
41 | }
42 |
43 | string GetFileSizeString(string path)
44 | {
45 | var units = new string[]{"B", "KB", "MB", "GB"};
46 | var size = (double)GetFileSize(path);
47 | foreach (var unit in units)
48 | {
49 | if (size < 1024d)
50 | return string.Format("{0:F}{1}", size, unit);
51 | size /= 1024;
52 | }
53 | return string.Format("{0:F}{1}", size, units[units.Length - 1]);
54 | }
55 |
56 | BuildTarget GetIOSBuildTarget()
57 | {
58 | #if UNITY_4_0 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6
59 | return BuildTarget.iPhone;
60 | #else
61 | return BuildTarget.iOS;
62 | #endif
63 | }
64 |
65 | void BuildiOS()
66 | {
67 | var oldTarget = EditorUserBuildSettings.activeBuildTarget;
68 | DirectoryEx.CreateDirectory(OutputDir);
69 |
70 | var app = BuildPlayer(GetIOSBuildTarget(), BuildOptions.None, "Assets/Level1.unity");
71 |
72 | var appDataDir = Path.Combine(app, "Data");
73 | var assetbundle = BuildStreamedSceneAssetBundle(GetIOSBuildTarget(), "Assets/Level2.unity");
74 |
75 | if (!AssetBundlePatch.IsSupport(assetbundle))
76 | {
77 | Debug.LogError("AssetBundlePatch.IsSupport failed!!!!");
78 | return;
79 | }
80 |
81 | EditorUserBuildSettings.SwitchActiveBuildTarget(oldTarget);
82 |
83 | var diff = Path.Combine(OutputDir, Updater.Diff);
84 | var ret = AssetBundlePatch.Diff(appDataDir, null, assetbundle, diff);
85 | if (ret != AssetBundlePatchResult.Succeed)
86 | {
87 | Debug.LogError("AssetBundlePatch.Diff failed!!!!");
88 | return;
89 | }
90 |
91 | // Real environment, you need to place this file on http server
92 | var diffZip = Path.Combine(appDataDir, "Raw");
93 | diffZip = Path.Combine(diffZip, Updater.DiffZip);
94 |
95 | ZipFile.CreateFromDirectory(new string[]{diff}, diffZip);
96 |
97 | var sb = new StringBuilder();
98 | sb.AppendLine(DateTime.Now.ToString());
99 | sb.AppendLine(string.Format("Assetbundle size:{0}", GetFileSizeString(assetbundle)));
100 | sb.AppendLine(string.Format("Diff size:{0}", GetFileSizeString(diff)));
101 | sb.AppendLine(string.Format("Diff zip size:{0}", GetFileSizeString(diffZip)));
102 | DebugInfo = sb.ToString();
103 | }
104 |
105 | void BuildAndroid()
106 | {
107 | var oldTarget = EditorUserBuildSettings.activeBuildTarget;
108 | DirectoryEx.CreateDirectory(OutputDir);
109 |
110 | var app = BuildPlayer(BuildTarget.Android, BuildOptions.AcceptExternalModificationsToPlayer, "Assets/Level1.unity");
111 | var appDataDir = Path.Combine(app, "OneBuilder/assets/bin/Data");
112 | var assetbundle = BuildStreamedSceneAssetBundle(BuildTarget.Android, "Assets/Level2.unity");
113 |
114 | if (!AssetBundlePatch.IsSupport(assetbundle))
115 | {
116 | Debug.LogError("AssetBundlePatch.IsSupport failed!!!!");
117 | return;
118 | }
119 |
120 | EditorUserBuildSettings.SwitchActiveBuildTarget(oldTarget);
121 |
122 | var diff = Path.Combine(OutputDir, Updater.Diff);
123 | var ret = AssetBundlePatch.Diff(appDataDir, null, assetbundle, diff);
124 | if (ret != AssetBundlePatchResult.Succeed)
125 | {
126 | Debug.LogError("AssetBundlePatch.Diff failed!!!!");
127 | return;
128 | }
129 |
130 | // Real environment, you need to place this file on http server
131 | var diffZip = Path.Combine(app, "OneBuilder/assets");
132 | diffZip = Path.Combine(diffZip, Updater.DiffZip);
133 |
134 | ZipFile.CreateFromDirectory(new string[]{diff}, diffZip);
135 |
136 | var sb = new StringBuilder();
137 | sb.AppendLine(DateTime.Now.ToString());
138 | sb.AppendLine(string.Format("Assetbundle size:{0}", GetFileSizeString(assetbundle)));
139 | sb.AppendLine(string.Format("Diff size:{0}", GetFileSizeString(diff)));
140 | sb.AppendLine(string.Format("Diff zip size:{0}", GetFileSizeString(diffZip)));
141 | DebugInfo = sb.ToString();
142 | }
143 |
144 | void OnGUI()
145 | {
146 | if (!string.IsNullOrEmpty(DebugInfo))
147 | GUILayout.TextArea(DebugInfo);
148 |
149 | GUILayout.Space(10);
150 |
151 | if (GUILayout.Button("Test iPhone"))
152 | BuildiOS();
153 |
154 | if (GUILayout.Button("Test Android"))
155 | BuildAndroid();
156 | }
157 | }
158 | }
--------------------------------------------------------------------------------
/Assets/Test/Editor/OneBuilderEditor.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1a56eee7356ec4719bf4fa3e45a1592a
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Test/Progress.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using ICSharpCode.SharpZipLib.Zip;
4 | using UnityEngine;
5 | using System.Net;
6 |
7 | namespace dpull
8 | {
9 | abstract class Progress
10 | {
11 | public enum State
12 | {
13 | Uncompleted,
14 | Succeed,
15 | Failed,
16 | }
17 |
18 | public State CurState = State.Uncompleted;
19 | public long ProgressCurValue = 0;
20 | public long ProgressTotalValue = 1;
21 |
22 | public virtual void Update()
23 | {
24 | throw new NotImplementedException();
25 | }
26 |
27 | public virtual string GetDebug()
28 | {
29 | return string.Empty;
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/Assets/Test/Progress.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 80af05e65a0804ab793cc860b57993e0
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Test/UnzipProgress.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using ICSharpCode.SharpZipLib.Zip;
4 | using UnityEngine;
5 | using System.Net;
6 |
7 | namespace dpull
8 | {
9 | class UnzipProgress : Progress
10 | {
11 | Stream SourceArchiveFile;
12 | ZipInputStream ZipStream;
13 | string DestinationDirectoryName;
14 | byte[] Buffer = new byte[ZipFile.BufferSize];
15 | Stream WriteFileStream;
16 |
17 | System.Diagnostics.Stopwatch ReaderCost = new System.Diagnostics.Stopwatch();
18 | System.Diagnostics.Stopwatch WriterCost = new System.Diagnostics.Stopwatch();
19 |
20 | public UnzipProgress(string sourceArchiveFileName, string destinationDirectoryName)
21 | {
22 | SourceArchiveFile = FileEx.OpenRead(sourceArchiveFileName);
23 | ZipStream = new ZipInputStream(SourceArchiveFile);
24 | DestinationDirectoryName = destinationDirectoryName;
25 | }
26 |
27 | public override void Update()
28 | {
29 | for (int i = 0; i < 8; ++i)
30 | {
31 | if (Process())
32 | break;
33 | }
34 | }
35 |
36 | public override string GetDebug()
37 | {
38 | return string.Format("Unzip:{0}, Write:{1}", ReaderCost.ElapsedMilliseconds, WriterCost.ElapsedMilliseconds);
39 | }
40 |
41 | bool Process()
42 | {
43 | try
44 | {
45 | if (WriteFileStream == null)
46 | {
47 | ProcessNextEntry();
48 | if (CurState != State.Uncompleted)
49 | return true;
50 | }
51 |
52 | ProcessFile();
53 | return false;
54 | }
55 | catch(Exception e)
56 | {
57 | CurState = State.Failed;
58 | Debug.LogException(e);
59 | return true;
60 | }
61 | }
62 |
63 | void ProcessNextEntry()
64 | {
65 | while (true)
66 | {
67 | var theEntry = ZipStream.GetNextEntry();
68 | if (theEntry == null)
69 | {
70 | CurState = State.Succeed;
71 | return;
72 | }
73 |
74 | var fileName = Path.GetFileName(theEntry.Name);
75 | if (string.IsNullOrEmpty(fileName))
76 | continue;
77 |
78 | string file = Path.Combine(DestinationDirectoryName, theEntry.Name);
79 | DirectoryEx.CreateDirectory(Directory.GetParent(file));
80 |
81 | WriteFileStream = File.OpenWrite(file);
82 | return;
83 | }
84 | }
85 |
86 | void ProcessFile()
87 | {
88 | ReaderCost.Start();
89 | var size = ZipStream.Read(Buffer, 0, Buffer.Length);
90 | ReaderCost.Stop();
91 |
92 | if (size <= 0)
93 | {
94 | WriteFileStream.Close();
95 | WriteFileStream = null;
96 | return;
97 | }
98 |
99 | ProgressCurValue = SourceArchiveFile.Position;
100 | ProgressTotalValue = SourceArchiveFile.Length;
101 |
102 | WriterCost.Start();
103 | WriteFileStream.Write(Buffer, 0, size);
104 | WriterCost.Stop();
105 | }
106 | }
107 | }
--------------------------------------------------------------------------------
/Assets/Test/UnzipProgress.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 92c479a8d744c4573a855271fd4f0e47
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Test/Updater.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System;
6 |
7 | namespace dpull
8 | {
9 | public class Updater : MonoBehaviour
10 | {
11 | public const string Diff = "diff.asset";
12 | public const string DiffZip = "diff.rtttl"; // for Android http://ponystyle.com/blog/2010/03/26/dealing-with-asset-compression-in-android-apps/
13 | private string DebugMessage = string.Empty;
14 | private string ProgressMessage = string.Empty;
15 | private Progress CurProgress = null;
16 | private Rect WindowRect = new Rect(Screen.width / 4, Screen.height / 4, Screen.width / 2, Screen.height / 2);
17 | private bool UpdateSucess;
18 |
19 | string GetAppDataDir()
20 | {
21 | switch (Application.platform)
22 | {
23 | case RuntimePlatform.IPhonePlayer:
24 | return Directory.GetParent(Application.streamingAssetsPath).FullName;
25 |
26 | case RuntimePlatform.Android:
27 | return Path.Combine(Application.streamingAssetsPath, "bin/Data");
28 |
29 | default:
30 | throw new UnityException("Not support:" + Application.platform.ToString());
31 | }
32 | }
33 |
34 | IEnumerator Start()
35 | {
36 | if (Application.platform != RuntimePlatform.Android && Application.platform != RuntimePlatform.IPhonePlayer)
37 | yield break;
38 |
39 | UpdateSucess = false;
40 |
41 | // Real environment, you need to download this file
42 | var diffZip = Path.Combine(Application.streamingAssetsPath, DiffZip);
43 | Debug.Log("DiffZip:" + diffZip);
44 |
45 | CurProgress = new UnzipProgress(diffZip, Application.persistentDataPath);
46 | yield return StartCoroutine(ProcessProgress(CurProgress));
47 |
48 | if (CurProgress.CurState != Progress.State.Succeed)
49 | {
50 | DebugMessage = "Unzip failed." + CurProgress.GetDebug();
51 | yield break;
52 | }
53 |
54 | var diff = Path.Combine(Application.persistentDataPath, Diff);
55 | Debug.Log("Diff:" + diff);
56 |
57 | var appDataDir = GetAppDataDir();
58 | Debug.Log("AppDataDir:" + appDataDir);
59 |
60 | var update = Path.Combine(Application.persistentDataPath, "update.asset");
61 | var ret = AssetBundlePatch.Merge(appDataDir, null, update, diff);
62 | if (ret != AssetBundlePatchResult.Succeed)
63 | {
64 | DebugMessage = "Merge failed.";
65 | yield break;
66 | }
67 |
68 | AssetBundle.CreateFromFile(update);
69 | UpdateSucess = true;
70 | }
71 |
72 | void OnGUI()
73 | {
74 | if (UpdateSucess)
75 | {
76 | if (GUILayout.Button("Enter Level 2"))
77 | {
78 | Application.LoadLevel("Level2");
79 | }
80 | return;
81 | }
82 |
83 | WindowRect = GUILayout.Window(0, WindowRect, (windowId)=>{
84 | GUILayout.Label(ProgressMessage);
85 |
86 | if (CurProgress != null)
87 | {
88 | var progress = 100 * CurProgress.ProgressCurValue / CurProgress.ProgressTotalValue;
89 | GUILayout.HorizontalScrollbar((float)progress, 0f, 0f, 100f);
90 | GUILayout.Label(progress.ToString() + "%");
91 | GUILayout.Label(CurProgress.CurState.ToString());
92 | }
93 | GUILayout.Label(DebugMessage);
94 | }, "Updater");
95 | }
96 |
97 | IEnumerator ProcessProgress(Progress curProgress)
98 | {
99 | while (true)
100 | {
101 | curProgress.Update();
102 | if (curProgress.CurState != Progress.State.Uncompleted)
103 | yield break;
104 | yield return null;
105 | }
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/Assets/Test/Updater.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c0ef8eebd93774d88a6436a5d212fd92
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Test/ZipFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using ICSharpCode.SharpZipLib.Zip; // https://github.com/icsharpcode/SharpZipLib
4 | using System.Collections;
5 | using UnityEngine;
6 |
7 | namespace dpull
8 | {
9 | public class ZipFile
10 | {
11 | public static int BufferSize = 1024 * 1024;
12 |
13 | public static void CreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName)
14 | {
15 | string[] filenames = Directory.GetFiles(sourceDirectoryName);
16 | var inDirStrLen = sourceDirectoryName.Length;
17 |
18 | if (!PathEx.EndWithDirectorySeparatorChar(sourceDirectoryName))
19 | inDirStrLen++;
20 |
21 | using (ZipOutputStream zipStream = new ZipOutputStream(File.Create(destinationArchiveFileName)))
22 | {
23 | byte[] buffer = new byte[BufferSize];
24 |
25 | zipStream.SetLevel(9);
26 |
27 | foreach (string file in filenames)
28 | {
29 | var entryName = file.Substring(inDirStrLen);
30 | var fileInfo = new FileInfo(file);
31 |
32 | ZipEntry entry = new ZipEntry(entryName);
33 | entry.DateTime = fileInfo.LastWriteTime;
34 | zipStream.PutNextEntry(entry);
35 |
36 | using (FileStream fileStream = File.OpenRead(file))
37 | {
38 | while (true)
39 | {
40 | int size = fileStream.Read(buffer, 0, buffer.Length);
41 | if (size <= 0)
42 | break;
43 |
44 | zipStream.Write(buffer, 0, size);
45 | }
46 | }
47 | }
48 |
49 | zipStream.Finish();
50 | zipStream.Close();
51 | }
52 | }
53 |
54 | public static void CreateFromDirectory(string[] sourceFileNames, string destinationArchiveFileName)
55 | {
56 | using (ZipOutputStream zipStream = new ZipOutputStream(File.Create(destinationArchiveFileName)))
57 | {
58 | byte[] buffer = new byte[BufferSize];
59 |
60 | zipStream.SetLevel(9);
61 |
62 | foreach (string file in sourceFileNames)
63 | {
64 | var entryName = Path.GetFileName(file);
65 | var fileInfo = new FileInfo(file);
66 |
67 | ZipEntry entry = new ZipEntry(entryName);
68 | entry.DateTime = fileInfo.LastWriteTime;
69 | zipStream.PutNextEntry(entry);
70 |
71 | using (FileStream fileStream = File.OpenRead(file))
72 | {
73 | while (true)
74 | {
75 | int size = fileStream.Read(buffer, 0, buffer.Length);
76 | if (size <= 0)
77 | break;
78 |
79 | zipStream.Write(buffer, 0, size);
80 | }
81 | }
82 | }
83 |
84 | zipStream.Finish();
85 | zipStream.Close();
86 | }
87 | }
88 |
89 | public static void ExtractToDirectory(string sourceArchiveFileName, string destinationDirectoryName)
90 | {
91 | using (var zipStream = new ZipInputStream(FileEx.OpenRead(sourceArchiveFileName)))
92 | {
93 | ZipEntry theEntry;
94 | byte[] data = new byte[BufferSize];
95 |
96 | while ((theEntry = zipStream.GetNextEntry()) != null)
97 | {
98 | var fileName = Path.GetFileName(theEntry.Name);
99 | if (string.IsNullOrEmpty(fileName))
100 | continue;
101 |
102 | string file = Path.Combine(destinationDirectoryName, theEntry.Name);
103 | DirectoryEx.CreateDirectory(Directory.GetParent(file));
104 |
105 | using (FileStream fileStream = File.Create(file))
106 | {
107 | while (true)
108 | {
109 | var size = zipStream.Read(data, 0, data.Length);
110 | if (size <= 0)
111 | break;
112 |
113 | fileStream.Write(data, 0, size);
114 | }
115 | }
116 | }
117 | }
118 | }
119 |
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/Assets/Test/ZipFile.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 396d11133c39e4381b6a06bc511c932e
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Thirdparty.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2d20f1187c7994084920ffd7627be776
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/SharpZip.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/Assets/Thirdparty/SharpZip.dll
--------------------------------------------------------------------------------
/Assets/Thirdparty/SharpZip.dll.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4cd05255fa1854c74ae3997b549dd9f0
3 | MonoAssemblyImporter:
4 | serializedVersion: 1
5 | iconMap: {}
6 | executionOrder: {}
7 | userData:
8 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1ffc3b1e438684d16b46da4a0ed8d78c
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/AndroidAssetStream.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System;
3 |
4 | #if UNITY_ANDROID
5 | namespace dpull
6 | {
7 | public class AndroidAssetStream : System.IO.Stream
8 | {
9 | AndroidJavaObject AndroidInputStream;
10 | long AndroidInputStreamLength = long.MaxValue;
11 | long AndroidInputStreamPostion = 0;
12 |
13 | public AndroidAssetStream(string fileName)
14 | {
15 | var noCompressExt = new string[]{
16 | ".jpg", ".jpeg", ".png", ".gif",
17 | ".wav", ".mp2", ".mp3", ".ogg", ".aac",
18 | ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet",
19 | ".rtttl", ".imy", ".xmf", ".mp4", ".m4a",
20 | ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2",
21 | ".amr", ".awb", ".wma", ".wmv"
22 | };
23 |
24 | var ext = System.IO.Path.GetExtension(fileName);
25 |
26 | using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
27 | {
28 | using (var activity = unityPlayer.GetStatic("currentActivity"))
29 | {
30 | using (var assetManager = activity.Call("getAssets")) //android.content.res.AssetManager
31 | {
32 | if (Array.Exists(noCompressExt, (obj)=>{ return obj == ext; }))
33 | {
34 | using (var assetFileDescriptor = assetManager.Call("openFd", fileName)) //assets/ //android.content.res.AssetFileDescriptor
35 | {
36 | AndroidInputStreamLength = assetFileDescriptor.Call("getLength");
37 | }
38 | }
39 | AndroidInputStream = assetManager.Call("open", fileName);
40 | }
41 | }
42 | }
43 |
44 | if (AndroidInputStream == null)
45 | throw new System.IO.FileNotFoundException("getAssets failed", fileName);
46 | }
47 |
48 | public override void Flush ()
49 | {
50 | throw new NotImplementedException();
51 | }
52 |
53 | public override int Read(byte[] buffer, int offset, int count)
54 | {
55 | var ret = Read(AndroidInputStream, buffer, offset, count);
56 | if (ret > 0)
57 | AndroidInputStreamPostion += ret;
58 | return ret;
59 | }
60 |
61 | public override long Seek(long offset, System.IO.SeekOrigin origin)
62 | {
63 | if (offset - AndroidInputStreamPostion < 0)
64 | throw new NotImplementedException();
65 |
66 | long skip;
67 | switch (origin)
68 | {
69 | case System.IO.SeekOrigin.Begin:
70 | skip = AndroidInputStream.Call("skip", offset - AndroidInputStreamPostion);
71 | AndroidInputStreamPostion += skip;
72 | break;
73 |
74 | case System.IO.SeekOrigin.Current:
75 | skip = AndroidInputStream.Call("skip", offset);
76 | AndroidInputStreamPostion += skip;
77 | break;
78 |
79 | case System.IO.SeekOrigin.End:
80 | throw new NotImplementedException();
81 | }
82 | return AndroidInputStreamPostion;
83 | }
84 |
85 | public override void SetLength(long value)
86 | {
87 | throw new NotImplementedException();
88 | }
89 |
90 | public override void Write(byte[] buffer, int offset, int count)
91 | {
92 | throw new NotImplementedException();
93 | }
94 |
95 | public override bool CanRead
96 | {
97 | get
98 | {
99 | return AndroidInputStream != null;
100 | }
101 | }
102 | public override bool CanSeek
103 | {
104 | get
105 | {
106 | return false;
107 | }
108 | }
109 | public override bool CanWrite
110 | {
111 | get
112 | {
113 | return false;
114 | }
115 | }
116 | public override long Length
117 | {
118 | get
119 | {
120 | if (AndroidInputStreamLength == long.MaxValue)
121 | throw new NotImplementedException();
122 | return AndroidInputStreamLength;
123 | }
124 | }
125 |
126 | public override long Position
127 | {
128 | get
129 | {
130 | return AndroidInputStreamPostion;
131 | }
132 | set
133 | {
134 | throw new NotImplementedException();
135 | }
136 | }
137 |
138 | int Read(AndroidJavaObject javaObject, byte[] buffer, int offset, int count)
139 | {
140 | var args = new object[]{buffer, offset, count};
141 | IntPtr methodID = AndroidJNIHelper.GetMethodID(javaObject.GetRawClass(), "read", args, false);
142 | jvalue[] array = AndroidJNIHelper.CreateJNIArgArray(args);
143 | try
144 | {
145 | var readLen = AndroidJNI.CallIntMethod(javaObject.GetRawObject(), methodID, array);
146 | if (readLen > 0)
147 | {
148 | var temp = AndroidJNI.FromByteArray(array[0].l);
149 | Array.Copy(temp, offset, buffer, offset, readLen);
150 | }
151 | return readLen;
152 | }
153 | finally
154 | {
155 | AndroidJNIHelper.DeleteJNIArgArray(args, array);
156 | }
157 | }
158 | }
159 | }
160 | #endif
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/AndroidAssetStream.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4e682e3f60e0a433e816fa2f9701ca0e
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/DynamicObject.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | using System.IO;
4 | using System.Runtime.Serialization.Formatters.Binary;
5 |
6 | namespace dpull
7 | {
8 | public static class DynamicObject
9 | {
10 | ///
11 | /// 作用 根据基类 和 子类型的type字符串创建一个子类的实例
12 | /// 要确保要创建的对象类型和 T在一个程序集中
13 | /// 继承于T的类名字
14 | /// 该类的构造函数参数
15 | /// 该类的构造函数参数
16 | /// 成功返回 类实例,失败返回null
17 | ///
18 | public static T Create(string typename, Type[] types, object[] parameters)
19 | {
20 | Assembly assembly = typeof(T).Assembly;
21 | Type type = assembly.GetType(typename);
22 | if (type == null)
23 | return default(T);
24 |
25 |
26 | ConstructorInfo constructor = type.GetConstructor(types);
27 | if (constructor == null)
28 | return default(T);
29 |
30 | T result = (T)constructor.Invoke(parameters);
31 | return result;
32 | }
33 |
34 | public static T Clone(T item)
35 | {
36 | MemoryStream ms = new MemoryStream();
37 | BinaryFormatter bf = new BinaryFormatter();
38 | bf.Serialize(ms, item);
39 | ms.Seek(0, SeekOrigin.Begin);
40 |
41 | return (T)bf.Deserialize(ms);
42 | }
43 |
44 | ///
45 | /// 这个限制很强的一个模板函数
46 | /// 生成镜像,把原类型中的属性转化为字符串赋值给目标类
47 | /// 目标类中字段或者属性是public,且都是字符串
48 | ///
49 | ///
50 | ///
51 | ///
52 | ///
53 | public static void MirrorTo(TSource source, /*ref*/TDestination destination)
54 | {
55 | Type sourceType = typeof(TSource);
56 | Type destinationType = typeof(TDestination);
57 |
58 | FieldInfo[] fields = destinationType.GetFields();
59 | foreach (FieldInfo field in fields)
60 | {
61 | string destinationValue = GetObjectValue(source, sourceType, field.Name).ToString();
62 | field.SetValue(destination, destinationValue);
63 | }
64 |
65 | PropertyInfo[] propertys = destinationType.GetProperties();
66 | foreach (PropertyInfo property in propertys)
67 | {
68 | if (!property.CanWrite)
69 | continue;
70 |
71 | string destinationValue = GetObjectValue(source, sourceType, property.Name).ToString();
72 | property.SetValue(destination, destinationValue, null);
73 | }
74 | }
75 |
76 | static object GetObjectValue(object obj, Type objType, string name)
77 | {
78 | object result = null;
79 | PropertyInfo property = objType.GetProperty(name);
80 | if (property != null)
81 | {
82 | result = property.GetValue(obj, null);
83 | }
84 | else
85 | {
86 | FieldInfo field = objType.GetField(name);
87 | if (field == null)
88 | throw new ArgumentException(string.Format("{0}不存在类型{1}", objType.Name, name));
89 |
90 | result = field.GetValue(obj);
91 | }
92 | return result;
93 | }
94 | }
95 | }
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/DynamicObject.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2fdd2715912d6433f931003bdcbfc109
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/Editor.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 050f3c0492bf14fd3adc8ae26ff35a3f
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/Editor/AssetDatabase.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections;
3 | using UnityEditor;
4 |
5 | namespace dpull
6 | {
7 | [ExecuteInEditMode]
8 | public static class AssetDatabaseEx
9 | {
10 | static string[] GetBeDependencies(string path)
11 | {
12 | var ret = new System.Collections.Generic.List();
13 | var assets = AssetDatabase.GetAllAssetPaths();
14 | foreach (var asset in assets)
15 | {
16 | var dependencies = AssetDatabase.GetDependencies(new string[]{asset});
17 | if (ArrayUtility.Contains(dependencies, path))
18 | ret.Add(asset);
19 | }
20 | return ret.ToArray();
21 | }
22 |
23 | [MenuItem("XStudio/Tools/Search Assets")]
24 | public static void Process()
25 | {
26 | var files = GetBeDependencies("Assets/Component/ClientUIEvent.cs");
27 | foreach (var file in files)
28 | Debug.Log(file);
29 | }
30 |
31 | static bool HasDependencies(string asset, string srcCodeFile)
32 | {
33 | var dependencies = AssetDatabase.GetDependencies(new string[]{asset});
34 | foreach (var dependencie in dependencies)
35 | {
36 | if (!dependencie.Contains(srcCodeFile))
37 | continue;
38 | return true;
39 | }
40 | return false;
41 | }
42 |
43 | static void Replace(string srcCodeFile) where T : Component
44 | {
45 | var assets = AssetDatabase.GetAllAssetPaths();
46 | foreach (var asset in assets)
47 | {
48 | if (!asset.StartsWith("Assets"))
49 | continue;
50 |
51 | var assetObj = AssetDatabase.LoadMainAssetAtPath(asset);
52 | if (assetObj == null)
53 | continue;
54 |
55 | if (PrefabUtility.GetPrefabType(assetObj) != PrefabType.Prefab)
56 | continue;
57 |
58 | if (!string.IsNullOrEmpty(srcCodeFile))
59 | {
60 | if (HasDependencies(asset, srcCodeFile))
61 | continue;
62 | }
63 |
64 | var go = GameObject.Instantiate(assetObj) as GameObject;
65 | if (go == null)
66 | continue;
67 |
68 | go.name = assetObj.name;
69 | var isChange = false;
70 |
71 | var children = go.GetComponentsInChildren();
72 | foreach (var child in children)
73 | {
74 | var serializedObject = new SerializedObject(child);
75 | var sp = serializedObject.FindProperty("prefabFile");
76 | var target = sp.objectReferenceValue;
77 | if (target != null)
78 | {
79 | var path = AssetDatabase.GetAssetPath(target);
80 | var spPath = serializedObject.FindProperty("prefabPath");
81 | if (path.StartsWith("Assets/Resources/"))
82 | {
83 | spPath.stringValue = path.Substring("Assets/Resources/".Length);
84 | sp.objectReferenceValue = null;
85 | serializedObject.ApplyModifiedProperties();
86 | isChange = true;
87 | }
88 | else
89 | {
90 | Debug.Log(string.Format("asset:{0}.{1}, path{2}", asset, child.name, path));
91 | }
92 | }
93 | }
94 |
95 | if (isChange)
96 | PrefabUtility.ReplacePrefab(go, assetObj);
97 | }
98 | }
99 | }
100 | }
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/Editor/AssetDatabase.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 268bed914b12942af9289de35a3889ac
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/Editor/CodeFormat.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections;
3 | using UnityEditor;
4 |
5 | namespace dpull
6 | {
7 | [ExecuteInEditMode]
8 | public static class CodeFormat
9 | {
10 | [MenuItem("XStudio/Tools/Code Format")]
11 | public static void Process()
12 | {
13 | // ProcessDirectory("Assets/Component");
14 | // ProcessDirectory("Assets/Thirdparty/AutoBuild");
15 | ProcessDirectory("Assets/Thirdparty/UnityUtils");
16 | ProcessDirectory("Assets/Thirdparty/NGUIParticleSystem");
17 | ProcessDirectory("Assets/Thirdparty/UnityLua/Expand");
18 | Debug.Log("Code format finish");
19 | }
20 |
21 | static void ProcessDirectory(string path)
22 | {
23 | var srcs = System.IO.Directory.GetFiles(path, "*.cs", System.IO.SearchOption.AllDirectories);
24 | var utf8Encoding = new System.Text.UTF8Encoding(true);
25 |
26 | foreach(var src in srcs)
27 | {
28 | var auto = System.IO.File.ReadAllText(src);
29 | auto = auto.Replace("\r\n", "\n");
30 | auto = auto.Replace("\t", " ");
31 | System.IO.File.WriteAllText(src, auto, utf8Encoding);
32 | }
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/Editor/CodeFormat.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f3939ca28bbef46fa9bf4513ab64f372
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/Editor/CommandLine.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 |
5 | namespace dpull
6 | {
7 | public class CommandArgs
8 | {
9 | public Dictionary ArgPairs
10 | {
11 | get { return mArgPairs; }
12 | }
13 |
14 | public List Params
15 | {
16 | get { return mParams; }
17 | }
18 |
19 | List mParams = new List();
20 | Dictionary mArgPairs = new Dictionary();
21 | }
22 |
23 | public class CommandLine
24 | {
25 | public static CommandArgs Parse(string[] args)
26 | {
27 | char[] kEqual = new char[] { '=' };
28 | char[] kArgStart = new char[] { '-', '\\' };
29 | CommandArgs ca = new CommandArgs();
30 |
31 | int ii = -1;
32 | string token = NextToken(args, ref ii);
33 |
34 | while (token != null)
35 | {
36 | if (IsArg(token))
37 | {
38 | string arg = token.TrimStart(kArgStart).TrimEnd(kEqual);
39 | string value = null;
40 |
41 | if (arg.Contains("="))
42 | {
43 | string[] r = arg.Split(kEqual, 2);
44 |
45 | if (r.Length == 2 && r[1] != string.Empty)
46 | {
47 | arg = r[0];
48 | value = r[1];
49 | }
50 | }
51 |
52 | while (value == null)
53 | {
54 | if (ii > args.Length)
55 | break;
56 |
57 | string next = NextToken(args, ref ii);
58 | if (next != null)
59 | {
60 | if (IsArg(next))
61 | {
62 | ii--;
63 | value = "true";
64 | }
65 | else if (next != "=")
66 | {
67 | value = next.TrimStart(kEqual);
68 | }
69 | }
70 | }
71 | ca.ArgPairs.Add(arg, value);
72 | }
73 | else if (token != string.Empty)
74 | {
75 | ca.Params.Add(token);
76 | }
77 |
78 | token = NextToken(args, ref ii);
79 | }
80 | return ca;
81 | }
82 |
83 | static bool IsArg(string arg)
84 | {
85 | return (arg.StartsWith("-") || arg.StartsWith("\\"));
86 | }
87 |
88 | static string NextToken(string[] args, ref int ii)
89 | {
90 | ii++;
91 | while (ii < args.Length)
92 | {
93 | string cur = args[ii].Trim();
94 | if (cur != string.Empty)
95 | {
96 | return cur;
97 | }
98 | ii++;
99 | }
100 | return null;
101 | }
102 | }
103 | }
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/Editor/CommandLine.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ed673f379a571514dbd253ea7248bc8b
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/Editor/EditorGUITools.cs:
--------------------------------------------------------------------------------
1 | using UnityEditor;
2 | using UnityEngine;
3 | using System.Collections.Generic;
4 | using System.Reflection;
5 |
6 | namespace dpull
7 | {
8 | public static class EditorGUITools
9 | {
10 | static public bool DrawHeader (string text)
11 | {
12 | return DrawHeader(text, null, false, false);
13 | }
14 |
15 | static public bool DrawHeader (string text, string key, bool forceOn, bool minimalistic)
16 | {
17 | key = (key == null) ? text : key;
18 | bool state = EditorPrefs.GetBool(key, true);
19 |
20 | if (!minimalistic) GUILayout.Space(3f);
21 | if (!forceOn && !state) GUI.backgroundColor = new Color(0.8f, 0.8f, 0.8f);
22 | GUILayout.BeginHorizontal();
23 | GUI.changed = false;
24 |
25 | if (minimalistic)
26 | {
27 | if (state) text = "\u25BC" + (char)0x200a + text;
28 | else text = "\u25BA" + (char)0x200a + text;
29 |
30 | GUILayout.BeginHorizontal();
31 | GUI.contentColor = EditorGUIUtility.isProSkin ? new Color(1f, 1f, 1f, 0.7f) : new Color(0f, 0f, 0f, 0.7f);
32 | if (!GUILayout.Toggle(true, text, "PreToolbar2", GUILayout.MinWidth(20f))) state = !state;
33 | GUI.contentColor = Color.white;
34 | GUILayout.EndHorizontal();
35 | }
36 | else
37 | {
38 | text = "" + text + "";
39 | if (state) text = "\u25BC " + text;
40 | else text = "\u25BA " + text;
41 | if (!GUILayout.Toggle(true, text, "dragtab", GUILayout.MinWidth(20f))) state = !state;
42 | }
43 |
44 | if (GUI.changed)
45 | EditorPrefs.SetBool(key, state);
46 |
47 | if (!minimalistic)
48 | GUILayout.Space(2f);
49 | GUILayout.EndHorizontal();
50 | GUI.backgroundColor = Color.white;
51 | if (!forceOn && !state)
52 | GUILayout.Space(3f);
53 | return state;
54 | }
55 |
56 | static public void BeginContents ()
57 | {
58 | GUILayout.BeginHorizontal();
59 | EditorGUILayout.BeginHorizontal("AS TextArea", GUILayout.MinHeight(10f));
60 | GUILayout.BeginVertical();
61 | GUILayout.Space(2f);
62 | }
63 |
64 | static public void EndContents ()
65 | {
66 | GUILayout.Space(3f);
67 | GUILayout.EndVertical();
68 | EditorGUILayout.EndHorizontal();
69 | GUILayout.Space(3f);
70 | GUILayout.EndHorizontal();
71 | GUILayout.Space(3f);
72 | }
73 | }
74 | }
75 |
76 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/Editor/EditorGUITools.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0bcaf6b7f80974708a654328b9604b72
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/Editor/UIAdapterEditor.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections;
3 | using UnityEditor;
4 |
5 | #if USE_NGUI
6 |
7 | namespace dpull
8 | {
9 | class UIAdapterEditor : EditorWindow
10 | {
11 | [MenuItem("XStudio/Tools/UI Adapter")]
12 | public static void UIAdapter()
13 | {
14 | EditorWindow.GetWindow(false, "UI Adapter", true).Show();
15 | }
16 |
17 | UIRoot.Scaling Scaling;
18 | int ManualWidth = 1280;
19 | int ManualHeight = 720;
20 | int MinimumHeight = 320;
21 | int MaximumHeight = 1536;
22 | bool FitWidth = false;
23 | bool FitHeight = true;
24 | bool AdjustByDPI = false;
25 | bool ShrinkPortraitUI = false;
26 |
27 | void AddLine(string name, string width, string height, string widthScale, string heightScale, string widthView, string heightView, string desc)
28 | {
29 | EditorGUILayout.BeginHorizontal();
30 | EditorGUILayout.LabelField(name, GUILayout.Width(100f));
31 | EditorGUILayout.LabelField(width, GUILayout.Width(60f));
32 | EditorGUILayout.LabelField(height, GUILayout.Width(60f));
33 | EditorGUILayout.LabelField(widthScale, GUILayout.Width(60f));
34 | EditorGUILayout.LabelField(heightScale, GUILayout.Width(60f));
35 | EditorGUILayout.LabelField(widthView, GUILayout.Width(60f));
36 | EditorGUILayout.LabelField(heightView, GUILayout.Width(60f));
37 | EditorGUILayout.LabelField(desc, GUILayout.Width(100));
38 | EditorGUILayout.EndHorizontal();
39 | }
40 |
41 | void AddLine(string name, int width, int height)
42 | {
43 | if (Scaling == UIRoot.Scaling.Flexible)
44 | {
45 | int manualWidth = width;
46 | int manualHeight = height;
47 |
48 | int heightScale = activeHeight(new Vector2(width, height));
49 | int widthScale = Mathf.RoundToInt((float)manualWidth * heightScale / manualHeight);
50 | AddLine(name, width.ToString(), height.ToString(), widthScale.ToString(), heightScale.ToString(), "", "", ((float)height / heightScale).ToString());
51 | }
52 | else
53 | {
54 | int heightScale = activeHeight(new Vector2(width, height));
55 | int widthScale = Mathf.RoundToInt((float)ManualWidth * heightScale / ManualHeight);
56 | int widthView = Mathf.RoundToInt((float)width * heightScale / height);
57 | int heightView = heightScale;
58 |
59 | AddLine(name, width.ToString(), height.ToString(), widthScale.ToString(), heightScale.ToString(), widthView.ToString(), heightView.ToString(), ((float)height / heightScale).ToString());
60 | }
61 |
62 | }
63 |
64 | void OnGUI()
65 | {
66 | Scaling = (UIRoot.Scaling)EditorGUILayout.EnumPopup("Scaling Style", Scaling);
67 |
68 | if (Scaling == UIRoot.Scaling.Flexible)
69 | {
70 | MinimumHeight = EditorGUILayout.IntField("Minimum Height", MinimumHeight);
71 | MaximumHeight = EditorGUILayout.IntField("Maximum Height", MaximumHeight);
72 | ShrinkPortraitUI = EditorGUILayout.Toggle("Shrink Portrait UI", ShrinkPortraitUI);
73 | AdjustByDPI = EditorGUILayout.Toggle("Adjust by DPI", AdjustByDPI);
74 |
75 | EditorGUILayout.LabelField("结果按手机实际显示,非编辑器预览显示");
76 | }
77 | else
78 | {
79 | GUILayout.BeginHorizontal();
80 | ManualWidth = EditorGUILayout.IntField("Content Width", ManualWidth, GUILayout.Width(260f));
81 | FitWidth = EditorGUILayout.Toggle("Fit", FitWidth);
82 | GUILayout.EndHorizontal();
83 |
84 | GUILayout.BeginHorizontal();
85 | ManualHeight = EditorGUILayout.IntField("Content Height", ManualHeight, GUILayout.Width(260f));
86 | FitHeight = EditorGUILayout.Toggle("Fit", FitHeight);
87 | GUILayout.EndHorizontal();
88 | }
89 |
90 | EditorGUILayout.Space();
91 | EditorGUILayout.Space();
92 | EditorGUILayout.Space();
93 | EditorGUILayout.BeginVertical();
94 | AddLine("手机", "像素长", "像素宽", "UI缩放长", "UI缩放宽", "UI可视长", "UI可视宽", "缩放");
95 | AddLine("iPhone4", 960, 640);
96 | AddLine("iPhone5", 1136, 640);
97 | AddLine("iPhone6", 1334, 750);
98 | AddLine("iPhone6 plus", 1920, 1080);
99 | AddLine("iPad mini", 1024, 768);
100 | AddLine("iPad air", 2048, 1536);
101 |
102 | AddLine("Android1", 1280, 720);
103 | AddLine("Android2", 1920, 1080);
104 |
105 | EditorGUILayout.EndVertical();
106 | }
107 |
108 | UIRoot.Constraint constraint
109 | {
110 | get
111 | {
112 | if (FitWidth)
113 | {
114 | if (FitHeight)
115 | return UIRoot.Constraint.Fit;
116 | return UIRoot.Constraint.FitWidth;
117 | }
118 | else if (FitHeight)
119 | return UIRoot.Constraint.FitHeight;
120 | return UIRoot.Constraint.Fill;
121 | }
122 | }
123 |
124 | int activeHeight(Vector2 screen)
125 | {
126 | if (Scaling == UIRoot.Scaling.Flexible)
127 | {
128 | float aspect = screen.x / screen.y;
129 |
130 | if (screen.y < MinimumHeight)
131 | {
132 | screen.y = MinimumHeight;
133 | screen.x = screen.y * aspect;
134 | }
135 | else if (screen.y > MaximumHeight)
136 | {
137 | screen.y = MaximumHeight;
138 | screen.x = screen.y * aspect;
139 | }
140 |
141 | // Portrait mode uses the maximum of width or height to shrink the UI
142 | int height = Mathf.RoundToInt((ShrinkPortraitUI && screen.y > screen.x) ? screen.y / aspect : screen.y);
143 |
144 | // Adjust the final value by the DPI setting
145 | return AdjustByDPI ? NGUIMath.AdjustByDPI(height) : height;
146 | }
147 | else
148 | {
149 | var cons = constraint;
150 | if (cons == UIRoot.Constraint.FitHeight)
151 | return ManualHeight;
152 |
153 | float aspect = screen.x / screen.y;
154 | float initialAspect = (float)ManualWidth / ManualHeight;
155 |
156 | switch (cons)
157 | {
158 | case UIRoot.Constraint.FitWidth:
159 | {
160 | return Mathf.RoundToInt(ManualWidth / aspect);
161 | }
162 |
163 | case UIRoot.Constraint.Fit:
164 | {
165 | return (initialAspect > aspect) ? Mathf.RoundToInt(ManualWidth / aspect) : ManualHeight;
166 | }
167 | case UIRoot.Constraint.Fill:
168 | {
169 | return (initialAspect < aspect) ? Mathf.RoundToInt(ManualWidth / aspect) : ManualHeight;
170 | }
171 | }
172 | return ManualHeight;
173 | }
174 | }
175 | }
176 | }
177 | #endif
178 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/Editor/UIAdapterEditor.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f172c1c2d038242f6b1728b9351165f2
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/EventHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace dpull
6 | {
7 | public static class EventHelper
8 | {
9 | //警告 8 CA1030
10 | public static void Raise(EventHandler hander, object sender, TEventArgs args)
11 | where TEventArgs : EventArgs
12 | {
13 | //.net设计规范 P128
14 | EventHandler eventHander = hander;
15 | if (eventHander != null)
16 | {
17 | eventHander(sender, args);
18 | }
19 | }
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/EventHelper.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f4dd23d51297444e294d741e5ec1f0d5
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/IO.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using UnityEngine;
4 | using System.Collections;
5 | using System.Text;
6 |
7 | namespace dpull
8 | {
9 | public class DirectoryEx
10 | {
11 | public static void CreateDirectory(string path)
12 | {
13 | path = Path.GetFullPath(path);
14 | CreateDirectory(new DirectoryInfo(path));
15 | }
16 |
17 | public static void CreateDirectory(DirectoryInfo path)
18 | {
19 | if (path.Exists)
20 | return;
21 |
22 | while (true)
23 | {
24 | var parent = path.Parent;
25 | if (parent == null || parent.Exists)
26 | break;
27 | CreateDirectory(parent);
28 | }
29 |
30 | path.Create();
31 | }
32 |
33 | public static void DeleteDirectory(string path)
34 | {
35 | path = Path.GetFullPath(path);
36 | if (Directory.Exists(path))
37 | Directory.Delete(path, true);
38 | }
39 | }
40 |
41 | public class FileEx
42 | {
43 | public static Stream OpenRead(string sourceFileName)
44 | {
45 | #if UNITY_ANDROID
46 | if (sourceFileName.StartsWith(Application.streamingAssetsPath))
47 | {
48 | var startIndex = Application.streamingAssetsPath.Length;
49 | if (!PathEx.EndWithDirectorySeparatorChar(Application.streamingAssetsPath))
50 | startIndex++;
51 |
52 | sourceFileName = sourceFileName.Substring(startIndex);
53 | return new AndroidAssetStream(sourceFileName);
54 | }
55 | #endif
56 | return File.OpenRead(sourceFileName);
57 | }
58 |
59 | public static bool SetFileLength(string filepath, long length)
60 | {
61 | try
62 | {
63 | using (FileStream fs = new FileStream(filepath, FileMode.Create, FileAccess.Write, FileShare.None))
64 | {
65 | fs.SetLength(length);
66 | }
67 | }
68 | catch (System.Exception e)
69 | {
70 | Debug.LogException(e);
71 | File.Delete(filepath);
72 | return false;
73 | }
74 |
75 | return true;
76 | }
77 |
78 | public static long GetFileLength(string filepath)
79 | {
80 | FileInfo fileInfo = new FileInfo(filepath);
81 | return fileInfo.Length;
82 | }
83 | }
84 |
85 | public class PathEx
86 | {
87 | public static bool EndWithDirectorySeparatorChar(string path)
88 | {
89 | return path.EndsWith("\\") || path.EndsWith("/");
90 | }
91 |
92 | ///
93 | /// 绝对路径转相对路径
94 | ///
95 | /// 基本路径
96 | /// 绝对路径
97 | /// strFullPath相对于strBasePath的相对路径
98 | public static string GetRelativePath(string strBasePath, string strFullPath)
99 | {
100 | if (strBasePath == null)
101 | throw new ArgumentNullException("strBasePath");
102 |
103 | if (strFullPath == null)
104 | throw new ArgumentNullException("strFullPath");
105 |
106 | strBasePath = Path.GetFullPath(strBasePath);
107 | strFullPath = Path.GetFullPath(strFullPath);
108 |
109 | var DirectoryPos = new int[strBasePath.Length];
110 | int nPosCount = 0;
111 |
112 | DirectoryPos[nPosCount] = -1;
113 | ++nPosCount;
114 |
115 | int nDirectoryPos = 0;
116 | while (true)
117 | {
118 | nDirectoryPos = strBasePath.IndexOf('\\', nDirectoryPos);
119 | if (nDirectoryPos == -1)
120 | break;
121 |
122 | DirectoryPos[nPosCount] = nDirectoryPos;
123 | ++nPosCount;
124 | ++nDirectoryPos;
125 | }
126 |
127 | if (!strBasePath.EndsWith("\\"))
128 | {
129 | DirectoryPos[nPosCount] = strBasePath.Length;
130 | ++nPosCount;
131 | }
132 |
133 | int nCommon = -1;
134 | for (int i = 1; i < nPosCount; ++i)
135 | {
136 | int nStart = DirectoryPos[i - 1] + 1;
137 | int nLength = DirectoryPos[i] - nStart;
138 |
139 | if (string.Compare(strBasePath, nStart, strFullPath, nStart, nLength, true) != 0)
140 | break;
141 |
142 | nCommon = i;
143 | }
144 |
145 | if (nCommon == -1)
146 | return strFullPath;
147 |
148 | var strBuilder = new StringBuilder();
149 | for (int i = nCommon + 1; i < nPosCount; ++i)
150 | strBuilder.Append("..\\");
151 |
152 | int nSubStartPos = DirectoryPos[nCommon] + 1;
153 | if (nSubStartPos < strFullPath.Length)
154 | strBuilder.Append(strFullPath.Substring(nSubStartPos));
155 |
156 | string strResult = strBuilder.ToString();
157 | return strResult == string.Empty ? ".\\" : strResult;
158 | }
159 | }
160 | }
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/IO.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 926594a7b1ad44952939b03be5706c75
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/Log.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections;
3 |
4 | namespace dpull
5 | {
6 | public class Log : MonoBehaviour
7 | {
8 | private System.IO.StreamWriter LogWriter;
9 |
10 | void Start ()
11 | {
12 | CleanOldLog();
13 | Application.RegisterLogCallback(HandleLog);
14 | }
15 |
16 | void OnDestory()
17 | {
18 | Application.RegisterLogCallback(null);
19 | }
20 |
21 | string GetLogDirectory()
22 | {
23 | var path = System.IO.Path.Combine(Application.persistentDataPath, "logs");
24 | if (!System.IO.Directory.Exists(path))
25 | System.IO.Directory.CreateDirectory(path);
26 | return path;
27 | }
28 |
29 | void CleanOldLog()
30 | {
31 | var dir = GetLogDirectory();
32 | var files = System.IO.Directory.GetFiles(dir, "*.log", System.IO.SearchOption.AllDirectories);
33 | var now = System.DateTime.Now;
34 | var expirationTime = new System.TimeSpan(24 * 3, 0, 0);
35 |
36 | foreach (var file in files)
37 | {
38 | var fileInfo = new System.IO.FileInfo(file);
39 | var subTime = now - fileInfo.LastWriteTime;
40 | if (subTime < expirationTime)
41 | continue;
42 |
43 | try
44 | {
45 | System.IO.File.Delete(file);
46 | }
47 | catch
48 | {
49 | }
50 | }
51 | }
52 |
53 | void HandleLog(string logString, string stackTrace, LogType type)
54 | {
55 | if (type == LogType.Log && !logString.StartsWith("Lua:"))
56 | return;
57 |
58 | if (LogWriter == null)
59 | {
60 | lock(this)
61 | {
62 | if (LogWriter == null)
63 | {
64 | try
65 | {
66 | var logfile = GetLogDirectory();
67 | logfile = System.IO.Path.Combine(logfile, string.Format("{0}.log", System.DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss")));
68 | LogWriter = new System.IO.StreamWriter(logfile);
69 | }
70 | catch
71 | {
72 | }
73 | }
74 | }
75 | }
76 |
77 | if (LogWriter != null)
78 | {
79 | this.SendMessage("CacheLog", new string[]{logString, stackTrace}, SendMessageOptions.DontRequireReceiver);
80 |
81 | string log = string.Format("{0}<{1}>: {2}", System.DateTime.Now.ToString("MM-dd HH:mm:ss"), type.ToString(), logString);
82 | LogWriter.WriteLine(log);
83 | if (!string.IsNullOrEmpty(stackTrace))
84 | {
85 | var formatStackTrace = stackTrace.Replace("\n", "\n\t");
86 | LogWriter.Write("\t");
87 | LogWriter.WriteLine(formatStackTrace);
88 | }
89 | LogWriter.Flush();
90 | }
91 | }
92 | }
93 | }
94 |
95 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/Log.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ab1b27f637c1d4df8aa907d15c5a855f
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/README.md:
--------------------------------------------------------------------------------
1 | # unity_utils #
2 |
3 | 是开发中用到的一些和项目无关的小工具
4 |
5 | ## Log ##
6 |
7 | 日志组件
8 |
9 | ## IO ##
10 |
11 | IO 扩展
12 |
13 | ## AndroidAssetStream ##
14 |
15 | Android AssetManager
16 |
17 | ## Editor/UIAdapterEditor ##
18 |
19 | 用来做NGUI适配
20 |
21 | ## Editor/CodeFormat ##
22 |
23 | 解决不同程序使用mac和windows系统开发引入的一些问题:
24 |
25 | 1. 换行符到底是\r\n 还是 \n
26 | 1. 文件中的中文是不是utf8
27 | 1. 文件有没有unf8 bom头
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/README.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 01b5646e6f0084461a3c0e4adbbb1e59
3 | DefaultImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/SimpleJson.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 91c2d808697a8490eb32aa082c83c936
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/Util.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 |
5 | public static class Util
6 | {
7 | public static T GetChildByName(this GameObject go, string name) where T:Component
8 | {
9 | var child = GetChildByName(go, name);
10 | if (child == null)
11 | return default(T);
12 |
13 | return child.gameObject.GetComponent();
14 | }
15 |
16 | public static GameObject GetChildByName(this GameObject go, string name)
17 | {
18 | var child = GetChildByName(go.transform, name);
19 | return child == null ? null : child.gameObject;
20 | }
21 |
22 | public static Transform GetChildByName(Transform tr, string name)
23 | {
24 | // 广度优先
25 | foreach (Transform child in tr)
26 | {
27 | if (child.name == name)
28 | return child;
29 | }
30 |
31 | foreach (Transform child in tr)
32 | {
33 | Transform c = GetChildByName(child, name);
34 | if (c != null)
35 | return c;
36 | }
37 |
38 | return null;
39 | }
40 |
41 | public delegate bool TraversalCallback(Transform go);
42 | public static bool Traversal(this Transform transform, TraversalCallback callback)
43 | {
44 | // 深度优先
45 | foreach (Transform child in transform)
46 | {
47 | if (!callback(child))
48 | return false;
49 |
50 | if (!child.Traversal(callback))
51 | return false;
52 | }
53 | return true;
54 | }
55 |
56 | public static void ChangeLayer(GameObject go, int layer)
57 | {
58 | go.layer = layer;
59 | go.transform.Traversal(child=>{child.gameObject.layer = layer; return true; });
60 | }
61 |
62 | public static string UrlToIP(string url)
63 | {
64 | try
65 | {
66 | var host = System.Net.Dns.GetHostEntry(url);
67 | foreach (System.Net.IPAddress ip in host.AddressList)
68 | {
69 | if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
70 | return ip.ToString();
71 | }
72 | return url;
73 | }
74 | catch(System.Exception e)
75 | {
76 | Debug.LogException(e);
77 | return url;
78 | }
79 | }
80 |
81 | public static string Md5File(string file)
82 | {
83 | using (var stream = System.IO.File.OpenRead(file))
84 | {
85 | var md5 = System.Security.Cryptography.MD5.Create();
86 | var data = md5.ComputeHash(stream);
87 | var sb = new System.Text.StringBuilder();
88 |
89 | foreach(var b in data)
90 | {
91 | sb.Append(b.ToString("x2"));
92 | }
93 | return sb.ToString().ToLower();
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/Assets/Thirdparty/UnityUtils/Util.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 18eda558b679f4a3bb9d4b93966e87b2
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015-2017 dpull.com
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/ProjectSettings/AudioManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/ProjectSettings/AudioManager.asset
--------------------------------------------------------------------------------
/ProjectSettings/DynamicsManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/ProjectSettings/DynamicsManager.asset
--------------------------------------------------------------------------------
/ProjectSettings/EditorBuildSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/ProjectSettings/EditorBuildSettings.asset
--------------------------------------------------------------------------------
/ProjectSettings/EditorSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/ProjectSettings/EditorSettings.asset
--------------------------------------------------------------------------------
/ProjectSettings/GraphicsSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/ProjectSettings/GraphicsSettings.asset
--------------------------------------------------------------------------------
/ProjectSettings/InputManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/ProjectSettings/InputManager.asset
--------------------------------------------------------------------------------
/ProjectSettings/NavMeshLayers.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/ProjectSettings/NavMeshLayers.asset
--------------------------------------------------------------------------------
/ProjectSettings/NetworkManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/ProjectSettings/NetworkManager.asset
--------------------------------------------------------------------------------
/ProjectSettings/Physics2DSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/ProjectSettings/Physics2DSettings.asset
--------------------------------------------------------------------------------
/ProjectSettings/ProjectSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/ProjectSettings/ProjectSettings.asset
--------------------------------------------------------------------------------
/ProjectSettings/QualitySettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/ProjectSettings/QualitySettings.asset
--------------------------------------------------------------------------------
/ProjectSettings/TagManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/ProjectSettings/TagManager.asset
--------------------------------------------------------------------------------
/ProjectSettings/TimeManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpull/AssetBundlePatch/d3f008d3c5d561f7c865f6178362a2396da240f6/ProjectSettings/TimeManager.asset
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AssetBundlePatch #
2 |
3 | `AssetBundlePatch` 可以对 Unity3d 的 AssetBundle进行差异更新。
4 |
5 | 可以根据客户端安装包资源和已有的AssetBundle包,判断出重复资源,只进行差异更新。
6 |
7 | 该插件诞生过程:[http://www.dpull.com/blog/2015-01-23-hero_assetbundle](http://www.dpull.com/blog/2015-01-23-hero_assetbundle)
8 |
9 | # 测试工程使用方法 #
10 | 测试环境:编辑器:unity4.6 mac, windows;移动设备:itouch4, 小米2
11 |
12 | ## iPhone ##
13 | 1. 打开XStudio->Tools->One Builder插件界面
14 | 1. 点击 Test iPhone 按钮
15 | 1. 运行 根目录中的 Bin/iPhone 文件夹中的XCode工程
16 | 1. 发布到手机上。
17 |
18 | ## Android ##
19 | 1. 打开XStudio->Tools->One Builder插件界面
20 | 1. 点击 Test Android 按钮
21 | 1. 使用Eclipse Import 根目录中的 Bin/Android 文件夹
22 | 1. 发布到手机上。
23 |
24 | # 做了什么 #
25 | 该工程共有两个场景,一个小人跑在蓝色的场景上(Level1),一个小人跑在绿色的场景上(Level2),也就是说,除了场景的材质,其他的资源都是一样的。
26 |
27 | 我们的安装包通过BuildPlayer只Build了Level1,然后通过BuildStreamedSceneAssetBundle制作了Level2的AssetBundle,这个AssetBundle有2.93MB,但其实这个AssetBundle中的大部分资源都在客户端安装包中,使用 `AssetBundlePatch`将其取差异,将差异压缩后大小为19.4KB,然后客户端开始运行时,通过`AssetBundlePatch` 将其恢复为原来2.93MB的AssetBundle,合并完成后客户端将Enter Level2的按钮,可以进入绿色背景的Level2.
28 |
29 |
30 | # 依赖库 #
31 |
32 | * [`SharpZip.dll`](https://github.com/icsharpcode/SharpZipLib) 多种压缩格式的解压和压缩库。
33 | * [`AssetBundleParser.dll`](https://github.com/dpull/AssetBundleParser) AssetBundle文件的解析库,因为效率,写在了C中,其实就是 [`disunity`](https://github.com/ata4/disunity) 的C版本
34 |
--------------------------------------------------------------------------------