- Home /
My bullets fly same direction no matter wich way I turn player c#.
If I use Random.Range for accuracy bullets fly same direction.
Changing Range I change accuracy. If I turn off Random.Range Bulletscript works correctly
but bullets fly straight line wich is not looking realistic. How can I use Random.Range to change accuracy level? This is my Bulletscript using UnityEngine; using System.Collections;
public class Bullet : MonoBehaviour {
private float BulletSpeed = 50f;
public GameObject Bulletprefab;
private Transform myTransform;
private float x, y, z;
void Start ()
{
}
void Update ()
{
float BulletMove = BulletSpeed * Time.deltaTime;
transform.Translate(Vector3.forward * BulletMove);
//If I exclude Random.Range function script works correctly
x = Random.Range(-3f, 3f); // I need Bullets fly within (-3, 3) Range. //That's for accuracy
y = Random.Range(-3f, 3f); // same
z = Random.Range(-3f, 3f); // same
transform.eulerAngles = new Vector3(x, y, z);
Destroy(gameObject, 2f);
}
} Player script using UnityEngine; using System.Collections;
public class Player : MonoBehaviour {
private float PlayerSpeed = 20;
private float rotationSpeed = 60;
public GameObject BulletPrefab;
void Update()
{
float PlayerMove = Input.GetAxisRaw("Vertical") * PlayerSpeed * Time.deltaTime;
transform.Translate(Vector3.forward * PlayerMove);
float PlayerRotation = Input.GetAxisRaw("Horizontal") * rotationSpeed * Time.deltaTime;
transform.Rotate(Vector3.up * PlayerRotation);
if(Input.GetKey(KeyCode.Mouse0))
{
Instantiate(BulletPrefab, transform.position, transform.rotation);
}
}
}
@alex55 Ins$$anonymous$$d of this
x = Random.Range(-3f, 3f);
just say
x += Random.Range(-3f, 3f);
do that for the y and z values as well. That should fix er right up.
Answer by Jacek_Wesolowski · May 04, 2012 at 07:29 PM
You've put the randomization code in the Update() function, which gets called every frame. That means you're picking a new random number every frame.
You're also replacing the old rotation with the new one, instead of adding spread to player's rotation, because your code says:
transform.eulerAngles = new Vector3(x, y, z);
rather than
transform.eulerAngles += new Vector3(x, y, z);
Doing this every frame also destroys the effect of randomness, because you're picking a large number of random numbers from the same range. You get various results for each number, but they kind of nullify each other: on one frame you get +2.3, on another -0.7, then +0.3, then -1.9, etc. and the end result is that it always boils down to the same average (in your case: 0).
What you need to do is move the randomization code to the player class, and apply it to the bullet right after you've instantiated it. You also want to add the random value to the bullet's rotation, rather than replacing the latter with the former.
I think transform.Translate(Vector3.FORWARD * Bullet$$anonymous$$ove); CONFLLICTS with NEW VECTOR3(x, y, z); So bullets fly Vector3.FORWARD direction if I use Random.Range. But I need Random.Range to change accuracy level.
Functions cannot "conflict" with each other, unless you're doing parallel program$$anonymous$$g, which is not the case here.
The Translate() function in the script moves the bullet along the so called "local" forward axis, as opposed to "global" axes. Global axes are always the same and cannot change, whereas local axes are relative to the direction an object is currently pointed at. Rotate the object, and its local axes will be rotated, too.
As long as you don't have the line "transform.eulerAngles = new Vector3(x, y, z);" at all, the bullet's direction is set to player's upon instantiation, and then the bullet is moved along its local forward axis. That's why it works.
The line "transform.eulerAngles = new Vector3(x, y, z);" is problematic, because it sets the rotation to a new value and discards the old one. The correct thing to do here is "transform.eulerAngles += new Vector3(x, y, z);", which looks almost the same, but actually adds a new value to the old one (and that's what needs to be done: spread needs to be added on top of player's rotation).
Also, this needs to be done outside of bullet's Update(). Otherwise, a new spread will be added on every frame.
Answer by Calumcj · May 04, 2012 at 07:35 PM
Hey, i had a similar issue with my game. I ended up changing to javascript to make it work, try somthing like this.
var Projectile: Transform;
var fireRate: float = 0.3;
private var nextFire: float = 2.0;
var Ammo: int = 30;
var gunfire: AudioClip;
var reload: AudioClip;
var empty: boolean = false;
function Update () {
if(Input.GetButton("Fire1")&&Time.time > nextFire)
{
if(Ammo > 0){
Fire();
}
else{
return;
}
}
if(Input.GetKeyUp("r")){
if(empty){
Reload();
}
}
if(Ammo <= 0){
empty = true;
}
else{
empty = false;
}
}
function Fire(){
audio.PlayOneShot(gunfire);
nextFire = Time.time + fireRate;
var shot = Instantiate(Projectile, transform.position, Quaternion.identity);
shot.rigidbody.AddForce (transform.forward * 3000);
Ammo--;
}
function Reload(){
audio.PlayOneShot(reload);
Ammo = 30;
}
function OnGUI(){
GUI.Box (Rect(Screen.width - 100, 1, 100, 80), "");
GUI.Label (Rect (Screen.width - 100, -3, 90, 20), "Ammo" + Ammo);
if(empty){
GUI.contentColor = Color.red;
GUI.Label (Rect (Screen.width - 100, 25, 90, 20), "RELOAD");
}
}
@script ExecuteInEditMode()
that should give you a working fire arm, then all you need to do is assine a projectile, this also has a ammo meter and a reload system (also some sound systems) but you can just take the parts you need. hope it helps :) If you need any help with javascript, just message :)
I can't find Random.Range in your script wich I use for accuracy level. Exemple script on c# using Random.Range is desirable.
Well its mroe about personal prefrence, i find javascript much easyer to understand and easier to program when it comes to ga$$anonymous$$g, the only this i would use c# for at the moment would be for console applications :)
Format your code! And post comments in the comments section, while you're at it.
Answer by sumiguchi · May 04, 2012 at 07:36 PM
First off it seems odd to me that you want to change the rotation on the bullet every frame while it shoots through the air. Wouldn't you just want to change the angle once when the bullet is instantiated?
In any case, it looks to me like the problem is you are replacing the transform with a value of -3 to 3, instead of adding to it. Instead of:
transform.eulerAngles = new Vector3(x, y, z);
try:
transform.eulerAngles += new Vector3(x, y, z);
"+" doesn't correct direction of shooting. Bullets still fly blue vector z direction no matter wich way I turn player. If I turn off Random.Range bullets fly the direction I turn player.
$$anonymous$$aybe I didn't explain it well enough. Here is some code that I've tested and it works for me.
Remove this from your Update in Bullet:
x = Random.Range(-3f, 3f); // I need Bullets fly within (-3, 3) Range. //That's for accuracy
y = Random.Range(-3f, 3f); // same
z = Random.Range(-3f, 3f); // same
transform.eulerAngles = new Vector3(x, y, z);
Then replace your instantiate with this in Player:
instanceShot = Instantiate(BulletPrefab, transform.position, Quaternion.identity) as Transform;
x = Random.Range(-3f, 3f); // I need Bullets fly within (-3, 3) Range. //That's for accuracy
y = Random.Range(-3f, 3f); // same
z = Random.Range(-3f, 3f); // same
instanceShot.transform.Rotate (transform.eulerAngles +new Vector3(x,y,z));
I didn't check for comments last few days. I'l check up your advice.