1
\$\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

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

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

    BoxCollider rayHold;
    ConstantForce2D cf;
    float myWidth, myHeight;
    Rigidbody2D rb;
    Ray rRay, lRay;
    Transform myTrans;
    Vector2 myVel;


    [SerializeField]
    RaycastHit hitinfo;

    // Start is called once at the beginning of run time
    void Start()
    {


        // Sets our shorthanded variables equal to the KoopaShell's Rigid Body and position; 
        myTrans = this.transform;
        rb = this.gameObject.GetComponent<Rigidbody2D>();

        //Ignores Collision Between the level boundaries/ power ups and the Koppa Shell
        Physics2D.IgnoreLayerCollision(9, 12);
        Physics2D.IgnoreLayerCollision(11, 12);

        // This is a variable to help short hand us accessing our Sprite Renderer component
        SpriteRenderer mySprite = this.gameObject.GetComponent<SpriteRenderer>();

        // These two variables are using the mySprite varaible to access the extents or total midway point of the sprite in both the x and y axis
        myWidth = mySprite.bounds.extents.x;
        myHeight = mySprite.bounds.extents.y;

        // Another batch of short handed varibales to store the 3d Box Collider in the child GameObject
        rayHold = this.gameObject.GetComponentInChildren<BoxCollider>();
    }

    // Update is called once per frame
    void FixedUpdate()
    {

        // Another batch of short handed varibale to store the Constant Force 2D component
        cf = gameObject.GetComponent<ConstantForce2D>();

        // Similar to our Gumba and Koopa Movement we will use linecasts to serve as flags
        Vector2 lineCastPos = myTrans.position.toVector2() - myTrans.right.toVector2() * myWidth + Vector2.up * myHeight;

        /*/////////////////////////////////////////////////////////////////////////////
        ****** 2D PHYSICS WILL NOT WORK WITH ANY 3D COLLIDERS, RIGIDBODIES, ETC ******
        ///////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////*/

        // These flags will help us change direction and handle any 2D Collision that the RayCast can not
        leftBlocked = Physics2D.Linecast(lineCastPos, lineCastPos - Vector2.right * .67f);
        rightBlocked = Physics2D.Linecast(lineCastPos, lineCastPos + Vector2.right * .67f);

        //This gives us a physical representation of our line cast... It will be shorter than the Raycast
        Debug.DrawLine(lineCastPos, lineCastPos + Vector2.right * .67f);
        Debug.DrawLine(lineCastPos, lineCastPos - Vector2.right * .67f);
        /*////////////////////////////////////////////////////////////////////////
                              *****END OF 2D PHYSICS******
        /////////////////////////////////////////////////////////////////////////

        //////////////////////////////////////////////////////////////////////////
         **** 3D PHYSICS WILL NOT WORK WITH ANY 2D COLLIDERS, RIGIDBODIES, ETC ***
        //////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////*/

        //A ray is an infinite line starting at origin and going in some direction
        //This ray's origin is in the center of or shell and going in the right direction
        //This gives us a nice reprensatation of our ray... that we acutally can see
        rRay = new Ray(rCast.position.toVector2() - rCast.right.toVector2() * myWidth + Vector2.up * myHeight, myTrans.TransformDirection(Vector2.right));
        Debug.DrawRay(rCast.position.toVector2() - rCast.right.toVector2() * myWidth + Vector2.up * myHeight, rRay.direction);

        //Same Thing just in the left direction
        lRay = new Ray(rCast.position.toVector2() + rCast.right.toVector2() * myWidth + Vector2.up * myHeight, myTrans.TransformDirection(Vector2.left));
        Debug.DrawRay(rCast.position.toVector2() + rCast.right.toVector2() * myWidth + Vector2.up * myHeight, lRay.direction);

        // A boolean flag becomes true when any rays come with in our Raycast distance
        shellRight = Physics.Raycast(lRay, out hitinfo, rayDis);
        shellLeft = Physics.Raycast(rRay, out hitinfo, rayDis);

        //Since our Moving boolean is a static variable just to make things more 
        isMoving = Moving;


        if (shellRight)
        {
            if (shellLeft == false)
            {
                // if detection from the left happens and No previous detection happens
                // then we will display a message and our shell will move to the right at a Constant Force
                Debug.Log("I have been hit on the left side by " + hitinfo);
                cf.relativeForce = new Vector2(30, 0);
            }
        }

        if (shellLeft)
        {
            if (shellRight == false)
            {
                // if detection from the left happens and No previous detection happens
                // then we will display a message and our shell will move to the right at a Constant Force
                Debug.Log("I have been hit by " + hitinfo);
                cf.relativeForce = new Vector2(-30, 0);
            }
        }
    }

    void OnCollisionEnter(Collision col) //3D Collision   
    {

        if (col.gameObject.tag == "Environment") //If moving shell hits a block or pipe
        {
            Vector3 curRot = myTrans.eulerAngles;
            curRot.y += 180;
            myTrans.eulerAngles = curRot;
            Debug.Log("you have been flipped!");
            //It's position will be rotated in the y axis
            //Turning it around in the opposite direction
        }
    }

    /*////////////////////////////////////////////////////////////////////////
                            *** END OF 3D PHYSICS ***
    ////////////////////////////////////////////////////////////////////////*/

    /*/////////////////////////////////////////////////////////////////////////////
     ****** 2D PHYSICS WILL NOT WORK WITH ANY 3D COLLIDERS, RIGIDBODIES, ETC ******
    ///////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////*/


    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;
    }
}
     /*////////////////////////////////////////////////////////////////////////
                       *****END OF 2D PHYSICS******
    ////////////////////////////////////////////////////////////////////////*/

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.

