How to check if any of the prefab position went beneath the particular constraint (good coding habits - Static variable usage)

Hi ,
I’m trying to build a small 2d game in which there is a bucket that catches the balls.
If any of the ball went beneath the bucket game should end. As I’m very new to the unity3d and scripting, I couldn’t figure out how to check this that if any of the ball go below a particular y position. Balls are dynamically created using prefab.I’m using this script for ball creation and is attached to my MainCamera

using UnityEngine;
using System.Collections;

public class ballCreationScript : MonoBehaviour {

    public GameObject ballPrefab;
    public Vector3 positions;
    
	// Use this for initialization
	void Start () {

        StartCoroutine(balls());
	}
	
	// Update is called once per frame
	void Update () {
	
	}
    IEnumerator balls() {
        while (true) {
            positions = new Vector3(Random.Range(-2.5f, 2f), 20, 0);
            Instantiate(ballPrefab , positions , Quaternion.identity);
            
            yield return new WaitForSeconds(1f);
            
        }
    }

    private object WaitForSeconds(float p)
    {
        throw new System.NotImplementedException();
    }
}

And for ball movement i’m using this script and is attached to Balls prefab

using UnityEngine;

using System.Collections;

public class BallMovementScript : MonoBehaviour
{

    public static float speed = -8;
    public static float ballYPosition;
    GameObject ball;


    // Use this for initialization
    void Start()
    {

        rigidbody.velocity = new Vector3(0, speed, 0);

    }

    // Update is called once per frame
    void Update()
    {
        if (ball.gameObject.tag == "Ball")
        {
            if (ball.gameObject.transform.position.y < -4)
            {
                print("not Good");
            }
        }

    }

}
![alt text][1]

This is the main Screen . For now I just placed paddle instead of Bucket. balls would come from above and if any of the ball misses the paddle game should end.

Below script is attached to my paddle. When collisions occurs it destroy that object.

using UnityEngine;
using System.Collections;

public class PaddleScript : MonoBehaviour {
    
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
        Ray rayOrigin = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hitInfo;
        if (Input.GetMouseButton(0))
        {
            if (Physics.Raycast(rayOrigin, out hitInfo))
            {
                transform.position = new Vector3(hitInfo.point.x, -1.993791f, 0);
           
            }
        }
	}
    void OnCollisionEnter(Collision col) {
        Destroy(col.collider.gameObject);
    }

}

I hope it clears my Point.

OK, first welcome and hello :slight_smile:

About what you’re trying to do, you don’t need to perform any checks about the balls’ y coordinate. You said there’s a bucket, right? - just like a basketball game - that bucket should have a collider (box collider is ok) within it, make sure to check ‘is trigger’ on the collider, which means it won’t intercept / physically collider with whatever comes through it - in other words, anything could pass right through it. Now whenever a ball gets into the bucket, it collides with that collider, and since you ticked ‘is trigger’, OnTriggerEnter gets ‘fired’ (OnTriggerEnter is an event - when you hear an event got ‘fired’ it means the event has happened or occurred, if you like) - Now, you will ‘handle’ this event in your ball script, like:

OnTriggerEnter(Collider other)
{
  if (other.gameObject.tag == Tags.bucket)
  {
     Debug.Log ("ball " + id + " is inside bucket"); // assuming you have an id for your balls, which could be a name, a number, etc
  }
}

You don’t have to handle it inside the ball, you can do it in the bucket script if you like:

OnTriggerEnter(Collider other)
{
  if (other.gameObject.tag == Tags.ball)
     // do something...
}

This is from a basketball tutorial I went through when I was staring (I don’t wanna give you links to, because their code quality just SUCKS!)

15366-basketball.png

Note that, in my case, I have to make some checks to make sure that the ball goes in the basket from top to bottom, and not the opposite. But since you’re using a bucket you don’t have to because it’s sealed from the bottom.

