- Home /
,I can't get the CannonBall to shoot in the expected direction
,I've got a cannon that you can move the barrel around. When I shoot a cannonball out of it, the cannonball spawns from an empty game object near the tip of the barrel. For the life of me, I cannot make the cannonball move along the expected trajectory. I can only make it move along the Z axis. So whether the barrel is pointed straight up, or left, or right, the cannonball just goes forward along the Z axis.
I've tried Transform.forward and Vector3.forward. Maybe I am doing something wrong on the rotations, but since I can't get any movement in the expected direction, I don't think that's it. Any help would be appreciated. The pertinent part of the code is at the bottom.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Joystick1 : MonoBehaviour
{
[SerializeField]
GameObject _gun;
[SerializeField]
GameObject _stand;
[SerializeField]
GameObject _explosion;
[SerializeField]
GameObject _BulletSpawn;
[SerializeField]
GameObject _CannonBall;
protected Joystick joystick;
protected Joy_button joybutton;
float smooth = 5.0f;
float tiltangle = 60.0f;
protected bool jump;
// Start is called before the first frame update
void Start()
{
joystick = FindObjectOfType<Joystick>();
joybutton = FindObjectOfType<Joy_button>();
}
// Update is called once per frame
void Update()
{
float tiltAroundY = joystick.Horizontal * tiltangle;
float tiltAroundX = joystick.Vertical * tiltangle;
if (tiltAroundX + 45 >= 0 && tiltAroundX + 45 <= 76 && tiltAroundY >= -20 && tiltAroundY <= 20)
{
_gun.transform.rotation = Quaternion.Euler(tiltAroundX + 45, tiltAroundY, 0);
_stand.transform.rotation = Quaternion.Euler(0, tiltAroundY, 0);
}
else if (tiltAroundX + 45 >= 76 && tiltAroundY >= -20 && tiltAroundY <= 20)
{
_gun.transform.rotation = Quaternion.Euler(76, tiltAroundY, 0);
_stand.transform.rotation = Quaternion.Euler(0, tiltAroundY, 0);
}
else if (tiltAroundX + 46 <= 0 && tiltAroundY >= -20 && tiltAroundY <= 20)
{
_gun.transform.rotation = Quaternion.Euler(0, tiltAroundY, 0);
_stand.transform.rotation = Quaternion.Euler(0, tiltAroundY, 0);
}
else if (tiltAroundX + 45 >= 0 && tiltAroundX + 45 <= 76 && tiltAroundY <= -20)
{
_gun.transform.rotation = Quaternion.Euler(tiltAroundX + 45, -20, 0);
_stand.transform.rotation = Quaternion.Euler(0, -20, 0);
}
else if (tiltAroundX + 45 >= 0 && tiltAroundX + 45 <= 76 && tiltAroundY >= 20)
{
_gun.transform.rotation = Quaternion.Euler(tiltAroundX + 45, 20, 0);
_stand.transform.rotation = Quaternion.Euler(0, 20, 0);
}
}
public void FireGun()
{
StartCoroutine(Boom());
}
IEnumerator Boom()
{
if (joybutton.Pressed)
{
_explosion.SetActive(true);
ShootCannon();
yield return new WaitForSeconds(1);
_explosion.SetActive(false);
}
if (!joybutton.Pressed)
{
_explosion.SetActive(false);
}
}
public void ShootCannon()
{
GameObject cloneCannonBall;
cloneCannonBall = Instantiate(_CannonBall, _BulletSpawn.transform.position, _BulletSpawn.transform.rotation);
cloneCannonBall.transform.Rotate(_BulletSpawn.transform.rotation.x, _BulletSpawn.transform.rotation.y, _BulletSpawn.transform.rotation.z);
cloneCannonBall.GetComponent<Rigidbody>().AddForce(transform.forward * 10);
}
Answer by unity_ek98vnTRplGj8Q · Jul 13, 2020 at 03:15 PM
If you are giving the cannon ball the rotation of the spawn point in the Instantiate call, you shouldn't also have to rotate it in the following line of code. Also make sure you are using the transform of the cannonball (or the spawn position since the rotations should be the same) when you are calling add force. transform.forward
uses the transform of whatever game object this script is attached to. Try cloneCannonBall.transform.forward
instead.
This got me going in the right direction. I'm sure I'm doing something redundant, but I changed the bottom of the code to this. Turns out my gun and turret are super small, so I'm having to shrink down the movement. I can tweak it from here to get to my next road block. Thank you!
{
GameObject cloneCannonBall;
cloneCannonBall = Instantiate(_CannonBall, _BulletSpawn.transform.position, _BulletSpawn.transform.rotation);
cloneCannonBall.transform.Rotate(_BulletSpawn.transform.rotation.x, _BulletSpawn.transform.rotation.y, _BulletSpawn.transform.rotation.z);
cloneCannonBall.GetComponent<Rigidbody>().AddForce(cloneCannonBall.transform.position.x * _stand.transform.rotation.y * .25f, cloneCannonBall.transform.position.y * .25f, -cloneCannonBall.transform.position.z);
}
This code worries me as you are double rotating your cannonball AND using the cannonball's position as a factor in your AddForce call. Try this code ins$$anonymous$$d, you can tweak the power of the cannonball by changing the cannonForce variable, but the direction should be correct
GameObject cloneCannonBall;
float cannonForce = 10f;
cloneCannonBall = Instantiate (_CannonBall, _BulletSpawn.transform.position, _BulletSpawn.transform.rotation);
cloneCannonBall.AddForce(cloneCannonBall.transform.forward * cannonForce);
This assumes that the rotation of your bullet spawn object is correct and its a child of the cannon. If its not then this code won't work
Your answer
![](https://koobas.hobune.stream/wayback/20220613003057im_/https://answers.unity.com/themes/thub/images/avi.jpg)