Unity S老師系列課程學習

AssetBundle(建立打包)入門學習(基於Unity2017) (已看)html

  分組策略ios

  1. 邏輯實體分組
  2. 按照類型分組
  3. 按照使用分組 

  分組策略----總結git

  1. 把常常更新的資源放在一個單獨的包裏面,跟不常常更新的包分離
  2. 把須要同時加載的資源放在一個包裏面
  3. 能夠把其餘包共享的資源放在一個單獨的包裏面
  4. 把一些須要同時加載的小資源打包成一個包
  5. 若是對於同一個資源有兩個版本,能夠考慮經過後綴來區分

  

  BuildAssetBundleOptionsgithub

  1. BuildAssetBundleOptions.None: 使用LZMA算法壓縮,壓縮的包更小,可是加載時間更長.使用以前須要總體壓縮.一旦被解壓,這個包會使用LZ4從新壓縮.使用資源的時候不須要總體解壓.在下載的時候可使用LZMA算法,一旦
  2. BuildAssetBundleOptions.UncompressedAssetBundle: 不壓縮,包大,加載快
  3. BuildAssetBundleOptions.ChunkBasedCompression: 使用LZ4壓縮,壓縮率沒有LZMA高,可是咱們能夠加載指定資源而不用解壓所有
ManifestFileVersion: 0 CRC: 1389444494 AssetBundleManifest: AssetBundleInfo: Info_0: Name: share.untiy3d Dependencies: {} Info_1: Name: capsulewall.unity3d Dependencies: Dependency_0: share.unity3d Info_2: Name: cubewall.unity3d Dependencies: Dependency_0: share.unity3d
AssetBundles.manifest

  文件校驗算法

  CRC MD5 SHA1
相同點:
  CRC、MD五、SHA1都是經過對數據進行計算,來生成一個校驗值,該校驗值用來校驗數據的完整性。
不一樣點:express

  1. 算法不一樣。CRC採用多項式除法,MD5和SHA1使用的是替換、輪轉等方法;
  2. 校驗值的長度不一樣。CRC校驗位的長度跟其多項式有關係,通常爲16位或32位;MD5是16個字節(128位);SHA1是20個字節(160位);
  3. 校驗值的稱呼不一樣。CRC通常叫作CRC值;MD5和SHA1通常叫作哈希值(Hash)或散列值;
  4. 安全性不一樣。這裏的安全性是指檢錯的能力,即數據的錯誤能經過校驗位檢測出來。CRC的安全性跟多項式有很大關係,相對於MD5和SHA1要弱不少;MD5的安全性很高,不過大概在04年的時候被山東大學的王小云破解了;SHA1的安全性最高。
  5. 效率不一樣,CRC的計算效率很高;MD5和SHA1比較慢。
  6. 用途不一樣。CRC通常用做通訊數據的校驗;MD5和SHA1用於安全(Security)領域,好比文件校驗、數字簽名等。

 

Asset: https://docs.unity3d.com/Manual/AssetWorkflow.html編程

  An Asset is a representation of any item you can use in your game or Project.windows

  An Asset may come from a file created outside of Unity, such as a 3D Model, an audio file, an image, or any of the other file types that Unity supports.設計模式

  There are also some Asset types that you can create in Unity, such as a ProBuilder Mesh , an Animator Controller , an Audio Mixer, or a Render Texture.緩存

SpecialFolders: https://docs.unity3d.com/Manual/SpecialFolders.html

  • Asset: The Assets folder is the main folder that contains the Assets used by a Unity project.
  • Editor: Scripts placed in a folder called Editor are treated as Editor scripts rather than runtime scripts.These scripts add functionality to the Editor during development, and are not available in builds at runtime.
  • Editor Default Resources: Editor scripts can make use of Asset files loaded-on-demand using the EditorGUIUtility.Load function. This function looks for the Asset files in a folder called Editor Default Resources. You can only have one 
  • Gizmos:  You can only have one Gizmos folder and it must be placed in the root of the Project.
  • Plug-ins: You can only have one Plugins folder and it must be placed in the root of the Project; directly within the Assets folders;
  • Resources: You can load Assets on-demand from a script instead of creating instances of Assets in a Scene for use in gameplay. You do this by placing the Assets in a folder called Resources
  • Standard Assets: When you import a Standard Asset package the Assets are placed in a folder called Standard Assets.
  • StreamingAssets: Place a file in a folder called StreamingAssets,so it is copied unchanged to the target machine, where it is then available from a specific folder.
  • Hidden Assets: During the import process, Unity completely ignores the following files and folders in the Assets folder
  1. Hidden folders
  2. Files and folders which start with '.'
  3. Files and folders which end with '~'
  4. Files and folders named cvs
  5. Files with the extension .tmp

StreamingAssets: https://docs.unity3d.com/Manual/StreamingAssets.html

  Any files placed in a folder called StreamingAssets (case-sensitive) in a Unity project will be copied verbatim to a particular folder on the target machine

    On a desktop computer:  path = Application.dataPath + "/StreamingAssets"

    On iOS, use:  path = Application.dataPath + "/Raw"

    On Android, use:  path = "jar:file://" + Application.dataPath + "!/assets/";

AssetBundles: https://docs.unity3d.com/Manual/AssetBundlesIntro.html

  AssetBundle Workflow  

    An AssetBundle is an archive file containing platform specific Assets (Models, Textures, Prefabs, Audio clips, and even entire Scenes) that can be loaded at runtime.

    AssetBundles can express dependencies between each other; e.g. a material in AssetBundle A can reference a texture in AssetBundle B.

    For efficient delivery over networks, AssetBundles can be compressed with a choice of built-in algorithms depending on use case requirements (LZMA and LZ4).

What's in an AssetBundle?

    AssetBundle can refer to two different, but related things.

      First is the actual file on disk. This we call the AssetBundle archive, or just archive for short in this document. The archive can be thought of as a container, like a folder, that holds additional files inside of it. These additional files consist of two types; the serialized file and resource files. The serialized file contains your assets broken out into their individual objects and written out to this single file. The resource files are just chunks of binary data stored separately for certain assets (textures and audio) to allow us to load them from disk on another thread efficiently.

      Second is the actual AssetBundle object you interact with via code to load assets from a specific archive. This object contains a map of all the file paths of the assets you added to this archive to the objects that belong to that asset that need to be loaded when you ask for it.

public class CRC32 { static UInt32[] crcTable = { 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 }; public static uint GetCRC32(string msg) { byte[] bytes = System.Text.Encoding.UTF8.GetBytes(msg); uint iCount = (uint)bytes.Length; uint crc = 0xFFFFFFFF; for (uint i = 0; i < iCount; i++) { crc = (crc << 8) ^ crcTable[(crc >> 24) ^ bytes[i]]; } return crc; } }
View Code

  Preparing Assets for AssetBundles

  Building AssetBundles

  AssetBundle Dependencies

    AssetBundles can become dependent on other AssetBundles if one or more of the UnityEngine.Objects contains a reference to a UnityEngine.Object located in another bundle. A dependency does not occur if the UnityEngine.Object contains a reference to a UnityEngine.Object that is not contained in any AssetBundle. In this case, a copy of the object that the bundle would be dependent on is copied into the bundle when you build the AssetBundles. If multiple objects in multiple bundles contain a reference to the same object that isn’t assigned to a bundle, every bundle that would have a dependency on that object will make its own copy of the object and package it into the built AssetBundle.

    Should an AssetBundle contain a dependency, it is important that the bundles that contain those dependencies are loaded before the object you’re attempting to instantiate is loaded. Unity will not attempt to automatically load dependencies.

    Consider the following example, a Material in Bundle 1 references a Texture in Bundle 2:

In this example, before loading the Material from Bundle 1, you would need to load Bundle 2 into memory. It does not matter which order you load Bundle 1 and Bundle 2, the important takeaway is that Bundle 2 is loaded before loading the Material from Bundle 1.

  Using AssetBundles Natively 

  Patching with AssetBundles

  Troubleshooting

  Unity Asset Bundle Browser tool 

AssetBundle框架設計_理論篇 (已看)

AssetBundle框架設計_框架篇 (已看)

AB打包分類  

  按類型  

  按場景  包名稱 = "場景名稱/功能文件夾名"

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using System.IO; namespace ABFramework { /// <summary>
    /// 1. 定義須要打包資源的文件夾根目錄 /// 2. 遍歷每一個"場景"文件夾(目錄) /// a. 遍歷本場景目錄下全部的目錄或者文件 /// 若是是目錄,則繼續"遞歸"訪問裏面的文件,直到定位到文件 /// b. 找到文件,則使用AssetImporter類,標記"包名"與"後綴名" /// </summary>
    public class AutoSetABName { /// <summary>
        /// 設置AB包名稱 /// </summary>
        [MenuItem("AssetBundleTools/Set AB Name")] public static void SetABName() { AssetDatabase.RemoveUnusedAssetBundleNames(); string abResPath = string.Empty; abResPath = PathTools.GetABResourcesPath(); DirectoryInfo[] dirScenesArray = null;  // 根目錄下的全部一級子目錄
 DirectoryInfo dirTempInfo = new DirectoryInfo(abResPath); dirScenesArray = dirTempInfo.GetDirectories(); foreach (var item in dirScenesArray) { string tempSceneDir = abResPath + "/" + item.Name;  // 全路徑 //DirectoryInfo tempSceneDirInfo = new DirectoryInfo(tempSceneDir);

                int tempIndex = tempSceneDir.LastIndexOf("/"); string tempSceneName = tempSceneDir.Substring(tempIndex + 1);  // 場景名稱
 JudgeDirOrFileRecursive(item, tempSceneName); } AssetDatabase.Refresh(); Debug.Log("AssetBundle 本次操做設置標記完成!"); } private static void JudgeDirOrFileRecursive(FileSystemInfo fileSystemInfo, string sceneName) { if (!fileSystemInfo.Exists) { Debug.LogError("文件或目錄名稱: " + fileSystemInfo + "不存在,檢查"); return; } DirectoryInfo dirInfo = fileSystemInfo as DirectoryInfo;    // 文件信息轉換爲目錄信息
            FileSystemInfo[] fileSystemInfoArr = dirInfo.GetFileSystemInfos(); foreach (var item in fileSystemInfoArr) { FileInfo fileInfo = item as FileInfo; if (fileInfo != null) { SetFileABName(fileInfo, sceneName); // 設置文件的AB名
                } else { JudgeDirOrFileRecursive(item, sceneName); // 遞歸目錄
 } } } /// <summary>
        /// 對指定的文件設置AB包名 /// </summary>
        private static void SetFileABName(FileInfo fileInfo, string sceneName) { string abName = string.Empty; string assetFilePath = string.Empty;    // 文件路徑(相對路徑)

            if (fileInfo.Extension == ".meta") { return; } abName = GetABName(fileInfo, sceneName); // 獲取資源文件的相對路徑
            int tempIndex = fileInfo.FullName.IndexOf("Assets"); assetFilePath = fileInfo.FullName.Substring(tempIndex); AssetImporter tempImporter = AssetImporter.GetAtPath(assetFilePath); tempImporter.assetBundleName = abName; //Debug.Log("assetFilePath: " + assetFilePath); //Debug.Log("abName: " + abName);

            if (fileInfo.Extension == ".unity") { tempImporter.assetBundleVariant = "u3d"; } else { tempImporter.assetBundleVariant = "ab"; } //Debug.Log(fileInfo.FullName); //Debug.Log(tempImporter.assetBundleVariant); //if (fileInfo.Extension == ".unity") { //    // 定義AB包的擴展名 //} //Debug.Log(assetFilePath); //AssetImporter tempImporter = AssetImporter.GetAtPath(fileInfo.FullName); //Debug.Log(tempImporter); //Debug.Log(tempImporter.)
 } /// <summary>
        /// 獲取AB包的名稱 /// 
        /// AB包造成規則 /// 文件AB包名稱 = "所在二級目錄名稱"(場景名稱) + "三級目錄名稱"(下一級的"類型名稱") /// </summary>
        private static string GetABName(FileInfo fileInfo, string sceneName) { string abName = string.Empty; // Win路徑
            string tempWinPath = fileInfo.FullName; // Unity路徑
            string tempUnityPath = tempWinPath.Replace("\\", "/"); // 定位"場景名稱"後面字符的位置
            int tempSceneNazmePos = tempUnityPath.IndexOf(sceneName) + sceneName.Length; // AB包中的"類型名稱"所在區域
            string abFileNameArea = tempUnityPath.Substring(tempSceneNazmePos + 1); if (abFileNameArea.Contains("/")) { string[] tempStrArr = abFileNameArea.Split('/'); abName = sceneName + "/" + tempStrArr[0]; } else { // .unity AB包名
                abName = sceneName + "/" + sceneName; } return abName; } } }
