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
1
Question by Herve_Simard · Apr 05, 2012 at 03:38 PM · c#addforcebomb

Use a vector3 position to calculate where a bomb falls

Hi everyone,

I've been working on a difficult problem since a few days and I'm bugged.

I'm trying to get a Vector3 position that will serve as a target. I'm trying to make something like a cannon fire at that precise position.

Here's my code right now:

using UnityEngine; using System.Collections;

public class Mortar : MonoBehaviour { public float force; public Vector3 torque; public GameObject explosion;

 private Transform target;
 private Vector3 targetPos;
 
 void Start () 
 {
     Destroy(gameObject, 5.0f);
     
     rigidbody.AddForce(transform.forward * force, ForceMode.Impulse);
     
     rigidbody.AddForce(transform.up * force, ForceMode.Impulse);
     
     rigidbody.AddTorque(torque, ForceMode.Force);
 }
 
 void OnCollisionEnter(Collision collision)
 {    
     foreach(ContactPoint cp in collision.contacts)
     {
         if(cp.otherCollider.gameObject.tag == "Floor")
         {
             Instantiate(explosion, collision.contacts[0].point, Quaternion.identity);
             Destroy(gameObject);
         }
     }        
 }
 
 void ReceiveTarget(Vector3 targetReceived)
 {
     targetPos = targetReceived;
     Debug.Log("targetPos = " + targetPos);
 }
 
 void ApplyDamage()
 {
     
 }

} Obviously, I'm still not done with getting my Vector3 from another script, but I'm working on that. The main problem is: when I get that info, how will I use it? I want my bomb, once fired, to do an arc from the canon tip to the target. I'm trying hard to figure how I can do this with the AddForce...

Anybody can help? Thank you.

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 AlucardJay · Apr 07, 2012 at 02:16 PM 0
Share

maybe there's something you can use from this : http://answers.unity3d.com/questions/235519/projectile-boomerang.html

2 Replies

· Add your reply
  • Sort: 
avatar image
5

Answer by aldonaletto · Apr 07, 2012 at 01:52 AM

I answered a similar question some time ago: http://answers.unity3d.com/questions/148399/shooting-a-cannonball.html
The code in that answer is in JS, thus I posted here a C# version.
In a brief, you should calculate the velocity necessary to reach the target, instantiate the projectile and set its rigidbody.velocity to the value calculated. If the target and the cannon are at the same height, the velocity magnitude can be calculated by sqrt(distance g sin(2 * elevation angle)). If there exists a small height difference between the cannon and the target, this can be compensated to some extent by a smart change in the distance value.
The function BallisticVel below receives the target transform and the elevation angle, and calculates the complete velocity vector (a vector with suitable direction and magnitude), including a linear compensation for small height differences (up to about 10% of the distance):

