Shooting with a shotgun 2D Top-down Shooter - c#

I'm trying to make shooting with a shotgun, I have already made shooting with one bullet. Code:
Vector2 shootingDirection = new Vector2(joystick.Horizontal, joystick.Vertical);
shootingDirection.Normalize();
if (shootingDirection != new Vector2(0, 0))
{
if(isShotGun) ShotGunShoot(shootingDirection);
GameObject bullet = Instantiate(bulletPrefab, crossHair.transform.position, Quaternion.identity);
bullet.transform.Rotate(0.0f, 0.0f, Mathf.Atan2(shootingDirection.y, shootingDirection.x) * Mathf.Rad2Deg);
bullet.GetComponent<Rigidbody2D>().AddForce(shootingDirection * 10f, ForceMode2D.Impulse);
}
}
But I'm just trying to create two other bullets with a slight deviation from the main one, so that it looks like a fraction, but it does not work correctly. Code:
private void ShotGunShoot(Vector2 dir)
{
GameObject shotGun = Instantiate(bulletPrefab, crossHair.transform.position, Quaternion.identity);
shotGun.transform.Rotate(0.0f, 0.0f, Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg - 30f);
shotGun.GetComponent<Rigidbody2D>().AddForce((dir + new Vector2(-.3f, 0f)) * 10f, ForceMode2D.Impulse);
shotGun = Instantiate(bulletPrefab, crossHair.transform.position, Quaternion.identity);
shotGun.transform.Rotate(0.0f, 0.0f, Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg + 30f);
shotGun.GetComponent<Rigidbody2D>().AddForce((dir+ new Vector2(.3f, 0f)) * 10f, ForceMode2D.Impulse);
}
As it should be
Here it is now
Thanks for help!

For the rotation. You can simply set the direction (from your image I can see that your bullet has to fly towards its right vector) like e.g.
shotgun.transform.right = dir;
shotgun.transform.Rotate(0, 0, 30);
For the add force: This uses world space directions.
You always pass in the direction and add the additional offset in world space. So that additional offset goes always in X axis direction regardless in which direction you shoot.
Rather take the direction into account by using the local force Rigidbody.AddRelativeForce
shotGun.GetComponent<Rigidbody2D>().AddForceRelative((shotgun.transform.right + new Vector2(0f, 0.3f)).normalized * 10f, ForceMode2D.Impulse);
This now uses the bullets right direction and additionally uses an offset of 0.3 along its local Y axis.
Btw: If you give your prefab the correct type
public Rigidbody bulletPrefab;
you can skip the GetComponent<Rigidbody> calls.

Related

How can I rotate 20 degrees off of a Vector2 direction in unity2d?

I'm trying to cast a ray on Vector2.right and another ray on either side of it by 20 degrees.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PathFinding : MonoBehaviour
{
public float speed = 5f;
// Update is called once per frame
private void Update()
{
//replace target.position with Camera.main.ScreenToWorldPoint(Input.mousePosition) to follow mouse pointer
Vector2 direction = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
Quaternion rotation = Quaternion.AngleAxis(angle, Vector3.forward);
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, speed * Time.deltaTime);
if (Input.GetKey(KeyCode.Space))
{
Debug.DrawRay(transform.position, transform.TransformDirection(Vector2.right) * 10f, Color.green);
RaycastHit2D front = Physics2D.Raycast(transform.position, transform.TransformDirection(Vector2.right), 10f);
if (front)
{
Debug.Log("Hit Something : " + front.collider.name);
//hit.transform.GetComponent<SpriteRenderer>().color = Color.red;
Debug.DrawRay(transform.position, transform.TransformDirection(Vector2.right) * 10f, Color.red);
}
RaycastHit2D left1 = Physics2D.Raycast(transform.position, transform.Rotate_Direction(Vector2.right), 10f);
}
}
}
It's just in the last line of code that I'm having a hard time. I want to add a slight rotation to the transform.Rotate_direction(Vector2.right) bit.
I'm pretty new to programming and especially to this here so if you could explain what you do and maybe show me how to implement it that would be greatly appreciated.
Thanks in advance.
By multiplying the Quaternion behind the vector you can change its direction. In your question, you need to use Quaternion.AngleAxis.
Quaternion.AngleAxis(20f, Vector3.forward) * Vector2.right

