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 /
  • Help Room /
avatar image
1
Question by jimjames · Nov 15, 2015 at 10:42 AM · list

Error while debugging list

I have a list which contains 2 variables:

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class SlowOrder //holds the values for slows
 {
     public float Speed;
     public float Duration;
     
     public SlowOrder(float speed, float duration)
     {
         Speed = speed;
         Duration = duration;
     }
 }
 
 public class UnityTest : MonoBehaviour 
 {
     public List<SlowOrder> slowOrder = new List<SlowOrder>();
 
     public float walking;
     public float currentSlowDuration;
 
     void SlowEffect(List<float> slowHolder) //sendmessage from projectiles //list [0] = percent [1] = duration
     {
         float wTemp = walking - (walking * slowHolder [0]); //new slowed walking speed
         float dTemp = currentSlowDuration - Time.time; //current slowed duration, left

             slowOrder.Add (new SlowOrder (wTemp, slowHolder[1] + Time.time));
 
         for(int i = 0; i < slowOrder.Count; i++) //debugging
         {
             Debug.Log ("speed = " + slowOrder[i].Speed + " / duration = " + slowOrder[i].Duration);
         }
 
         slowHolder.Clear (); //clears this methods list "SlowOrder" for next
     }
 }

I get this Error:

 ArgumentException: does not implement right interface

But only when I add to the list and then debugs. The first fire dose not give errors.

I used this type of list and not a dictionary cause i will have duplicate keys and values.

Still learning scripting, so be nice and simple.

James

Comment
Add comment · Show 6
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 Jessespike · Nov 15, 2015 at 11:36 AM 2
Share

Does the list ever call .Sort()? I only ask cause that same error would be thrown since SlowOrder doesn't implement IComparable. I'm not sure why this error is happening.

avatar image jimjames · Nov 15, 2015 at 12:13 PM 0
Share

Yes it does but the .Sort() dose not get called till latter. After the debug. usually 5 secs

avatar image jimjames · Nov 15, 2015 at 12:17 PM 0
Share

I just tested this out and you are right. How would I go about sorting then?

avatar image Jessespike · Nov 15, 2015 at 12:42 PM 2
Share

