- Home /
AddForce and AddRelativeForce not forcing in the right directions
Hey there guys, I am having an issue with the directions of force being produced by a rigidbody. I am trying to make a gun that shoots a bullet casing out the right of the gun, but when happens is it always shoots to the right of the world space, so if i spin 180° the bullet casing is now being shot of of the left side of the gun, i have provided a detailed video clip to both explain what im trying to achieve and show what has previously been suggested, but does not work.
My Coding
Bullet Casing Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class caseEjector : MonoBehaviour {
float thrust = 250;
float flickThrust = 0.1f;
public GameObject bulletCase;
Rigidbody rig;
public void shoot()
{
GameObject cap = Instantiate(bulletCase, transform.position, Quaternion.Euler(0, 0, 0));
cap.transform.parent = gameObject.transform;
rig = cap.GetComponent<Rigidbody>();
rig.AddRelativeForce(new Vector3(1, 0.1f, 0).normalized * thrust);
cap.transform.parent = null;
}
}
Gun Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestShoot : MonoBehaviour {
public bool canShoot;
public bool reloading;
public float bulletClip = 17;
float origClip;
float shotTimer;
float startRTimer;
float reloadTimer = 1.5f;
Animation anim;
public AudioClip shotFired;
public AudioClip reloadSound;
public AudioClip emptyClip;
AudioSource aud;
public GameObject caseEjectorGO;
public Transform casing;
public Transform casePos;
public Vector3 shootLoc;
public Transform bullet;
public Transform shootPos;
void Start () {
origClip = bulletClip;
startRTimer = reloadTimer;
aud = this.GetComponent<AudioSource>();
anim = this.GetComponent<Animation>();
canShoot = true;
reloading = false;
}
void Update () {
shotTimer += Time.deltaTime;
if(shotTimer <= 0.4f)
{
canShoot = false;
}
else
{
canShoot = true;
}
if (canShoot && bulletClip > 0)
{
if (Input.GetButtonDown("Shoot"))
{
anim.Play("APCFire");
aud.PlayOneShot(shotFired);
bulletClip -= 1;
shotTimer = 0;
shootLoc = shootPos.transform.position;
caseEjectorGO.GetComponent<caseEjector>().shoot();
Instantiate(bullet, shootLoc, Quaternion.Euler(0, 90, 0));
}
}
if (bulletClip <= 0 && canShoot)
{
if (Input.GetButtonDown("Shoot"))
{
aud.PlayOneShot(emptyClip);
shotTimer = 0;
}
}
if (Input.GetButtonDown("Reload"))
{
aud.PlayOneShot(reloadSound);
canShoot = false;
reloading = true;
anim.Play("APCReload");
}
if (reloading)
{
reloadTimer -= Time.deltaTime;
if(reloadTimer <= 0)
{
bulletClip = origClip;
reloading = false;
canShoot = true;
reloadTimer = startRTimer;
}
}
}
}
Answer by Jinkata · Jul 13, 2017 at 10:42 PM
on this line in your CaseEjector
rig.AddRelativeForce(new Vector3(1, 0.1f, 0).normalized * thrust);
try this instead
rig.AddForce((this.transform.right + (Vector3.up * 0.1f)).normalized * thrust);
this will apply a force to the 'right' direction of the whatever GameObject this script is on plus an up force on the y axis of 0.1f. I'm assuming that this script is on a GameObject that has it's forward facing toward the front of the gun and the up facing to the top of the gun.
Thank you for the reply, but this still shoots only to the right of the world, in no way does it follow the rotation of the character and gun.
I updated it. I meant to change the AddRelativeForce to simply AddForce
Still no difference, this was the case i had in my previous question, AddForce and AddRelativeForce. made no noticeable difference at all
EDIT: i just noticed you changed it to rig.AddForce((this.transform.right + (Vector3.up * 0.1f)).normalized * thrust);
i have implemented this and it works, but is shooting backward, i will fix the direction it shoots from and update you on how that goes! looking good! thank you!
Thanks mate! this was what i needed was just the this.transform, i just had no idea in how to implement in to actually take the 'this' axis but thankyou you pointed me in the direction i was looking for. i used this to fix it.
rig.AddForce((this.transform.right).normalized * thrust);
(i had removed the Vector3.up due to the caseEjectorGO handles the angles, i just had to spin it 90° to it could take right as actually being right)
Thank you very much for you input i have awarded you the correct answer
Right on. Glad myself and @Bunny83 could help out. I upvoted their answer as well since it's very important to keep in $$anonymous$$d the orientation of the GameObjects.
Answer by Bunny83 · Jul 13, 2017 at 10:55 PM
Your actual problem is that you do not rotate your instantiated object the way your gun looks.
GameObject cap = Instantiate(bulletCase, transform.position, Quaternion.Euler(0, 0, 0));
You rotate the cap object to the default identity rotation. Parenting the object does keep the worldspace orientation.
There are two solutions to rotate your "cap" the same way the case ejector looks.
First use the new SetParent with the second parameter set to false. That will keep the local orientation and carry it over to the new space. This will change the worldspace orientation.
The second solution is to directly instantiate the object with the right rotation. For example:
GameObject cap = Instantiate(bulletCase, transform.position, transform.rotation);
Note that you have to use only one of the two solutions.
This was my next problem I was facing, so thank you for providing this input, i have simply remove the Quaternion and replaced it with transform.rotation to take the rotation of the caseEjector attached the the gun! Thanks again!
That also solves your initial problem with the force. Since you apply a local space force the object always moved in the same direction since the object was always rotated the same way.