How to rotate a game object in runtime in unity

How can I rotate something in unity in runtime?
I tried:
transform.rotation = Quaternion.Euler(new Vector3(x,y,z));
,
transform.Rotate(x,y,z);
,
transform.eulerAngles = new Vector3(x,y,z)
Nothing I tried worked.
transform.Rotate (new Vector3 (0, 0, 45) * Time.deltaTime);
Visit this site, it will help you https://learn.unity.com/tutorial/collectable-objects#
sorry if I am wrong
To rotate a GameObject in Unity, the best way is using the Rotate function:
public float speed = 20f
public void Update()
{
transform.Rotate(Vector3.right * speed * Time.deltaTime);
}
With this code, your GameObject will rotate to the right, you can use Vector3.up or Vector3.forward.
If you only want to set a new rotation for your GameObject, change the localEulerAngles of the transform component:
transform.localEulerAngles = new Vector3(x, y, z);
If you want to rotate to a certain position, I recommend using:
transform.rotation = Quaternion.Euler(Vector3.forward * degrees);

What is difference between Transform Rotate and forward Rotate?

I want rotated 'transform.forward' with not rotate transform.
but have problem result of 'rot * tf.forward'
I have to make a lot of rotate transform.forward.
I know transform.Rotate is high cost.
Why are those different?
Transform tf = transform;
Quaternion rot = Quaternion.Euler(90f, 0f, 0f);
Vector3 eulerRot1 = rot * tf.forward * Mathf.Rad2Deg;
tf.roration *= rot;
Vector3 eulerRot2 = tf.forward * Mathf.Rad2Deg;
if(eulerRot1 == eulerRot2)
{
Debug.Log("Same");
}
else
{
Debug.Log("Not same");
}
tf.forward does not rotate your gameobject forward. tf.forward is a vector point forward relative to your game object.
transform.Rotate is not high cost, moving your game object directly via it's transform is never expensive. Moving it with it's physics component is expensive

Unity: How to apply rotation on object's velocity?

I am making top-down shooter on Unity and I need to implement shotgun, which will release 5 rounds at a time, each next will have rotation 10 degrees less than previous (from 20 to -20 in total). Instantiating the bullet on firepoint, the velocity is applied to it by bullet script, attached to bullet prefab. I apply the rotation in instantiating method too, but the bullet just rotates around itself, not to direction it flying.
Shooting code:
Vector2 mouseScreenPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 direction = (mouseScreenPosition - (Vector2) transform.position).normalized;
transform.up = direction;
GameObject newBullet1 = Instantiate(bullet, firePoint.position, Quaternion.Euler(0f, 0f, 20f)) as GameObject;
newBullet1.GetComponent<Bullet>().direction = direction;
GameObject newBullet2 = Instantiate(bullet, firePoint.position, Quaternion.Euler(0f, 0f, 10f)) as GameObject;
newBullet2.GetComponent<Bullet>().direction = direction;
Bullet code:
public Vector3 direction;
public float bulletSpeed;
void Update () {
GetComponent<Rigidbody2D>().velocity = new Vector3 (direction.x, direction.y, transform.position.z) * bulletSpeed;
}
You need to apply the rotation to the direction vector for each bullet. Formula for the rotation of a vector is...
x1 = x0*cos(angle) - y0*sin(angle);
y1 = x0*sin(angle) + y0*cos(angle);
Vector2 direction10 = new Vector2(direction.x*Mathf.cos(10*Mathf.Deg2Rad) - direction.y*Mathf.sin(10*Mathf.Deg2Rad), direction.x*Mathf.sin(10*Mathf.Deg2Rad) + direction.y*Mathf.cos(10*Mathf.Deg2Rad));
Vector2 direction20 = new Vector2(direction.x*Mathf.cos(20*Mathf.Deg2Rad) - direction.y*Mathf.sin(20*Mathf.Deg2Rad), direction.x*Mathf.sin(20*Mathf.Deg2Rad) + direction.y*Mathf.cos(20*Mathf.Deg2Rad));
newBullet2.GetComponent<Bullet>().direction = direction10;
newBullet3.GetComponent<Bullet>().direction = direction20;
... //etc
Can probably do this cleaner with a loop.