AutoSetABName
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using System.IO; namespace ABFramework { public class BuildAssetBundle { [MenuItem("AssetBundleTools/BuildAllAssetBundles")] public static void BuildAllAB() { string abOutPathDir = string.Empty; abOutPathDir = PathTools.GetABOutputPath(); if (!Directory.Exists(abOutPathDir)) { Directory.CreateDirectory(abOutPathDir); } BuildPipeline.BuildAssetBundles(abOutPathDir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64); } } }
BuildAssetBundle
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using System.IO; namespace ABFramework { public class DeleteAssetBundle { [MenuItem("AssetBundleTools/DeleteAllAssetBundle")] public static void DelAssetBundle() { string deleteDir = string.Empty; deleteDir = PathTools.GetABOutputPath(); if (!string.IsNullOrEmpty(deleteDir)) { Directory.Delete(deleteDir, true); File.Delete(deleteDir + " .meta"); AssetDatabase.Refresh(); } } } }
DeleteAssetBundle
using System.Collections; using System.Collections.Generic; using UnityEngine; namespace ABFramework { /* 委託定義 */
    public delegate void ABLoadComplete(string abName); public class ABDefine { public static readonly string ASSETBUNDLEMANIFEST = "AssetBundleManifest"; } }
ABDefine
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PathTools { /* 路徑常量 */
    public const string AB_RESOURCES = "AB_Res"; /// <summary>
    /// 獲取AB資源的輸入目錄 /// </summary>
    public static string GetABResourcesPath() { return Application.dataPath + "/" + AB_RESOURCES; } /// <summary>
    /// 獲取AB資源的輸出目錄 /// 1. 平臺路徑 /// 2. 平臺的名稱 /// </summary>
    public static string GetABOutputPath() { return GetPlatformPath() + "/" + GetPlatformName(); } /// <summary>
    /// 獲取平臺路徑 /// </summary>
    private static string GetPlatformPath() { string platformPath = string.Empty; switch (Application.platform) { case RuntimePlatform.WindowsPlayer: case RuntimePlatform.WindowsEditor: platformPath = Application.streamingAssetsPath; break; case RuntimePlatform.IPhonePlayer: case RuntimePlatform.Android: platformPath = Application.persistentDataPath; break; } return platformPath; } /// <summary>
    /// 獲取平臺名稱 /// </summary>
    public static string GetPlatformName() { string platformName = string.Empty; switch (Application.platform) { case RuntimePlatform.WindowsPlayer: case RuntimePlatform.WindowsEditor: platformName = "Windows"; break; case RuntimePlatform.IPhonePlayer: platformName = "iPhone"; break; case RuntimePlatform.Android: platformName = "Android"; break; } return platformName; } /// <summary>
    /// 獲取WWW下載(AB包)路徑 /// </summary>
    public static string GetWWWPath() { string WWWPath = string.Empty; switch (Application.platform) { case RuntimePlatform.WindowsPlayer: case RuntimePlatform.WindowsEditor: WWWPath = "file://" + GetABOutputPath(); break; case RuntimePlatform.Android: WWWPath = "jar:file://" + GetABOutputPath(); break; case RuntimePlatform.IPhonePlayer: WWWPath = GetABOutputPath() + "/Raw/"; break; } return WWWPath; } }
PathTools
using System.Collections; using System.Collections.Generic; using UnityEngine; namespace ABFramework { /// <summary>
    /// 讀取AssetBundle依賴關係文件 /// </summary>
    public class ABManifestLoader : System.IDisposable { private static ABManifestLoader instance; private AssetBundleManifest manifest; private string manifestPath; // 讀取Manifest的AB
        private AssetBundle manifestAB; private bool isLoaded; public bool IsLoaded { get { return isLoaded; } } public static ABManifestLoader Instance { get { if (instance == null) { instance = new ABManifestLoader(); } return instance; } } private ABManifestLoader() { manifestPath = PathTools.GetWWWPath() + "/" + PathTools.GetPlatformName(); manifest = null; manifestAB = null; isLoaded = false; } /// <summary>
        /// 加載Manifest清單文件 /// </summary>
        /// <returns></returns>
        public IEnumerator LoadManifest() { using (WWW www = new WWW(manifestPath)) { yield return www; if (www.progress >= 1) { AssetBundle ab = www.assetBundle; if (ab != null) { manifestAB = ab; manifest = manifestAB.LoadAsset(ABDefine.ASSETBUNDLEMANIFEST) as AssetBundleManifest;    // "AssetBundleManifest"固定寫法
                        isLoaded = true; } else { Debug.Log(GetType() + "/LoadManifest()/WWW下載出錯,請檢查! manifestPath = " + manifestPath + " 錯誤信息: " + www.error); } } } } /// <summary>
        /// 獲取Manifest /// </summary>
        public AssetBundleManifest GetABManifest() { if (isLoaded) { if (manifest != null) { return manifest; } else { Debug.Log(GetType() + "/GetABManifest()/manifest == null!請檢查"); } } else { Debug.Log(GetType() + "/GetABManifest()/isLoaded == false,Manifest沒有加載完畢!請檢查"); } return null; } /// <summary>
        /// 獲取Manifest中指定包名的依賴項 /// </summary>
        /// <returns></returns>
        public string[] GetAllDependency(string abName) { if (manifest != null && !string.IsNullOrEmpty(abName)) { return manifest.GetAllDependencies(abName); } return null; } /// <summary>
        /// 釋放資源 /// </summary>
        public void Dispose() { if (manifestAB != null) { manifestAB.Unload(true); } } } }
ABManifestLoader
using System.Collections; using System.Collections.Generic; using UnityEngine; namespace ABFramework { /// <summary>
    /// 1. 存儲指定AB包的全部依賴關係包 /// 2. 存儲指定AB包的全部被引用關係包 /// </summary>
    public class ABRelation { // 當前AB包名
        private string abName; // 當前AB包的全部依賴包
        private List<string> dependencyABList; // 當前AB包的全部被引用包
        private List<string> referenceABList; public ABRelation(string abName) { if (!string.IsNullOrEmpty(abName)) { this.abName = abName; } dependencyABList = new List<string>(); referenceABList = new List<string>(); } /* 依賴關係 */

        /// <summary>
        /// 增長依賴關係 /// </summary>
        public void AddDependency(string abName) { if (!dependencyABList.Contains(abName)) { dependencyABList.Add(abName); } } /// <summary>
        /// 移除依賴關係 /// </summary>
        /// <returns>
        /// true 此AB沒有依賴項 /// false 此AB還有依賴項 /// </returns>
        public bool RemoveDependency(string abName) { if (dependencyABList.Contains(abName)) { dependencyABList.Remove(abName); } if (dependencyABList.Count > 0) { return false; } else { return true; } } /// <summary>
        /// 獲取全部依賴關係 /// </summary>
        /// <returns></returns>
        public List<string> GetAllDependency() { return dependencyABList; } /* 被引用關係 */


        /// <summary>
        /// 增長被引用關係 /// </summary>
        public void AddReference(string abName) { if (!referenceABList.Contains(abName)) { referenceABList.Add(abName); } } /// <summary>
        /// 移除被引用關係 /// </summary>
        /// <returns>
        /// true 此AB沒有被引用項 /// false 此AB還有被引用項 /// </returns>
        public bool RemoveReference(string abName) { if (referenceABList.Contains(abName)) { referenceABList.Remove(abName); } if (dependencyABList.Count > 0) { return false; } else { return true; } } /// <summary>
        /// 獲取全部被引用關係 /// </summary>
        /// <returns></returns>
        public List<string> GetAllReference() { return referenceABList; } } }
ABRelation
using System.Collections; using System.Collections.Generic; using UnityEngine; namespace ABFramework { /// <summary>
    /// 框架主流程(4): 全部場景的AssetBundle管理 /// 
    /// 1. 讀取Manifest /// 2. 以場景爲單位,管理整個項目中全部的AssetBundle包 /// </summary>
    public class AssetBundleMgr : MonoBehaviour { private static AssetBundleMgr instance; private Dictionary<string, MultiABMgr> multiABMgrDict = new Dictionary<string, MultiABMgr>(); private AssetBundleManifest manifest = null; public static AssetBundleMgr Instance() { if (instance == null) { instance = new GameObject("AssetBundleMgr").AddComponent<AssetBundleMgr>(); } return instance; } private AssetBundleMgr() { } private void Awake() { StartCoroutine(ABManifestLoader.Instance.LoadManifest()); } public IEnumerator LoadAssetBundle(string sceneName, string abName, ABLoadComplete abLoadComplete) { // 參數檢查
            if (string.IsNullOrEmpty(sceneName) || string.IsNullOrEmpty(abName)) { Debug.LogError(GetType() + "/LoadAssetBundle()/sceneName or abName == null,請檢查!"); yield return null; } // 等待Manifest文件加載完成
            while (!ABManifestLoader.Instance.IsLoaded) { yield return null; } manifest = ABManifestLoader.Instance.GetABManifest(); if (manifest == null) { Debug.LogError(GetType() + "/LoadAssetBundle()/manifest == null,請檢查!"); yield return null; } // 加入當前場景
            if (!multiABMgrDict.ContainsKey(sceneName)) { MultiABMgr multiABMgr = new MultiABMgr(sceneName, abName, abLoadComplete); multiABMgrDict.Add(sceneName, multiABMgr); } // 調用下一層(多包管理)
            MultiABMgr tempMultiABMgr = multiABMgrDict[sceneName]; if (tempMultiABMgr == null) { Debug.LogError(GetType() + "/LoadAssetBundle()/tempMultiABMgr == null,請檢查!"); } yield return tempMultiABMgr.LoadAssetBundle(abName); } /// <summary>
        /// 加載(AB包中)資源 /// </summary>
        public UnityEngine.Object LoadAsset(string sceneName, string abName, string assetName, bool isCache) { if (multiABMgrDict.ContainsKey(sceneName)) { MultiABMgr multiABMgr = multiABMgrDict[sceneName]; return multiABMgr.LoadAsset(abName, assetName, isCache); } Debug.LogError(GetType() + "/LoadAsset()/找不到場景名稱,沒法加載資源,請檢查! sceneName: " + sceneName); return null; } /// <summary>
        /// 釋放資源 /// </summary>
        public void DisposeAllAsset(string sceneName) { if (multiABMgrDict.ContainsKey(sceneName)) { MultiABMgr multiABMgr = multiABMgrDict[sceneName]; multiABMgr.DisposeAllAsset(); } else { Debug.LogError(GetType() + "/LoadAsset()/找不到場景名稱,沒法釋放資源,請檢查! sceneName: " + sceneName); } } } }
AssetBundleMgr
using System.Collections; using System.Collections.Generic; using UnityEngine; namespace ABFramework { /// <summary>
    /// 框架主流程 1. AB資源加載類 /// 
    /// AB包內資源的加載 /// 
    /// 功能: /// 1. 管理與加載指定AB的資源 /// 2. 加載具備"緩存功能"的資源,帶選用參數 /// 3. 卸載,釋放AB資源 /// 4. 查看當前AB資源 /// </summary>
    public class AssetLoader : System.IDisposable { private AssetBundle currentAB; private Dictionary<string, Object> ht; public AssetLoader(AssetBundle ab) { if (ab != null) { currentAB = ab; ht = new Dictionary<string, Object>(); } else { Debug.LogError(GetType() + "/構造函數 AssetBundle()/ 參數 ab == null!,請檢查"); } } /// <summary>
        /// 加載當前包中指定的資源 /// </summary>
        public UnityEngine.Object LoadAsset(string assetName, bool isCache = false) { return LoadResource<UnityEngine.Object>(assetName, isCache); } /// <summary>
        /// 加載當前AB包的資源 /// </summary>
        private T LoadResource<T>(string assetName, bool isCahce) where T: UnityEngine.Object { if (ht.ContainsKey(assetName)) { return ht[assetName] as T; } T tempRes = currentAB.LoadAsset<T>(assetName); if (tempRes != null && isCahce) { ht.Add(assetName, tempRes); } else if (tempRes == null) { Debug.LogError(GetType() + "/LoadResource<T>/參數 tempRes==null, 請檢查"); } return tempRes; } /// <summary>
        /// 卸載指定資源 /// </summary>
        public bool UnLoadAsset(UnityEngine.Object asset) { if (asset != null) { Resources.UnloadAsset(asset); return true; } Debug.LogError(GetType() + "/UnLoadAsset()/參數 asset == null, 請檢查"); return false; } /// <summary>
        /// 釋放當前AssetBundle內存鏡像資源 /// </summary>
        public void Dispose() { currentAB.Unload(false); } /// <summary>
        /// 釋放當前AssetBundle內存鏡像資源,且釋放內存資源 /// </summary>
        public void DisposeAll() { currentAB.Unload(true); } /// <summary>
        /// 查詢當前AssetBundle中包含的全部資源名稱 /// </summary>
        /// <returns></returns>
        public string[] GetAllAssetName() { return currentAB.GetAllAssetNames(); } } }
