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 /
avatar image
0
Question by chrisall76 · Aug 09, 2012 at 04:40 AM · physicsraycastguns

bullet physics using raycast?

As the title says, I need a way to have bullet physics but using raycast. I search but most didn't give a answer to it. Kind of like this video at around 8:30: http://www.youtube.com/watch?v=3eYEOS4IHW8&feature=channel&list=UL

right now for all of the scripts I'm using a forward raycast from the camera, and some guns I don't want to do that. Here's the sniper rifle script I want to change:

 var GunCamera : Camera;
 var shotSound: AudioClip; // Shot sound
 var bloodPrefab: GameObject; // Blood for enemy
 var sparksPrefab: GameObject; // Sparks for groun
 var muzzleFlash : GameObject;
 var ShellPrefab : Transform;
 var shootEnabled: boolean = true; // allows disabling the shots
 var ChangeWep : boolean = true;
 var MaxBullets = 9;
 var Bullets = 9;
 var Clip = 9000;
 var shotInterval = 1.0;
 var force = 50;
 var RayCastDist : float = 50;
 var Zoom : int;
 
 function Shoot(){
     var cam : Transform = Camera.main.transform;
     var ray = new Ray(cam.position, cam.forward);
     var hit : RaycastHit;
     var trf = transform; // a little optimization
     var hitRotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
     MuzzleFlashOn();
     audio.PlayOneShot(shotSound); // play the shot sound...
     var ShellClone = GameObject.Instantiate(ShellPrefab, GameObject.Find("ShellSpawner").transform.position, Quaternion.identity);
     ShellClone.rigidbody.AddForce(transform.up + transform.right * 200);
     
         if(Physics.Raycast (ray, hit, RayCastDist)){
         var rot = Quaternion.FromToRotation(Vector3.up, hit.normal);
                  
             if(hit.collider.gameObject.tag == "Box"){
                 Debug.Log ("Hit A Box!");
                 if (sparksPrefab) Instantiate(sparksPrefab, hit.point, rot); 
                 hit.rigidbody.AddForceAtPosition(force * transform.forward , hit.point);
                 hit.collider.SendMessageUpwards("ApplyDamage", 5.0);
                 //Instantiate(bulletHole, hit.point, rot);
         }
             if(hit.collider.gameObject.tag == "Enemy"){
                 Debug.Log ("Hit A Enemy!");
                 if (sparksPrefab) Instantiate(sparksPrefab, hit.point, rot);
         } 
             if(hit.collider.gameObject.tag == "Target"){
                 Debug.Log ("Target hit!");
                 hit.rigidbody.AddForceAtPosition(force * transform.forward , hit.point);
                 hit.rigidbody.isKinematic = false;
                 hit.rigidbody.useGravity = true;
                 if (sparksPrefab) Instantiate(sparksPrefab, hit.point, rot); 
             } else {            
             if (sparksPrefab) Instantiate(sparksPrefab, hit.point, rot);
             Debug.Log ("Hit Other!");
         }
         ChangeWep = false;
         SendMessageUpwards("Recoil");
         shootEnabled = false;
         yield WaitForSeconds(shotInterval);
         shootEnabled = true;
         ChangeWep = true;    
         }
     }
  
Comment
Add comment
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

3 Replies

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

Answer by sman_47o · Aug 09, 2012 at 04:46 PM

what i would do is to make a Vector3 to simulate gravity multiply it by the distance between the hit and shooter and then add that vector to the hit.point. so depending on how far from the hit is from the shooter, the hit will drop a distance that is scale to its traveled path.

