Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
1
Question by Vengroe · Jun 03, 2013 at 01:16 AM · raycastvector3shootingbullet

How can I create Raycast bullet innaccuracy as a cone?

The earliest solutions I had come up with for having deviation from perfect accuracy involved varying the direction up and down as well as left and right by a random number. While this worked (and it was on a much earlier project that I no longer have), it produced a square pattern. While I have figured out how to make the possible area a cone, I now cannot figure out how to get it to point in the appropriate direction.

     float absDir = Random.value * Mathf.PI * 2;
     float offShoot = Random.value * accuracy;
     Vector3 Dir = new Vector3(Mathf.Cos(absDir) * offShoot,Mathf.Sin(absDir) * offShoot, 100);
     Dir.Normalize();
     RaycastHit wasShot;
     if (Physics.Raycast(Muzzle.position, Dir, out wasShot, 1000.0f))
     //Etc

I can't multiply it by another Vector3, such as Muzzle.forward, and none of the Vector3 class functions look like they'd be of much use, either.

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image sotirosn · Jun 03, 2013 at 07:35 AM 0
Share

convert the dir vector into a quaternion rotation with Quaternion.LookRotation() then multiply that rotation by the direction you want to fire.

Quaternion randomRot = Quaternion.LookRotation(randomDir); Vector3 exactDir = randomRot * generalDir;

2 Replies

· Add your reply
  • Sort: 
avatar image
4
Best Answer

Answer by Chronos-L · Jun 03, 2013 at 02:03 AM

I extracted this from my scripts, it might not be what you want or work with your project, but I am sure it will help you in one way or another.

 using UnityEngine;
 using System.Collections;
 
 public class Shotgun : MonoBehaviour {
     
     //These 2 controls the spread of the cone
     public float scaleLimit = 2.0f;    
     public float z = 10f;
     
     //Shoots multiple rays to check the programming
     public int count = 30;
     
     void Update () {
         for( int i = 0; i < count; ++i ) {
             ShootRay();    
         }
     }
     
     void ShootRay() {
         //  Try this one first, before using the second one
         //  The Ray-hits will form a ring
         float randomRadius = scaleLimit;             
         //  The Ray-hits will be in a circular area
         float randomRadius = Random.Range( 0, scaleLimit );        
         
         float randomAngle = Random.Range ( 0, 2 * Mathf.PI );
         
         //Calculating the raycast direction
         Vector3 direction = new Vector3(
             randomRadius * Mathf.Cos( randomAngle ),
             randomRadius * Mathf.Sin( randomAngle ),
             z
         );
         
         //Make the direction match the transform
         //It is like converting the Vector3.forward to transform.forward
         direction = transform.TransformDirection( direction.normalized );
         
         //Raycast and debug
         Ray r = new Ray( transform.position, direction );
         RaycastHit hit;        
         if( Physics.Raycast( r, out hit ) ) {
             Debug.DrawLine( transform.position, hit.point );    
         }    
     }
 }
 
Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Chronos-L · Jun 03, 2013 at 02:13 AM 0
Share

After closer inspection to your code, the only thing that is different between our code is the transform.TransformDirection(). I think your code will work properly when you use the TransformDirection().

avatar image aldonaletto · Jun 03, 2013 at 03:07 AM 3
Share

A good alternative is to use Random.insideUnitCircle:

     void ShootRay() {
        //  Generate a random XY point inside a circle:
        Vector3 direction = Random.insideUnitCircle * scaleLimit;
        direction.z = z; // circle is at Z units 
        direction = transform.TransformDirection( direction.normalized );    
        //Raycast and debug
        Ray r = new Ray( transform.position, direction );
        RaycastHit hit;     
        if( Physics.Raycast( r, out hit ) ) {
          Debug.DrawLine( transform.position, hit.point ); 
        } 
     }
avatar image Chronos-L · Jun 03, 2013 at 04:31 AM 0
Share

@aldonaletto, just doing so will just make it a hemisphere, we will have no control over the cone.

avatar image syclamoth · Jun 03, 2013 at 04:35 AM 0
Share

Not so, the size of the random vector (the scaleLimit) gives complete control over the size of the cone.

avatar image Chronos-L · Jun 03, 2013 at 06:03 AM 0
Share

Oh, my mistake. I was thinking that Random.insideUnitSphere and we are just flipping the z over one side.

@aldonaletto's alternative is way better and cleaner.

Show more comments
avatar image
0

Answer by sotirosn · Jun 03, 2013 at 07:25 AM

This seems like a geometry problem where the center axis of the cone is where the player fires, i.e. the cross hairs, then you apply a random rotation to point that offset that direction. So, I would first tilt the center axis between zero and your max cone angle along a single axis perpendicular to the center. Then I would spin the result between zero and 360 degrees along the original center axis. So,

 Quaternion GetRandomInsideCone(float conicAngle) {
     // random tilt right (which is a random angle around the up axis)
     Quaternion randomTilt = Quaternion.AngleAxis(Random.Range(0f, conicAngle), Vector3.up);
     
     // random spin around the forward axis
     Quaternion randomSpin = Quaternion.AngleAxis(Random.Range(0f, 360f), Vector3.forward);
     
     // tilt then spin
     return (randomSpin * randomTilt);
 }
 

you can then do

     // fire in direction with random 10 degree offset
     Vector3 fireInDirection = new Vector3(3, 4, 5);
     Vector3 fireInRandomDirection = GetRandomInsideCone(10) * fireInDirection;
     
     // or rotate an object within the cone
     Transform weapon = GetSomeTransform();
     weapon.rotation = GetRandomInsideCone(conicAngle) * originalRotation;
     

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Owen-Reynolds · Jun 03, 2013 at 04:01 PM 0
Share

The important part here, and in the OPs partial solution, is you have complete control of how the random is rolled. You can roll uniform 0-max. Or can get a more centered spread by adding 2 dice, or can force yourself to miss by rolling max/2 to max (for enemies who miss the first few shots and get better.)

For the Quaternions, can also use Quaternion.EulerAngle(0,randomSpin,randomTilt) then multiply that by weapon.forward; to get the line.

avatar image lgarczyn · Mar 11, 2017 at 11:30 PM 0
Share

Your answer is not uniform, and will not yield good results at high angles. A fully uniform function would be this:

 public static Vector3 RandomInsideCone(float radius)
 {
     //(sqrt(1 - z^2) * cosϕ, sqrt(1 - z^2) * sinϕ, z)
     float radradius = radius * $$anonymous$$athf.PI / 360;
     float z = Random.Range($$anonymous$$athf.Cos(radradius), 1);
     float t = Random.Range(0, $$anonymous$$athf.PI * 2);
     return new Vector3($$anonymous$$athf.Sqrt(1 - z * z) * $$anonymous$$athf.Cos(t), $$anonymous$$athf.Sqrt(1 - z * z) * $$anonymous$$athf.Sin(t), z);
 }
 


source: http://math.stackexchange.com/questions/56784/generate-a-random-direction-within-a-cone

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

20 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Test if a bullet will hit before shooting it? 2 Answers

Bullet goes sideways when the player gets hit 1 Answer

Range not working c# - shooting script using raycast 0 Answers

Rotate Vector to hit.normal only by set degrees 0 Answers

Doom/Wolfenstein 3D-style targeting system. Detect enemies in camera view? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges