• 9
• 9
• 10
• 9
• 10
• ### Similar Content

• ...if you got time to read and answer i would be happy .

So me and my co try to do a game.
It should be in unity couse my co do everything in this engine.

We got the rpg package from evila for inventor, but it only runs on pc right now.

I like to make a online store for guns in the game and a multiplayer open world that runs on pc, android, mobile, ps4, xbox one.
Somebody told me that you "only" need to program it like so and that its possible in every engine...

So if you are one of the lucky guys who could help me out or programm that, or even if you know a newer better package for maybe unreal which offers that - please let me know now.

• I'm having a weird issue with detecting a collision. I've tried everything I could find online but nothing seems to work. I have a brick object. It has a 2D Collider attached and I have also attached a 2D Rigidbody on it. I also have an EndScreen 2D Collider. The EndScreen 2D collider is tagged with "EndScreen". I am trying to detect when a brick collides with the end screen collider and simply print "game over" in the console.
This is my current code for this part of the program, it is attached to the bricks:
void OnCollisionEnter (Collision2D collision) { if (collision.gameObject.tag == "EndScreen") { Debug.Log("Game over"); } } Several things have happened depending on the set up. If I have the rigidbody 2D set as static, my ball object can still collide with the bricks, but I get no Log message. If I set it to Kinematic or Dynamic, I get absolutely no interaction between the ball and the bricks, and nothing when the bricks pass through the collider. I have tried to set the collider to a trigger and use OnTriggerEnter2D, no change. I have tried to put the rigidbody on the EndScreen object and tried to set it's body type to all 3 settings, no change. The only thing I can think of that I have not done is put the script on the EndScreen object and switch the tag to the bricks. The reason I have not done this is because I will have several types of bricks, some of which will have different tags.

Please tell me somebody can see what I'm doing wrong here, because I'm losing my mind over something I feel should be ridiculously simple. Thanks.

# Unity 2D Projectiles Continued

This topic is 4361 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Well my old thread has since been retired unfortunately so I have to make a lousey link to it so people will know what Im talking about lol here ya go: old forum That's the link. The problem is still the same! Bullets don't function properly. New varation of the problem however. Now we have two things happening depending on what I do to the code: When the bullet goes past the visible left or right hand side of the screen it disappears naturally. However, upon hitting the left side the bullet freezes in animation but I can still move around. Second: If I switch | with & in this code
if(Bullet.getx()<0 | Bullet.getx()>640){


the bullet will just go past the screen with no problems. BUT! In both cases said bullet does not seem to delete itself from the linked list I have to track the bullets! I am not able to fire more than one bullet when I should be able to shoot up to 20. Here's the bullet code for your reading enjoyment:
#define BULLETS 20

Sprite Bullet[BULLETS];

struct bullet{
float x;
float y;
float xvel;
float yvel;
int direction;
bullet *next;
bullet *previous;
};
bullet* first_bullet = NULL;
bullet* current_bullet = NULL;

int bdraw[BULLETS];

bullet* NewBullet()
{
for(int i=0;i<BULLETS;i++){
if(bdraw == 0){
if(first_bullet==NULL)
{
first_bullet=new bullet;
current_bullet=first_bullet;
current_bullet->direction = face_right;
current_bullet->x = mario.getx();
current_bullet->y = mario.gety();
current_bullet->xvel = Bullet.getSpeed() * current_bullet->direction;
Bullet.set(current_bullet->x += 1, current_bullet->y += 0);
current_bullet->next=NULL;
current_bullet->previous=NULL;
}

else
{
current_bullet->next=new bullet;
current_bullet->next->direction = face_right;
current_bullet->next->x = mario.getx();
current_bullet->next->y = mario.gety();
current_bullet->next->xvel = Bullet.getSpeed() * current_bullet->next->direction;
current_bullet->next->previous=current_bullet->next;
current_bullet=current_bullet->next;
Bullet.set(current_bullet->x+=1, current_bullet->y+=0);
current_bullet->next=NULL;
}
bdraw = 1;
}
}
return current_bullet;
}

void DeleteAllBullets()
{
bullet* this_bullet=first_bullet;
while(this_bullet!=NULL)
{
this_bullet=this_bullet->next;
}
first_bullet=NULL;
current_bullet=NULL;
}

void RenderBullet()
{

bullet* this_bullet=first_bullet;
while(this_bullet!=NULL)
{
{
this_bullet=this_bullet->next;
{
first_bullet=this_bullet;
if(this_bullet!=NULL)
{
this_bullet->previous=NULL;
}
}
else
{
if(this_bullet!=NULL)
{
}
}
{
}
}
else
{
for(int i=0;i<BULLETS;i++){
if(bdraw == 1){
Bullet.draw();
if(Bullet.getx()<0 | Bullet.getx()>640){
bdraw=0;
}
}
}
this_bullet = this_bullet->next;
}
}
}

void UpdateBullet()
{
bullet* this_bullet=first_bullet;
while(this_bullet!=NULL)
{
this_bullet=this_bullet->next;
}
for (int i=0;i<BULLETS;i++){
if(bdraw == 1){
Bullet.updateBG();
}
}
}


I've gone through this over and over again and I think I just ended up complicating things by patching a bug here and there. Any help solving this problem would be greatly appreciated! (I think the bdraw=0 might be the reason my bullet animation freezes.... Ill check it out)

##### Share on other sites
Hey Caldiar,

I use a somewhat similar approach to handling short-life projectiles, and thought I might throw out a suggestion.

If I understand you right, you delete a projectile from the list once it becomes inactive (according to whatever rules, offscreen etc.), correct?
I had problems with this same thing for a while so I finally switched to an uglier method that works for me.

Instead of using one list, I made two, and a key variable to tell me which one was the active list. When a projectile needs to be added, it is added to the list which is currently active. If the number of projectiles in the list becomes larger than some arbitrary number ( a max limit if you will), then the active list variable is switched and the previously inactive list is completely emptied and the projectile gets inserted into this list (I base insertion off of Y value for 2D rendering purposes).
The main difference is that a projectile is never deleted individually, just made inactive, which therefore prevents it from being updated or rendered anymore.
But, all of the projectiles in the inactive list are still updated and rendered as normal, until they become inactive or the inactive list is emptied in preparation for becoming the active list.
Like I said this approach is ugly, but I was going crazy.
Hopefully this made some kind of sense and I am willing to send you the source if you want to see it/are brave enough to decipher it.

Coby

##### Share on other sites
that sounds interesting. So you have something like:
List A - Bullet 1, Bullet 2 - ACTIVE
List B - Empty - INACTIVE

List A has a max capacity of 2 bullets.

List A = List B

List A - Bullet 1, Bullet 2 -INACTIVE
List B - Bullet 3 - ACTIVE

List A is emptied of all bullets.

List A - Bullet 5 - ACTIVE
List B - Bullet 3, Bullet 4 - INACTIVE

If this is the case and say you shoot 5 bullets in a short amount of time would two bullets suddenly disappear when they're cleared from the original list?

I would be extremely interested in seeing the source code =) my email is caldiar (at) eqguild (dot) net