Restrict rotation of 3d model in Unity 3d

I want to rotate my 3d model based on player touch on x and y direction.
So that I am detecting horizontal and vertical touch.
But in this I want to restrict z direction rotation. For this I tried multiple codes and ask suggestions in other forums too. At present no suggestion is working for me.
Basically, I don't want z direction rotation. Following image give you more idea, where things going wrong. Model rotated completely into z direction. I want to stop this.
Here is my multiple tries to achieve same thing.
void Update ()
{
// If there are two touches on the device...
if (Input.touchCount == 1 && GameManager.Instance.IsGameStart) {
// Store currnet touch.
Touch touch = Input.GetTouch (0);
// transform.RotateAround (transform.position, Vector3.up, - touch.deltaPosition.x Time.deltaTime 15f);
// transform.RotateAround (transform.position, Vector3.right, touch.deltaPosition.y Time.deltaTime 15f);
// transform.RotateAround (transform.position, Vector3.forward, 0f);
// transform.Rotate (Vector3.up, -touch.deltaPosition.x Time.deltaTime 10f, Space.World);
// transform.Rotate (Vector3.right, touch.deltaPosition.y Time.deltaTime 5f, Space.World);
// transform.Rotate (Vector3.forward, 0f, Space.World);
myRigidbody.MoveRotation (myRigidbody.rotation Quaternion.Euler (Vector3.right touch.deltaPosition.y Time.deltaTime 5f));
myRigidbody.MoveRotation (myRigidbody.rotation Quaternion.Euler (Vector3.up -touch.deltaPosition.x Time.deltaTime 10f));
}
}
In above each block represent unique effort to restrict z direction.
Now please give me some suggestion to achieve same thing.
As well my discussion running at Unity forum
Touch based rotation of 3d model
EDIT: I have tried with restricting rigidbody in z rotation. So my inspector look something like this.
EDIT : After discussion on game development chat room. I have following kind of code :
float prevZ = transform.eulerAngles.z;
transform.Rotate (Vector3.up, -touch.deltaPosition.x Time.deltaTime 10f, Space.World);
transform.Rotate (Vector3.right, touch.deltaPosition.y Time.deltaTime 5f, Space.World);
Vector3 modelVec = transform.eulerAngles;
modelVec.z = prevZ;
transform.eulerAngles = modelVec;
I am just near to solution but now my golf globe model can't able to move more that 180 degree from top or bottom side drag. I just reach around 180 degree and it gets just rotated towards any other direction.
Ok after your comments, it sounds like you may need to start fresh.
Based on what I understand, try this out:
Vector3 rotation = new Vector3();
rotation.y = -touch.deltaPosition.x * Time.deltaTime * yRotSpeed;
rotation.x = touch.deltaPosition.y * Time.deltaTime * xRotSpeed;
rotation.z = 0;
transform.Rotate(rotation);
and then I'd suggest adding:
public float yRotSpeed;
public float xRotSpeed;
as fields of your script so that you can adjust the rotating speed within the unity engine in the future.
Just do like this.
// private variables
private Vector3 inputRotation; // difference of input mouse pos and screen mid point
private Vector3 mouseinput;
// Update is called once per frame
void Update() {
FindPlayerInput();
}
void FindPlayerInput()
{
mouseinput = Input.mousePosition;
mouseinput.z = 0; // for no rotation in z direction
inputRotation = mouseinput - new Vector3(Screen.width * 0.5f, Screen.height * 0.5f,0);
ProcessMovement();
}
void ProcessMovement(){
transform.rotation = Quaternion.LookRotation(inputRotation);
}

Categories

Resources