Advertisement

Hi all. I need help with my C# script on Unity 5.

Started by December 01, 2016 07:57 PM
12 comments, last by Eulagrief 8 years ago

Hi everyone. I am new here. I just started learning scripting C# on Unity not long ago.

Currently, I am following along a tutorial but I am having a major problem that I cannot seems to solve.I have posted on Unity forum, but there isn't any response yet.

Hope someone can help me here. Thank you very much,

I have uploaded my game on gamebucket.

http://www.gamebucket.io/game/4a79944a-0946-41e1-8ea9-18a165461ecc

The game is currently script to Autoplay, so it doesn't matter.

I have 1 problem. If I click start on the first screen, it will take me to the "first level". no problem. If I left mouse click, the ball will move. no problem.

However, if I clicked start and move to the next screen, "first level" but I don't click on the mouse. I let the ball stationary. If I stay idle for a few seconds, it will take me to the Game Over screen.

I look through the tutorial 3 times and I still cannot find the problem.

Is there an "idle timer" that I have placed accidentally between the codes?

I have zip the scripts into a zip file. The zip file only contains all scripts that are involved in this project and nothing else.

I will also paste the code here if you do not wish to download the zip folder.

LevelManager.cs = Responsible for loading the levels, win and game over scene,


using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;

public class LevelManager : MonoBehaviour {

	public void LoadScene(string name){
		Brickblock.brickCount = 0;
		SceneManager.LoadScene (name);
	}
	public void QuitScene(){
		
		Application.Quit ();
	}

	public void brickDestroyed(){
		if (Brickblock.brickCount <= 0) {
			LoadNextLevel ();
		}
	}

	public void LoadNextLevel(){
		Brickblock.brickCount = 0;
		SceneManager.LoadScene (SceneManager.GetActiveScene().buildIndex + 1);

	}

}

Ball.cs = Responsible for the moving ball on every level.


using UnityEngine;
using System.Collections;

public class Ball : MonoBehaviour {

	public AudioSource soundSource;

	private Paddle paddle;
	//Declare variables and naming
	private Vector3 paddleToBallVector;
	private Rigidbody2D rb2d;
	private bool GameStart=false;

	private void Awake (){
		rb2d = GetComponent<Rigidbody2D> ();
		}

	// Use this for initialization
	void Start () {
		paddle = GameObject.FindObjectOfType<Paddle> ();
		paddleToBallVector = this.transform.position - paddle.transform.position;

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

		//Game have not start

		if (!GameStart) {
			this.transform.position = paddle.transform.position + paddleToBallVector;
		}
		//Game start on mouse click
		if (Input.GetMouseButtonDown (0)) {

			this.rb2d.velocity = new Vector2 (3f, 15f);
			GameStart = true;
		}
	}

	void OnCollisionEnter2D (Collision2D Collision){
		soundSource = GetComponent<AudioSource> ();

		Vector2 tweak = new Vector2 (Random.Range (0f, 0.2f), Random.Range (0f, 0.2f));

		if (GameStart) {
			soundSource.Play();
			this.rb2d.velocity += tweak;

		}
	}
		
}

Brickblock = Responsible for the blocks to be hit.


using UnityEngine;
using System.Collections;

public class Brickblock : MonoBehaviour {

	public Sprite[] hitSprites;
	public static int brickCount = 0;
	public GameObject particlesVfx;

	private int timesHits;
	private LevelManager levelManager;
	private bool isBreakable;

	// Use this for initialization
	void Start () {
		timesHits = 0;
		isBreakable = (this.tag == "Breakable");

		if (isBreakable) {
			brickCount++;
		}

		levelManager = GameObject.FindObjectOfType<LevelManager> ();
	}

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

	}

	void OnCollisionEnter2D (Collision2D Collision){
		if (isBreakable) {
			hitsCounter ();
		}
	}

	void hitsCounter () {
		timesHits++;
		int maxHits = hitSprites.Length + 1; 
		if (timesHits >= maxHits) {
			brickCount--;
			levelManager.brickDestroyed ();
			particlesEffect ();
			Destroy (gameObject);
		} else {
			LoadSprites ();
		}
	}

	void particlesEffect (){
		GameObject particlesVfxObject = Instantiate (particlesVfx, transform.position, Quaternion.identity) as GameObject;
		particlesVfx.GetComponent<ParticleSystem> ().startColor = gameObject.GetComponent<SpriteRenderer> ().color;
	}

	void LoadSprites (){
		int spriteValues = timesHits - 1;

		if (hitSprites [spriteValues]) {
			this.GetComponent<SpriteRenderer> ().sprite = hitSprites [spriteValues];
		}
	}

}

