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
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Cone Shaped Bullet Spread.

Discussion in 'Scripting' started by TwoTen, Jul 2, 2016.

  1. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    So I am working on a weapon system. And I saw some threads about Cone Bullet Spread. But It's not working for me.
    Code:
    Code (CSharp):
    1.  
    2.             var bullet = (GameObject)Instantiate(
    3.                 bulletPrefab,
    4.                 bulletSpawn.position,
    5.                 bulletSpawn.rotation);
    6.  
    7.  
    8.  
    9.             bullet.GetComponent<Rigidbody>().AddForce(bullet.transform.forward * shootForce);
    10.  
    11.             NetworkServer.Spawn(bullet);
    12.  
    13.  
    How can I add bullet spread in the shape of a cone that I can modify the amount depending on such like If the player is running or not.

    Thanks in advance
     
  2. Henning_Justare

    Henning_Justare

    Joined:
    Nov 10, 2014
    Posts:
    21
    If it doesn't have to be a circular cone, you can use the following to make a frustum instead, and adjust the coneSize variable according to your speed to get the decided effect.

    Code (CSharp):
    1.  
    2.     public float coneSize;
    3.  
    4. ...
    5.           var bullet = Instantiate(bulletPrefab);
    6.  
    7.             float width = Random.Range(-1f,1f) * coneSize;
    8.             float height = Random.Range(-1f,1f) * coneSize;
    9.  
    10.             bullet.GetComponent<Rigidbody>().AddForce(transform.forward * shootForce + transform.right * width + transform.up * height);
    11.      
    12.  
    Test project : https://drive.google.com/file/d/0B4yTMINoNEheRlZiQ1Y2ZjFsaGM/view?usp=sharing

    Hope this was helpful :)
     
  3. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    A much more efficient approach would be to apply spread to the rotation when you instantiate the bullet and then apply forward force.

    I believe this should work..
    Code (CSharp):
    1. public float ConeSize;
    2.  
    3. float xSpread = Random.Range(-1, 1);
    4. float ySpread = Random.Range(-1, 1);
    5. //normalize the spread vector to keep it conical
    6. Vector3 spread = new Vector3(xSpread, ySpread, 0.0f).normalized * ConeSize;
    7. Quaternion rotation = Quaternion.Euler(spread) * bulletSpawn.rotation;
    8. var bullet = (GameObject)Instantiate(bulletPrefab, bulletSpawn.position, rotation);
     
    Last edited: Jul 3, 2016
  4. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    I would prefer a circular cone.
    Will give it a shot
     
  5. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    Neither of those worked. Is there a way to do this with raycasts?
     
  6. BluHornet

    BluHornet

    Joined:
    Feb 23, 2015
    Posts:
    40
    there are 2 classic approaches to bullets and they will determine how you do "spread". the two ways are raycast with animations and sprites and the other is to physically spawn a bullet into the world.

    If you are using raycast bullets the best way is to use a ray object in the script. http://docs.unity3d.com/ScriptReference/Ray.html you can alter the direction of the ray with Random.Range on the vertical and horizontal axis. This will simulate a random spread that is not predictable.

    If you are instantiating the bullet into the world and using the bullet's collision to determine hits all you need to do is spawn the bullet at the point matching the rotation. Then alter the rotation the same way.

    Many big game companies are going over to the spawned bullets because it gives the ability for bullet drop, wind deviation, and flight time where as raycasts are like shooting lasers. They are unaffected by physics other than line of sight.
     
  7. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    Is it possible / fairly easy to simulate the physics for a physical bullet?
     
  8. BluHornet

    BluHornet

    Joined:
    Feb 23, 2015
    Posts:
    40
    yes. all you do is make an actual bullet. the rigidbody will make the bullet effected by gravity for "bullet drop". If you want wind you need to script the wind physics by adding the winds directional force ever fixed update. then when you fire you place a bullet at the muzzle of the gun and give it an impulse force. BLAM the built in physics will take care of the rest. Another trick if you are going to use physical bullets is to make a bullet pool to use from so you are not instantiating and destroying during runtime.
     
  9. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    I ment for a raycast sorry. I know how to add physics to a physical bullet. But is it easy to simulate on a raycast? things like traveltime etc.
     
  10. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    there is always https://docs.unity3d.com/ScriptReference/Random-insideUnitSphere.html ; spread being controlled by the size of the sphere and the "distance" that sphere is reckoned to be from the muzzle (i.e. 1m spread at 100m)

    doesn't matter what approach you take with simulating the projectile you still need to work out the rotation, raycast or force, both need to know what direction they're going in.
     
  11. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    How would I do that? This is what I currently use:
    Code (CSharp):
    1.   if (Physics.Raycast(camTransform.TransformPoint(0,0,0.1f), camTransform.forward, out hit, range))
    2. {
    3. //my code
    4. }
    5.  
    6.  
    Thats pretty much everything I use atm.
     
  12. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    I'd recommend using an empty for the muzzlepoint rather than the offset, makes things simpler

    upload_2016-7-21_21-31-33.png
    second arguement in the raycast would be something like:
    Code (csharp):
    1.  
    2. (muzzle.transform.position - ((d * tranform.forward) + Random.insideUnitSphere(r))).normalize
    3.  
    (i.e. the red line as a unit direction)

    use "insideUnitSphere if you want to have a higher density of shots in the middle, onUnitSphere for a more even spread
     
  13. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    How would I apply your code to my code? To me this seems very confusing.
     
  14. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    What do you mean neither worked? They work perfectly fine when I test them. Please elaborate.
     
  15. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    Sorry. My bad. I was a bit quick at typing then. I ment that I need one that will work for Raycasts as I have figured out that's the route I want to take.

    Sorry for the confusion.
     
  16. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    Is there a reason you're using raycasts for this instead of just a projectile? An actual physics based projectile would be much more efficient and you could encapsulate the collision handling inside a Bullet script.
     
  17. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    I have experimented and I just decided that a raycast is the route I want to take. No real
     
  18. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    Well, you can still use the method I posted above to calculate a rotation. I believe if you normalize the euler angles of the resulting rotation it should give you a functioning conical direction vector. I don't have time to test it though. If you test it please let me know if it works :D

    Example:
    Code (CSharp):
    1. public void ConicalBulletRaycast(Transform bulletSpawn, float coneSize, float range)
    2. {
    3.      float xSpread = Random.Range(-1, 1);
    4.      float ySpread = Random.Range(-1, 1);
    5.      //normalize the spread vector to keep it conical
    6.      Vector3 spread = new Vector3(xSpread, ySpread, 0.0f).normalized * coneSize;
    7.      Vector3 direction = ((Quaternion.Euler(spread) * bulletSpawn.rotation).eulerAngles).normalized;
    8.      RaycastHit hit;
    9.      if (Physics.Raycast(bulletSpawn.position, direction, out hit, range))
    10.      {
    11.        //handle collision
    12.      }
    13. }
     
    Last edited: Jul 23, 2016
  19. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    as a general answer, very high velocity objects can cause the physics engine issues (missed collisions, passing through objects etc.) raycasts can be a lot more reliable in those instances.

    ... instead of the "camTransform.forward". r and d would be variables
    r=1 d=100
     
  20. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    They added continuous and continuous dynamic collision detection modes to prevent that.
     
  21. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    Oh?

    How does that work. Cause what LeftyRighty said is currently why I don't use Prefabs.
     
  22. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    I'm not sure exactly how it's handled internally but I assume it uses raycasts to determine if a collision occurs between physics updates. It should work exactly like implementing your own raycast methods for collisions. You can read more about the Detection Modes here.