##### Share on other sites
Yep, that is the idea. To avoid the situation you mentioned, you just have to set the limit to a number that is slightly higher than roughly half of the maximum amount of projectiles that can be on screen, but is reasonable enough so that it doesn't eat up a lot of memory. For my RPG, there are never more than 50-70 projectiles on the screen at one time, so I set the arbitray limit for each list to 50 to make sure there will never be projectiles that suddenly vanish. This also makes sure that there will only be a maximum of 100 projectiles in memory at any given time.

I'll send the source now.
EDIT: I'll just post it here.

bool Game::AddNewSpell(CPoint* p,int x,int y,int typ,int flag){	CUtil u;	bool valid;	if(SpellArrayKey==1)								//If First List is Active	{		if(CurrentSpellSlot<=50)					//If Capacity has not been reached		{			valid=Spells1[CurrentSpellSlot].SetSpell(typ,x,y,p,flag); //Addition Successful			CurrentSpellSlot++;		}		else																	//Capacity has been reached		{			Spells2.DecrementDimen(50);					//Empty the Second List			Spells2.IncrementDimen(50);					//Re-establish Maximum Allocation for Second List			for(int az=1;az<=50;az++)				Spells2[az].SetGamePointer(this); //Re-establish Game pointers			SpellArrayKey=2; 										//Second List is now Active			CurrentSpellSlot=1;									//One Spell in Second List			valid=Spells2[CurrentSpellSlot].SetSpell(typ,x,y,p,flag); //Addition Successful			CurrentSpellSlot++;		}	}	else if(SpellArrayKey==2) //If Second List is Active	{		if(CurrentSpellSlot<=50)				//If Capacity has not been reached		{			valid=Spells2[CurrentSpellSlot].SetSpell(typ,x,y,p,flag);	//Addition Successful			CurrentSpellSlot++;				}		else													//Capacity has been reached		{			Spells1.DecrementDimen(50);								//Empty the First list			Spells1.IncrementDimen(50);								//Re-establish Maximum Allocation for First list			for(int azl=1;azl<=50;azl++)				Spells1[azl].SetGamePointer(this);			//Re-establish Game Pointers			SpellArrayKey=1;													//First List is now Active			CurrentSpellSlot=1;												//One Spell in First List			valid=Spells1[CurrentSpellSlot].SetSpell(typ,x,y,p,flag);	//Addition Successful			CurrentSpellSlot++;						}	}	else		u.ProcessTerminalError("Game::AddSpell-Invalid SpellArrayKey!!");	//Error catch	return valid;}

##### Share on other sites
if((Bullet.getx()<0) || (Bullet.getx()>640)){ Bullet->dead = true;}

| and & do bitwise calculations on ints. || is what you want in this case. And you need to assign to dead!

##### Share on other sites
Shadow - Thank you very much for the source code. Ill take a look at it right now!

Bob - I thought the | operator meant "or"? Ill have to look that one up hehe =)
Well, I tried it out anyways and I get a new access violation =) I smell progress.
Oh. the bullet->dead doesn't work for my code because bullet is referring to a class while this_bullet is the node in the linked list referring to a struct that initilizes a bullet based on the class settings. That might have come out a bit confusing hehe.

