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

Calculate power needed for projectile to reach target

Discussion in 'Scripting' started by Kovenant, Sep 16, 2018.

  1. Kovenant

    Kovenant

    Joined:
    Sep 18, 2013
    Posts:
    254
    I'm working on a tank game and I have a reticle that is positioned at Input.mousePosition; whenever the player shoots a projectile I want to shoot the projectile at the reticle. Shooting the projectile in the direction of the reticle is easy, I use my fireTransform's forward vector. However I want to calculate how much power should be applied for the projectile to "land" at the reticle's position. But I have no idea how..

    Code (CSharp):
    1.     [Command]
    2.     private void CmdSpawnShell()
    3.     {
    4.         GameObject instance = Instantiate(shellPrefab, fireTransform.position, fireTransform.rotation) as GameObject;
    5.  
    6.         instance.GetComponent<Rigidbody>().AddForce(fireTransform.forward * power, ForceMode.Impulse);
    7.         NetworkServer.Spawn(instance);
    8.     }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,797
    The arc a ballistic object takes is called its trajectory.

    Google up unity calculate trajectory and you'll find a lot of good stuff.

    It's just math, nothing to be afraid of. :)
     
    Kovenant likes this.
  3. Kovenant

    Kovenant

    Joined:
    Sep 18, 2013
    Posts:
    254
    Thank you, @Kurt-Dekker .
    I have solved the most crucial problem.. However (I literally SUCK at math and have NO idea what I'm doing).. I would like to remove the time parameter from this function and make the projectile go at a certain speed at all times instead.. Because now, if I aim close to my tank - it takes too long for the projectile to hit the ground. And if I aim far away from my tank the projectile goes waaay too fast. Would you mind helping me solve this? :)

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Networking;
    3. using System.Collections;
    4.  
    5. public class TankShooting : NetworkBehaviour {
    6.  
    7.     [SerializeField] GameObject shellPrefab;
    8.     [SerializeField] Transform fireTransform;
    9.     [SerializeField] float projTime = .5f;
    10.  
    11.     IP_Tank_Controller controller;
    12.  
    13.     private void Start()
    14.     {
    15.         controller = GetComponent<IP_Tank_Controller>();
    16.     }
    17.  
    18.     private void Update()
    19.     {
    20.         if (!isLocalPlayer)
    21.             return;
    22.  
    23.         if(Input.GetButtonDown("Fire1"))
    24.         {
    25.             CmdSpawnShell();
    26.         }
    27.     }
    28.  
    29.     [Command]
    30.     private void CmdSpawnShell()
    31.     {
    32.         GameObject instance = Instantiate(shellPrefab, fireTransform.position, fireTransform.rotation) as GameObject;
    33.  
    34.         instance.GetComponent<Rigidbody>().velocity = CalculateVelocity(controller.reticleTransform.position, fireTransform.position, projTime);
    35.         NetworkServer.Spawn(instance);
    36.     }
    37.  
    38.     private Vector3 CalculateVelocity(Vector3 target, Vector3 origin, float time)
    39.     {
    40.         Vector3 distance = target - origin;
    41.         Vector3 distanceXZ = distance;
    42.  
    43.         distanceXZ.y = 0f;
    44.  
    45.         float sY = distance.y;
    46.         float sXZ = distanceXZ.magnitude;
    47.  
    48.         float vXZ = sXZ / time;
    49.         float vY = sY / time + .5f * Mathf.Abs(Physics.gravity.y) * time;
    50.  
    51.         Vector3 result = distanceXZ.normalized;
    52.         result *= vXZ;
    53.         result.y = vY;
    54.  
    55.         return result;
    56.     }
    57. }