Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by candybar · Oct 03, 2016 at 06:00 AM · buildlistdll

Alternative for System.Collections.Generic.List, to reduce build size.

Hello, I just finished, built and uploaded my game to the Google Play Store and I just noticed that the build size is quite big considering it's actual functionality. All the game does is show you some text and some icons and then change the text and icons when you tap. The text and the icons come from a list.

I read that you can reduce the size of your build by avoiding System.dll, but in order to use the list I need System.generics. So I am looking for an alternative to the list so that I can reduce the size of mye build. Also any other tips on how to reduce the size of the game is very welcome.

Here is my editor log, showing what makes up the size of the build, as well as the dlls I'm using.

 Textures      235.2 kb     4.7% 
 Meshes        0.0 kb     0.0% 
 Animations    0.0 kb     0.0% 
 Sounds        0.0 kb     0.0% 
 Shaders       175.5 kb     3.5% 
 Other Assets  45.9 kb     0.9% 
 Levels        7.3 kb     0.1% 
 Scripts       482.5 kb     9.7% 
 Included DLLs 3.9 mb     80.8% 
 File headers  8.5 kb     0.2% 
 Complete size 4.9 mb     100.0% 
 
 Mono dependencies included in the build
 Dependency assembly - Mono.Security.dll
 Dependency assembly - System.Core.dll
 Dependency assembly - System.dll
 Dependency assembly - mscorlib.dll
 Dependency assembly - UnityEngine.Advertisements.dll
 Dependency assembly - UnityEngine.UI.dll
 Dependency assembly - UnityEngine.Networking.dll
 Dependency assembly - Assembly-CSharp.dll

As you can see, dlls take up more than 75% of the size, which is inconvenient.