AssetLoader
using System.Collections; using System.Collections.Generic; using UnityEngine; namespace ABFramework { /// <summary>
    /// 主流程(3): (一個場景中)多個AssetBundle管理 /// 
    /// 1. 獲取AB包的依賴與引用 /// 2. 管理AB包之間的自動連鎖(遞歸)加載機制 /// </summary>
    public class MultiABMgr { private SingleABLoader singleABLoader; // 緩存AB包,防止重複加載
        private Dictionary<string, SingleABLoader> singleABLoaderDict; // 當前場景(調試使用)
        private string currentSceneName; private string currentABName; private Dictionary<string, ABRelation> abRelationDict; private ABLoadComplete loadCompleteHandler; public MultiABMgr(string sceneName, string abName, ABLoadComplete abLoadComplete) { currentSceneName = sceneName; currentABName = abName; singleABLoaderDict = new Dictionary<string, SingleABLoader>(); abRelationDict = new Dictionary<string, ABRelation>(); loadCompleteHandler = abLoadComplete; } /// <summary>
        /// 完成指定AB包的調用 /// </summary>
        /// <param name="abName"></param>
        private void LoadABCompleted(string abName) { //Debug.Log(GetType() + "/當前完成ABName:" + abName);
            if (abName.Equals(currentABName)) { if (loadCompleteHandler != null) { loadCompleteHandler(abName); } } } /// <summary>
        /// 加載AB包 /// </summary>
        public IEnumerator LoadAssetBundle(string abName) { // AB包關係的創建
            if (!abRelationDict.ContainsKey(abName)) { ABRelation abRelation = new ABRelation(abName); abRelationDict.Add(abName, abRelation); } ABRelation tempABRelation = abRelationDict[abName]; // 獲得指定AB包全部的依賴關係(查詢manifest文件)
            string[] abDependencyArr = ABManifestLoader.Instance.GetAllDependency(abName); foreach (var item in abDependencyArr) { Debug.Log("abName: " + abName + ", depenABName: " + item); // 添加依賴項
 tempABRelation.AddDependency(item); // 添加被引用項
                yield return LoadReference(item, abName); } //Debug.Log(tempABRelation.GetAllDependency()); //Debug.Log(tempABRelation.GetAllReference()); // 真正加載AB包
            if (singleABLoaderDict.ContainsKey(abName)) { yield return singleABLoaderDict[abName].LoadAssetBundle(); } else { singleABLoader = new SingleABLoader(abName, LoadABCompleted); singleABLoaderDict.Add(abName, singleABLoader); yield return singleABLoader.LoadAssetBundle(); } } /// <summary>
        /// 加載被引用AB包 /// </summary>
        private IEnumerator LoadReference(string abName, string refABName) { if (abRelationDict.ContainsKey(abName)) { ABRelation tempABRelation = abRelationDict[abName]; // 添加AB包被引用關係(被依賴)
 tempABRelation.AddReference(refABName); } else { ABRelation tempABRelation = new ABRelation(abName); tempABRelation.AddReference(refABName); abRelationDict.Add(abName, tempABRelation); // 開始加載依賴的包
                yield return LoadAssetBundle(abName); } } /// <summary>
        /// 加載(AB包中)資源 /// </summary>
        public UnityEngine.Object LoadAsset(string abName, string assetName, bool isCache) { foreach (var item in singleABLoaderDict.Keys) { if (abName == item) { return singleABLoaderDict[item].LoadAsset(assetName, isCache); } } Debug.LogError(GetType() + "/LoadAsset()/找不到AssetBundle包,沒法加載資源,請檢查! abName = " + abName + ", assetName = " + assetName); return null; } /// <summary>
        /// 釋放本場景中全部的資源 /// </summary>
        public void DisposeAllAsset() { try { foreach (var item in singleABLoaderDict.Values) { item.DisposeAll(); } } finally { singleABLoaderDict.Clear(); singleABLoaderDict = null; abRelationDict.Clear(); abRelationDict = null; currentABName = null; currentSceneName = null; loadCompleteHandler = null; Resources.UnloadUnusedAssets(); System.GC.Collect(); } } } }
MultiABMgr
using System.Collections; using System.Collections.Generic; using UnityEngine; namespace ABFramework { /// <summary>
    /// 框架主流程 /// 2. WWW 加載AssetBundle /// 
    /// AB包內資源的加載 /// 
    /// 功能: /// 1. 管理與加載指定AB的資源 /// 2. 加載具備"緩存功能"的資源,帶選用參數 /// 3. 卸載,釋放AB資源 /// 4. 查看當前AB資源 /// </summary>
    public class SingleABLoader : System.IDisposable { private AssetLoader assetLoader; private ABLoadComplete abLoadCompleteHandler; private string abName; private string abDownloadPath; public SingleABLoader(string abName, ABLoadComplete loadComplete) { assetLoader = null; abLoadCompleteHandler = loadComplete; this.abName = abName; abDownloadPath = PathTools.GetWWWPath() + "/" + abName; } public IEnumerator LoadAssetBundle() { using (WWW www = new WWW(abDownloadPath)) { yield return www; if (www.progress >= 1) { AssetBundle ab = www.assetBundle; if (ab != null) { assetLoader = new AssetLoader(ab); if (abLoadCompleteHandler != null) { abLoadCompleteHandler(abName); } } else { Debug.LogError(GetType() + "/LoadAssetBundle()/www下載出錯,請檢查! AssetBundle URL: " + abDownloadPath + " 錯誤信息: " + www.error); } } } } /// <summary>
        /// 加載(AB包內)資源 /// </summary>
        public UnityEngine.Object LoadAsset(string assetName, bool isCache) { if (assetLoader != null) { return assetLoader.LoadAsset(assetName, isCache); } Debug.LogError(GetType() + "/LoadAsset/assetLoader==null!, 請檢查!"); return null; } /// <summary>
        /// 卸載(AB包內)資源 /// </summary>
        public void UnLoadAsset(UnityEngine.Object asset) { if (assetLoader != null) { assetLoader.UnLoadAsset(asset); } else { Debug.LogError(GetType() + "/UnLoadAsset()/參數 assetLoader == null, 請檢查!"); } } /// <summary>
        /// 釋放資源 /// </summary>
        public void Dispose() { if (assetLoader != null) { assetLoader.Dispose(); assetLoader = null; } else { Debug.LogError(GetType() + "/Dispose()/參數 assetLoader == null, 請檢查!"); } } /// <summary>
        /// 釋放當前AssetBundle資源包,且卸載全部資源 /// </summary>
        public void DisposeAll() { if (assetLoader != null) { assetLoader.DisposeAll(); assetLoader = null; } else { Debug.LogError(GetType() + "/DisposeAll()/參數 assetLoader == null, 請檢查!"); } } /// <summary>
        /// 查詢當前AssetBundle包中全部的資源 /// </summary>
        public string[] GetAllAssetName() { if (assetLoader != null) { return assetLoader.GetAllAssetName(); } Debug.LogError(GetType() + "/RetrieveAllAssetName()/參數 assetLoader == null, 請檢查!"); return null; } } }
SingleABLoader
using System.Collections; using System.Collections.Generic; using UnityEngine; namespace ABFramework { public class Test_SingleABLoader : MonoBehaviour { private SingleABLoader loader = null; private string dependABName1 = "scene_1/textures.ab"; private string dependABName2 = "scene_1/materials.ab"; private string abName1 = "scene_1/prefabs.ab"; private string assetName1 = "TestCubePrefab.prefab"; #region 簡單(無依賴包)預設的加載

        //void Start() { // loader = new SingleABLoader(abName1, LoadComplete); // StartCoroutine(loader.LoadAssetBundle()); //} //private void LoadComplete(string abName) { // var prefab = loader.LoadAsset(assetName1, false); // GameObject.Instantiate(prefab); //}

        #endregion

        void Start() { //SingleABLoader dependABLoader = new SingleABLoader(dependABName1, LoadDependAB1Complete); //StartCoroutine(dependABLoader.LoadAssetBundle()); //StartCoroutine(ABManifestLoader.Instance.LoadManifest());
 } void Update() { if (Input.GetKeyDown(KeyCode.A)) { Debug.Log("釋放資源"); //loader.Dispose();
 loader.DisposeAll(); } } private void LoadDependAB1Complete(string abName) { Debug.Log(abName + "加載完成"); SingleABLoader dependABLoader = new SingleABLoader(dependABName2, LoadDependAB2Complete); StartCoroutine(dependABLoader.LoadAssetBundle()); } private void LoadDependAB2Complete(string abName) { Debug.Log(abName + "加載完成"); loader = new SingleABLoader(abName1, LoadAB1Complete); StartCoroutine(loader.LoadAssetBundle()); } private void LoadAB1Complete(string abName) { Debug.Log(abName + "加載完成"); var prefab = loader.LoadAsset(assetName1, false); GameObject.Instantiate(prefab); string[] arr = loader.GetAllAssetName(); foreach (var item in arr) { Debug.Log(item); } } } }
Test_SingleABLoader
using System.Collections; using System.Collections.Generic; using UnityEngine; namespace ABFramework { public class Test_Framework : MonoBehaviour { private string sceneName = "scene_1"; private string abName = "scene_1/prefabs.ab"; private string assetName = "TestCubePrefab.prefab"; private void Start() { Debug.Log("開始 ABFramework 測試"); // 調用AB包(連鎖智能調用AB包)
 StartCoroutine(AssetBundleMgr.Instance().LoadAssetBundle(sceneName, abName, LoadALLABComplete)); } private void LoadALLABComplete(string abName) { Debug.Log("全部的AB包都已經加載完畢了"); Object tempObj = AssetBundleMgr.Instance().LoadAsset(sceneName, abName, assetName, false); if (tempObj != null) { Instantiate(tempObj); } } private void Update() { if (Input.GetKeyDown(KeyCode.A)) { Debug.Log("測試銷燬資源"); AssetBundleMgr.Instance().DisposeAllAsset(sceneName); } } } }
Test_Framework

 

 

Lua編程 (已看)

  https://www.lua.org/

  https://www.runoob.com/lua/lua-tutorial.html

  https://github.com/rjpcomputing/luaforwindows/releases

  http://luadist.org/

 

xLua遊戲中的熱更新(基於Unity2017) (已看)

  https://gameinstitute.qq.com/community/detail/111400

  https://github.com/Tencent/xLua

CSharpCallLua.lua.txt print('hi') a = 100 str = "siki" isDie = false person = { name = "siki1", 11, 22, 33, 44, age = 10, eat = function(self, a, b) print(a + b) end } function add(a, b) print(a + b) return a + b, a, b end --[[ function person:eat(a,b) print(a + b) end --]] CSharpCallLua.cs using System.Collections; using System.Collections.Generic; using UnityEngine; using XLua; using System; public class CSharpCallLua : MonoBehaviour { void Start() { LuaEnv luaEnv = new LuaEnv(); luaEnv.DoString("require 'CSharpCallLua'"); int a = luaEnv.Global.Get<int>("a"); print(a); string str = luaEnv.Global.Get<string>("str"); print(str); bool isDie = luaEnv.Global.Get<bool>("isDie"); print(isDie); //Person p = luaEnv.Global.Get<Person>("person"); //print(p.name + "-" + p.age); //IPerson p = luaEnv.Global.Get<IPerson>("person"); //print(p.name + "-" + p.age); //p.name = "Sikiedu.com"; //p.eat(12, 34); //luaEnv.DoString("print(person.name)"); //luaEnv.Dispose(); //Dictionary<string,object> dict = luaEnv.Global.Get<Dictionary<string, object>>("person"); //foreach (string key in dict.Keys) { // print(key + "-" + dict[key]); //} //List<object> list = luaEnv.Global.Get<List<object>>("person"); //foreach (object o in list) { // print(o); //} //LuaTable tab = luaEnv.Global.Get<LuaTable>("person"); //print(tab.Get<string>("name")); //print(tab.Length); //Action<int, int> act = luaEnv.Global.Get<Action<int, int>>("add"); //act(1, 2); //Add add = luaEnv.Global.Get<Add>("add"); //int resa, resb; //int res = add(1, 2, out resa, out resb); //print(res + " " + resa + " " + resb);
 LuaFunction func = luaEnv.Global.Get<LuaFunction>("add"); object[] os = func.Call(1, 2); foreach (object o in os) { print(o); } luaEnv.Dispose(); } [CSharpCallLua] delegate int Add(int a, int b, out int resa, out int resb); class Person { public string name; public int age; } [CSharpCallLua] interface IPerson { string name { get; set; } int age { get; set; } void eat(int a, int b); } } LuaCallCSharp.lua.txt CS.UnityEngine.GameObject("new by lua") print(CS.UnityEngine.Time.deltaTime) local camera = CS.UnityEngine.GameObject.Find("Main Camera") camera.name = "update" local cameraCom = camera:GetComponent("Camera") CS.UnityEngine.GameObject.Destroy(cameraCom) LuaCallCSharp.cs using System.Collections; using System.Collections.Generic; using UnityEngine; using XLua; public class LuaCallCSharp : MonoBehaviour { // Use this for initialization
    void Start () { LuaEnv luaEnv = new LuaEnv(); luaEnv.DoString("require 'LuaCallCSharp'"); luaEnv.Dispose(); } // Update is called once per frame
    void Update () { } }
View Code

 

遊戲熱更新實戰案例(基於xLua) (已看)

1.0版本