Vector3 BallisticVel(Transform target, float angle){ Vector3 dir = target.position - transform.position; // get target direction float h = dir.y; // get height difference dir.y = 0; // retain only the horizontal direction float dist = dir.magnitude ; // get horizontal distance float a = angle * Mathf.Deg2Rad; // convert angle to radians dir.y = dist * Mathf.Tan(a); // set dir to the elevation angle dist += h / Mathf.Tan(a); // correct for small height differences // calculate the velocity magnitude float vel = Mathf.Sqrt(dist * Physics.gravity.magnitude / Mathf.Sin(2 * a)); return vel * dir.normalized; }

// This is a test code: drag the target and projectile prefab to the appropriate // fields in the Inspector, then press B to shoot. You can change the shootAngle, // initially set to 30 degrees - the projectile slows down for higher angles, // and get faster for lower angles:

public Transform myTarget; // drag the target here public GameObject cannonball; // drag the cannonball prefab here public float shootAngle = 30; // elevation angle

void Update(){ if (Input.GetKeyDown("b")){ // press b to shoot GameObject ball = Instantiate(cannonball, transform.position, Quaternion.identity) as GameObject; ball.rigidbody.velocity = BallisticVel(myTarget, shootAngle); Destroy(ball, 10); } } This C# version was not tested, thus let me know if it has any errors.
NOTE: The projectile must not collide with the cannon, or it will never reach the target. You can have a cannon without collider, or with isTrigger=true, or attach this script to an empty object that will be the spawn point.

Comment
Add comment · Show 4 · 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 Herve_Simard · Apr 07, 2012 at 01:46 PM 0
Share

Seems like I'm getting somewhere!

Thanks to your effort, I've understood my mistake. First:

  • I've been trying to modify the direction of my mortar dynamically, meaning that I was trying in my script up above to change the direction in mid-air; this was NOT intended and assuredly not in my concept.

  • Reading both of your comments allowed me to understand that it was not my cannonball which I needed to modify, but the cannon which instantiate the ball.

So I've applied your script to my cannon. Although things seem to improve, it doesn't quite work well. Before, the bomb would spawn behind my cannons and would not move; now they spawn at the right place, but with no velocity whatsoever. $$anonymous$$eh.

Here's the script of my canon (corrected):

using UnityEngine; using System.Collections;

public class $$anonymous$$ortarGun : $$anonymous$$onoBehaviour { public Transform gunTip; public Transform target; public GameObject mortar; public GameObject name; public float fireRate; private float shotTime = 0.0f; public float shootAngle;

 void Update () 
 {
     shotTime += Time.deltaTime;
     
     if(shotTime >= fireRate)
     {
         if(!(name.GetComponent("Tower") as Tower).canAim)
         {
             GameObject cannonBall = Instantiate(mortar, gunTip.position, Quaternion.identity) as GameObject;
             cannonBall.rigidbody.velocity = BallisticVelocity(target, shootAngle);
             shotTime = 0.0f;
         }
     }
 }
 
 Vector3 BallisticVelocity(Transform target, float angle)
 {
     Vector3 dir = target.position = transform.position; // get Target Direction
     float height = dir.y; // get height difference
     dir.y = 0; // retain only the horizontal difference
     float dist = dir.magnitude; // get horizontal direction
     float a = angle * $$anonymous$$athf.Deg2Rad; // Convert angle to radians
     dir.y = dist * $$anonymous$$athf.Tan(a); // set dir to the elevation angle.
     dist += height / $$anonymous$$athf.Tan(a); // Correction for small height differences
     
     // Calculate the velocity magnitude
     float velocity = $$anonymous$$athf.Sqrt(dist * Physics.gravity.magnitude / $$anonymous$$athf.Sin(2 * a));
     return velocity * dir.normalized; // Return a normalized vector.
 }

} As you can see, the canon does the job of instantiating the cannonBall. But there's a twist: I used to add some properties to my mortar with which I played. Those were :

void Start () 
    {
        rigidbody.AddForce(transform.forward * force, Force$$anonymous$$ode.Impulse);
        rigidbody.AddForce(transform.up * force, Force$$anonymous$$ode.Impulse);
        rigidbody.AddTorque(torque, Force$$anonymous$$ode.Force);
    }

If I remove them, the cannonBall no longer move with velocity, just falls softly in front of the cannon...

avatar image aldonaletto · Apr 07, 2012 at 03:21 PM 2
Share

You must not apply any other force to the cannonball, or it will never reach the target! The cannonball is just a rigidbody driven by initial velocity and gravity - remove that code!
Your script actually doesn't work because you made a typo in the first BallisticVel line (changed a - signal to =). But there's another problems: you're instantiating the cannonball at gunTip, but the calculation is being done based on transform.position - unless the script is attached to gunTip, the result will be wrong.
To avoid this problem, I changed the function to use gunTip.position. I also fixed the typo, and made the cannonball be destroyed after 10 seconds (to avoid a scene crowded with lost cannonballs). That's the result:

using UnityEngine; using System.Collections;

public class $$anonymous$$ortarGun : $$anonymous$$onoBehaviour { public Transform gunTip; public Transform target; public GameObject mortar; public GameObject name; // name is a GameObject property - you should rename this variable public float fireRate; private float shotTime = 0.0f; public float shootAngle;

 void Update () 
 {
     shotTime += Time.deltaTime;
     
     if(shotTime >= fireRate)
     {
         if(!(name.GetComponent("Tower") as Tower).canAim)
         {
             GameObject cannonBall = Instantiate(mortar, gunTip.position, Quaternion.identity) as GameObject;
             cannonBall.rigidbody.velocity = BallisticVelocity(target, shootAngle);
             Destroy(cannonBall, 10); // cannonball disappears after 10 seconds
             shotTime = 0.0f;
         }
     }
 }
 
 Vector3 BallisticVelocity(Transform target, float angle)
 {
     Vector3 dir = target.position - gunTip.position; // get Target Direction
     float height = dir.y; // get height difference
     dir.y = 0; // retain only the horizontal direction
     float dist = dir.magnitude; // get horizontal distance
     float a = angle * $$anonymous$$athf.Deg2Rad; // Convert angle to radians
     dir.y = dist * $$anonymous$$athf.Tan(a); // set dir to the elevation angle.
     dist += height / $$anonymous$$athf.Tan(a); // Correction for small height differences
     
     // Calculate the velocity magnitude
     float velocity = $$anonymous$$athf.Sqrt(dist * Physics.gravity.magnitude / $$anonymous$$athf.Sin(2 * a));
     return velocity * dir.normalized; // Return the velocity vector.
 }

}

avatar image PauloFernandes aldonaletto · Jun 08, 2016 at 10:58 PM 0
Share

Hi! Would you $$anonymous$$d explaining how you achieved your solution?

I am new to the coding world, so I am struggling to understand some variables, such as 'GameObject name' and expressions as used in "if(!(name.GetComponent("Tower") as Tower).canAim)"

Thanks!

avatar image Herve_Simard · Apr 08, 2012 at 12:26 AM 0
Share

Wow... it works! Thanks a lot ^^ Now I've got issues with my targetting system, but hey, at least I've got something :) Thanks again!

avatar image
1

Answer by kolban · Apr 05, 2012 at 03:47 PM

So if I understand you, you have two points ... the source and the target and you want to move an object from the source to the target in a "ballistic" fashion following a trajectory?

I think the answer to your question will presumably involve physics and math. You will want to calculate the vector of initial launch of the projectile and the force to be applied to it. The calculation of these factors will be based on the mathematics of Trajectory.

See:

http://en.wikipedia.org/wiki/Trajectories

Comment
Add comment · Show 1 · 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 Herve_Simard · Apr 07, 2012 at 12:48 AM 0
Share

That's a nice idea you got there.

I've done something similar based on a class project we made a few weeks ago, using what you just suggested:

using UnityEngine; using System.Collections;

public class $$anonymous$$ortar : $$anonymous$$onoBehaviour { public float force; public Vector3 torque; public GameObject explosion; public Transform target; public float speed; public Transform guntip; public AnimationCurve curve;

 private Vector3 departPos;
 private Vector3 destination;
 private float currentTime = 0.0f;
     
 void Start () 
 {
     //Destroy(gameObject, 5.0f);
     
     rigidbody.AddForce(transform.forward * force, Force$$anonymous$$ode.Impulse);
     rigidbody.AddForce(transform.up * force, Force$$anonymous$$ode.Impulse);
     rigidbody.AddTorque(torque, Force$$anonymous$$ode.Force);
     
     departPos = guntip.position;
 }
 
 void OnCollisionEnter(Collision collision)
 {    
     foreach(ContactPoint cp in collision.contacts)
     {
         if(cp.otherCollider.gameObject.tag == "Floor")
         {
             Instantiate(explosion, collision.contacts[0].point, Quaternion.identity);
             Destroy(gameObject);
         }
     }        
 }
 
 void ApplyDamage()
 {
     
 }
 
 void Update()
 {
     currentTime += speed * Time.deltaTime;
     
     destination = target.position;
     
     transform.position = Vector3.Lerp(departPos, destination, curve.Evaluate(currentTime));
 }

}

But it does not work. $$anonymous$$y mortar appears BEHIND the canon and does not move...

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

7 People are following this question.

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

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

How can I add force in the opposite direction of the mouse? C# 0 Answers

How to add a delay to a bomb explostion 1 Answer

How to create a variable jump height 2 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