Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question I need help bouncing a projectile

Discussion in 'Physics' started by MGK69, Sep 3, 2023.

  1. MGK69


    Sep 13, 2021
    I'm going to do my best to avoid the X Y Problem, so please bare with me.

    My overall goal is to create a projectile similar to the Koopa Shell in the Mario Kart series. In which the projectile is fired forward, it bounces off of walls, and has what seems to be simulated gravity. I say simulated because it will fall downward when it goes off a ledge, but it doesn't slow down at all when it goes up a hill.
    My main problem is the projectile flies forward just fine, it goes up hills and whatnot well, but it wont bounce off of walls. It just slams into them and tries to keep going forward. Now I can assume this is because on the rigidbody settings I have the rotations all frozen, but I'll explain why later on. Also if it matters, gravity is set to off on the rigidbody as well.

    I'll try to give as much detail as I can, without overloading you with irrelevant information.

    The projectile is triggered when the "bulletFired" Bool is set to true. It begins this Coroutine on the player object.

    Code (CSharp):
    1. IEnumerator ProjectileBulletFired()
    2.     {
    4.         SoulShot.fireSpeed = SpeedAdditive;
    5.         var soulShotObj = Instantiate(bullet, projectilePivot.position, projectileRotationFromCamera.rotation) as GameObject;
    8.         bulletFired = false;
    11.          yield return new WaitForSeconds(0.2f);
    12.         soulShotObj.tag = "LightDamage";
    14.         yield return null;
    15.     }
    I then have two scripts on the instantiated projectile. This is the script attached to the parent object of the projectile.

    Code (CSharp):
    1. {
    2.     public float fireSpeed;
    3.     public float raycastDistance = 5f;
    4.     public float downwardForce = 30.0f;
    5.     public float upwardForce = 5.0f;
    6.     public int maxRecasts = 3;
    8.     private Rigidbody rb;
    9.     private Vector3 lastVelocity;
    11.     void Start()
    12.     {
    13.         rb = GetComponent<Rigidbody>();
    14.         rb.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
    16.     }
    18.     void FixedUpdate()
    19.     {
    20.         // Maintain sliding speed
    21.         rb.velocity = transform.forward * fireSpeed;
    22.         bool hitTerrain = false;
    23.         RaycastHit hit = new RaycastHit();
    25.         for (int i = 0; i < maxRecasts; i++)
    26.         {
    27.             if (Physics.Raycast(transform.position, Vector3.down, out hit, raycastDistance))
    28.             {
    29.                 hitTerrain = true;
    30.                 break; // Exit loop if raycast hits terrain
    31.             }
    32.         }
    34.         if (hitTerrain)
    35.         {
    36.             Vector3 newPosition = hit.point;
    37.             newPosition.y += hit.normal.y * 0.2f;
    38.             rb.MovePosition(newPosition);
    41.             rb.AddForce(Vector3.up * upwardForce, ForceMode.Acceleration);
    42.         }
    43.         else
    44.         {
    46.             rb.AddForce(Vector3.down * downwardForce, ForceMode.Force);
    47.         }
    49.         lastVelocity = rb.velocity;
    50.     }
    55. }
    My apologies if that has too much unnecessary information, I included this script because I was unsure if maybe the position setting could be causing issues. Also if it isn't already obvious I used ChatGPT for help on the raycasting parts. I know its a terrible practice, but I was just frustrated trying to get all of these components to work together, I'm currently in the process of learning more about raycasts specifically so I can make this part myself.

    This script is on a child of the projectile. I put this one on the child because it has a different collider that I would like to use for bouncing collision purposes, whereas the collider on the parent is for player hitbox collision purposes. I'm unsure if that is even a viable approach.

    Code (CSharp):
    1. {
    3.     float minBounceSpeed;
    4.     private Rigidbody rb;
    5.     private Vector3 lastVelocity;
    6.     // Start is called before the first frame update
    7.     void Awake()
    8.     {
    9.         rb = GetComponentInParent<Rigidbody>();
    10.     }
    12.     // Update is called once per frame
    13.     void Update()
    14.     {
    16.         lastVelocity = rb.velocity;
    19.     }
    21.     private void OnCollisionEnter(Collision collision)
    22.     {
    24.         var speed = lastVelocity.magnitude;
    25.         var direction = Vector3.Reflect(lastVelocity.normalized, collision.contacts[0].normal);
    27.         rb.velocity = direction * Mathf.Max(speed, 0f);
    28.     }
    29. }
    In the first half of this gif you can see the projectile with rotations unfrozen, second half they are frozen.

    Additional notes that I don't know if they're relevant or not:
    I set the speed of the projectile in the player script and not the projectile itself because there's a little formula that fires the projectile at different speeds depending on how fast the player is going to encourage good driving, drifts, combos etc.

    This used to work well, as far as bouncing was concerned. I could get it to bounce off of walls, but then it started bouncing everywhere. Off of the terrain itself, skyrocketing off slopes. I changed something to combat this, unfortunately I can't remember exactly what it was since I work on this project very infrequently. I'm hoping you're able to see what I can't. I appreciate any advice.


    Feb 8, 2022
    why on earth did chatgpt tell you to cast multiple rays, there's literally no reason at all if theyre all going to the same place during the same frame.

    anyway, you are setting it to move forward every fixed update, and when you flip it you only change the velocity, not the rotation of the rigidbody or transform.

    velocity is basically like speed
    MGK69 likes this.