Effect

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; /// <summary>
/// 星星閃耀的特效 /// </summary>
public class Shine : MonoBehaviour { private Image img; public float speed=4; private bool add; public void Awake() { img = GetComponent<Image>(); } // Use this for initialization
    void Start () { } // Update is called once per frame
    void Update () { transform.Rotate(Vector3.forward * 4, Space.World); if (!add) { img.color -= new Color(0, 0, 0, Time.deltaTime * speed); if (img.color.a <=0.2f) { add = true; } } else { img.color += new Color(0, 0, 0, Time.deltaTime * speed); if (img.color.a >=0.8f) { add = false; } } } }
Shine  Main/Canvas/Panel/UI_Stars/Img_Star
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; /// <summary>
/// 隱藏顯示閃耀UI的特效,好比槍,星星 /// </summary>
public class ShineHide : MonoBehaviour { private float timeVal = 0; private bool isAdd = false; private Image img; public float defineTime = 3; void Awake() { img = GetComponent<Image>(); } // Use this for initialization
    void Start () { } // Update is called once per frame
    void Update () { timeVal += Time.deltaTime; if (!isAdd) { img.color -= new Color(0, 0, 0, Time.deltaTime * 5); if (timeVal > defineTime) { img.color = new Color(img.color.r, img.color.g, img.color.b, 0); isAdd = true; timeVal = 0; } } else { img.color += new Color(0, 0, 0, Time.deltaTime * 5); if (timeVal > defineTime) { img.color = new Color(img.color.r, img.color.g, img.color.b, 1); isAdd = false; timeVal = 0; } } } } 
ShineHide  Main/Canvas/Panel/UI_StartGame/But_StartGame
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary>
/// 爆炸特效 /// </summary>
public class Explosion : MonoBehaviour { public float DestoryTime = 0.2f; // Use this for initialization
    void Start () { Destroy(this.gameObject, DestoryTime); } // Update is called once per frame
    void Update () { transform.localScale +=new Vector3(Time.deltaTime*10, Time.deltaTime*10, Time.deltaTime*10) ; } }
Explosion  Prefabs/Effects/explosion...
using UnityEngine; using System.Collections; public class Pao : MonoBehaviour { /// <summary>
/// 遊戲中產生的泡泡 /// </summary>
    public int moveSpeed; public bool isGamePao; // Use this for initialization
    void Start () { if (isGamePao) { moveSpeed = Random.Range(2, 4); Destroy(this.gameObject, Random.Range(0.5f, 1f)); } else { moveSpeed = Random.Range(40, 100); Destroy(this.gameObject, Random.Range(7f, 10f)); } } // Update is called once per frame
    void Update () { transform.Translate(-transform.right*moveSpeed*Time.deltaTime,Space.World); } }
Pao  Prefabs/Effects/Pao
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary>
/// boss攻擊玩家產生的震動方法 /// </summary>
public class Shake : MonoBehaviour { private float cameraShake = 2; public GameObject UI; // Use this for initialization
    void Start () { } // Update is called once per frame
    void Update () { if (Gun.Instance.bossAttack) { UI.SetActive(true); transform.position = new Vector3((Random.Range(0f, cameraShake)) - cameraShake*0.5f, transform.position.y, transform.position.z); transform.position = new Vector3(transform.position.x, transform.position.y, (Random.Range(0f, cameraShake)) - cameraShake * 0.5f); cameraShake = cameraShake / 1.05f; if (cameraShake<0.05f) { cameraShake= 0; UI.SetActive(false); Gun.Instance.bossAttack = false; } } else { cameraShake = 5; } } }
Shake  Fish/Main Camera
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; /// <summary>
/// 隱藏顯示閃耀UI的特效,好比槍,星星 /// </summary>
public class ShineHide : MonoBehaviour { private float timeVal = 0; private bool isAdd = false; private Image img; public float defineTime = 3; void Awake() { img = GetComponent<Image>(); } // Use this for initialization
    void Start () { } // Update is called once per frame
    void Update () { timeVal += Time.deltaTime; if (!isAdd) { img.color -= new Color(0, 0, 0, Time.deltaTime * 5); if (timeVal > defineTime) { img.color = new Color(img.color.r, img.color.g, img.color.b, 0); isAdd = true; timeVal = 0; } } else { img.color += new Color(0, 0, 0, Time.deltaTime * 5); if (timeVal > defineTime) { img.color = new Color(img.color.r, img.color.g, img.color.b, 1); isAdd = false; timeVal = 0; } } } } 
ShineHide  Fish/Canvas/Img_Gun/Img_GunLight
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary>
/// 水紋播放的特效 /// </summary>
public class Water : MonoBehaviour { private SpriteRenderer sr; public Sprite[] pictures; private int count=0; // Use this for initialization
    void Start () { sr = GetComponent<SpriteRenderer>(); } // Update is called once per frame
    void Update () { sr.sprite = pictures[count]; count++; if (count==pictures.Length) { count = 0; } } }
Water  Prefabs/Enemy/Fish1/Fire

Enemy

using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary>
/// 擋子彈的氣泡 /// </summary>
public class Qipao : MonoBehaviour { //屬性
    public float moveSpeed = 2; //計時器
    private float rotateTime; // Use this for initialization
    void Start() { Destroy(this.gameObject, 14); } // Update is called once per frame
    void Update() { fishMove(); } public void fishMove() { transform.Translate(transform.right * moveSpeed * Time.deltaTime, Space.World); if (rotateTime >= 5) { transform.Rotate(transform.forward * Random.Range(0, 361), Space.World); rotateTime = 0; } else { rotateTime += Time.deltaTime; } } public void TakeDamage(int attackValue) { Destroy(this.gameObject); } }
Qipao  Prefabs/Enemy/Qipao
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary>
/// boss腳本 /// </summary>

public class Boss : MonoBehaviour { public int hp = 50; public GameObject deadEeffect; public int GetGold = 10; public int GetDiamands = 10; public GameObject diamands; public GameObject gold; public float moveSpeed = 2; protected int m_reduceGold; protected int m_reduceDiamond; protected Transform playerTransform; protected GameObject fire; protected GameObject ice; protected Animator iceAni; protected Animator gameObjectAni; protected AudioSource bossAudio; //計時器
    private float rotateTime; private float timeVal; protected bool hasIce; protected bool isAttack; void Start() { fire = transform.Find("Fire").gameObject; ice = transform.Find("Ice").gameObject; iceAni = ice.transform.GetComponent<Animator>(); gameObjectAni = GetComponent<Animator>(); bossAudio = GetComponent<AudioSource>(); playerTransform = Gun.Instance.transform; m_reduceGold = 10; m_reduceDiamond = 0; } // Update is called once per frame
    void Update() { //冰凍效果
        if (Gun.Instance.Ice) { gameObjectAni.enabled = false; ice.SetActive(true); if (!hasIce) { iceAni.SetTrigger("Ice"); hasIce = true; } } else { gameObjectAni.enabled = true; hasIce = false; ice.SetActive(false); } //灼燒效果
        if (Gun.Instance.Fire) { fire.SetActive(true); } else { fire.SetActive(false); } if (Gun.Instance.Ice) { return; } //boss的行爲方法
 Attack(m_reduceGold, m_reduceDiamond); if (!isAttack) { fishMove(); } } public virtual void TakeDamage(int attackValue) { if (Gun.Instance.Fire) { attackValue *= 2; } hp -= attackValue; if (hp <= 0) { Instantiate(deadEeffect, transform.position, transform.rotation); Gun.Instance.GoldChange(GetGold * 10); Gun.Instance.DiamandsChange(GetDiamands * 10); for (int i = 0; i < 11; i++) { GameObject itemGo = Instantiate(gold, transform.position, Quaternion.Euler(transform.eulerAngles + new Vector3(0, 18 + 36 * (i - 1), 0))); itemGo.GetComponent<Gold>().bossPrize = true; } for (int i = 0; i < 11; i++) { GameObject itemGo = Instantiate(diamands, transform.position, Quaternion.Euler(transform.eulerAngles + new Vector3(0, 36 + 36 * (i - 1), 0))); itemGo.GetComponent<Gold>().bossPrize = true; } Destroy(this.gameObject); } } public void fishMove() { transform.Translate(transform.right * moveSpeed * Time.deltaTime, Space.World); if (rotateTime >= 5) { transform.Rotate(transform.forward * Random.Range(0, 361), Space.World); rotateTime = 0; } else { rotateTime += Time.deltaTime; } } public void Attack(int reduceGold, int reduceDiamond) { if (timeVal > 20) { transform.LookAt(playerTransform); transform.eulerAngles += new Vector3(90, -90, 0); isAttack = true; timeVal = 0; } else { timeVal += Time.deltaTime; } if (isAttack) { gameObjectAni.SetBool("isAttack", true); transform.position = Vector3.Lerp(transform.position, playerTransform.position, 1 / Vector3.Distance(transform.position, playerTransform.position) * Time.deltaTime * moveSpeed); if (Vector3.Distance(transform.position, playerTransform.position) <= 4) { if (reduceGold != 0) { Gun.Instance.GoldChange(reduceGold); } if (reduceDiamond != 0) { Gun.Instance.DiamandsChange(reduceDiamond); } gameObjectAni.SetBool("isAttack", false); isAttack = false; Gun.Instance.BossAttack(); rotateTime = 0; Invoke("ReturnAngle", 4); } } } public void ReturnAngle() { transform.eulerAngles = new Vector3(90, 0, 0); } }
Boss  Prefabs/Enemy/Boss2
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary>
/// 產魚器 /// </summary>

public class CreateFish : MonoBehaviour { //引用
    public GameObject[] fishList; public GameObject[] item; public GameObject boss; public GameObject boss2; public GameObject boss3; public Transform[] CreateFishPlace; private float ItemtimeVal = 0;//遊戲物體計時器
    private float createManyFish; private float timeVals = 0; //成員變量
    private int num; private int ItemNum; private int placeNum; private int CreateMorden; //x:-26 - 26 //z:-16 - 16
    private void Awake() { } // Use this for initialization
    void Start() { } void Update() { //魚羣的生成
 CreateALotOfFish(); //單種魚的生成
        if (ItemtimeVal >= 0.5) { //位置隨機數
            num = Random.Range(0, 4); //遊戲物體隨機數
            ItemNum = Random.Range(1, 101); //產生氣泡
            if (ItemNum < 20) { CreateGameObject(item[3]); CreateGameObject(fishList[6]); } //貝殼10% 85-94 //第一種魚42% 42
            if (ItemNum <= 42) { CreateGameObject(fishList[0]); CreateGameObject(item[0]); CreateGameObject(fishList[3]); CreateGameObject(item[0]); } //第二種魚30% 43-72
            else if (ItemNum >= 43 && ItemNum < 72) { CreateGameObject(fishList[1]); CreateGameObject(item[0]); CreateGameObject(fishList[4]); } //第三種魚10% 73-84
            else if (ItemNum >= 73 && ItemNum < 84) { CreateGameObject(fishList[2]); CreateGameObject(fishList[5]); } //第一種美人魚5%,第二種3% 95-98 99-100


            else if (ItemNum >= 94 && ItemNum <= 98) { CreateGameObject(item[1]); } else if (ItemNum >= 84 && ItemNum < 86) { CreateGameObject(boss2); } else if (ItemNum > 98 && ItemNum < 100) { CreateGameObject(item[2]); CreateGameObject(boss); } else { CreateGameObject(item[0]); CreateGameObject(boss3); } ItemtimeVal = 0; } else { ItemtimeVal += Time.deltaTime; } } //生成魚羣
    private void CreateALotOfFish() { if (createManyFish >= 15) { if (CreateMorden == 2) { GameObject go = fishList[Random.Range(2, fishList.Length)]; for (int i = 0; i < 11; i++) { GameObject itemGo = Instantiate(go, transform.position, Quaternion.Euler(transform.eulerAngles + new Vector3(0, 45 * i, 0))); itemGo.GetComponent<Fish>().cantRotate = true; } createManyFish = 0; } else if (CreateMorden == 0 || CreateMorden == 1) { createManyFish += Time.deltaTime; if (createManyFish >= 18) { createManyFish = 0; } if (timeVals >= 0.2f) { int num = Random.Range(0, 2); GameObject itemGo = Instantiate(fishList[num], CreateFishPlace[placeNum].position + new Vector3(0, 0, Random.Range(-2, 2)), CreateFishPlace[placeNum].rotation); itemGo.GetComponent<Fish>().cantRotate = true; timeVals = 0; } else { timeVals += Time.deltaTime; } } } else { createManyFish += Time.deltaTime; placeNum = Random.Range(0, 2); CreateMorden = Random.Range(0, 3); } } private void CreateFishs(GameObject go) { Instantiate(go, RandomPos(num), Quaternion.Euler(go.transform.eulerAngles)); } //產生遊戲物體
    private void CreateGameObject(GameObject go) { Instantiate(go, RandomPos(num), Quaternion.Euler(RandomAngle(num) + go.transform.eulerAngles)); } //隨機位置
    private Vector3 RandomPos(int num) { Vector3 Vpositon = new Vector3(); switch (num) { case 0: Vpositon = new Vector3(-24, 1, Random.Range(-14f, 14f));//-30 - 30
                break; case 1: Vpositon = new Vector3(Random.Range(-24f, 24f), 1, 14);//60 - 120
                break; case 2: Vpositon = new Vector3(24, 1, Random.Range(-14f, 14f));//150-210
                break; case 3: Vpositon = new Vector3(Random.Range(-24f, 24f), 1, -14);//-60- -120
                break; default: break; } return Vpositon; } //隨機角度
    private Vector3 RandomAngle(int num) { Vector3 Vangle = new Vector3(); switch (num) { case 0: Vangle = new Vector3(0, Random.Range(-30f, 30f), 0);//-30 - 30
                break; case 1: Vangle = new Vector3(0, Random.Range(60f, 120f), 0);//60 - 120
                break; case 2: Vangle = new Vector3(0, Random.Range(150f, 210f), 0);//150-210
                break; case 3: Vangle = new Vector3(0, Random.Range(-60f, -120f), 0);//-60- -120
                break; default: break; } return Vangle; } }
