I've been tinkering with this for a while and can't seem to get it to work properly, it sometimes works but other times does not.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class gun: MonoBehaviour
{
public Transform firePoint;
public GameObject BulletPrefab;
float Speed = 20f;
void Update()
{
if(Input.GetButtonDown("Fire1"))
{
Shoot();
}
}
void Shoot()
{
int a = 0;
float[] b1 = {-15f,0f,15f};
while (a != 3)
{
GameObject bullet = Instantiate(BulletPrefab, firePoint.position, firePoint.rotation);
Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
Transform tr = bullet.GetComponent<Transform>();
tr.rotation = firePoint.rotation;
tr.Rotate(new Vector3(0f,0f,b1[a]),Space.Self);
rb.AddForce(tr.up * Speed, ForceMode2D.Impulse);
a++;
}
}
}
It's supposed to offset the projectiles at 15 degrees angles and shoot them, but sometimes it just rotates inwards and shoots straight forward.
Tried to convert it to vectors and back but have no clue how to do that and can't seem to find help on this even on page 2 of Google.
I believe that, from the few information that are present, you want to "triple shoot" your bullets from your gun position and make it go forward depending on your gun rotation and rotation offset? If so then here are the problems and solutions to your code:
The problem
I recommend using tr.eulerAngles
which uses Vector3 and it's easier to understand and manipulate. With that, you can simply do:
tr.eulerAngles = firePoint.transform.eulerAngles
This will make your bullet copy the gun rotation. Now, if you want to add some rotation to your bullet to make a "triple shot" effect, you would only need to add a Vector3 to modify the y value of your angle. Example:
tr.eulerAngles = firePoint.transform.eulerAngles + new Vector3(0, -15, 0);
This will fix your problem with rotation.
Tips to upgrade your code
Even though this simply line of code will fix your problem, your script has a lot of issues with proper coding and video games basic rules.
First rule of video games, is to never instantiate object during Runtime.
Why? Let's say you shoot 10 bullets at once with a fast firerate, then your game will be very laggy because you are instantiating new objects in your memory (and erasing afterwards). It's a very beginner issue that simply requires the use of Object Pooling .
Another tip is to better name your variables and respect naming conventions. Instead of using 1-2 letter(s) variables use understandable key-words:
tr -> transform
a -> rotationOffset
BulletPrefab -> bulletPrefab
Speed -> speed
You should learn the conventions so your code is more clear for others but also for yourself.
Last tip, if your loop can predict it's end (in this case it's a triple shot so it's from 0 to 3 exclusive) then you should use a for() instead of while() loop.
I highly recommend you to check out some basic coding lessons/tutorials, it will save you from lot of issues in the future.
Some general suggestions here
First make your Inspector exposed field of the correct type right away
public Rigidbody2D bulletPrefab;
this way you ensure the referenced object actually has such a component and don't need GetComponent
later.
Then you create an array everytime you shoot.. rather have it persistent
private static readonly float[] offsets = {-15f,0f,15f};
then usually you would use a proper for
loop and iterate over the actual size of the array instead of using a while
for(var i = 0; i < offsets.Length; i++)
{
...
}
and finally you shouldn't go through transform
at all when using physics but only the Rigidbody2D
and do eg
void Shoot()
{
for(var i = 0; i < offsets.Length; i++)
{
var bullet = Instantiate(bulletPrefab, firePoint.position, firePoint.rotation * Quaternion.Euler(0, 0, offsets[i]));
rb.AddForce(Quaternion.Euler(0, 0, rb.rotation * Vector3.up * Speed, ForceMode2D.Impulse);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.