Now, you mentioned good habits? - here’s a few:

  • NEVER use statics unless you know
    what you’re doing. When you make a
    variable static it means that
    ALL instances/objects of your class will
    share/have the same variable. When to
    use this? - let’s say you wanted to
    make a ball id (integer), each time
    you instantiate a ball, you give it a
    new id (assuming that you don’t
    destroy them, they will keep their id
    unique) - how would you do that?

A simple way is using static variable to count how many balls do we have, use the value of that counter as our id, like so:

public class Ball
{

    private static int counter = 0;
    public int Id { private set; get; }  // this is a property, anybody can 'get' its value, but only inside this class, that its value can be 'set'

    void Start()
    {
       Id = counter++;
    }
}

This is OK, it makes sense for all balls to have the same counter, right? :slight_smile:
With the previous code, first ball gets instantiated will have an Id of 0, 2nd one will have 1, then 2, 3, 4, etc. This is because counter is static, it will remain the same between all ball instances. BUT, why didn’t I make Id static? o.O - Ask yourself: “Should all balls have the same Id?” - Of course not! otherwise it’s not an identifier that I could identify a ball with - it’s like you’re saying all the balls are the same :smiley:

This is exactly what you did with:

 public static float speed = -8;
 public static float ballYPosition;

That way, all balls have the same speed and ballYPosition :confused:

Another good example of statics: It’s always best to organize your tags in your game, keep things in one place and not scattered around. Because what if you changed your tag? - you would have to go and change it in numerous places. The way I like to do it, is to use a “Tags” class - It’s a class that I always like to use to store all my tags. A Tags sample class would be:

public abstract class Tags
{
    public static string bucket = "Bucket"; // you can use static instead of const
    public static string ball   = "Ball";
    public static string player = "Player";
}

(abstract means that you can’t make an instance of your class = you can’t instantiate objects of that class - this is good for our purposes because we are intending to access the members of the class in a static manner)

And then you can access your tags in a static manner as we mentioned, like so:

if (collider.tag == Tags.player)
{
  // do something
}

You don’t need an instance of the class to access a static variable, just nameOfClass.myStaticVar; - Which makes sense. There is a bit more about static variables, I will leave learning their basics and googling to you, but for example.
More about usages of static variables within Unity (great example!).

  • Give your variables self-explanatory
    non-confusing names. Like your
    positions variable. A rule of
    thumb: Always try to make your
    variables identifiable by their
    names. By identifiable I mean someone
    can easily tell what they serve and
    what’s their purpose. And sometimes,
    good naming could lead to the
    discovery of the data type of the
    variable. On the contrary bad naming will lead to confusion. For me when I saw
    positions I immediately thought
    it’s either a list or an array of
    Vector3.

There’s a lot that I would love to cover for you :slight_smile: - But I think it’s best to learn from some good tutorials. Please understand that there are a TON of shitty ugly disgusting crappy tutorials EVERYWHERE! - Just make sure you choose the good ones, ones that are tutored by ‘good’ programmers, who write good quality good, there are a lot of course.

  • Programming-related: LEARN OOP!
    And get your basics together just
    right.

  • Unity-related: I have a few,
    Quilly is very friendly to
    new-comers and explains things just
    right! (basic-intermidate, uses C#) - Then you got
    BurgZergArcade, great
    programmer! Got an extensive
    400-videos RPG series! (Basic, intermediate, advanced, uses C#) You Got
    UnityGems which I mentioned
    earlier (a bit more advanced stuff).
    You can’t go wrong with these guys,
    anything they say is like sacred! :smiley: (Intermidate-advanced, uses C#)
    Then you got Brackeys (Basic-intermidate, not sure about lang) and Etiskee (Basic-intermidate, uses JS) for FPS-related stuff. Great, but not very technical. Finally thewalkerboys (Basic, uses JS) and thetornadotwins (Basic, not sure about lang)

Lastly, what are you doing with:

private object WaitForSeconds(float p)
{
   throw new System.NotImplementedException();
}

WaitForSeconds is already implemented for you, unless you don’t want to make something like, WaitForRealSeconds I don’t think you need to bother yourself with re-implementing it :slight_smile: