How do you shoot bullets at Mouses position - c#

I recently started developing my very first top down 2d game. My problem is not knowing exactly how to get the bullet to go where the mouse is facing at the time of the activation of the bullet. I have a face mouse function as seen here
void faceMouse()
{
Vector3 mousePosition = Input.mousePosition;
mousePosition = Camera.main.ScreenToWorldPoint(mousePosition);
Vector2 direction = new Vector2(
mousePosition.x - transform.position.x,
mousePosition.y - transform.position.y);
transform.up = direction;
}
However, I am not sure how to incorporate that if at all to be able to shoot at the location of my mouse. Thanks in advance!

You could try Quaternion.LookRotation() which creates a rotation based on a forward and upward vector (Documentation). Then you need to assing that rotation to your object. I use it something like this:
cursorPos = mainCamera.ScreenToWorldPoint(Input.mousePosition);
var forwardDirection = transform.position - cursorPos;
//Vector3.forward because is the z axis which is up/down in 2D
Quaternion playerRotation = Quaternion.LookRotation(forwardDirection, Vector3.forward);
transform.rotation = playerRotation;

Related

How do I make an object rotate based on another object?

I have a cog that the user can turn to rotate a drawbridge. Currently I have the cog and the drawbridge rotating at the same rate, like so: https://gyazo.com/14426947599095c30ace94a046e9ca21
Here is my current code:
[SerializeField] private Rigidbody2D thingToRotate;
void OnMouseDrag()
{
Vector3 mousePosition = Input.mousePosition;
mousePosition = Camera.main.ScreenToWorldPoint(mousePosition);
Vector2 direction = new Vector2(
mousePosition.x - transform.position.x,
mousePosition.y - transform.position.y
);
transform.right = direction;
thingToRotate.transform.up = transform.right;
}
I want it so that when the user turns the cog it only turns the object a little bit, so the user can turn the cog a few times before the drawbridges closes.
I've tried adding to the drawbridges euler angle. I've tried setting the drawbridges rotation to the cog rotation and dividing that rotation by 2.
Don't set fixed orientations but use the proper methods instead.
Mathf.SignedAngle to determine the angle difference between current transform.right and the direction
If using RigidBody2D use Rigidbody2D.MoveRotation instead of setting the rotation through the Transform component.
Then I would store the totalAngle that was rotated in order to e.g. invoke some event when enough rotation was done.
The thingToRotate you simply rotate only to totalAngle / factor.
// Adjust in the Inspector how often the cog thing has to be turned
// in order to make the thingToRotate perform a full 360° rotation
public float factor = 5f;
private float totalAngle = 0f;
[SerializeField] private Rigidbody2D thingToRotate;
private void OnMouseDrag()
{
var mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
// this is shorter ;)
Vector2 direction = (mousePosition - transform.position).normalized;
// get the angle difference you will move
var angle = Vector2.SignedAngle(transform.right, direction);
// rotate yourselve correctly
transform.Rotate(Vector3.forward * angle);
// add the rotated amount to the totalangle
totalAngle += angle;
// for rigidBodies rather use MoveRotation instead of setting values through
// the Transform component
thingToRotate.MoveRotation(totalAngle / factor);
}

Unity 3D - rotating gameobject without rotating axis