Here's how I use the List

 using UnityEngine;
 using System.Collections.Generic;
 
 public class ListOfStatements : MonoBehaviour {
 
     List<Statement> statements;
     public List<Statement> shuffledList;
 
     // Use this for initialization
     void Awake () {
         statements = new List<Statement>();
         shuffledList = new List<Statement>();
 
         FillList();
 
         for (int i = 0; i < statements.Count;)
         {
             int r = Random.Range(0, statements.Count);
 
             shuffledList.Add(statements[r]);
             statements.Remove(statements[r]);
         }
 
         foreach (Statement s in shuffledList)
         {
             Debug.Log(s.text + " " + s.drinks + " " + s.category);
         }
 
 
 
     }
     
     // Update is called once per frame
     void FillList ()
     {
         statements.Add(new Statement("Vært vikar", 1, 1));
         statements.Add(new Statement("Vært barnevakt", 2, 1));
         statements.Add(new Statement("Bygd trehytte", 1, 1));
         statements.Add(new Statement("Gravd en snøhule", 1, 1));

These are just 4 of the 300 or so statements in my List.

This is a Statement

 public class Statement
 {
     public string text;
     public int drinks;
     public int category;
 
     public Statement(string _text, int _drinks, int _category)
     {
         text = _text;
         drinks = _drinks;
         category = _category;
     }
 }
 

Aaand here's how I change the statements

 using UnityEngine;
 using UnityEngine.UI;
 using UnityEngine.Advertisements;
 
 public class StatementManager : MonoBehaviour {
 
     public Text currentStatement;
 
     public GameObject oneDrink, threeDrink, fiveDrink, oneShot;
 
     GameObject currentDrink;
     ListOfStatements listOfStatements;
     int listIndex = 0;
     public bool ranOnce = false;
     int adIndex = 15;
 
     void Awake()
     {
         listOfStatements = GetComponent<ListOfStatements>();
         
     }
 
     void Start()
     {
         currentStatement.text = listOfStatements.shuffledList[0].text;
         ChangeIcon();
     }
 
     public void ChangeText()
     {
         if (!ranOnce)
         {
             if (listIndex == adIndex)
             {
                 adIndex += 15;
                 //ShowDefaultAd();
             }
 
             ranOnce = true;
             listIndex++;
             Destroy(currentDrink);
             currentStatement.text = listOfStatements.shuffledList[listIndex].text;
             ChangeIcon();
             
 
         }
         if (listIndex == listOfStatements.shuffledList.Count-1)
         {
             listIndex = 0;
         }
     }
 
     void ChangeIcon()
     {
         switch (listOfStatements.shuffledList[listIndex].drinks)
         {
             case 1:
                 currentDrink = Instantiate(oneDrink);
                 break;
             case 2:
                 currentDrink = Instantiate(threeDrink);
                 break;
             case 3:
                 currentDrink = Instantiate(fiveDrink);
                 break;
             case 4:
                 currentDrink = Instantiate(oneShot);
                 break;
         }
     }
 
 
 
 using UnityEngine;
 
 public class TouchManager : MonoBehaviour
 {
     StatementManager statementManager;
 
     void Awake()
     {
         statementManager = GetComponent<StatementManager>();
     }
 
     void Update()
     {
         if (Input.touchCount > 0)
         {
             statementManager.ChangeText();
         }
         if (Input.touchCount < 1)
         {
             statementManager.ranOnce = false;
         }
     }
 }


Basicly, every Statement has a String and an int that decides what Text to show and which icon to show with it. The Statement has an int Category as well, which is not used in this build, but is in there for integrating a new function later.

I need a list or an array to hold these Statements and let me sequentially cycle through them.

Also, if you have any ideas on optimizing the shuffling of the List, I'd gladly accept.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by Mindmapfreak · Oct 03, 2016 at 08:09 PM

EDIT: The following does not work, see Bunny83's comment below.

You can just use the relevant code from the reference source, remove the Contract statements and replace the ThrowHelper statements. The following code should work, but bear in mind that this snippet only contains the functions you use in your code. However, it should be fairly simple to add other functions if needed. You also still have to use System and it probably would not be worthwhile to replace the classes from System with the reference code, but hopefully the size gets small enough without System.Collections.Generic.

 using System;
 public interface IEnumerator
 {    
     bool MoveNext();
 
     System.Object Current
     {
         get;
     }
         
     void Reset();
 }
 
 public interface IEnumerator<out T> : IDisposable, IEnumerator
 {
     new T Current
     {
         get;
     }
 }
 
 public class List<T>
 {
     private const int _defaultCapacity = 4;
 
     private T[] _items;
     private int _size;
     private int _version;
 
     static readonly T[] _emptyArray = new T[0];
 
 
     public int Capacity
     {
         get
         {
             return _items.Length;
         }
         set
         {
             if (value < _size)
             {
                 throw new ArgumentOutOfRangeException();                
             }
             
             if (value != _items.Length)
             {
                 if (value > 0)
                 {
                     T[] newItems = new T[value];
                     if (_size > 0)
                     {
                         Array.Copy(_items, 0, newItems, 0, _size);
                     }
                     _items = newItems;
                 }
                 else
                 {
                     _items = _emptyArray;
                 }
             }
         }
     }
 
     public int Count
     {
         get
         {
             return _size;
         }
     }
 
     public List()
     {
         _items = _emptyArray;
     }
 
     private void EnsureCapacity(int min)
     {
         if (_items.Length < min)
         {
             int newCapacity = _items.Length == 0 ? _defaultCapacity : _items.Length * 2;
             if ((uint)newCapacity > System.Int32.MaxValue) newCapacity = System.Int32.MaxValue;
             if (newCapacity < min) newCapacity = min;
             Capacity = newCapacity;
         }
     }
 
     public T this[int index]
     {
         get
         {
             if ((uint)index >= (uint)_size)
             {
                 throw new ArgumentOutOfRangeException();
             }
             return _items[index];
         }
 
         set
         {
             if ((uint)index >= (uint)_size)
             {
                 throw new ArgumentOutOfRangeException();
             }
             _items[index] = value;
             _version++;
         }
     }
 
     public void Add(T item)
     {
         if (_size == _items.Length) EnsureCapacity(_size + 1);
         _items[_size++] = item;
         _version++;
     }
 
     public int IndexOf(T item)
     {
         return Array.IndexOf(_items, item, 0, _size);
     }
 
     public void RemoveAt(int index)
     {
         if ((uint)index >= (uint)_size)
         {
             throw new ArgumentOutOfRangeException();         
         }
         _size--;
         if (index < _size)
         {
             Array.Copy(_items, index + 1, _items, index, _size - index);
         }
         _items[_size] = default(T);
         _version++;
     }
 
     public bool Remove(T item)
     {
         int index = IndexOf(item);
         if (index >= 0)
         {
             RemoveAt(index);
             return true;
         }
 
         return false;
     }
 
     public Enumerator GetEnumerator()
     {
         return new Enumerator(this);
     }
 
     [Serializable]
     public struct Enumerator : IEnumerator<T>, IEnumerator
     {
         private List<T> list;
         private int index;
         private int version;
         private T current;
 
         internal Enumerator(List<T> list)
         {
             this.list = list;
             index = 0;
             version = list._version;
             current = default(T);
         }
 
         public void Dispose()
         {
         }
 
         public bool MoveNext()
         {
 
             List<T> localList = list;
 
             if (version == localList._version && ((uint)index < (uint)localList._size))
             {
                 current = localList._items[index];
                 index++;
                 return true;
             }
             return MoveNextRare();
         }
 
         private bool MoveNextRare()
         {
             if (version != list._version)
             {
                 throw new InvalidOperationException();
             }
 
             index = list._size + 1;
             current = default(T);
             return false;
         }
 
         public T Current
         {
             get
             {
                 return current;
             }
         }
 
         System.Object IEnumerator.Current
         {
             get
             {
                 if (index == 0 || index == list._size + 1)
                 {
                     throw new InvalidOperationException();
                 }
                 return Current;
             }
         }
 
         void IEnumerator.Reset()
         {
             if (version != list._version)
             {
                 throw new InvalidOperationException();
             }
 
             index = 0;
             current = default(T);
         }
 
     }
 }




Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image candybar · Oct 04, 2016 at 12:01 AM 0
Share

This looks awesome, thank you. I'm not that proficient at this stuff yet, so it'll take me a bit of time to understand and implement this, but I'll try it out and let you know how it plays out. Cheers, mate!

avatar image Bunny83 · Oct 04, 2016 at 12:34 AM 1
Share

Sorry nut all that work is pointless and actually will increase the build size. The generic List is defined inside the mscorlib and not inside System.dll. A lot people seem to confuse the concept of namespaces with the concept of assemblies. The name of an assembly has no relation to the namespaces it contains. Actually most "System" and child namespaces of System are defined in the mscorlib. Only a few special classes are inside the System.dll or other assemblies.

If you want to track down what classes might be responsible i strongly recommend using ILSpy and have a look into the System.dll to see which classes / interfaces are defined there which you might be using.

Again, if a namespace starts with "System" it doesn't mean it's inside the System.dll. Namespaces are a way to seperate classes logically, while assemblies are there to seperate classes physically. The mscorlib as well as the System.dll define classes in the System.Collections.Generic namespace, it depends on which you use. It contains things like the generic LinkedList, Queue, Stack, SortedDictionary and SortedList.

$$anonymous$$aybe you use something from the "System.Net" namespace ?

avatar image Mindmapfreak Bunny83 · Oct 04, 2016 at 12:11 PM 0
Share

Oh, you are right. You can actually see that List is part of mscorelib in the reference code. As you said: I confused namespaces and assemblies.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Distribute terrain in zones 3 Answers

A node in a childnode? 1 Answer

The program can't start because UnityPlayer.dll is missing from your computer. 2 Answers

Build C# to dll for .NET 3.5 w/ VS 2017 0 Answers

Build itextsharp dll Lite 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges