Search Unity

CharacterController getting pushed around

Discussion in 'Physics' started by Nubz, Jan 11, 2015.

  1. Nubz

    Nubz

    Joined:
    Sep 22, 2012
    Posts:
    553
    I have a bullet eject system in my current fps project.
    How it works is I have an empty game object parented to my rifle.
    This empty is to set where the bullet would eject.
    Then in my shooting script it instantiates the empty shell prefab with each round fired.
    Also there is a script on the shell that handles the force and rotation of the shell when it ejects.

    The shell has a rigidbody and a sphere collider on it and it is saved as a prefab for the shooting script to instantiate.


    So the problem is when I am aimed down the sight the bullets are bouncing off my character controller knocking me to the left.
    I had this happening when firing from the hip position also and narrowing my charactercontroller fixed it.
    But I don't think having the CharacterController pencil thin so when I aim down sight this won't happen is a good idea haha.
    Was wondering if there is a better solution to this.

    The function that instantiates the shell in my shooting script is
    Code (CSharp):
    1. void EjectShell()
    2.     {
    3.         Instantiate(emptyShell, ejectBullet.transform.position, ejectBullet.transform.rotation);
    4.     }
    And also there is a refence to the 2 gameobjects in there of course
    And when I fire I call the function

    Code (CSharp):
    1. EjectShell();
    This is the script that I have on the empty shell

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class BulletEject : MonoBehaviour
    5. {
    6.  
    7.     public int randomMovement;
    8.     public int randomForce;
    9.     public int rMoveX;
    10.     public int rMoveY;
    11.  
    12.  
    13.  
    14.     void Start()
    15.     {
    16.         Destroy(gameObject, 0.5f);
    17.  
    18.         randomMovement = Random.Range(rMoveX, rMoveY);
    19.         randomForce = Random.Range(1, 2);
    20.         rigidbody.AddRelativeForce(55, randomForce, 0);
    21.         rigidbody.AddRelativeTorque(randomMovement, randomMovement, 55);
    22.     }
    23. }
    24.  
     
  2. ddulshan

    ddulshan

    Joined:
    Mar 16, 2014
    Posts:
    190
  3. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    there certainly is a better solution. Layers!

    make your player on one layer, the bullet on another, and disable collisions between those two layers via the layer collision matrix. its in edit > Project settings > physics

    thats how i'm handling projectiles atm anyway



    Now that aside, there's an important physics detail that you really need to note. Relative frames of reference.

    If you stand inside a bus, even through you appear to be standing still compared to the interior of the bus, you're actually moving through the world at the bus's speed. The same applies to bullets inside a gun (and immediately after firing them). They have the velocity of their frame of reference. Therefore you should set the starting velocity of each bullet (as in directly set it as a value) to the velocity of the player, or whatever. and then apply forces on top of that.

    If you fire a gun while sprinting forward, the bullets do literally move faster. although in life bullets generally move so fast compared to a human that the differenge is negligible

    I think what might be happening in your case, is that your bullets are coming out too slow, and your character is actually outpacing them, and walking into the back of them as they fly through the air. that's a common problem.

    So yeah. Ultimately, two solutions. The hacky gamey one of selectively ignoring collisions, and the realistic simulation one of tight collision boxes and inheriting velocity
     
  4. Nubz

    Nubz

    Joined:
    Sep 22, 2012
    Posts:
    553
    Had to read through it twice to get the hang of it but makes perfect sense.
    Thanks for the reply.
     
  5. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    let me know which option (if either) you go with, and how it works out <3
     
  6. Nubz

    Nubz

    Joined:
    Sep 22, 2012
    Posts:
    553
    Im not sure what I'm going to do about it really I suck with physics lol

    I had a lot of help just writing that little bit hahaha. I will post back what I come up with. This is probably what is going to be worked on next since I got one other thing taken care of tonight.
     
  7. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    Okay, the simplest possible thing you can do:

    1. void EjectShell()
    2. {
    3. Instantiate(emptyShell, ejectBullet.transform.position, ejectBullet.transform.rotation);
    4. emptyShell.rigidbody.velocity = rigidbody.velocity;
    5. }
    Assuming the player has it's own rigidbody. If not you'll need to get the velocity some other way. But however you do it, just make sure you have the player's velocity on hand while instantiating the shell, and set the shell's velocity to that before applying forces

    For additional robustness, i'd suggest moving the force applications out of Start() and into some seperate function like ApplyForces, and then call that function from the code above. Just to make sure you're not setting the velocity after the forces are applied, since that would cancel them out.
     
  8. Nubz

    Nubz

    Joined:
    Sep 22, 2012
    Posts:
    553
    It's not a rigidbody but I really don't have a problem switching it/

    Would switching make things like this easier to solve?
     
  9. Nubz

    Nubz

    Joined:
    Sep 22, 2012
    Posts:
    553
    Anyway I ended up using the easy solution for now and setting the layers.
    Eventually when I learn a little more the other way you mentioned sounds better.