CreateFish  Fish/CreateFish/Place/FishCreate
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary>
/// 有護盾的boss /// </summary>
public class DeffendBoss : Boss { private bool isDeffend = false; private float deffendTime = 0; public GameObject deffend; void Start() { fire = transform.Find("Fire").gameObject; ice = transform.Find("Ice").gameObject; iceAni = ice.transform.GetComponent<Animator>(); gameObjectAni = GetComponent<Animator>(); bossAudio = GetComponent<AudioSource>(); playerTransform = Gun.Instance.transform; } // Update is called once per frame
    void Update() { //冰凍效果
        if (Gun.Instance.Ice) { gameObjectAni.enabled = false; ice.SetActive(true); if (!hasIce) { iceAni.SetTrigger("Ice"); hasIce = true; } } else { gameObjectAni.enabled = true; hasIce = false; ice.SetActive(false); } //灼燒效果
        if (Gun.Instance.Fire) { fire.SetActive(true); } else { fire.SetActive(false); } if (Gun.Instance.Ice) { return; } //boss的行爲方法
 Attack(m_reduceGold, m_reduceDiamond); if (!isAttack) { fishMove(); } //保護方法
        if (deffendTime >= 10) { deffendTime = 0; DeffenMe(); } else { deffendTime += Time.deltaTime; } } void DeffenMe() { isDeffend = true; deffend.SetActive(true); Invoke("CloseDeffendMe", 3); } private void CloseDeffendMe() { deffend.SetActive(false); isDeffend = false; } public override void TakeDamage(int attackValue) { if (isDeffend) { return; } base.TakeDamage(attackValue); } }
DeffendBoss  Prefabs/Enemy/Boss1
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary>
/// 普通魚的類 /// </summary>

public class Fish : MonoBehaviour { //屬性
    public float moveSpeed = 2; public int GetCold = 10; public int GetDiamands = 10; public int hp = 5; //計時器
    private float rotateTime; private float timeVal; //引用
    public GameObject gold; public GameObject diamands; private GameObject fire; private GameObject ice; private Animator iceAni; private Animator gameObjectAni; private SpriteRenderer sr; public GameObject pao; //開關
    private bool hasIce = false; public bool isnet; private bool isDead = false; public bool cantRotate = false; // Use this for initialization
    void Start() { fire = transform.Find("Fire").gameObject; ice = transform.Find("Ice").gameObject; iceAni = ice.transform.GetComponent<Animator>(); gameObjectAni = GetComponent<Animator>(); sr = GetComponent<SpriteRenderer>(); Destroy(this.gameObject, 20); } // Update is called once per frame
    void Update() { if (timeVal >= 14 || isDead) { sr.color -= new Color(0, 0, 0, Time.deltaTime); } else { timeVal += Time.deltaTime; } if (isDead) { return; } //冰凍效果
        if (Gun.Instance.Ice) { gameObjectAni.enabled = false; ice.SetActive(true); if (!hasIce) { iceAni.SetTrigger("Ice"); hasIce = true; } } else { gameObjectAni.enabled = true; hasIce = false; ice.SetActive(false); } //灼燒方法
        if (Gun.Instance.Fire) { fire.SetActive(true); } else { fire.SetActive(false); } if (Gun.Instance.Ice) { return; } if (isnet) { Invoke("Net", 0.5f); return; } fishMove(); } public void Net() { if (isnet) { isnet = false; } } public void fishMove() { transform.Translate(transform.right * moveSpeed * Time.deltaTime, Space.World); if (cantRotate) { return; } if (rotateTime >= 5) { transform.Rotate(transform.forward * Random.Range(0, 361), Space.World); rotateTime = 0; } else { rotateTime += Time.deltaTime; } } public void TakeDamage(int attackValue) { if (Gun.Instance.Fire) { attackValue *= 2; } hp -= attackValue; if (hp <= 0) { isDead = true; for (int i = 0; i < 9; i++) { Instantiate(pao, transform.position, Quaternion.Euler(transform.eulerAngles + new Vector3(0, 45 * i, 0))); } gameObjectAni.SetTrigger("Die"); Invoke("Prize", 0.7f); } } private void Prize() { Gun.Instance.GoldChange(GetCold); if (GetDiamands != 0) { Gun.Instance.DiamandsChange(GetDiamands); Instantiate(diamands, transform.position, transform.rotation); } Instantiate(gold, transform.position, transform.rotation); Destroy(this.gameObject); } }
Fish  Prefabs/Enemy/Fish
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary>
/// 會隱藏的boss /// </summary>
public class InvisibleBoss : Boss { private bool isInvisible = false; private float invisibleTime = 0; private float recoverTime = 0; private BoxCollider box; private SpriteRenderer sr; void Start() { fire = transform.Find("Fire").gameObject; ice = transform.Find("Ice").gameObject; iceAni = ice.transform.GetComponent<Animator>(); gameObjectAni = GetComponent<Animator>(); box = GetComponent<BoxCollider>(); sr = GetComponent<SpriteRenderer>(); bossAudio = GetComponent<AudioSource>(); playerTransform = Gun.Instance.transform; } // Update is called once per frame
    void Update() { //冰凍效果
        if (Gun.Instance.Ice) { gameObjectAni.enabled = false; ice.SetActive(true); if (!hasIce) { iceAni.SetTrigger("Ice"); hasIce = true; } } else { gameObjectAni.enabled = true; hasIce = false; ice.SetActive(false); } //灼燒效果
        if (Gun.Instance.Fire) { fire.SetActive(true); } else { fire.SetActive(false); } if (Gun.Instance.Ice) { return; } //boss的行爲方法
 Attack(m_reduceGold, m_reduceDiamond); if (!isAttack) { fishMove(); } //隱形方法
        if (invisibleTime >= 10) { invisibleTime = 0; Invisible(); } else { invisibleTime += Time.deltaTime; } if (isInvisible) { sr.color -= new Color(0, 0, 0, Time.deltaTime); box.enabled = false; } else { sr.color += new Color(0, 0, 0, Time.deltaTime); if (recoverTime >= 3) { recoverTime = 0; sr.color = new Color(sr.color.r, sr.color.g, sr.color.b, 1); } else { recoverTime += Time.deltaTime; } box.enabled = true; } } private void Invisible() { isInvisible = true; Invoke("CloseInvisible", 3); } private void CloseInvisible() { isInvisible = false; } }
InvisibleBoss  Prefabs/Enemy/Boss3

Item

using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary>
/// 鋪到貝殼的道具卡 /// </summary>
public class Card : MonoBehaviour { private Transform playerTransform; public int num; public Sprite[] cards; private SpriteRenderer sr; private AudioSource audios; // Use this for initialization
    void Start () { Destroy(this.gameObject,1); audios = GetComponent<AudioSource>(); sr = GetComponent<SpriteRenderer>(); sr.sprite = cards[num]; audios.Play(); } // Update is called once per frame
    void Update () { } }
Card  Prefabs/Item/Card
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary>
/// 漁網 /// </summary>
public class FishNet : MonoBehaviour { // Use this for initialization
    void Start () { Destroy(this.gameObject,0.2f); } // Update is called once per frame
    void Update () { //transform.Translate(-Vector3.up * moveSpeed * Time.deltaTime,Space.World);
 } private void OnTriggerEnter(Collider other) { if (other.tag=="fish") { other.GetComponent<Fish>().isnet = true; } } }
FishNet  Prefabs/Item/Net
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary>
/// 金幣,鑽石 /// </summary>
public class Gold : MonoBehaviour { public enum ThePlaceTo { gold, diamands, imageGold, imageDiamands } public ThePlaceTo thePlaceTo; private Transform playerTransform; public float moveSpeed = 3; public GameObject star2; private AudioSource audios; public AudioClip goldAudio; public AudioClip diamandsAudio; private float timeVal2; public float defineTime2; private float timeBecome; private float timeVal3; public bool bossPrize = false; private bool beginMove = false; // Use this for initialization
    private void Awake() { audios = GetComponent<AudioSource>(); switch (thePlaceTo) { case ThePlaceTo.gold: playerTransform = Gun.Instance.goldPlace; audios.clip = goldAudio; break; case ThePlaceTo.diamands: playerTransform = Gun.Instance.diamondsPlace; audios.clip = diamandsAudio; break; case ThePlaceTo.imageGold: playerTransform = Gun.Instance.imageGoldPlace; audios.clip = goldAudio; break; case ThePlaceTo.imageDiamands: playerTransform = Gun.Instance.imageDiamandsPlace; audios.clip = diamandsAudio; break; default: break; } audios.Play(); } void Start() { } // Update is called once per frame
    void Update() { if (timeBecome >= 0.5f) { beginMove = true; } else { timeBecome += Time.deltaTime; } if (beginMove) { transform.position = Vector3.Lerp(transform.position, playerTransform.position, 1 / Vector3.Distance(transform.position, playerTransform.position) * Time.deltaTime * moveSpeed); if (thePlaceTo == ThePlaceTo.imageDiamands || thePlaceTo == ThePlaceTo.imageGold) { if (Vector3.Distance(transform.position, playerTransform.position) <= 2) { Destroy(this.gameObject); } return; } if (transform.position == playerTransform.position) { Destroy(this.gameObject); } timeVal2 = InistStar(timeVal2, defineTime2, star2); } else { transform.localScale += new Vector3(Time.deltaTime * 3, Time.deltaTime * 3, Time.deltaTime * 3); if (bossPrize) { if (timeVal3 <= 0.3f) { timeVal3 += Time.deltaTime; transform.Translate(transform.right * moveSpeed * Time.deltaTime, Space.World); } } } } private float InistStar(float timeVals, float defineTimes, GameObject stars) { if (timeVals >= defineTimes) { Instantiate(stars, this.transform.position, Quaternion.Euler(this.transform.eulerAngles.x, this.transform.eulerAngles.y, this.transform.eulerAngles.z + Random.Range(-40f, 40f))); timeVals = 0; } else { timeVals += Time.deltaTime; } return timeVals; } }
Gold  Prefabs/Item/Gold
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary>
/// 美人魚 /// </summary>
public class Missile : MonoBehaviour { //屬性
    public int hp=15; public int GetGold = 10; public float moveSpeed=5; //引用
    public GameObject gold; private GameObject fire; private GameObject ice; private Animator iceAni; private Animator gameObjectAni; public GameObject deadEeffect; private SpriteRenderer sr; //計時器
    private float rotateTime; //開關
    private bool hasIce = false; private float timeVal; // Use this for initialization
    void Start () { fire = transform.Find("Fire").gameObject; ice = transform.Find("Ice").gameObject; iceAni = ice.transform.GetComponent<Animator>(); gameObjectAni = GetComponent<Animator>(); sr = GetComponent<SpriteRenderer>(); Destroy(this.gameObject, 8); } // Update is called once per frame
    void Update () { if (timeVal >= 7) { sr.color -= new Color(0, 0, 0, Time.deltaTime); } else { timeVal += Time.deltaTime; } //冰凍效果
        if (Gun.Instance.Ice) { gameObjectAni.enabled = false; ice.SetActive(true); if (!hasIce) { iceAni.SetTrigger("Ice"); hasIce = true; } } else { gameObjectAni.enabled = true; hasIce = false; ice.SetActive(false); } //灼燒效果
        if (Gun.Instance.Fire) { fire.SetActive(true); } else { fire.SetActive(false); } if (Gun.Instance.Ice) { return; } transform.Translate(transform.right * moveSpeed * Time.deltaTime, Space.World); if (rotateTime >= 5) { transform.Rotate(transform.forward * Random.Range(0, 361), Space.World); rotateTime = 0; } else { rotateTime += Time.deltaTime; } } public void Lucky(int attckValue) { Gun.Instance.GoldChange(GetGold); Instantiate(gold, transform.position, transform.rotation); if (Gun.Instance.Fire) { attckValue *= 2; } hp -= attckValue; if (hp<=0) { Instantiate(deadEeffect, transform.position, transform.rotation); gameObjectAni.SetTrigger("Die"); Invoke("Prize", 0.7f); } } private void Prize() { Gun.Instance.GoldChange(GetGold * 10); for (int i = 0; i < 5; i++) { Instantiate(gold, transform.position + new Vector3(-5f + i, 0, 0), transform.rotation); } Destroy(this.gameObject); } }