so for example:

         //what i changed
         var Gravity : Vector3 = Vector3(0,-0.5,0); //you might wanna mess around with this number
         if(Physics.Raycast (ray, hit, RayCastDist)){
             var rot = Quaternion.FromToRotation(Vector3.up, hit.normal);
             hit.point = hit.point + hit.distance*Gravity;
         //what i changed
 
         if(hit.collider.gameObject.tag == "Box"){
             Debug.Log ("Hit A Box!");
             if (sparksPrefab) Instantiate(sparksPrefab, hit.point, rot); 
             hit.rigidbody.AddForceAtPosition(force * transform.forward , hit.point);
             hit.collider.SendMessageUpwards("ApplyDamage", 5.0);
             //Instantiate(bulletHole, hit.point, rot);
     }
         if(hit.collider.gameObject.tag == "Enemy"){
             Debug.Log ("Hit A Enemy!");
             if (sparksPrefab) Instantiate(sparksPrefab, hit.point, rot);
     } 
         if(hit.collider.gameObject.tag == "Target"){
             Debug.Log ("Target hit!");
             hit.rigidbody.AddForceAtPosition(force * transform.forward , hit.point);
             hit.rigidbody.isKinematic = false;
             hit.rigidbody.useGravity = true;
             if (sparksPrefab) Instantiate(sparksPrefab, hit.point, rot); 
         } else {            
         if (sparksPrefab) Instantiate(sparksPrefab, hit.point, rot);
         Debug.Log ("Hit Other!");
     }
Comment
Add comment · Show 5 · 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 chrisall76 · Aug 10, 2012 at 03:20 AM 0
Share

This works, only thing is that when I draw the raycast it looks like it's just A instant drop from the start point and not a drop over time. Could be that and the drawline doesn't show it .

avatar image sman_47o · Aug 13, 2012 at 01:23 AM 0
Share

I'm not sure... What you could do is have it log the location of the hit in the debug window and shoot an object at say 10 meters and then shoot an object at 100 meters (and of course make sure to either disable your mouselook script or just try not to move the mouse at all)

avatar image aldonaletto · Aug 13, 2012 at 01:52 PM 0
Share

Your basic idea is ok, but in some cases it may produce weird results: since you just shift down the hit.point according to distance, it may goes out of the surface hit and let a bullet hole in mid air. To fix this, you could get a valid hit.point just doing a second raycast to the shifted point:

    ...
    // original raycast:
    if (Physics.Raycast (ray, hit, RayCastDist)){
      hit.point = hit.point + hit.distance*Gravity;
      // do a second raycast to the shifted point:
      if (Physics.Raycast(ray.origin, hit.point, hit, RayCastDist)){
        // the original hit code goes here:
        var rot = Quaternion.FromToRotation(Vector3.up, hit.normal);
        if(hit.collider.gameObject.tag == "Box"){
          Debug.Log ("Hit A Box!");
          ...
      }
    }
avatar image sman_47o · Aug 14, 2012 at 05:34 PM 0
Share

Thanks I hadnt thaught of that and now that I think of it I'm not sure that if you were to aim above a targets, lts say head, weather or not it would ever register a hit. How I would fix my own silly mistake would be to actually apply the gravity vector directly to the ray in the if statement like so:

 Ray.direction = ray.direction * gravity * RayCastDist
 If(physics.Raycast(ray, hit, RayCastDist){

I think this will actually hit two birds with one stone and with it you wpuldnt need to change the hit position after the fact. Also remember that the Gravity vector could also include wind or other forces that would Change the trajectory of your bullet. I also believe it could be possible to dynamically change the "physics" being applied on the bullet (in order to cause it to curve or drop suddenly) but that would require some complex code and possibly several rays :P.

avatar image chrisall76 · Sep 12, 2012 at 04:56 AM 0
Share

So how would I use that in the original code you posted?

avatar image
0

Answer by aldonaletto · Aug 13, 2012 at 01:34 PM

The shooting technique used in Elite Squad probably uses multiple rays - the segments that appear in the linked video. You could do something similar by calculating the position each Update or FixedUpdate with speed, gravity and wind taken into account, and check collisions with Linecast between the last and the current positions. An easier possibility is to let Unity do the hard work for you: simply shoot a fast rigidbody (the bullet) and let physics handle the trajectory, but still check collisions with Linecast each FixedUpdate, or you'll probably miss the smaller targets - something like this (bullet script):

var bulletSpeed: float = 250; private var startPos: Vector3; // initial position (used for hit.distance calculation) private var lastPos: Vector3; // bullet position last physics cycle private var hit: RaycastHit; // hit info will be passed here

function Start(){ // initialize variables: startPos = rigidbody.position; lastPos = startPos; // accelerate the bullet: rigidbody.velocity = transform.forward * bulletSpeed; }

function FixedUpdate(){ var curPos = rigidbody.position; if (Physics.Linecast(lastPos, curPos, hit)){ HitSomething(); } lastPos = curPos; // update lastPos }

// regular collisions may be detected as well: function OnCollisionEnter(col: Collision){ // copy the important fields from col to hit: hit.rigidbody = col.rigidbody; hit.transform = col.transform; var contact = col.contacts[0]; hit.point = contact.point; hit.normal = contact.normal; hit.distance = Vector3.Distance(hit.point, startPos); HitSomething(); }

function HitSomething(){ Destroy(gameObject); // destroy the bullet when hit something // your hit code goes here: var rot = Quaternion.FromToRotation(Vector3.up, hit.normal); if(hit.collider.gameObject.tag == "Box"){ Debug.Log ("Hit A Box!"); if (sparksPrefab) Instantiate(sparksPrefab, hit.point, rot); hit.rigidbody.AddForceAtPosition(force * transform.forward , hit.point); hit.collider.SendMessageUpwards("ApplyDamage", 5.0); ... } Your Shoot function would become simpler:

... var bulletPrefab: GameObject; // drag the bullet prefab here

function Shoot(){ var trf = transform; // a little optimization MuzzleFlashOn(); audio.PlayOneShot(shotSound); // play the shot sound... var ShellClone = GameObject.Instantiate(ShellPrefab, GameObject.Find("ShellSpawner").transform.position, Quaternion.identity); ShellClone.rigidbody.AddForce(transform.up + transform.right * 200); Instantiate(bulletPrefab, trf.position, trf.rotation); ChangeWep = false; SendMessageUpwards("Recoil"); shootEnabled = false; yield WaitForSeconds(shotInterval); shootEnabled = true; ChangeWep = true;
} Notice that this is just a basic suggestion: adapting your current code to this will probably cause a couple headaches, because some parts (the hit detection and particles generation) were moved to the bullet script. The Shoot script should be attached to a spawn point object - usually an empty game object childed to the weapon and positioned at the weapon tip, oriented in the weapon forward direction. The original code always shot in the camera's forward direction, hitting anything at the screen center, but this ballistic-like code will shoot in the direction the weapon is aiming to.

Comment
Add comment · 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
0

Answer by Estevominador · Nov 01, 2012 at 03:55 PM

I did that! I shoot a raycast and within time, it'll increase the range. to simulate the trajectory I made to the transform decrease the rotation in the x-axis depending on bullet's weight, the air density, and the current speed of the bullet.

works cool, but if anything cross through the bullet's trajectory, even if the range is 1km still detecting the collision.

Comment
Add comment · 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

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

11 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

Related Questions

Can someone explain to me why this raycast doesn't fire straight? 1 Answer

HOW DO I USE RAYCASTHIT 2D???? 1 Answer

Applying Normal force from ground to player 1 Answer

Problem With Physics.Raycast 1 Answer

2D Slope acceleration 1 Answer


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