Jump to content
  • Advertisement

ethancodes

Member
  • Content count

    151
  • Joined

  • Last visited

Community Reputation

17 Neutral

About ethancodes

  • Rank
    Member

Personal Information

  • Role
    Programmer
  • Interests
    Design
    DevOps
    Programming

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Oooh I see. Alright I'll give it a shot! Thanks!
  2. Not entirely sure that will work as this is a 2D game, and all the balls spawning are basically identical so I'm not sure how I could put them on different layers as they are spawned and destroyed and new ones are spawned all the time.
  3. I'm working on spawning several balls in the same location and shooting them all outward randomly within a certain angle. I need to know how I can spawn the balls in the same spot though without them hitting each other. I need them to hit everything else except other balls. Is there a way to do this?
  4. I got it! Someone on stackoverflow pointed out that I was not actually accessing the instance of the newBall, but rather the prefab. So I put var ball = Instantiate blah blah blah and that fixed it. Thanks for the help!
  5. Scratch that, it is in fact getting the vector from the original ball, but for whatever reason, it is not launching the ball when it is handed the vector. I'm really not sure why this would be. Everything looks right to me.
  6. Yes i do need gravity. I have not tried that... I'll give it a shot real quick. Ok that did not work, but let me backtrack a little bit. I could have sworn when I checked before I was getting the vector of "mainBall", but maybe I was mistaken cause I just checked it again and it's all 0's. This is the code for grabbing the vector from mainBall: mainBallVector = mainBall.GetComponent<Rigidbody2D>().velocity; Am I missing something here as to why it would not be grabbing the info from this?
  7. Tried this, but I'm getting the same result.
  8. I've got a bunch of balls all spawning in a timed interval and I am setting the velocity of them when they spawn so that they will spawn and immediately start going in the direction I want. However, they don't do that. Instead they spawn in place and gravity makes them begin to fall straight down. if they hit something, then they take off like just like they should have spawned. I'm not sure why they have to hit something for this to happen. Any ideas? The code below is the ball spawning code. The mainballVector is set in a different section and I have verified it does have the correct values. Instantiate(newBall, new Vector3(paddle.transform.position.x, (paddle.transform.position.y + 1), 0), Quaternion.identity); newBall.GetComponent<Ball>().hasStarted = true; GameManager.pickUpManager.allBalls.Add(newBall.GetComponent<Ball>()); newBall.GetComponent<Rigidbody2D>().velocity = mainBallVector; //use the original ball's vector3 to follow it directly
  9. ethancodes

    problem with a coroutine

    I think I was thinking incorrectly, after reading your post I realized that putting the whole loop in the coroutine may actually fix the issue IF I put the stuff that is already in the coroutine inside the loop. The way I was first thinking about it was to have the timer, followed by the loop, in which case the timer would only be called once. Now it makes sense! I'll give it a shot!
  10. ethancodes

    problem with a coroutine

    The method is called by an event, the event is called by a ball colliding with the paddle, so yes OnCollisionEnter2D. As for putting the loop inside the coroutine, I don't believe that would work. I need to spawn ball, wait, spawn ball, wait, spawn ball, wait, etc. But if the loop is inside the coroutine it is going to wait...spawn ball, spawn ball, spawn ball, etc. I suppose I can possibly try a boolean like you suggest, but also like you said I'm not sure that will work or that it's a good idea. Are there any alternatives to coroutines that would work as a timer that I could use in this situation? I'm open to other ways of doing this. I tried using a timer of some sort previously but it of course stopped everything else in the game while the timer was counting which won't work for what I need.
  11. I'm having an issue with a coroutine. I believe it is working as it should, but it's not what I want and I'm having problems figuring out how to rework my code to do what I want. Here is what I want it to do: This is an arkanoid clone game. The ball come in and hits the paddle when a special pick up is active. When it hits the paddle, as it bounces away, the AssaultRifleShot method is called, it runs a few lines of code and then calls the StartCoroutine method, that method waits for a time, then calls the SpecialShot method. That method creates a new ball, does a few other things, then returns the control to the AssaultRifleShot method, which will keep going through the while loop as long as it needs to. The purpose of the coroutine is so that the balls all spawn in a line going in one direction, without hitting each other or spawning on top of each other. Here is what it is actually doing: The coroutine timer is in fact waiting, but it is immediately returning control to the AssaultRifleShot even while the coroutine is still waiting. So by the time the first ball is firing, the other coroutines are nearly finished running, so all the balls end up spawning at almost the exact same time, which causes them to collide with each other and go flying all over the place. So, is there a way to modify this so that the control is not given back to the AssaultRifleShot until AFTER the timer has finished running and the rest of SpecialShot method has been run? Here is the code for the AssaultRiflePickUp: public class AssaultRiflePickUp : BasePickUp, ISpecialShotPickUp { private int AmmoRemaining = 35; private float timer = 0.8f; private Vector3 mainBallVector; public GameObject newBall; void Start () { //assign paddle to variable paddle = GameObject.FindObjectOfType<Paddle> (); //find the ball and assign it to this variable foreach (Ball ball in GameManager.pickUpManager.allBalls) { if (ball.mainBall) { mainBall = ball; } } } public override void ActivatePickUp (MonoBehaviour coroutineHost) { Debug.Log("ActivatePickUp"); //subscribe to events mainBall.onBallHitPaddle += AssaultRifleShot; mainBall.onBallCollided += DestroyExtraBalls; } public void SpecialShot () //spawn a new ball. add it to the list of balls. set it's spawn location, set it's velocity to match the original ball { Debug.Log("SpecialShot"); Instantiate(newBall, new Vector3(paddle.transform.position.x, (paddle.transform.position.y + 1), 0), Quaternion.identity); newBall.GetComponent<Ball>().hasStarted = true; GameManager.pickUpManager.allBalls.Add(newBall.GetComponent<Ball>()); //newBall.GetComponent<Ball>().paddleToBallVector = newBall.transform.position - paddle.transform.position; //newBall.transform.position = paddle.transform.position + newBall.GetComponent<Ball>().paddleToBallVector; newBall.GetComponent<Rigidbody2D>().velocity = mainBallVector; //use the original ball's vector3 to follow it directly } public void DestroyExtraBalls (GameObject ball) { if (GameManager.pickUpManager.allBalls.Count > 1) { Debug.Log("DestroyExtraBalls"); } //TODO: Implement observer pattern to watch for balls colliding with something. If they do and they are not the main ball, destroy them. } public void DestroyPickUp () { Debug.Log("DestroyPickUp"); Destroy (GameManager.pickUpManager.pickUpQueue [0]); GameManager.pickUpManager.pickUpQueue.RemoveAt (0); GameManager.pickUpManager.pickUpActive = false; } //a timer used for timed pick ups public IEnumerator PowerUpTimer (float delay) { Debug.Log("PowerUpTimer"); yield return new WaitForSeconds (delay); mainBallVector = mainBall.GetComponent<Rigidbody2D>().velocity; //grab mainBall's direction and speed before making it a destroyable ball SpecialShot(); } //The coroutine is used to start a short timer so that the balls don't spawn on top of each other all at the same time. public void StartCoroutine (float delay, MonoBehaviour coroutineHost) { coroutineHost.StartCoroutine(PowerUpTimer(delay)); } //Controls the pick up's cycle public void AssaultRifleShot (GameObject mainBall) { Debug.Log("AssaultRifleShot called"); if (AmmoRemaining > 0) { int i = 6; while(i > 0) { Debug.Log("AssaultRifleShot - Inside If Statement"); //if there is ammo remaining, set the main ball to just a normal ball so it can be destroyed on impact and then start coroutine mainBall.GetComponent<Ball> ().mainBall = false; Debug.Log("AssaultRifleShot - 1"); mainBall.GetComponent<Ball> ().onBallHitPaddle -= AssaultRifleShot; //unsubscribe to event when mainBall is set to false. Debug.Log("AssaultRifleShot - 2"); StartCoroutine(timer, GameManager.monoBehaviour); Debug.Log("AssaultRifleShot - 3"); AmmoRemaining -= 1; Debug.Log("AssaultRifleShot - 4"); i--; } } else { DestroyPickUp(); } } }
  12. ethancodes

    ball isn't spawning where desired

    @vinterberg I have "Instantiate(newBall);" The new ball is definitely there, I can see it and interact with it. As for what @KKTHXBYE , I'm not sure what you are trying to say. What code did I not show? I'm actually not sure if I need the paddleToBallVector because that set up is originally used to make the ball stay with the paddle while the paddle is moved around. I don't actually want that. I just want it to spawn at the paddle and then launch immediately. So maybe I don't need the paddleToBallVector?
  13. ethancodes

    ball isn't spawning where desired

    So if I take that line of code out, it seems to help, but of course the player is still moving the paddle, so it seems to spawn where the paddle was, but not where it is now. From what I can tell, it's kind of hard to say for sure though. I don't want to save the original ball's location when it hit the paddle because if the paddle moves, it's going to spawn where the ball was and not where the paddle is. That line of code should be spawning it right above the paddle I thought, unless I have a mistake somewhere there.
  14. Ooohhhh boy. I'm back with more questions. I am having a horrible time with this pick up I'm working on. I've got multiple issues but I'm trying to make a list and work through them one by one. If you haven't already seen one of my other posts, I'm working on an arkanoid clone type game, with a pickup that when active, the ball will come back and hit the paddle, and as it leave the paddle, 6 additional balls should be spawned, with a short delay between each one, and then they all follow the first ball in a straight line away from the paddle until they all hit whatever is in front of them. Each ball is destroyed on impact except for the last ball in the line. So, onto my problem: Currently, the original ball hits the paddle and bounces away fine, and another ball is spawned. However, this ball is not spawned over the paddle like it should be. Some times it spawns right next to the paddle, sometimes it spawns half way across the screen. Left or right of the paddle, either way. Can't seem to find any rhyme or reason to it's spawn location. I have added code directly to this ball so that right after it is spawned, it's location should be initialized in a location over the paddle. I used the same code that I use on the original ball at the beginning of the game. Also, when this ball spawns, it falls. I thought I had it set so that the vector of the original ball would be assigned to this new ball and it would just move in the same direction as it, but apparently I'm missing something there. I'll post all my code for this pick up and also for the Ball class and maybe someone can explain what I'm doing wrong. This pickup is really making me lose my mind! AssaultRiflePickUp class: public class AssaultRiflePickUp : BasePickUp, ISpecialShotPickUp { private int AmmoRemaining = 35; private float timer = 0.3f; private Vector3 mainBallVector; public GameObject newBall; void Start () { //assign paddle to variable paddle = GameObject.FindObjectOfType<Paddle> (); //find the ball and assign it to this variable foreach (Ball ball in GameManager.pickUpManager.allBalls) { if (ball.mainBall) { mainBall = ball; } } } public override void ActivatePickUp (MonoBehaviour coroutineHost) { Debug.Log("ActivatePickUp"); //subscribe to events mainBall.onBallHitPaddle += AssaultRifleShot; mainBall.onBallCollided += DestroyExtraBalls; } public void SpecialShot () //spawn a new ball. add it to the list of balls. set it's spawn location, set it's velocity to match the original ball { Debug.Log("SpecialShot"); Instantiate(newBall); newBall.GetComponent<Ball>().hasStarted = true; GameManager.pickUpManager.allBalls.Add(newBall.GetComponent<Ball>()); newBall.GetComponent<Ball>().paddleToBallVector = newBall.transform.position - paddle.transform.position; newBall.transform.position = paddle.transform.position + newBall.GetComponent<Ball>().paddleToBallVector; //use the original ball's vector3 to follow it directly newBall.GetComponent<Rigidbody2D>().velocity = mainBallVector; } public void DestroyExtraBalls (GameObject ball) { if (GameManager.pickUpManager.allBalls.Count > 1) { } //TODO: Implement observer pattern to watch for balls colliding with something. If they do and they are not the main ball, destroy them. } public void DestroyPickUp () { Debug.Log("DestroyPickUp"); Destroy (GameManager.pickUpManager.pickUpQueue [0]); GameManager.pickUpManager.pickUpQueue.RemoveAt (0); GameManager.pickUpManager.pickUpActive = false; } //a timer used for timed pick ups public IEnumerator PowerUpTimer (float delay) { Debug.Log("PowerUpTimer"); yield return new WaitForSeconds (delay); SpecialShot(); } //The coroutine is used to start a short timer so that the balls don't spawn on top of each other all at the same time. public void StartCoroutine (float delay, MonoBehaviour coroutineHost) { coroutineHost.StartCoroutine(PowerUpTimer(delay)); } //Controls the pick up's cycle public void AssaultRifleShot (GameObject mainBall) { Debug.Log("AssaultRifleShot called"); mainBallVector = mainBall.GetComponent<Rigidbody2D>().velocity; //grab mainBall's direction and speed before making it a destroyable ball mainBall.GetComponent<Ball>().mainBall = false; //deactivate the original ball as the mainBall so that it may be destroyed on impact if (AmmoRemaining > 0) { Debug.Log("AssaultRifleShot - Inside If Statement"); //if there is ammo remaining, set the main ball to just a normal ball so it can be destroyed on impact and then start coroutine mainBall.GetComponent<Ball> ().mainBall = false; Debug.Log("AssaultRifleShot - 1"); mainBall.GetComponent<Ball> ().onBallHitPaddle -= AssaultRifleShot; //unsubscribe to event when mainBall is set to false. Debug.Log("AssaultRifleShot - 2"); StartCoroutine(timer, GameManager.monoBehaviour); Debug.Log("AssaultRifleShot - 3"); AmmoRemaining -= 1; Debug.Log("AssaultRifleShot - 4"); } else { DestroyPickUp(); } } } Side note: There is some base class code for the pick up, if it is decided that that is needed as well I can post it. But I don't think it's relevant. Ball class: public class Ball : MonoBehaviour { private Paddle paddle; public Vector3 paddleToBallVector; public bool mainBall = false; public float Speed { get; set; } public float MaxSpeed = 10.198f; public bool hasStarted = false; public delegate void DestroyBalls(GameObject ball); public event DestroyBalls onBallCollided; public delegate void BallHitPaddle(GameObject ball); public event BallHitPaddle onBallHitPaddle; void Start () { //find the paddle and assign it to variable paddle = GameObject.FindObjectOfType<Paddle> (); paddleToBallVector = this.transform.position - paddle.transform.position; Speed = 1; } // Update is called once per frame void Update () { if (!hasStarted) { //Lock the ball relative to the paddle. this.transform.position = paddle.transform.position + paddleToBallVector; //Wait for a mouse press to launch. if (Input.GetMouseButtonDown (0)) { hasStarted = true; this.GetComponent<Rigidbody2D> ().velocity = new Vector2 (2f, 10f); } } } void OnCollisionEnter2D (Collision2D collider) { //use this vector2 to adjust the velocity so the ball does not get stuck in a vertical bouncing loop if (hasStarted) { //apply sound when the ball hits something AudioSource audio = this.gameObject.GetComponent<AudioSource> (); audio.Play (); Vector2 tweak = new Vector2 (UnityEngine.Random.Range (0f, 0.2f), UnityEngine.Random.Range (0f, 0.2f)); //the following lines set the speed and direction of the ball based on built in physics, and the current speed of the ball. Speed can be changed based on pick ups this.gameObject.GetComponent<Rigidbody2D> ().velocity = this.gameObject.GetComponent<Rigidbody2D> ().velocity.normalized; this.gameObject.GetComponent<Rigidbody2D> ().velocity *= Speed * MaxSpeed; this.gameObject.GetComponent<Rigidbody2D> ().velocity += tweak; if (collider.gameObject.name == "Paddle" && this.mainBall) { if (onBallHitPaddle != null) { onBallHitPaddle (this.gameObject); } } } } }
  15. This did fix the error I was getting and is making the ball wait to spawn as desired! Thanks!
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!