Missile  Prefabs/Item/Missile
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary>
/// 貝殼 /// </summary>
public class Shell : MonoBehaviour { //計時器
    private float rotateTime; private float timeVal = 0;//無敵狀態計時器 //屬性
    public float moveSpeed = 5; //開關
    private bool isDeffend=true; private bool hasIce = false; //引用
    public GameObject card; private GameObject fire; private GameObject ice; private Animator iceAni; private Animator gameObjectAni; private SpriteRenderer sr; private float timeVals; // Use this for initialization
    void Start () { fire = transform.Find("Fire").gameObject; ice = transform.Find("Ice").gameObject; iceAni = ice.transform.GetComponent<Animator>(); gameObjectAni = GetComponent<Animator>(); sr = GetComponent<SpriteRenderer>(); Destroy(this.gameObject,10); } // Update is called once per frame
    void Update () { if (timeVals >= 9) { sr.color -= new Color(0, 0, 0, Time.deltaTime); } else { timeVals += Time.deltaTime; } //灼燒效果
        if (Gun.Instance.Fire) { fire.SetActive(true); } else { fire.SetActive(false); } //冰凍效果
        if (Gun.Instance.Ice) { gameObjectAni.enabled = false; ice.SetActive(true); if (!hasIce) { iceAni.SetTrigger("Ice"); hasIce = true; } } else { gameObjectAni.enabled = true; hasIce = false; ice.SetActive(false); } if (Gun.Instance.Ice) { return; } transform.Translate(transform.right * moveSpeed * Time.deltaTime, Space.World); if (rotateTime >= 5) { transform.Rotate(transform.forward * Random.Range(0, 361), Space.World); rotateTime = 0; } else { rotateTime += Time.deltaTime; } if (timeVal<1) { timeVal += Time.deltaTime; } else if (timeVal>=1&&timeVal<1.5) { timeVal += Time.deltaTime; isDeffend = false; } else if (timeVal>=1.5) { isDeffend = true; timeVal = 0; } } public void GetEffects() { if (isDeffend) { return; } else { int num = Random.Range(0, 3); switch (num) { case 0:Gun.Instance.CanShootForFree(); break; case 1:Gun.Instance.CanGetDoubleGold(); break; case 2:Gun.Instance.CanShootNoCD(); break; default: break; } GameObject go= Instantiate(card, transform.position, card.transform.rotation) as GameObject; go.GetComponent<Card>().num = num; Destroy(this.gameObject); } } }
Shell  Prefabs/Item/Shell

Player

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; /// <summary>
////// </summary>

public class Gun : MonoBehaviour { //屬性
    public int gold = 100; public int diamands = 50; public int gunLevel = 1; private float rotateSpeed = 5f; public float attackCD = 1; private float GunCD = 4; public int level = 1; //引用

    public AudioClip[] bullectAudios; private AudioSource bullectAudio; public Transform attackPos; public GameObject[] Bullects; public GameObject net; public GunChange[] gunChange; public Transform goldPlace; public Transform diamondsPlace; public Transform imageGoldPlace; public Transform imageDiamandsPlace; public Text goldText; public Text diamandsText; //開關
    private bool canShootForFree = false; private bool canGetDoubleGold = false; public bool canShootNoCD = false; public bool canChangeGun = true; public bool bossAttack = false; public bool Fire = false; public bool Ice = false; public bool Butterfly = false; public bool attack = false; public bool changeAudio; private static Gun instance; public static Gun Instance { get { return instance; } set { instance = value; } } private void Awake() { instance = this; gold = 1000; diamands = 1000; level = 2; bullectAudio = GetComponent<AudioSource>(); } // Use this for initialization
    void Start() { } // Update is called once per frame
    void Update() { goldText.text = gold.ToString(); diamandsText.text = diamands.ToString(); //旋轉槍的方法
 RotateGun(); if (GunCD <= 0) { canChangeGun = true; GunCD = 4; } else { GunCD -= Time.deltaTime; } //攻擊的方法

        if (canShootNoCD) { Attack(); attack = true; return; } if (attackCD >= 1 - gunLevel * 0.3) { Attack(); attack = true; } else { attackCD += Time.deltaTime; } } /// <summary>
    /// 如下是方法的定義 /// </summary>




    //旋轉槍

    private void RotateGun() { float h = Input.GetAxisRaw("Mouse Y"); float v = Input.GetAxisRaw("Mouse X"); transform.Rotate(-Vector3.forward * v * rotateSpeed); transform.Rotate(Vector3.forward * h * rotateSpeed); ClampAngle(); //245,115
 } //換槍的方法

    public void UpGun() { gunLevel += 1; if (gunLevel == 4) { gunLevel = 1; } gunChange[0].ToGray(); gunChange[1].ToGray(); canChangeGun = false; } public void DownGun() { gunLevel -= 1; if (gunLevel == 0) { gunLevel = 3; } gunChange[0].ToGray(); gunChange[1].ToGray(); canChangeGun = false; } //限制角度
    private void ClampAngle() { float y = transform.eulerAngles.y; if (y <= 35) { y = 35; } else if (y >= 150) { y = 150; } transform.eulerAngles = new Vector3(transform.eulerAngles.x, y, transform.eulerAngles.z); } //攻擊方法

    private void Attack() { if (Input.GetMouseButtonDown(0)) { bullectAudio.clip = bullectAudios[gunLevel - 1]; bullectAudio.Play(); if (Butterfly) { Instantiate(Bullects[gunLevel - 1], attackPos.position, attackPos.rotation * Quaternion.Euler(0, 0, 20)); Instantiate(Bullects[gunLevel - 1], attackPos.position, attackPos.rotation * Quaternion.Euler(0, 0, -20)); } Instantiate(Bullects[gunLevel - 1], attackPos.position, attackPos.rotation); if (!canShootForFree) { GoldChange(-1 - (gunLevel - 1) * 2); } attackCD = 0; attack = false; } } //增減金錢

    public void GoldChange(int number) { if (canGetDoubleGold) { if (number > 0) { number *= 2; } } gold += number; } //增減鑽石

    public void DiamandsChange(int number) { diamands += number; } /// <summary>
    /// 貝殼觸發的一些效果方法 /// </summary>


    public void CanShootForFree() { canShootForFree = true; Invoke("CantShootForFree", 5); } public void CantShootForFree() { canShootForFree = false; } public void CanGetDoubleGold() { canGetDoubleGold = true; Invoke("CantGetDoubleGold", 5); } public void CantGetDoubleGold() { canGetDoubleGold = false; } public void CanShootNoCD() { canShootNoCD = true; Invoke("CantShootNoCD", 5); } public void CantShootNoCD() { canShootNoCD = false; } //boss攻擊的方法
    public void BossAttack() { bossAttack = true; } }
Gun  Fish/PlayerManager
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; /// <summary>
/// 切槍的按鈕 /// </summary>
public class GunChange : MonoBehaviour { public bool add; private Button button; private Image image; public Sprite[] buttonSprites;//0.+ 1.灰色的+ 2.- 3.灰色的- // Use this for initialization
    void Start() { button = transform.GetComponent<Button>(); button.onClick.AddListener(ChangeGunLevel); image = GetComponent<Image>(); } // Update is called once per frame
    void Update() { if (Gun.Instance.canChangeGun) { if (add) { image.sprite = buttonSprites[0]; } else { image.sprite = buttonSprites[2]; } } } public void ChangeGunLevel() { if (Gun.Instance.canChangeGun) { if (add) { Gun.Instance.UpGun(); } else { Gun.Instance.DownGun(); } } } public void ToGray() { if (add) { image.sprite = buttonSprites[1]; } else { image.sprite = buttonSprites[3]; } } }
GunChange  Fish/Canvas/UI_LeftTable/AddGunLevel
using UnityEngine; using System.Collections; public class Bullect : MonoBehaviour { public GameObject explosions; public GameObject star; public GameObject star1; public GameObject star2; public float moveSpeed; private float timeVal; public float defineTime; private float timeVal1; public float defineTime1; private float timeVal2; public float defineTime2; public Transform CreatePos; public GameObject net; public int level; public float attackValue; // Use this for initialization
    void Start () { } // Update is called once per frame
    void Update () { timeVal=InistStar(timeVal,defineTime,star); timeVal1=InistStar(timeVal1,defineTime1,star1); timeVal2=InistStar(timeVal2,defineTime2,star2); transform.Translate(transform.up*moveSpeed*Time.deltaTime,Space.World); } private float InistStar(float timeVals,float defineTimes,GameObject stars) { if (timeVals>=defineTimes) { Instantiate(stars, CreatePos.transform.position, Quaternion.Euler(CreatePos.transform.eulerAngles.x, CreatePos.transform.eulerAngles.y, CreatePos.transform.eulerAngles.z+Random.Range(-40f,40f))); timeVals=0; } else { timeVals+=Time.deltaTime; } return timeVals; } private void OnTriggerEnter(Collider other) { if (other.tag == "fish" || other.tag == "boss") { other.SendMessage("TakeDamage", attackValue); GameObject go = Instantiate(net, transform.position + new Vector3(0, 1, 0), transform.rotation); go.transform.localScale = new Vector3(level, level, level); Instantiate(explosions, transform.position, transform.rotation); Destroy(this.gameObject); } else if (other.tag == "missile") { other.SendMessage("Lucky", attackValue); GameObject go = Instantiate(net, transform.position + new Vector3(0, 1, 0), transform.rotation); go.transform.localScale = new Vector3(level, level, level); Instantiate(explosions, transform.position, transform.rotation); Destroy(this.gameObject); } else if (other.tag == "Shell") { other.SendMessage("GetEffects"); GameObject go = Instantiate(net, transform.position + new Vector3(0, 1, 0), transform.rotation); go.transform.localScale = new Vector3(level, level, level); Instantiate(explosions, transform.position, transform.rotation); Destroy(this.gameObject); } else if (other.tag == "Qipao") { GameObject go = Instantiate(net, transform.position + new Vector3(0, 1, 0), transform.rotation); go.transform.localScale = new Vector3(level, level, level); Instantiate(explosions, transform.position, transform.rotation); Destroy(this.gameObject); } /*else*/
        if (other.tag == "Wall") { float angleValue = Vector3.Angle(transform.up, other.transform.up); if (angleValue < 90) { transform.eulerAngles += new Vector3(0, 0, 2*angleValue); } else if (Vector3.Angle(transform.up, other.transform.up) > 90) { transform.eulerAngles -= new Vector3(0, 0, 360-2 * angleValue); } else { transform.eulerAngles += new Vector3(0, 0, 180); } } } }
Bullet  Prefabs/Player/Bullet1,2,3

  PlayerUI

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; /// <summary>
/// 灼燒 /// </summary>
public class Fire : MonoBehaviour { private Button but; private float timeVal = 15; private bool canUse = true; private float totalTime = 15; public Slider cdSlider; private int reduceDiamands; private void Awake() { but = transform.GetComponent<Button>(); but.onClick.AddListener(Attack); } // Use this for initialization

    void Start() { reduceDiamands = 10; } // Update is called once per frame
    void Update() { if (timeVal >= 15) { timeVal = 15; } cdSlider.value = timeVal / totalTime; if (timeVal >= 15) { canUse = true; cdSlider.transform.Find("Background").gameObject.SetActive(false); } else { timeVal += Time.deltaTime; } } private void Attack() { if (canUse) { if (!Gun.Instance.Ice && !Gun.Instance.Fire) { if (Gun.Instance.diamands <= reduceDiamands) { return; } Gun.Instance.DiamandsChange(-reduceDiamands); Gun.Instance.Fire = true; canUse = false; cdSlider.transform.Find("Background").gameObject.SetActive(true); timeVal = 0; Invoke("CloseFire", 6); } } } //關閉必殺的方法
    private void CloseFire() { Gun.Instance.Fire = false; } }
Fire  Fish/Canvas/UI_Skills/Img_Fire/But_Fire
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; /// <summary>
/// 冰凍 /// </summary>
public class Ice : MonoBehaviour { private float timeVal = 10; private bool canUse = true; public Slider cdSlider; private float totalTime = 10; Button but; private AudioSource fireAudio; private int reduceDiamands; // Use this for initialization
    private void Awake() { but = transform.GetComponent<Button>(); but.onClick.AddListener(ice); fireAudio = GetComponent<AudioSource>(); } void Start() { reduceDiamands = 10; } private void Update() { if (timeVal >= 10) { timeVal = 10; } cdSlider.value = timeVal / totalTime; if (timeVal >= 10) { cdSlider.transform.Find("Background").gameObject.SetActive(false); canUse = true; } else { timeVal += Time.deltaTime; } } private void ice() { //必殺的方法
        if (canUse) { if (!Gun.Instance.Fire && !Gun.Instance.Ice) { if (Gun.Instance.diamands <= reduceDiamands) { return; } if (fireAudio.isPlaying) { return; } fireAudio.Play(); Gun.Instance.DiamandsChange(-reduceDiamands); Gun.Instance.Ice = true; canUse = false; cdSlider.transform.Find("Background").gameObject.SetActive(true); timeVal = 0; Invoke("CloseIce", 4); } } } //關閉必殺的方法
    private void CloseIce() { Gun.Instance.Ice = false; } }
