Collision doesn't make sense

Hello everyone. I have been trying to make a simple FPS. Nothing complicated. Everything is blocky. Think “Krunker IO” aesthetics. All the limbs are separated since they are just blocks, like Minecraft. All the enemies are blocky like this. I simply want them to chase the player and I want the player to be able to shoot them for points. I have an empty parented to my gun and it shoots out a “bullet.” When the bullet hits it activates the “collision sensor” and it adds 1 to the tally of number of hit shots. I added this tally so that I could see if my shots were landing. For some reason, it seems random when it hits and when it doesn’t. I shoot the enemy and either the collision is working perfectly and then the next second I can’t hit a single shot. I have tried combining all the limbs of the enemy character and making it one mesh, I have tried making an empty and using it as a hit box, I have tried all combinations of collision shapes. Any help would be appreciated!

I guess you should create a box which is abit bigger than your whole character, and then give it a material which will be sensed by the collision sensor, and then go to the physics tab and chage the physics type to SENSOR, and make it invisible, then parent this box to the main part of the character like the chest, then add the collsion sensor to the bullet which detects the collision with than sensor box material, and when it does collide, add a property and then everything might work as you want

Alright, I have not tried a collision sensor. However, if the bullet is sensing the collision and not the enemy, then how would I tell each independent enemies which one got hit? I should have noted that, this will be an endless survival game. So I will spawn the same character many times in one scene

1 Like

Dude, you can rename the material for each different material

dont use physics for bullets. generally bullets go at least a few meters per frame. so odds are, your bullet will never actually collide since it teleports right past.

use raycasting instead. a raycast on the bullet will work as well to replace collision sensor. be sure ray length is as long as how fast its moving.

3 Likes

It sounds like you’ve got your collision sensor on the bullet. It should be on the object you’re shooting at. Also, if you aren’t ending the bullet’s life after shooting it, it will still be there when you spawn the next one, and that might be affecting your results, depending on your how your logic is set up.

What physics types are the bullet and the object it hits, and what kind of collision bounds do they have?

According to @Daedalus_MDW

Here is an example:

from bge import logic

def bullet_action(cont):

    own = cont.owner

    player = own.scene.objects['player']
    
    if player['active_weapon']:        
        if not 'weapon_data' in own:            
            weapon_data = player['weapons'][player['active_weapon']]
            own['weapon_data'] = weapon_data
            
    speed = own['weapon_data']['bullet_speed']
    damage = own['weapon_data']['bullet_damage']
    bullet_drop = own['weapon_data']['bullet_drop']
    hole = own['weapon_data']['bullet_hole']

    distance = speed/logic.getLogicTicRate()

    own.applyMovement([0,distance,-bullet_drop], 1)

    y_vec = own.worldOrientation.copy().col[1] 
    y_vec.magnitude = distance

    end_vec = own.worldPosition.copy() + y_vec
    ray = own.rayCast(end_vec, own.worldPosition.copy(), 0)

    if ray[0]:

        if 'health' in ray[0]:
            ray[0]['health'] -= damage
            
            if ray[0]['health'] <= 0:
                ray[0].endObject()
            
        bullet_hole(cont,ray,hole)
        
        
def bullet_hole(cont,ray,bullet_hole):
    
    own = cont.owner
    own.endObject()
 
    bullet_hole = own.scene.addObject(bullet_hole, ray[0], 300)
    
    offset = ray[2]
    offset.magnitude = 0.001
    
    bullet_hole.alignAxisToVect(ray[2], 2, 1)
    bullet_hole.worldPosition = ray[1] + offset
    bullet_hole.setParent(ray[0])

If you want to use this you need to alter some things in the script, should be easy with a tiny bit of python knowledge.

2 Likes

I have my collision on the enemy. They are dynamic with a cube collision. The Bullet has a property “B” and when B collides with the enemy the enemy’s hit count goes up. So it counts how many times it gets hit.

I will try this. Is ray harder to set up? I have not done this before

in many ways a ray sensor is similar to a collision sensor. the logic bricks are pretty much interchangable if i remember correctly.

@Cotaks posted a more advanced solution if you want some extra effects added.

1 Like

@Cotaks caould you explain how I would get that raycast code to work? I’m just curious. Still trying to learn, lol.

Thanks :slight_smile:

from bge import logic

# place on the bullet
# always (true pulse) -> python(module) ->scriptname.bullet_action
# make sure the script in text editor ends with .py

def bullet_action(cont):

    own = cont.owner
    
    # how fast bullet goes 
    speed = 340
    # damage bullet does
    damage = 18
    # how much the bullet needs to drop
    bullet_drop = 0.0001
    # plane that represent the bullet_hole
    hole = own.scene.objects['bullet_hole']

    distance = speed/logic.getLogicTicRate()

    own.applyMovement([0,distance,-bullet_drop], 1)

    y_vec = own.worldOrientation.copy().col[1] 
    y_vec.magnitude = distance

    end_vec = own.worldPosition.copy() + y_vec
    ray = own.rayCast(end_vec, own.worldPosition.copy(), 0)

    if ray[0]:

        if 'health' in ray[0]:
            ray[0]['health'] -= damage
            
            if ray[0]['health'] <= 0:
                ray[0].endObject()
            
        bullet_hole(cont,ray,hole)
        
        
def bullet_hole(cont,ray,bullet_hole):
    
    own = cont.owner
    own.endObject()
 
    bullet_hole = own.scene.addObject(bullet_hole, ray[0], 300)
    
    offset = ray[2]
    offset.magnitude = 0.001
    
    bullet_hole.alignAxisToVect(ray[2], 2, 1)
    bullet_hole.worldPosition = ray[1] + offset
    bullet_hole.setParent(ray[0])

#edit
Bullet does not need collision, so turn it physics to no collision, no bounding box so that can be turned off as well. Same thing for the bullet_hole plane.

Just spawn in the bullet in front of gun and see the magic happen.

Do you need to connect the Python controller to anything? Nothing happened. If anything it hasn’t hit a single time. What exactly do I need to do to my characters?

Edit: So it sometimes works but I have the same problem. Sometimes it hits and other times it doesn’t. Nothing has changed

Then you got something wrong with your blend, the script works perfectly fine, i created it for my own fps project.

you don’t have to do anything, just place the script on the bullet.
now you can just spawn the bullet and the script will handle the rest, of course you need to aim etc.

Simply remove everything from the bullet, and place an always(true pulse) → python on it with the script explained in above post.

once you shoot you add that bullet, script will then take over.

Yep, that’s what I did. I will have to keep looking for answers then. Thank you!

here you see it in action, it’s an old video but you see it wont miss.

Lol yeah, I wasn’t doubting your script. I am always finding bugs with BGE