2
\$\begingroup\$

I am a trying to recreate the first stage of Super Mario Brothers, but I am having a bit of trouble with the collision system between Koopa Shells. I have written two different scripts in hopes to achieve this:

This First script is to handle the Basic movement and start shell movement on Player Collision

It's Rather long so I took the liberty of including only parts that were in direct correlation/ causation of the problem

     public class KoopaShell : MonoBehaviour
     {
         //Makes this accessible to other Scripts
         public bool Moving;

         // Boolean Flags to be inherited 
         bool shellLeft, shellRight, rightBlocked, leftBlocked;
         public float rayDis;
         public LayerMask enemyMask;
         public Transform rCast;

 [... Rest of the code..]
         void OnCollisionEnter2D(Collision2D coll) 
         {
             if (leftBlocked || rightBlocked) // If the either side of the shell is hit
                 if (coll.gameObject.tag == "Player" && Moving == false) // If the player makes contact with a resting shell 
                 {
                     MoveShell();
                 }
         }

         public IEnumerator MoveShell() //Courotine for 2D Collision
         {
                     //The Courotine will wait for the end of the frame 
                     yield return new WaitForFixedUpdate();
                     //Then set moving to true
                     Moving = true;
         }
     }

The Second Script handles all other collision and inherits from the first in an attempt to simplify the calling from script to script.... Could also be the cause of my problem.

public class MovingShellScript : KoopaShell
{

//This is a continuation of the KoopaShell Script
//Dealing with 2D Collision

void OnCollisionEnter2D(Collision2D col)
{
   if (col.gameObject.tag == "Koopa Shell") //  if contact is made with another shell that is moving
     if(col.gameObject.Equals(Moving) == false) //if the shell is not moving
     {
      {
          Destroy(col.gameObject);  // Then the resting shell is destroyed
          Debug.Log("Looks like another shell is unemployed");
       }
     }

    if (col.gameObject.tag == "Enemy") // If a Enemy is hit by the Shell
       if (Moving == true) // and If the Shell is moving
       {
                     // The GameObject hit is Destroyed
                     Destroy(col.gameObject);
       }
     }
 }

Currently the script above does not destroy the various gameobjects under the Enemy and Player tag. Maybe this could be done implicitly with an associated script to the desired gameobject that correlates with the tag....

Also the script destroys both shells during a collision. I don't understand why my various boolean flags aren't creating the desired result(s)

  • If both shells are moving then both shells are destroyed.

  • If only one shell is moving then the resting shell is destroyed.

I am seeking to understand the error in my logic for this to work as desired.

Thank you for your time!

\$\endgroup\$
2
\$\begingroup\$

I think you may be misunderstanding what the Equals() method does - it's checking whether the GameObject instance col.gameObject is equal to whatever you pass in as an argument. You're passing in a Boolean value, which is not a GameObject, so the result will always be false.

I think you mean to write something more like this:

void OnCollisionEnter2D(Collision2D col)
{
   if (col.gameObject.CompareTag("Koopa Shell")) //  if contact is made with another shell
   {
        // Get a reference to the other shell:
        KoopaShell otherShell = col.gameObject.GetComponent<KoopaShell>();

        if(otherShell.Moving == false) //if the other shell is not moving
        {
             Destroy(col.gameObject);  // Then the resting shell is destroyed
             Debug.Log("Looks like another shell is unemployed");
        }
    }

...
\$\endgroup\$
  • \$\begingroup\$ Thank you for your help, however I still am running into the same problem where both instances of the shell are destroyed. I cannot think of any reason for this. Destroy(col.gameObject) destroys both objects while Destroy(gameObject) does nothing. \$\endgroup\$ – Ham Jul 14 '16 at 1:44
  • \$\begingroup\$ This is the expected outcome if both (this.Moving == false) && (otherShell.Moving == false) since each will destroy the other. Have you tried inspecting the Moving flag on each object to check whether they have the values you expect at the moment of collision? \$\endgroup\$ – DMGregory Jul 14 '16 at 1:49
  • \$\begingroup\$ Firstly I want to thank you once again for taking the time to help me figure out this problem. I am beyond grateful! I realized a few errors in my logic after your last comment. \$\endgroup\$ – Ham Jul 16 '16 at 16:17
  • \$\begingroup\$ Firstly, my Moving boolean was a static varibale(this was changed before I asked this question). Secondly, I failed to reference the object I was colliding with thus building on my first logic error of the static boolean - which made all instances share the same value. Lastly, after realizing the later of the two and the fact that my code was not properly allowing the entire engine to access the value of the Moving boolean - which you so kindly pointed out to check, it was then when I realized I was prematurely calling my coruotine with out the use of StartCoruotine(). \$\endgroup\$ – Ham Jul 16 '16 at 16:23
  • \$\begingroup\$ I'm glad you got it solved! Feel free to elaborate on your solution in an answer and mark it accepted so others can learn from your experience. \$\endgroup\$ – DMGregory Jul 16 '16 at 16:27
0
\$\begingroup\$

Firstly, my Moving Boolean was a static variable(this was changed before I asked this question). Secondly, I failed to reference the object I was colliding with thus building on my first logic error of the static Boolean - which made all instances share the same value. Lastly, after realizing the later of the two and the fact that my code was not properly allowing the entire engine to access the value of the Moving Boolean - which was kindly pointed out to me to check, it was then when I realized I was prematurely calling my coruotine without the use of StartCoruotine().

  IEnumerator MoveShell() //Courotine for 2D Collision
     {
                 //The Courotine will wait for the end of the frame 
                 yield return new WaitForSeconds(0.001f);
                 //Then set moving to true
                 yield return Moving = true;
     }

     void OnCollisionEnter2D(Collision2D coll) 
     {
         // Any collision that deals with the Player will be here
         if (leftBlocked || rightBlocked) // If the either side of the shell is hit
             if (coll.gameObject.tag == "Player" && this.Moving == false) // If the player makes contact with a resting shell 
             {
                 StartCoroutine(MoveShell()); // Calls our Courotine 
             }

         // Any collision that deals with other Koopa Shells will be here
         if (coll.gameObject.CompareTag("Koopa Shell")) //  if contact is made with another shell
         {
             // Get a reference to the other shell:
             KoopaShell otherShell = coll.gameObject.GetComponent<KoopaShell>();
             if (otherShell.Moving == false && this.Moving == true) //if one of the shells is at rest
             {
                 Destroy(coll.gameObject);  // Then the resting shell is destroyed
                 Debug.Log("The Shell at rest was destroyed");
             }
                 if(otherShell.Moving == true && this.Moving == true)// if both shells are not moving
                 {
                     Destroy(this.gameObject); //Destroy the moving shell that this script is attached to 
                     Destroy(coll.gameObject); //Destroy the moving shell that is being collided with
                     Debug.Log("Both Shells involved were destroyed");
                 }
         }
     }

The Actually code is no where as near as this broken up. Please forgive the failed attempt of presentation.

Thank you again for all that followed or assisted me in any way! :)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.