Ice  Fish/Canvas/UI_Skills/UI_Ice/But_Ice
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; /// <summary>
/// 散彈按鈕 /// </summary>
public class ButterFly : MonoBehaviour { Button but; private float timeVal = 15; private bool canUse = true; private float totalTime = 15; public GameObject uiView; public Slider cdSlider; private int reduceDiamands; private void Awake() { but = transform.GetComponent<Button>(); but.onClick.AddListener(Fire); } void Start() { reduceDiamands = 10; } // Update is called once per frame
    void Update() { if (timeVal >= 15) { timeVal = 15; } cdSlider.value = timeVal / totalTime; if (timeVal >= 15) { canUse = true; cdSlider.transform.Find("Background").gameObject.SetActive(false); } else { timeVal += Time.deltaTime; } } private void Fire() { if (canUse) { if (Gun.Instance.diamands <= reduceDiamands) { return; } Gun.Instance.DiamandsChange(-reduceDiamands); Gun.Instance.Butterfly = true; canUse = false; cdSlider.transform.Find("Background").gameObject.SetActive(true); timeVal = 0; Invoke("CloseFire", 8); uiView.SetActive(true); } } //關閉必殺的方法
    private void CloseFire() { uiView.SetActive(false); Gun.Instance.Butterfly = false; } }
ButterFly  Fish/Canvas/UI_Skills/UI_ButterflyShoot/But_ButterflyShoot
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; /// <summary>
/// 負責UI顯示的槍 /// </summary>
public class GunImage : MonoBehaviour { public Sprite[] Guns; private Image img; public Transform idlePos; public Transform attackPos; private float rotateSpeed = 5f; private void Awake() { img = transform.GetComponent<Image>(); } // Use this for initialization
    void Start() { } // Update is called once per frame
    void Update() { //旋轉槍的方法
 RotateGun(); img.sprite = Guns[Gun.Instance.gunLevel - 1]; //攻擊的方法



        if (Gun.Instance.attack) { if (Input.GetMouseButtonDown(0)) { attack(); } } } private void attack() { transform.position = Vector3.Lerp(transform.position, attackPos.position, 0.5f); Invoke("idle", 0.4f); } private void idle() { transform.position = Vector3.Lerp(transform.position, idlePos.position, 0.2f); } //旋轉槍

    private void RotateGun() { float h = Input.GetAxisRaw("Mouse Y"); float v = Input.GetAxisRaw("Mouse X"); transform.Rotate(-Vector3.forward * v * rotateSpeed); transform.Rotate(Vector3.forward * h * rotateSpeed); ClampAngle(); } //限制角度
    private void ClampAngle() { float z = transform.eulerAngles.z; if (z <= 35) { z = 35; } else if (z >= 150) { z = 150; } transform.eulerAngles = new Vector3(transform.eulerAngles.x, transform.eulerAngles.y, z); } }
GunImage  Fish/Canvas/Img_Gun 

  UI

using UnityEngine; using System.Collections; /// <summary>
/// 產生UI泡泡 /// </summary>
public class CreatePao : MonoBehaviour { public GameObject pao; public Transform panel; private float timeVal = 6; // Use this for initialization
    void Start() { } // Update is called once per frame
    void Update() { if (timeVal >= 6) { for (int i = 0; i < 4; i++) { Invoke("InstPao", 1); } timeVal = 0; } else { timeVal += Time.deltaTime; } } private void InstPao() { GameObject itemGo = Instantiate(pao, transform.position, Quaternion.Euler(0, 0, Random.Range(-80, 0))) as GameObject; itemGo.transform.SetParent(panel); } }
CreatePao  Main/Canvas/Panel/CreatePao
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.SceneManagement; public class StartGame : MonoBehaviour { private Button but; // Use this for initialization
    void Start () { but = GetComponent<Button>(); but.onClick.AddListener(StartGames); } private void StartGames() { SceneManager.LoadScene(1); } // Update is called once per frame
    void Update () { } }
StartGame  Main/Canvas/Panel/UI_StartGame/But_StartGame
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.SceneManagement; public class LoadGame : MonoBehaviour { public Slider processView; // Use this for initialization
    void Start () { LoadGameMethod(); } // Update is called once per frame
    void Update () { } public void LoadGameMethod() { StartCoroutine(StartLoading_4(2)); } private IEnumerator StartLoading_4(int scene) { int displayProgress = 0; int toProgress = 0; AsyncOperation op = SceneManager.LoadSceneAsync(scene); op.allowSceneActivation = false; while (op.progress < 0.9f) { toProgress = (int)op.progress * 100; while (displayProgress < toProgress) { ++displayProgress; SetLoadingPercentage(displayProgress); yield return new WaitForEndOfFrame(); } } toProgress = 100; while (displayProgress < toProgress) { ++displayProgress; SetLoadingPercentage(displayProgress); yield return new WaitForEndOfFrame(); } op.allowSceneActivation = true; } private void SetLoadingPercentage(float v) { processView.value = v / 100; } }
LoadGame  Loading/Canvas/Panel/LoadGame
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; /// <summary>
/// 寶藏 /// </summary>
public class Treasour : MonoBehaviour { private Button but; private Image img; public GameObject gold; public GameObject diamands; public GameObject cdView; public Transform cavas; private bool isDrease; private void Awake() { but = GetComponent<Button>(); but.onClick.AddListener(OpenTreasour); img = GetComponent<Image>(); } void OpenTreasour() { if (img.color.a != 1) { return; } cdView.SetActive(true); Gun.Instance.GoldChange(Random.Range(100, 200)); Gun.Instance.DiamandsChange(Random.Range(10, 50)); CreatePrize(); isDrease = true; } private void CreatePrize() { for (int i = 0; i < 5; i++) { GameObject go = Instantiate(gold, transform.position + new Vector3(-10f + i * 30, 0, 0), transform.rotation); go.transform.SetParent(cavas); GameObject go1 = Instantiate(diamands, transform.position + new Vector3(0, 30, 0) + new Vector3(-10f + i * 30, 0, 0), transform.rotation); go1.transform.SetParent(cavas); } } // Use this for initialization
    void Start() { } // Update is called once per frame
    void Update() { if (isDrease) { img.color -= new Color(0, 0, 0, Time.deltaTime * 10); if (img.color.a <= 0.2) { img.color = new Color(img.color.r, img.color.g, img.color.b, 0); isDrease = false; } } else { img.color += new Color(0, 0, 0, Time.deltaTime * 0.01f); if (img.color.a >= 0.9) { img.color = new Color(img.color.r, img.color.g, img.color.b, 1); cdView.SetActive(false); } } } }
Treasour  Fish/Canvas/UI_Treasour/But_Treasour
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary>
/// 地圖背景 /// </summary>
public class Ground : MonoBehaviour { private MeshRenderer mr; public Material[] materialList; private AudioSource audioSource; public AudioClip[] audioClips; // Use this for initialization
    void Start() { mr = GetComponent<MeshRenderer>(); audioSource = GetComponent<AudioSource>(); } // Update is called once per frame
    void Update() { if (Gun.Instance.changeAudio) { audioSource.clip = audioClips[Gun.Instance.level - 1]; audioSource.Play(); Gun.Instance.changeAudio = false; } if (Gun.Instance.level == 1) { if (Gun.Instance.Fire) { mr.material = materialList[1]; } else if (Gun.Instance.Ice) { mr.material = materialList[2]; } else { mr.material = materialList[0]; } } else if (Gun.Instance.level == 2) { if (Gun.Instance.Fire) { mr.material = materialList[4]; } else if (Gun.Instance.Ice) { mr.material = materialList[5]; } else { mr.material = materialList[3]; } } else if (Gun.Instance.level == 3) { if (Gun.Instance.Fire) { mr.material = materialList[7]; } else if (Gun.Instance.Ice) { mr.material = materialList[8]; } else { mr.material = materialList[6]; } } } }
Ground  Fish/Plane
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class Mylight : MonoBehaviour { public Sprite[] lights; private Image img; private int i; private float timeVal; private void Awake() { img = GetComponent<Image>(); } // Use this for initialization
    void Start () { } // Update is called once per frame
    void Update () { if (timeVal>=0.08f) { img.sprite = lights[i]; i++; if (i == lights.Length) { i = 0; } timeVal = 0; } else { timeVal += Time.deltaTime; } } }
Mylight  Fish/Canvas/Img_Gun/Img_GunEffectRight
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.SceneManagement; public class ReturnMain : MonoBehaviour { private Button but; // Use this for initialization
    void Start() { but = GetComponent<Button>(); but.onClick.AddListener(StartGames); } public void StartGames() { SceneManager.LoadScene(0); } // Update is called once per frame
    void Update() { } }
ReturnMain  Fish/Canvas/UI_ReturnMenu/But_ReturnMenu
using UnityEngine; using System.Collections; public class Star : MonoBehaviour { public float moveSpeed=1; // Use this for initialization
    void Start () { Destroy(gameObject,Random.Range(0.4f,1)); } // Update is called once per frame
    void Update () { //transform.Translate(-transform.right*moveSpeed*Time.deltaTime,Space.World);
 } }
Star  Prefabs/Effects/star...
--1.1 點擊寶箱領取的金幣鑽石太擁擠,分散一點。 local UnityEngine=CS.UnityEngine xlua.hotfix(CS.Treasour,'CreatePrize',function(self) for i=0,4,1 do local go=UnityEngine.GameObject.Instantiate(self.gold,self.transform.position+UnityEngine.Vector3(-10+i*40,0,0),self.transform.rotation) go.transform.SetParent(go.transform,self.cavas) local go1=UnityEngine.GameObject.Instantiate(self.diamands,self.transform.position+UnityEngine.Vector3(0,40,0)+UnityEngine.Vector3(-10+i*40,0,0),self.transform.rotation) go1.transform.SetParent(go1.transform,self.cavas) end end) --******************************************************************



--1.1 玩家金幣鑽石不夠時沒有相應處理。 xlua.private_accessible(CS.Gun) xlua.hotfix(CS.Gun,'Attack',function(self) if UnityEngine.Input.GetMouseButtonDown(0) then --1.2 與UI交互時不能發射子彈 if UnityEngine.EventSystems.EventSystem.current:IsPointerOverGameObject() then return end --[[ if self.gold<1+(self.gunLevel-1)*2 or gold==0 then return end --]] --1.3 炮臺3太強,且鑽石沒用處,不削弱,只有氪金纔可以使用 if self.gunLevel==3 and self.diamands<3 then return elseif self.gunLevel~=3 then if self.gold<1+(self.gunLevel-1)*2 or gold==0 then return end end self.bullectAudio.clip=self.bullectAudios[self.gunLevel-1] self.bullectAudio:Play() if self.Butterfly then UnityEngine.GameObject.Instantiate(self.Bullects[self.gunLevel-1],self.attackPos.position,self.attackPos.rotation*UnityEngine.Quaternion.Euler(0,0,20)) UnityEngine.GameObject.Instantiate(self.Bullects[self.gunLevel-1],self.attackPos.position,self.attackPos.rotation*UnityEngine.Quaternion.Euler(0,0,-20)) end UnityEngine.GameObject.Instantiate(self.Bullects[self.gunLevel-1],self.attackPos.position,self.attackPos.rotation) if not self.canShootForFree then if self.gunLevel==3 then self:DiamandsChange(-3) else self:GoldChange(-1-(self.gunLevel-1)*2) end end self.attackCD=0 self.attack=false end end) --******************************************************************

-- 1.2 技能扣鑽石太多。 xlua.private_accessible(CS.Fire) xlua.hotfix(CS.Fire,'Start',function(self) self.reduceDiamands = 8; end) xlua.private_accessible(CS.Ice) xlua.hotfix(CS.Ice,'Start',function(self) self.reduceDiamands = 8; end) xlua.private_accessible(CS.ButterFly) xlua.hotfix(CS.ButterFly,'Start',function(self) self.reduceDiamands = 5; end) --*************************************************************

-- 1.2 boss撞擊玩家數值變更同樣且不是減小是增長。 local util=require 'util' xlua.private_accessible(CS.Boss) util.hotfix_ex(CS.Boss,'Start',function(self) self.Start(self) self.m_reduceGold=self.m_reduceGold-20 end) xlua.private_accessible(CS.DeffendBoss) util.hotfix_ex(CS.DeffendBoss,'Start',function(self) self.Start(self) self.m_reduceGold=self.m_reduceGold-30 end) xlua.private_accessible(CS.InvisibleBoss) util.hotfix_ex(CS.InvisibleBoss,'Start',function(self) self.Start(self) self.m_reduceDiamond=self.m_reduceDiamond-5 end) --********************************************************************