LoseCollider= Responsible for the collision to occur when the ball drop below the screen.


using UnityEngine;
using System.Collections;

public class LoseCollider : MonoBehaviour {

	private LevelManager levelManager;

	void OnTriggerEnter2D (Collider2D Trigger){
		levelManager = GameObject.FindObjectOfType<LevelManager> ();
		levelManager.LoadScene ("Game_Over");
	}

	void OnCollisionEnter2D (Collision2D Collision){
		print ("Collision");
	}
}

Paddle = Responsible for the movement of the moving brick to deflect the ball upwards.


using UnityEngine;
using System.Collections;

public class Paddle : MonoBehaviour {

	public bool autoPlay=false;

	private Ball ball;

	// Use this for initialization
	void Start () {
		ball = GameObject.FindObjectOfType<Ball> ();
	}

	// Update is called once per frame
	void Update () {
		if (!autoPlay) {
			MouseMovement ();
		} else {
			AutoPlay ();
		}
	}

	void MouseMovement () {
		Vector3 paddlePos = new Vector3 (0.5f, transform.position.y, 0f);
		float mousePosInUnits = Input.mousePosition.x / Screen.width * 16;
		paddlePos.x = Mathf.Clamp (mousePosInUnits, 1f, 15f);
		transform.position = paddlePos;
	}

	void AutoPlay () {
		Vector3 paddlePos = new Vector3 (0.5f, transform.position.y, 0f);
		Vector3 ballPos = ball.transform.position;
		paddlePos.x = Mathf.Clamp (ballPos.x, 1f, 15f);
		transform.position = paddlePos;
	}
}

BGMusic.cs = Respobsible for the BGmusic.


using UnityEngine;
using System.Collections;

public class BGMusic : MonoBehaviour {

	static BGMusic instance = null;

	// Use this for initialization
	void Start () {
		if (instance != null) {
			Destroy (gameObject);
		} else {
			instance = this;
			GameObject.DontDestroyOnLoad (gameObject);
		}
	}
	
	// Update is called once per frame
	void Update () {
	
	}
}

Put a breakpoint on LoseCollider.OnTriggerEnter2D and see what it's colliding with. It's possible the lose collider is being triggered by a different object than what you want.

Advertisement

Put a breakpoint on LoseCollider.OnTriggerEnter2D and see what it's colliding with. It's possible the lose collider is being triggered by a different object than what you want.

Thank you for your reply.

I have tried Debug.Log already but apparently, there is no way to see who is colliding with LoseCollider.

It seems there's an object colliding with the collider but it's invisible. I select all the objects in my hierachy, pause the game but I still cannot cannot see who is colliding with losecollider

I played them frame by frame and it will trigger the game over scene after a few seconds.

I tried pullling the losecollider down further from the camera, so it will take slightly longer for the ball to collide with the losecollider but all it does is only extend the idle time, meaning there is some object I can't see that seems to be colliding with the losecollider.

I'm pretty new to Unity dev myself, but it looks like maybe the ball does not get any velocity until you click (triggers GameStart), and you are setting the ball position to the paddle position in Start ( ) in Ball.cs. If your paddle is close enough to the LoseCollider (your thing below the screen), it may just trigger it right away.

EDIT: Sorry wrote this before, and didn't see your response above! Maybe try setting the ball position to some manual xyz (until GameStart) and see if it still triggers?

-Mark the Artist

Digital Art and Technical Design
Developer Journal

I'm pretty new to Unity dev myself, but it looks like maybe the ball does not get any velocity until you click (triggers GameStart), and you are setting the ball position to the paddle position in Start ( ) in Ball.cs. If your paddle is close enough to the LoseCollider (your thing below the screen), it may just trigger it right away.

EDIT: Sorry wrote this before, and didn't see your response above! Maybe try setting the ball position to some manual xyz (until GameStart) and see if it still triggers?

Thank you for your reply!

Thank you for your suggestion. I am going to take suggestion a try when I wake up. Sigh It's 5am I've been trying to figure out this thing for many hrs now. lol.

Put a breakpoint on LoseCollider.OnTriggerEnter2D and see what it's colliding with. It's possible the lose collider is being triggered by a different object than what you want.

Thank you for your reply.

I have tried Debug.Log already but apparently, there is no way to see who is colliding with LoseCollider.