Thanks a bunch for all the help guys! =)

##### Share on other sites
Oh, yeah, Bullets is a Sprite not a Bullet. Damn, that's confusing. Well, you need to find the Bullet object corresponding to Bullets and set its dead to true, otherwise it won't get removed by Update. I think this_bullet->dead = true will do the trick, actually, looking at the context of that code.

| is bitwise or, i.e. 4 | 3 is 7, 6 | 2 is 6 ... it sets all bits in the answer that are in one of the arguments. || is logical or, which is almost always what you want in if tests.

##### Share on other sites
hmm well, this_bullet->dead = true does this:
Something like a Memory Access Violation at this line of code:
this_bullet=this_bullet->next;
in the Update Bullet function.

EDIT: Ah, its an Access Violation (Segmentation Fault)

##### Share on other sites
ok moved the this_Bullet=this_bullet->next; to the spot where it really belonged and I received my original error that I was trying to get back again.

bullet* NewBullet(){ for(int i=0;i<BULLETS;i++){ if(bdraw == 0){  if(first_bullet==NULL)  {    first_bullet=new bullet;    current_bullet=first_bullet;    current_bullet->direction = face_right;    current_bullet->x = mario.getx();    current_bullet->y = mario.gety();    current_bullet->xvel = Bullet.getSpeed() * current_bullet->direction;    Bullet.set(current_bullet->x += 1, current_bullet->y += 0);    current_bullet->next=NULL;    current_bullet->previous=NULL;  }    else  {    current_bullet->next=new bullet;    current_bullet->next->direction = face_right;    current_bullet->next->x = mario.getx();    current_bullet->next->y = mario.gety();    current_bullet->next->xvel = Bullet.getSpeed() * current_bullet->next->direction;    current_bullet->next->previous=current_bullet->next;    current_bullet=current_bullet->next;    Bullet.set(current_bullet->x+=1, current_bullet->y+=0);    current_bullet->next=NULL;  }  bdraw = 1;  }  }  current_bullet->dead=false; ----THIS IS THE AFFECTED LINE  return current_bullet;  }

Access Violation (Segmentation Fault) and current_bullet->dead=false; is highlighted.

Im thinking since this_bullet is originally the first bullet then moves on until its at the current bullet Im actually setting current_bullet-> dead to true AND false at the same time? I wonder if that really is the problem...

##### Share on other sites
Okay, well I suspect that your bullet creation code is borked, not the killing code, in that case. What exactly are you trying to do? ... fill out the first unused bullet in the array? If so you ought to break out of your for loop when you've done one (i.e. inside the if(draw == 1) section).

It also strikes me that you are duplicating about 10 lines of code near the top of that function, and that smells of a refactoring opportunity:
bullet* NewBullet(){ // Save the previous 'current bullet' so we can  // link the new one to it bullet* last_bullet = current_bullet; // Depending on your sorting techniques etc, this // might not be necessary while(last_bullet->next == NULL) last_bullet = last_bullet->next; for(int i=0;i<BULLETS;i++){  if(bdraw == 0){   if(first_bullet==NULL)   {    first_bullet=new bullet;    current_bullet=first_bullet;    MakeBullet(current_bullet, NULL, NULL, i);   }      else   {     current_bullet->next=new bullet;     MakeBullet(current_bullet->next, current_bullet, NULL, i);   }   bdraw = 1;   break;  // made one now, so don't do any more  } } current_bullet->dead=false; ----THIS IS THE AFFECTED LINE last_bullet->next = current_bullet; // link to the rest of the list return current_bullet;}void MakeBullet(Bullet* target, Bullet prev, Bullet next, int index){ // New function to fill out a bullet // NB syntax may be wrong, I don't write C++ code target->direction = face_right; target->x = mario.getx(); target->y = mario.gety(); target->xvel = Bullet[index].getSpeed() * target->direction; Bullet[index].set(target->x += 1, target->y += 0); target->next=prev; target->previous=next;}

You're also mixing things up by storing some of your data in the linked list of Bullet structs, and some in a fixed array of Sprites. I think you need to pick one of those two and stick with it. At the minute the array is limiting the number of Bullets you can have, so why bother with the linked list?

You also had a bug in the second part of the creation code where you set the prev pointer of the new bullet to itself, and you don't link in the new bullet at all. I've added that functionality in.