Hope my title summarises my problem. I have a rocket on a 2d game that only moves horizontally across the screen. I want it to rotate towards the players finger (the direction of movement), but cannot find a way to rotate the object without rotating the whole axis it moves on. I simply need it to seem like it has turned, but it should keep moving along the x. How can I go about this?
void Start () {
//scoreT = GetComponent<TextMeshProUGUI> ();
gameSpeed = 1;
score = 0;
Rigidbody2D rb2d = GetComponent<Rigidbody2D> ();
}
// Update is called once per frame
void Update () {
float MoveHorizontal = Input.GetAxis ("Horizontal");
Vector2 Movement = new Vector2 (MoveHorizontal, 0.0f);
rb2d.rotation = Quaternion.Euler (0.0f, 0, 0f, rb2d.velocity.x * -tilt);
transform.Translate (MoveHorizontal * speed, 0, 0);
One thing you can do is to modify rigidbody.rotation of your rocket rocket to make it tilt, when it moves, to one direction or to another. For example:
float tilt - 0.3f;
//In case you prefer the rotation in another axis you just need to modify the position of the rigidbody.velocity.x * -tilt
rigidbody.rotation = Quaternion.Euler (0.0f, 0.0f, rigidbody.velocity.x * -tilt);
Since you didn't add any code I am not sure how you are moving your rocket, so I will post a generic code you will need to adapt depending on your own project:
public class PlayerController : MonoBehaviour
{
public float speed;
//The tild factor
public float tilt;
//The limit within the spaceship can move
public Boundary boundary;
void FixedUpdate ()
{
//You will need to capture the screen touchs of the user for the inputs
float moveHorizontal = Input.GetAxis ("Horizontal");
float moveVertical = Input.GetAxis ("Vertical");
//Applying the movement to the GameObject
Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
rigidbody.velocity = movement * speed;
//To ensure the GameObject doesnt move outside of the game boundary
rigidbody.position = new Vector3
(
Mathf.Clamp (rigidbody.position.x, boundary.xMin, boundary.xMax),
0.0f,
Mathf.Clamp (rigidbody.position.z, boundary.zMin, boundary.zMax)
);
//Here is where you apply the rotation
rigidbody.rotation = Quaternion.Euler (0.0f, 0.0f, rigidbody.velocity.x * -tilt);
}
}
As an aside, you are doing a space 2D game you may be interested in checking this tutorial:
https://unity3d.com/learn/tutorials/s/space-shooter-tutorial
What you want is to move your object in global/world space. As it seems the movement of your rocket is currently happening within local space. So when you rotate the rocket it's local coordinates are rotated as well. The world space coordinates are fixed and will never rotate when you change your rocket.
Here is another explanation at that.
You can also have a look at Transform.localPosition and Transform.position and see how your rocket behaves when using one or the other.
You could make the sprite/renderer a child of the GameObject that is your rocket.
Then you can freely rotate the sprite/renderer around without changing the rotation you move the parent GameObject.
This is a hacky solution but it achieves the desired result.
You must move your object relative to the world and rotate locally.
So use Transform.position to move your object and Transform.LocalRotation to rotate it.
Or you can put the part that must rotate as a children of the object that translate, and rotate the children.

Player rotation and camera rotation

i want the player to look into the direction, the camera is looking.
The camera follows the player (3rd person game style).
I've tried it with
transform.localRotation = new Quaternion(transform.localRotation.x,
cameraMain.transform.localRotation.y,
transform.localRotation.z,
transform.localRotation.w);
but it doesn't work.
Sometimes the player starts rotating the other direction.
the following code will make the object (specified in the parameter) face in the direction of where the main camera is looking:
public void lookInDirectionOfCamera(Transform object) {
RayCastHit hit;
if (Physics.raycast(cameraMain.transform.position, cameraMain.transform.forward, out hit)) {
object.forward = hit.point - object.position;
}else { //if the raycast didnt hit anything, make the object face 100 units in front of the camera
Vector3 point = Camera.main.transform.position + Camera.main.transform.forward * 100;
object.forward = point - object.position;
}
}
This will make the player face the point that is forward to the camera. If you just want them to have the same rotation in the y-axis don't use Quaternions!
Instead, you can just do it with Euler angles:
transform.eulerAngles = new Vector3(transform.eulerAngles.x,
cameraMain.transform.eulerAngles.y,
transform.eulerAngles.y);
The reason not to use transform.localRotation is because that is a Quaternion. The y component in a Quaternion is not the same as the y-axis in a Euler angle (what you are used to seeing), Quaternions are very confusing so you should almost never set individual values in them. If you want to edit them only use the built-in methods.
Get the direction the camera is looking with cameraMain.transform.forward, make a copy with a y value of zero, then use Quaternion.SetLookRotation to look in that direction with the global up direction.:
Vector3 cameraDirection = cameraMain.transform.forward;
Vector3 characterLookDirection = new Vector3(cameraDirection.x,
0f,
cameraDirection.z);
Quaternion newRotation = new Quaternion();
newRotation.SetLookRotation(characterLookDirection, Vector3.up);
transform.rotation = newRotation;

Moving an object on the x axis based on relative position of mouse

I'm creating a 2D game in the Unity engine with C#. I have a player object that moves up on the y axis consistently, and i want to have the player steer it by dragging the cursor on the screen (think of swiping in mobile devices).
I've tried something already, but i have to drag all the way to the edge of my screen to get my player to the edge of the camera view. How do i improve the controls so the player follows the position of the mouse on the x axis?
Thanks.
if (moving == true)
{
Vector3 mouse Camera.main.ScreenToViewportPoint(Input.mousePosition);
transform.position = new Vector3(mouse.x, transform.position.y, 0);
}
You can start by creating a variable that stores the position on mouse click, and the position of the player.
Then move the player relative to the position.
This is what you could possible do: (This could be improved)
Vector3 mouseStartPosition;
Vector3 playerPosOnMouseClick;
if(Input.GetButtonDown(KeyCode.Mouse0){
mouseStartPosition = Camera.main.ScreenToViewportPoint(Input.mousePosition);
playerPosOnMouseClick = transform.position;
}
if (moving)
{
Vector3 currentMousePosition = Camera.main.ScreenToViewportPoint(Input.mousePosition);
Vector3 newPosition = playerPosOnMouseClick + (mouseStartPosition - currentMousePosition);
transform.position = new Vector3(newPosition.x, newPosition.y, 0);
}

Detect the corner of the gameobject

I have a script that can rotate an object by touch or mouse on it but I want to rotate the object when mouse goes over the corner of the object only. How can I do this?
The code I'm using is
private float baseAngle = 0.0f;
void OnMouseDown(){
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
pos = Input.mousePosition - pos;
baseAngle = Mathf.Atan2(pos.y, pos.x) * Mathf.Rad2Deg;
baseAngle -= Mathf.Atan2(transform.right.y, transform.right.x) *Mathf.Rad2Deg;
}
void OnMouseDrag(){
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
pos = Input.mousePosition - pos;
float ang = Mathf.Atan2(pos.y, pos.x) *Mathf.Rad2Deg - baseAngle;
transform.rotation = Quaternion.AngleAxis(ang, Vector3.forward);
}
Put invisible GameObjects or RectTransforms onto the corners of your object you want to rotate, and use them as the controls for the parent object.
One way of doing so would be to add colliders to the corners of your object.
Using OnCollisionStay(), you could then trigger the appropriate functions when the mouse button is pressed. I've done similar myself, and this way does work.
Another method to the madness:
You could raycast where you are clicking, if your raycast is within an appropriate distance to the corners (which you could calculate based on its dimensions) then permit the rotation on click.

Categories