That is not true at all. The collider2d passed in, you can get to the game object from it easily, via .gameObject. You could debug.log("yourmessage, Collision.gameObject) inside the LoseCollider script OnTriggerEnter2d method. Or you could put a breakpoint there, and look at the value of the game object.

Advertisement

Put a breakpoint on LoseCollider.OnTriggerEnter2D and see what it's colliding with. It's possible the lose collider is being triggered by a different object than what you want.

Thank you for your reply.

I have tried Debug.Log already but apparently, there is no way to see who is colliding with LoseCollider.

That is not true at all. The collider2d passed in, you can get to the game object from it easily, via .gameObject. You could debug.log("yourmessage, Collision.gameObject) inside the LoseCollider script OnTriggerEnter2d method. Or you could put a breakpoint there, and look at the value of the game object.

OH! thank you so much for your help.

I have added the debug code. Yes, it is the ball that is colliding with the losecollider.

When I delete the ball, the problem goes away.

However, even after tweaking the script. I am still unable to solve the problem. No matter what, the ball will collide with the lose collider if I stay idle.

Ball script.


using UnityEngine;
using System.Collections;

public class Ball : MonoBehaviour {

	public AudioSource soundSource;

	private Paddle paddle;
	//Declare variables and naming
	private Vector3 paddleToBallVector;
	private bool GameStart=false;

	// Use this for initialization
	void Start () 
	{
		paddle = GameObject.FindObjectOfType<Paddle> ();
		paddleToBallVector = transform.position - paddle.transform.position;

	}
	
	// Update is called once per frame
	void Update () 
	{	
		//Game have not start
		if (!GameStart) {
			this.transform.position = paddle.transform.position + paddleToBallVector;
		}

		//Game start on mouse click
		if (Input.GetMouseButtonDown (0)) 
		{	
			GameStart = true;
			gameObject.GetComponent<Rigidbody2D> ().velocity = new Vector2 (3f, 15f);
		}
	}

	void OnCollisionEnter2D (Collision2D Collision)
	{
		soundSource = GetComponent<AudioSource> ();

		Vector2 tweak = new Vector2 (Random.Range (0f, 0.2f), Random.Range (0f, 0.2f));

		if (GameStart) 
		{
			soundSource.Play();
			gameObject.GetComponent<Rigidbody2D> ().velocity += tweak;

		}
	}
		
}

Losecollider script.


using UnityEngine;
using System.Collections;

public class LoseCollider : MonoBehaviour {

	private LevelManager levelManager;

	// Remove/add star slash to enable/disable.

	void OnTriggerEnter2D (Collider2D Trigger){
		levelManager = GameObject.FindObjectOfType<LevelManager> ();
		Debug.Log (Trigger.GetComponent<Collider2D>().gameObject.name);
		levelManager.LoadScene ("Game_Over");
	}

	void OnCollisionEnter2D (Collision2D Collision){
		print ("Collision");
	}
}

Thank you.

Update:

After playing frame by frame. I notice something very weird.

On my hierarchy, if I clicked on "Ball" Game object and "Losecollider" game object together, there is a transform tool appearing.

If I select all objects on my hierarchy, that transform goes away.

I will attach screenshot.

m02Kbmf.jpg

XPtdi8O.jpg

TQ1KxTt.jpg

q17jQBt.jpg

What's it look like if you have only the ball selected? That might just be a red herring and unity is showing you an aggregated box of everything you have selected. If that box shows up when you have the ball selected, your sprite maybe be off center. Though it shouldn't really matter as long as your collider is in the right spot and your not trying to do any rotation of the ball manually. You might try deleting the ball, recreating it manually, and re-adding your scripts, to ensure you didn't mess with something odd like an anchor point, center of the rigidbody or whatever.

Is your ball colliding with the paddle while idle, thus sending the ball down towards your offscreen zone? Where is your ball at the time of it colliding with the game over zone?

Also, double check where your zone is when the game is running, how are you placing it? I like to stick those kind of objects programmatically below the viewport, with some extra space, because offscreen a little bit before 'game over' or 'death' is not a big deal.

What's it look like if you have only the ball selected? That might just be a red herring and unity is showing you an aggregated box of everything you have selected. If that box shows up when you have the ball selected, your sprite maybe be off center. Though it shouldn't really matter as long as your collider is in the right spot and your not trying to do any rotation of the ball manually. You might try deleting the ball, recreating it manually, and re-adding your scripts, to ensure you didn't mess with something odd like an anchor point, center of the rigidbody or whatever.

Is your ball colliding with the paddle while idle, thus sending the ball down towards your offscreen zone? Where is your ball at the time of it colliding with the game over zone?

Also, double check where your zone is when the game is running, how are you placing it? I like to stick those kind of objects programmatically below the viewport, with some extra space, because offscreen a little bit before 'game over' or 'death' is not a big deal.

Thank you so much for your reply ferrous. I will give it a try now. :)

This topic is closed to new replies.

Advertisement