[SOLVED] List.Contains() not working

if (List.Contains(gameObject.GetComponent)) simply doesn’t work. I’ve debugged and found that Stun() > 0 works perfecly. The problem lies within this conditional. For some reason, this is always false. Through Inspector I can see that Entity receives and Add Stun to the List. Game runs without any problem, but this is simply always false.

//Stun script

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class Stun : CCTemplate {

    [Server]
    public override void ApplyCC(Entity entity, Skill skill){

        if (entity.cc3.Contains (gameObject.GetComponent<Stun>())) {


        } else {
            entity.cc3.Add (this);
            skill.stunTimeEnd = NetworkTime.UnifiedServerTime() + skill.stunDuration;
            entity.stunDuration = skill.stunDuration;
            entity.stunTimeEnd = skill.stunTimeEnd;
        }
}
//Entity script

public List<CCTemplate> cc3 = new List<CCTemplate>();

void Update() {

        serverTime = NetworkTime.UnifiedServerTime ();

        CCControl ();
        calcStun ();

}

[Server]
    public float calcStun(){
        return serverTime >= stunTimeEnd ? 0f : stunTimeEnd - serverTime;
    }

[Server]
    public void CCControl (){

        if (calcStun () > 0) {
            isStunned = true;
        } else if (cc3.Contains(gameObject.GetComponent<Stun>())){
            stunTimeEnd = 0f;
            isStunned = false;
        }
}

A print screen of Stun prefab.

You didn’t show how you’re passing entity to ApplyCC(). Is it the right object?

But hard to say anything, only you can see the debugs.

1 Like

Both Player and Monster are derived from Entity. Players casts a skill which calls ApplyCC(target, skill). It works when I use an array of Strings, something like entity.cc = “Stun”. I switched to Lists since I’ll need info from Stun, like Toolstips, etc. Now this doesn’t work anymore. I have a guess that in entity.cc3.Add(this); the result is not object that contains Stun script, but I don’t have sure. I’m not sure what data type goes to Monster when I do this. Anyway, this is what shows on my Monster Inspector.

CCTemplate is a MonoBehavior, correct? Assuming you created it with null parent, and now trying to assign it to the gameobject?

This would seem to be the right way:

(edit: It’s still correct it seems, just the one with string parameter is no longer supported.)

But Unity has powerful debugging tools, you can do:

Debug.Log(entity);
Debug.Log(gameObject.GetComponent<Stun>());
Debug.Log(entity.cc3.Contains (gameObject.GetComponent<Stun>()));
if (entity.cc3.Contains (gameObject.GetComponent<Stun>())) {
2 Likes

Well, I changed the approach… Went back to using Array (Lists are not much my type anyway).

[Server]
    public override void ApplyCC(Entity entity, Skill skill){

        for (int i = 0; i < entity.cc.Length; i++) {
            if (entity.isStunned == true) {
                break;
            }

            if (entity.cc [i] == null) {

                entity.cc [i] = gameObject.GetComponent<Stun>();
                skill.stunTimeEnd = NetworkTime.UnifiedServerTime () + skill.stunDuration;
                entity.stunDuration = skill.stunDuration;
                entity.stunTimeEnd = skill.stunTimeEnd;
                break;
            }
        }
    }
}

Here is how Entity receives the CCTemplate:

[Server]
    public void CCControl (){

        if (calcStun () > 0) {
            isStunned = true;
        } else {
            for (int i = 0; i < cc.Length; i++) {
                if (cc [i] == gameObject.GetComponent<Stun>()) {
                    stunTimeEnd = 0f;
                    isStunned = false;
                    break;
                }
            }
        }

Now, the weird thing is: cc = null right after isStunned doesn’t work. I’ve tried several methods, only one that seemed to work was Array.Clear (cc, i, i). But problem is I don’t have only “Stun” on my array, I have several other CCTemplates. Array.Clear(cc, i, i) erases ALL indexes of the array… So, I kinda made it work ,but stepped into this other problem :frowning:

This call adds a Stun that is local to one gameObject:

            entity.cc3.Add (this);

And this call looks for a Stun that is local to itself:

  public void CCControl (){
  if (calcStun () > 0) {
  isStunned = true;
  } else if (cc3.Contains(gameObject.GetComponent<Stun>())){ // gameObject is THIS entity, not the entity that stunned me

I doubt the entity is stunning itself in the first call, so you need to sort out a different way to search your List since you probably don’t have a reference to the entity that stunned you from outside of the Stun component itself.

Try something like:

public T GetCC<T>() where T : CCTemplate
{
   foreach(CCTemplate cc in cc3)
   {
       if(cc is T)
         return cc;
   }

   return null;
}

Then to find out if you’re stunned (or some other type of CC):

Stun stunned = GetCC<Stun>();

if(stunned != null)
{
   // stunned
}

A handy tool in the Inspector is that if you double click that Stun reference in your CC3 list, it will show you what GameObject it belongs to.

1 Like

Thank you very much for your efforts in trying to help me!

Those answers gave me an ideia. Instead of declaring an array / a list of CCTemplate, I created a GameObject list. On Stun.cs I did: List.Add(this.gameObject as GameObject) ( I doubt this redundance was needed, but, just in case…)

Then on enttity I made a loop to check if there was a gameobject with a name “Stun”. Worked like a charm!

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using System.Linq;

public class Stun : CCTemplate {


    [Server]
    public override void ApplyCC (Entity entity, Skill skill)
    {

        if (entity.isStunned == true) {

        } else {
            entity.cc2.Add (this.gameObject as GameObject);
            skill.stunTimeEnd = NetworkTime.UnifiedServerTime () + skill.stunDuration;
            entity.stunDuration = skill.stunDuration;
            entity.stunTimeEnd = skill.stunTimeEnd;
        }

    }

}
#region CC Handle
        if (calcStun () > 0) {
            isStunned = true;
        } else if (cc2.Count > 0) {
            for (int i = 0; i < cc2.Count; i++) {
                if (cc2 [i].name == "Stun") {
                    stunTimeEnd = 0f;
                    isStunned = false;
                    var temp = cc2 [i];
                    skillCur = skillCurTemp;
                    cc2.Remove (temp);
                    break;
                }
            }
        }

Everything works now! Tyvm to both of you :slight_smile:

EDIT: Passing as GameObject allows me even to get a reference to the Icon of ccs, tooltip describing it and even the sender of the attack! Ty SO MUCH!