I'm building a topdown game with my main player rotating towards the mouse pointer but for some reason the player looks at the pointer from his right(his x axis) and i need need him to look from his Y.
I tried multiple ways and still the same as in i tried changing the vector from vector3 to vector2 but it will make things i don't need it to do, and i even tried using Quaternions.
void controlScheme()
{
if (Input.GetKey(KeyCode.W))
{
transform.Translate(Vector3.up * PlayerSpeed * Time.deltaTime,Space.World);
}
if (Input.GetKey(KeyCode.S))
{
transform.Translate(Vector3.down * PlayerSpeed * Time.deltaTime,Space.World);
}
if (Input.GetKey(KeyCode.A))
{
transform.Translate(Vector3.left * PlayerSpeed * Time.deltaTime,Space.World);
}
if (Input.GetKey(KeyCode.D))
{
transform.Translate(Vector3.right * PlayerSpeed * Time.deltaTime,Space.World);
}
transform.up = dir;*/
var dir = Input.mousePosition - Camera.main.WorldToScreenPoint(transform.position);
var angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
the only weird thing that there is no code the tell the engine to make the player rotate towards the mouse from the player's right side.
One solution is to find a vector you want the character to rotate "from" -- the direction of the sprite's "front" -- and where it should rotate "to" -- the direction from the character to the mouse position -- and then use transform.rotation.SetFromToRotation to set any rotation necessary to make that change:
Vector3 desiredDirection = Camera.main.WorldToScreenPoint(transform.position) - Input.mousePosition;
Vector3 startDirection = Vector3.up; // the vector direction of the character's
// "front" before any rotation is applied.
transform.rotation.SetFromToRotation(startDirection, desiredDirection);
Vector2 diff = Camera.main.ScreenToWorldPoint(Input.mousePosition) - this.transform.position;
float rot_z = Mathf.Atan2(diff.y, diff.x) * Mathf.Rad2Deg;
this.transform.rotation = Quaternion.Euler(0f, 0f, rot_z -90);
i found a way with code though still the character was looking at the mouse pointer from his right, i rotated him -90 degrees so it can look better again, my problem was a bit dumb but still there wasn't a proper way to fix this.
Thank you guys. :D
Related
this is my direction vector
new Vector3(target.transform.position.x - projectile.position.x, 0, target.transform.position.z - projectile.position.z).normalized
I tried multiplying it by Quaternion.AngleAxis(45, Vector3.up) but that simply doesn't work
All other orientations like Vector3.left, right, etc. don't help either
The only thing I could observe is the way that the angle changes when I move the target or projectile
You were close. Use cross product to get the axis you need, use that in AngleAxis, then finally apply that rotation to your starting direction:
Vector3 RotateTowardsUp(Vector3 start, float angle)
{
// if you know start will always be normalized, can skip this step
start.Normalize();
Vector3 axis = Vector3.Cross(start, Vector3.up);
// handle case where start is colinear with up
if (axis == Vector3.zero) axis = Vector3.right;
return Quaternion.AngleAxis(angle, axis) * start;
}
I have made a projectile shooting system. I want to shoot an object from position A to B following an indicated path. Everything is working fine except for one thing. The velocity applied on the object is calculated based on the distance between A and B, the value of time is 1 to travel this distance. Meaning that the farther I hit, the quicker it goes. I want to have control of the force applied. Meaning that it should go with my set speed whether I hit near or far. Tried normalizing the velocity and multiplied it by my custom force value, but then it moves away from its trajectory.
(See this link below, no matter how close or far we hit the object. It goes with the same speed while following the trajectory indicated. I want to develop this functionality.
https://play.google.com/store/apps/details?id=com.ghakilo.trickytrack)
Vector3 calculateVelocity(Vector3 target, Vector3 origin, float time)
{
Vector3 distance = target - origin;
Vector3 distanceXZ = distance;
distanceXZ.y = 0f;
float Sy = distance.y;
float Sxz = distanceXZ.magnitude;
float Vxz = Sxz / time;
float Vy = 0f;
Vy = Sy / time + 0.5f * Mathf.Abs(Physics.gravity.y) * time;
Vector3 result = distanceXZ.normalized;
result = result * Vxz;
result.y = Vy;
return result;
}
Physics time!
Velocity is a vector whose magnitude is speed.
If you want to fix the speed at which your projectile starts, that only leaves the direction of the velocity in your hands, so you need to calculate the direction in which you want to yeet your projectile.
If you're like me, you shoot straight at the target, so you'd set the direction vector to go from the origin to the target. Which is simply target - origin, or what you calculate as distance. I'm going to call this direction because that's what it really is being used for.
Now to use this as the direction vector for your velocity, convert distance to a unit vector (not sure how you do this in the unity framework, but direction.Normalize()?)
Then multiply this by the speed to get your velocity vector!
Vector3 calculateVelocity(Vector3 target, Vector3 origin, float speed)
{
Vector3 direction = target - origin;
direction.Normalize();
Vector3 result = direction * speed;
return result;
}
First add rigidbody to your bullet and set the gravity scale to .5
and add this code to your bullet prefab
Vector3 calculateVelocity(Transform target, Transform origin, float time)
{
Vector3 direction = target.transform.position - origin.transform.position;
float distance = Vector3.Distance(origin.transform.position, target.transform.position);
result = direction.normalized * distance * speed * Time.deltaTime;
return result;
}
//pew pew
Vector3 mousePosition = Input.mousePosition;
mousePosition = Camera.main.ScreenToWorldPoint(mousePosition);
Vector2 direction = new Vector2(mousePosition.x - transform.position.x, mousePosition.y - transform.position.y);
var rad = Math.Atan2(direction.y, direction.x);
var deg = rad * (180 / Math.PI);
Debug.Log(deg);
Instantiate(bulletprefab, firePoint.position, deg);
Hi! Basically, I am trying to shoot a bullet in the direction of the mouse, but cant find any answers I understand. I'm a beginner.
You are passing the single float value deg to Instantiate(Transform, Vector3, Quaternion) in
Instantiate(bulletprefab, firePoint.position, deg);
It expects a rotation Quaternion as third parameter here!
Since this is supposed to be in 2D it means you are searching for a rotation about deg degrees on the global Z axis. Now there are multiple ways of how to get that. You could e.g. use Quaternion.Euler
Instantiate(bulletprefab, firePoint.position, Quaternion.Euler(Vector3.forward * deg));
I'm currently creating a game involving a hover-bike. when the bike collides with something , it's angles change naturally. I wish to create some sort of way for it to tend back to 0. Here's what I've tried:
if (hoverbike.rotation.x != 0 || hoverbike.rotation.z != 0)
{
hoverbike.AddTorque(x: Mathf.MoveTowardsAngle(hoverbike.rotation.x, 0, 0.01f), y: hoverbike.rotation.y, z: Mathf.MoveTowardsAngle(hoverbike.rotation.z, 0, 0.01f));
}
transform.Rotate(0.0f, -Input.GetAxis("Mouse X") * 0.5f, 0.0f);
It's hard to explain what it's doing because I don't understand what it's doing, it just seems to spin out.
Here's the rest of my code if interested: https://pastebin.com/kzMDQMVF, it's a mess but I'm still learning how to use Unity.
Oh and angle y shouldn't tend to 0 because that's the horizontal angle.
You can determine the quaternion that would rotate the hovercraft from its current up to world up using Quaternion.FromToRotation:
Rigidbody hoverRB; // hovercraft's rigidbody
Quaternion deltaQuat = Quaternion.FromToRotation(hoverRB.transform.up, Vector3.up);
Then use Quaternion.ToAngleAxis to convert that to an angle & axis:
Vector3 axis;
float angle
deltaQuat.ToAngleAxis(out angle, out axis);
Then, cancel out some of any existing rotational velocity so that you'll eventually reach the goal:
float dampenFactor = 0.8f; // this value requires tuning
hoverRB.AddTorque(-hoverRB.angularVelocity * dampenFactor, ForceMode.Acceleration);
And then apply some torque along the axis we found before, scaled by how much angle remains:
float adjustFactor = 0.5f; // this value requires tuning
hoverRB.AddTorque(axis.normalized * angle * adjustFactor, ForceMode.Acceleration);
Any conversion between radians Rigidbody uses and degrees of ToAngleAxis is redundant with the float constants, so don't worry too much about it.
Make sure this is all being done in FixedUpdate (or a function called/running in FixedUpdate time) due to how the torque's direction will likely need to change from one physics step to another. So, altogether:
Rigidbody hoverRB; // hovercraft's rigidbody
...
void FixedUpdate()
{
Quaternion deltaQuat = Quaternion.FromToRotation(hoverRB.transform.up, Vector3.up);
Vector3 axis;
float angle
deltaQuat.ToAngleAxis(out angle, out axis);
float dampenFactor = 0.8f; // this value requires tuning
hoverRB.AddTorque(-hoverRB.angularVelocity * dampenFactor, ForceMode.Acceleration);
float adjustFactor = 0.5f; // this value requires tuning
hoverRB.AddTorque(axis.normalized * angle * adjustFactor, ForceMode.Acceleration);
}
I have steering wheel that is controlled by physical daydream controller(it works similar to wii controller). I use this code to do it:
void Update() {
transform.localRotation = GvrController.Orientation;
transform.localRotation = new Quaternion(0.0f, 0.0f, -transform.localRotation.y, transform.localRotation.w);
}
I need to mess with axis, beacause default position of the controller isn't good for a steering wheel.
But in 3-axis angle between maximum rotation to the left and to the right is 180 degrees. In this range everything is fine, but if I rotate a little bit more this values change to negative and everything is messed up. What can i do to allow the player to rotate only in this range(0 - 180 on z axis of 3-axis rotation)?
EDIT: The main problem is that the values of rotation after crossing 0 or 180 change to negative values, which are the same for both, but in different order. After crossing 0 it s form -1 to -180 and and for 180 its -180 to -1.
Firstly, we need a value that we can actually clamp. We'll get that from the eulerAngles.z field (as a typical onscreen wheel rotates about z - you might need to change that to some other field depending on the controller):
void Update() {
// Get the angle:
float angle = GvrController.Orientation.eulerAngles.z;
// The magic - clamp it:
if(angle < -180f){
angle = -180f;
}
else if(angle > 180f){
angle = 180f;
}
// Apply it as a new rotation:
transform.localRotation = Quaternion.Euler(0f,0f,angle);
}
Try this:
if (transform.eulerAngles.z > 180)
transform.eulerAngles = new Vector3(transform.eulerAngles.y, transform.eulerAngles.y, 180);
else if (transform.eulerAngles.z < 0)
transform.eulerAngles = new Vector3(transform.eulerAngles.y, transform.eulerAngles.y, 0);
If anyone wonders I found a solution, based on a script from Luke's answer. I realized that the values that change to negative are fine, only thing wrong with them is that they are negative. So this is the working script:
transform.localRotation = GvrController.Orientation;
float angle = -transform.localRotation.y;
if (angle < 0.0f) {
angle = Mathf.Abs(angle);
}
transform.localRotation = new Quaternion(0.0f, 0.0f, angle, transform.localRotation.w);
Try this:
If (transform.rotation > 180)
transforn.rotation = 180;