-- 1.3 boss撞擊玩家當鑽石金幣不夠時會產生負數。 util.hotfix_ex(CS.Gun,'GoldChange',function(self,number) self.GoldChange(self,number) if self.gold<-number then self.gold=0
            return end end) util.hotfix_ex(CS.Gun,'DiamandsChange',function(self,number) self.DiamandsChange(self,number) if self.diamands<-number then self.diamands=0
            return end end) --******************************************************************

-- 1.3 大魚太多 local canCreateNewFish=true local changeMapTimeval=0 xlua.hotfix(CS.CreateFish,'Start',function(self) --self.hotFixScript:LoadResource('level3fish3','gameobject\\enemy.ab') --self.hotFixScript:LoadResource('SeaWave','gameobject\\wave.ab') end) xlua.private_accessible(CS.CreateFish) xlua.hotfix(CS.CreateFish,'Update',function(self) -- 2.0 生成海浪 if canCreateNewFish then if changeMapTimeval >=50 then go=CS.HotFixScript.GetGameObject('SeaWave') UnityEngine.GameObject.Instantiate(go) canCreateNewFish=false changeMapTimeval=0
        else changeMapTimeval=changeMapTimeval+UnityEngine.Time.deltaTime end else
        return end self:CreateALotOfFish() --單種魚的生成 if self.ItemtimeVal>=0.5 then --位置隨機數 self.num =UnityEngine.Mathf.Floor(UnityEngine.Random.Range(0, 4) ) --遊戲物體隨機數 self.ItemNum =UnityEngine.Mathf.Floor(UnityEngine.Random.Range(1, 101)) local halfLength=self.fishList.Length/2 local littlefishTypeIndex=UnityEngine.Mathf.Floor(UnityEngine.Random.Range(0,halfLength)) local bigfishTypeIndex=UnityEngine.Mathf.Floor(UnityEngine.Random.Range(halfLength,self.fishList.Length)) local itemTypeIndex=UnityEngine.Mathf.Floor(UnityEngine.Random.Range(0,self.item.Length)) --產生氣泡 if self.ItemNum<20 then self:CreateGameObject(self.item[3]) end if  self.ItemNum <= 42 then for i=0,2,1 do self:CreateGameObject(self.fishList[littlefishTypeIndex]) end self:CreateGameObject(self.item[itemTypeIndex]) elseif self.ItemNum >= 43 and self.ItemNum < 72 then for i=0,1,1 do self:CreateGameObject(self.fishList[bigfishTypeIndex]) end self:CreateGameObject(self.item[itemTypeIndex]) --2.0 新魚 elseif self.ItemNum >= 73 and self.ItemNum < 83 then newFish=CS.HotFixScript.GetGameObject('level3fish3') self:CreateGameObject(newFish) elseif self.ItemNum >= 84 and self.ItemNum < 86 then self:CreateGameObject(self.boss) elseif self.ItemNum >= 87 and self.ItemNum <= 88 then self:CreateGameObject(self.boss2) elseif self.ItemNum==100 then self:CreateGameObject(self.boss3) else self:CreateGameObject(self.item[0]); end self.ItemtimeVal = 0
        else self.ItemtimeVal =self.ItemtimeVal+CS.UnityEngine.Time.deltaTime; end end) --**********************************************************************************

-- 1.4 撲魚是考慮了魚的血量與子彈的傷害來模擬機率,這樣玩家體驗很差,要使用傳統的機率來撲魚。 xlua.private_accessible(CS.Fish) xlua.hotfix(CS.Fish,'TakeDamage',function(self,attackValue) if UnityEngine.Gun.Instance.Fire then attackValue=attackValue*2; end local catchValue=UnityEngine.Mathf.Floor(UnityEngine.Random.Range(0,100)) if catchValue<=(50-(self.hp-attackValue))/2 then self.isDead = true
            for i=0,8,1 do UnityEngine.GameObject.Instantiate(self.pao, self.transform.position, UnityEngine.Quaternion.Euler(self.transform.eulerAngles + UnityEngine.Vector3(0, 45 * i, 0))) end self.gameObjectAni:SetTrigger("Die") self:Invoke("Prize", 0.7) end end) xlua.hotfix(CS.Boss,'TakeDamage',function(self,attackValue) if UnityEngine.Gun.Instance.Fire then attackValue=attackValue*2; end local catchValue=UnityEngine.Mathf.Floor(UnityEngine.Random.Range(0,100)) if catchValue<=(attackValue*3-self.hp/10) then UnityEngine.GameObject.Instantiate(self.deadEeffect, self.transform.position, self.transform.rotation) CS.Gun.Instance:GoldChange(self.GetGold * 10) CS.Gun.Instance:DiamandsChange(self.GetDiamands * 10) for i=0,10,1 do local itemGo =UnityEngine.GameObject.Instantiate(self.gold, self.transform.position, UnityEngine.Quaternion.Euler(self.transform.eulerAngles + UnityEngine.Vector3(0, 18 + 36 * (i - 1), 0))) itemGo:GetComponent('Gold').bossPrize = true end for i=0,10,1 do local itemGo1 =UnityEngine.GameObject.Instantiate(self.diamands,self.transform.position, UnityEngine.Quaternion.Euler(self.transform.eulerAngles + UnityEngine.Vector3(0, 36 + 36 * (i - 1), 0))) itemGo1:GetComponent('Gold').bossPrize = true end UnityEngine.Object.Destroy(self.gameObject) end end) -- ***********************************************************************************

-- 1.4 炮臺移動是根據鼠標的水平數值滑動來模擬跟隨的,改成玩家按下ad鍵來旋轉炮臺 xlua.hotfix(CS.Gun,'RotateGun',function(self) if UnityEngine.Input.GetKey(UnityEngine.KeyCode.A) then self.transform:Rotate(UnityEngine.Vector3.forward * self.rotateSpeed) elseif UnityEngine.Input.GetKey(UnityEngine.KeyCode.D) then self.transform:Rotate(-UnityEngine.Vector3.forward * self.rotateSpeed) end self:ClampAngle() end) xlua.private_accessible(CS.GunImage) xlua.hotfix(CS.GunImage,'RotateGun',function(self) if UnityEngine.Input.GetKey(UnityEngine.KeyCode.A) then self.transform:Rotate(UnityEngine.Vector3.forward * self.rotateSpeed) elseif UnityEngine.Input.GetKey(UnityEngine.KeyCode.D) then self.transform:Rotate(-UnityEngine.Vector3.forward * self.rotateSpeed) end self:ClampAngle() end) -- 2.0 海浪 xlua.private_accessible(CS.HotFixEmpty) xlua.hotfix(CS.HotFixEmpty,'Start',function(self) self:Invoke("BehaviourMethod",8) end) xlua.hotfix(CS.HotFixEmpty,'Update',function(self) self.transform:Translate(-self.transform.right*4*UnityEngine.Time.deltaTime,UnityEngine.Space.World) end) xlua.hotfix(CS.HotFixEmpty,'OnTriggerEnter',function(self,other) if other.tag~="Untagged" and other.tag~="Wall" then UnityEngine.Object.Destroy(other.gameObject) end end) xlua.hotfix(CS.HotFixEmpty,'BehaviourMethod',function(self) CS.Gun.Instance.level=CS.Gun.Instance.level+1
    if CS.Gun.Instance.level==4 then CS.Gun.Instance.level=1 end canCreateNewFish=true CS.Gun.Instance.changeAudio=true UnityEngine.Object.Destroy(self.gameObject) end) xlua.hotfix(CS.Treasour,'CreatePrize',nil) xlua.hotfix(CS.Gun,'Attack',nil) xlua.hotfix(CS.Ice,'Start',nil) xlua.hotfix(CS.Fire,'Start',nil) xlua.hotfix(CS.ButterFly,'Start',nil) xlua.hotfix(CS.Boss,'Start',nil) xlua.hotfix(CS.DeffendBoss,'Start',nil) xlua.hotfix(CS.InvisibleBoss,'Start',nil) xlua.hotfix(CS.Gun,'GoldChange',nil) xlua.hotfix(CS.Gun,'DiamandsChange',nil) xlua.hotfix(CS.CreateFish,'Update',nil) xlua.hotfix(CS.Fish,'TakeDamage',nil) xlua.hotfix(CS.Boss,'TakeDamage',nil) xlua.hotfix(CS.Gun,'RotateGun',nil) xlua.hotfix(CS.GunImage,'RotateGun',nil) xlua.hotfix(CS.CreateFish,'Start',nil) xlua.hotfix(CS.HotFixEmpty,'Start',nil) xlua.hotfix(CS.HotFixEmpty,'Update',nil) xlua.hotfix(CS.HotFixEmpty,'OnTriggerEnter',nil) xlua.hotfix(CS.HotFixEmpty,'BehaviourMethod',nil)
View Code

 

 

Unity商業遊戲底層資源加載框架(Unity2018.1)

using System.Collections; using System.Collections.Generic; using UnityEngine; public class ResourceTest : MonoBehaviour { //public GameObject m_Prefab;

    void Start() { //GameObject obj = GameObject.Instantiate(Resources.Load("Attack") as GameObject); //AssetBundle assetBundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/attack"); //GameObject obj = GameObject.Instantiate(assetBundle.LoadAsset<GameObject>("attack"));
 GameObject obj = GameObject.Instantiate(UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>("Assets/GameData/Prefabs/Attack.prefab")); } }
經常使用四種加載方式
TestSerialize using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Xml.Serialization; [System.Serializable] public class TestSerialize { [XmlAttribute("Id")] public int Id { get; set; } [XmlAttribute("Name")] public string Name { get; set; } [XmlElement("List")] public List<int> List { get; set; } } AssetSerialize using System.Collections; using System.Collections.Generic; using UnityEngine; [CreateAssetMenu(fileName = "TestAssets", menuName = "CreateAssets", order = 0)] public class AssetSerialize : ScriptableObject { public int Id; public string Name; public List<string> TestList; } ResourceTest using System.Collections; using System.Collections.Generic; using UnityEngine; using System.IO; using System.Xml.Serialization; using System.Runtime.Serialization.Formatters.Binary; public class ResourceTest : MonoBehaviour { void Start() { // SerializeTest(); // DeSerializeTest(); // BinarySerializeTest(); //BinaryDeserializeTest();
 ReadTestAssets(); } void ReadTestAssets() { AssetSerialize assets = UnityEditor.AssetDatabase.LoadAssetAtPath<AssetSerialize>("Assets/Scripts/TestAssets.asset"); Debug.Log(assets.Id); Debug.Log(assets.Name); foreach (string str in assets.TestList) { Debug.Log(str); } } void SerializeTest() { TestSerialize testSerialize = new TestSerialize(); testSerialize.Id = 1; testSerialize.Name = "測試"; testSerialize.List = new List<int>(); testSerialize.List.Add(2); testSerialize.List.Add(3); XmlSerialize(testSerialize); } void DeSerializeTest() { TestSerialize testSerialize = XmlDeSerialize(); Debug.Log(testSerialize.Id + " " + testSerialize.Name); foreach (int a in testSerialize.List) { Debug.Log(a); } } void XmlSerialize(TestSerialize testSerialize) { FileStream fileStream = new FileStream(Application.dataPath + "/test.xml", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); StreamWriter sw = new StreamWriter(fileStream, System.Text.Encoding.UTF8); XmlSerializer xml = new XmlSerializer(testSerialize.GetType()); xml.Serialize(sw, testSerialize); sw.Close(); fileStream.Close(); } TestSerialize XmlDeSerialize() { FileStream fs = new FileStream(Application.dataPath + "/test.xml", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); XmlSerializer xs = new XmlSerializer(typeof(TestSerialize)); TestSerialize testSerialize = (TestSerialize)xs.Deserialize(fs); fs.Close(); return testSerialize; } void BinarySerializeTest() { TestSerialize testSerialize = new TestSerialize(); testSerialize.Id = 2; testSerialize.Name = "二進制測試"; testSerialize.List = new List<int>(); testSerialize.List.Add(10); testSerialize.List.Add(18); BinarySerialize(testSerialize); } void BinaryDeserializeTest() { TestSerialize testSerialize = BinaryDeserialize(); Debug.Log(testSerialize.Id + " " + testSerialize.Name); foreach (int a in testSerialize.List) { Debug.Log(a); } } void BinarySerialize(TestSerialize serialize) { FileStream fs = new FileStream(Application.dataPath + "/test.bytes", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(fs, serialize); fs.Close(); } TestSerialize BinaryDeserialize() { TextAsset textAsset = UnityEditor.AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/test.bytes"); MemoryStream stream = new MemoryStream(textAsset.bytes); BinaryFormatter bf = new BinaryFormatter(); TestSerialize testSerialize = (TestSerialize)bf.Deserialize(stream); stream.Close(); return testSerialize; } }
序列化

 

 

Unity資源熱更及代碼熱更(ILRuntime)

 

 

Unity 遊戲框架搭建 2019 第一季 C# 核心知識與簡易 Manager Of Managers 框架搭建 (已看)

Unity 遊戲框架搭建 2019 第二季 模塊/系統設計、命名、測試(資源管理/熱更新)

 

遊戲開發中的設計模式

 

 

 

 

相關文章

unity 打包AssetBundle

unity 熱更新思路和實現

相關文章
相關標籤/搜索