using UnityEngine;
using System.Collections;

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.GetComponent<KoopaShell>().isMoving == 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);
            }

            if (col.gameObject.tag == "Player") // If the Player is hit by a shell and If the Shell is moving
            {
                // The GameObject hit is Destroyed
                Destroy(col.gameObject);
                Debug.Log("You may not live to tell the tale");
            }


    }

}

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....

This Script Destroys both shells during a collision. I don't understand why my various boolean flags aren't creating the desired result(s) of 1. If one shell is moving then the resting shell is destroyed 2. If both shells are moving then both shells are destroyed I am seeking to understand the error in my logic for this to work as desired. Thank you for your time!

\$\endgroup\$
  • \$\begingroup\$ Why is the Moving field static? Edit: Your code formatting is awful. It was hard to read your code. \$\endgroup\$ – S. Tarık Çetin Jul 10 '16 at 12:57
  • \$\begingroup\$ @S.TarıkÇetin the Moving field being static is one of my many logic errors. I just corrected this and still am having the problem of being able to access the instance of the Prefab's class in order to execute the desired outcome. \$\endgroup\$ – Ham Jul 11 '16 at 1:07
  • \$\begingroup\$ @S.TarıkÇetin And as far as my code formatting, I felt as if I did a decent job with formatting and commenting.... Could you give me specific examples or tips to make my formatting better please? \$\endgroup\$ – Ham Jul 11 '16 at 1:09
  • \$\begingroup\$ First of all please fix the bracing, braces should start right after the line they belong to (either on the same line or on a new line), not somewhere else. Also avoid extra lines, that makes your code look partitional. Your commenting is OK, it is a good habit to comment every single line if possible. And last but not least, I strongly suggest following .Net naming conventions. \$\endgroup\$ – S. Tarık Çetin Jul 11 '16 at 1:40
  • \$\begingroup\$ @S.TarıkÇetin Ahh I see. I will fix this right away. Thank you for time! I shall look into the .Net naming conventions \$\endgroup\$ – Ham Jul 11 '16 at 1:57

Your Answer

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

Browse other questions tagged or ask your own question.