I haven't done this a lot, but I think it would go something like this:

 using System;
 
 public class SlowOrder : IComparable<SlowOrder> //holds the values for slows
 {
     public int CompareTo(SlowOrder obj) {
         if (obj == null) return 0;
         if (obj.Duration > this.Duration) return 1;
         return 0;
      }
avatar image jimjames · Nov 15, 2015 at 12:50 PM 0
Share

IComparable is unavailable in mono. it does allow IComparer

Show more comments

1 Reply

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by RickyAh · Nov 15, 2015 at 01:32 PM

If you want to sort a List the elements in the list must be comparable in some way. Common types like int, float, and strings are already comparable. However if you define your own type you must also define a way to sort the elements, otherwise the Sort method won't know what to do.

You have two options to define how you want to sort a new type.

Using IComparable Make SlowOrder implements the interface IComparable which requires to define a method named CompareTo. This is basically what @Jessespike suggested. The interface is available on Unity, I've used it several times. If it gives you a compilation error then you must add using System; to the beginning of the file.

Using IComparer The previous approach can be useful to define a default sorting for SlowOrder elements, the problem is that it only allows sorting in one specific way, and you might be interested in sorting a list in different ways. Maybe you want to sort by Speed, ascending or descending depending on the situation, or maybe you have one case where you want to sort SlowOrder elements by Duration, instead of Speed.

For this situation you can create new classes that implements IComparer. That interface only's purpose is define a method with the algorithm to sort collections containing other types, so you can create several classes implementing IComparer where each class contains a different sorting algorithm:

 using System.Collections.Generic;

 public class SlowOrderSortByDuration : IComparer<SlowOrder>
 {
      int Compare(SlowOrder x, SlowOrder y) 
      {
           return x.Duration < y.Duration;
       }
 }
 
 // Now sort the list using this comparer
 slowHolder.Sort(new SlowOrderSortByDuration());

To avoid creating a new object each time that you want to sort a list, I recommend you to just add an static field of the IComparer to the class you want to sort:

 public class SlowOrder //holds the values for slows
  {
      public class SortByDuration : IComparer<SlowOrder>
      {
          int Compare( SlowOrder x, SlowOrder y) 
          {
               return( x.Duration < y.Duration;
           }
      }
      static public SortByDuration  ByDuration = new SortByDuration();
 
      public float Speed;
      public float Duration;
      
      public SlowOrder(float speed, float duration)
      {
          Speed = speed;
          Duration = duration;
      }
  }

So now you can sort your list like this:

 slowHolder.Sort(SlowOrder.ByDuration);

Now, if you want to sort SlowOrder elements in different ways, you only need to create another different class implementing IComparer and implementing the new sorting method, for example:

    slowHolder.Sort(SlowOrder.BySpeedDescending)
Comment
Add comment · Show 8 · 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 jimjames · Nov 16, 2015 at 01:56 AM 0
Share

Wow. just simply wow. Great answer and so well explained. Love how you gave me an understanding of how this works. I fully dont but after playing with it I am sure I will.

I have a question: Is this a good way of applying debufs to players/enemies? Each player/enemy will have this in there scripts which also controls other things. By making it static wont it be global? Could I add:

 [System.Serializable] //this
 public class SlowOrder //holds the values for slows
   {
       public class SortByDuration : IComparer<SlowOrder>
       {
           int IComparer.Compare( SlowOrder x, SlowOrder y) 
           {
                return( x.Duration < y.Duration;
            }
       }
       static public SortByDuration  ByDuration = new SortByDuration();
  
       public float Speed;
       public float Duration;
       
       public SlowOrder(float speed, float duration)
       {
           Speed = speed;
           Duration = duration;
       }
   }

Above and make it this class specific? Or am I understanding this all wrong?

Also SlowHolder is just used to transfer var amounts. Ill need to Sort() "SlowOrder"

avatar image jimjames · Nov 16, 2015 at 02:29 AM 0
Share

Also getting a error x2:

 Assets/Attempt 3/Enemies/Scripts/Enemy$$anonymous$$eleeGrunt.cs(28,31): error CS0540:

for line:

 int IComparer.Compare (SlowOrder x, SlowOrder y)
avatar image RickyAh · Nov 16, 2015 at 06:14 AM 0
Share

No problem making it static: The class does not contains data, you only need the algorithm Also as it does not contains data it is safe to serialize the class because, there is nothing to serialize! :)

About the error I think you need to remove the IComparer. from the lines IComparer.Comparer $$anonymous$$y bad

avatar image jimjames · Nov 16, 2015 at 06:18 AM 0
Share

Thanks. I was reading up on these kinds of lists and came up with:

 [System.Serializable]
 public class SlowOrder : IComparable<SlowOrder> //holds the values for slows
 {
     public int CompareTo(SlowOrder other) 
     {
         if (this.Speed > other.Speed)
             return 1;
         else if (this.Speed < other.Speed)
             return -1;
         else
             return 0; //will add another search camparing the duration
 
         //return this.Speed.CompareTo (other.Speed); //short form
     }
 
     public float Speed;
     public float Duration;
 
     public SlowOrder(float speed, float duration)
     {
         Speed = speed;
         Duration = duration;
     }
 }

what do you think? I need something optimaized due to being a bullet hell game.

avatar image RickyAh jimjames · Nov 16, 2015 at 06:25 AM 0
Share

Seems ok, I don't think you'll get a comparison algorithm more optimized than that. The problem -if you find any- won't be in this Compare method, but probably in the number of times you call Sort. Here's the Sort method doc in case you are interested: https://msdn.microsoft.com/en-us/library/234b841s(v=vs.110).aspx

avatar image jimjames · Nov 16, 2015 at 06:33 AM 0
Share

Sort() will be only called when the enemy current slow runs out and there are more in the SlowOrder due to being a lesser slow then the current one but with a longer duration.

Show more comments

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

32 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

problem with loading list of strings on buttons 2 Answers

add object to list button script in inspector? 0 Answers

How do I properly use List-Vector3-.Contains()? 1 Answer

How would I implement a random spawn timer into a list based spawn system? 2 Answers

List, for loop and removal of items 2 Answers


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