I'm making an arrow, I'm able to make it spin and rotate, but not at the same time. To rotate it (so that the tip points down) I've used this code:
transform.LookAt(transform.position + rigidbody.velocity);
Or this other one:
transform.forward = Vector3.Slerp(transform.forward, rigidbody.velocity.normalized, 10 * Time.deltaTime);
They both works in rotating the arrow toward the terrain.
To spin it I use this code:
transform.Rotate(Vector3.forward, rotatioSpeed * Time.deltaTime);
Unfortunately, if it rotates it doesn't spin, the spin code is placed after the rotation code but the arrow spin only if I comment out the latter.
I'm new to Unity, do you have any idea on how to make it rotate and spin at the same time independently?
A few things you can try
transform.Rotate(transform.forward, rotatioSpeed * Time.deltaTime, Space.World); // <--- transform.forward maybe?
What i would do though is put the arrow inside of a parent empty GameObject that way you can rotate the parent for the direction of the arrow, and then rotate the arrow itself around its own axis independently and that should work for you!
Related
When I try to rotate an object towards a point, it starts spinning, but I want it to be able to freely spin, while still rotating towards that point. I can't just clamp the y rotation, because obviously it's already rotating towards a point and setting the absolute y rotation while doing so and you can't access an object's relative angles in Unity. As seen here, the blue gizmo always faces the top of the sphere (the centre of the sphere is the point I'm rotating towards). I want it to be able to move freely.
Here's my rotation code:
Quaternion dir = Quaternion.LookRotation((target - transform.position).normalized) * Quaternion.Euler(new Vector3(-90, 0, 0));
transform.rotation = Quaternion.Slerp(transform.rotation, dir, smooth);
Does anyone know how to fix this?
I have a ball object in Unity 2D, this ball spawns at random positions on the screen and I want it to move in a 'straight-line depending on its direction e.g. if it's from the left it goes to the right or if it's from the top it goes to the bottom. I'm not sure if I should use transform.position/addforce/velocity to accomplish this and what direction I should use.
The following are what I have tried so far (I've tried using all directions)
ballRigidBody.AddForce(transform.up * speed);
ballRigidBody.velocity = Vector2.up * speed;
transform.position+=Vector2.up;
In Unity3D transform.forward is the go to variable when you want to move forward.
In Unity2D transform.right is the standard.
You can move your ball to its right with this code:
void Update()
{
GetComponent<Rigidbody2D>().velocity = transform.right * speed;
}
If you run this code the ball will always move into the direction of the red arrow.
You can see the arrows by selecting the move tool on the top left and then clicking on your ball inside the editor.
If you want to have your ball to always follow the green arrow you have to use transform.up.
transform.right and transform.up are both used relative to your object.
That means by changing the z rotation of your object you can modify the direction it should go in.
You can try out the following code to see your ball move to its right and rotate slowly on its z axis. This will cause the ball to move in a circle since it is still following the red arrow.
void Update()
{
GetComponent<Rigidbody2D>().velocity = transform.right * speed;
float speedRotate = 100;
transform.Rotate(Vector3.forward * speedRotate * Time.deltaTime);
}
When you always want to move an object to the right, no matter the rotation, you use Vector3.right instead of transform.right.
From your other comments I understand that you want your ball to always face into the direction in the middle of the screen. You can just rotate it to the middle of the screen when it spawns by using this code:
void Start()
{
transform.right = new Vector3(0, 0, 0) - transform.position;
}
This will get the ball to face the 0,0,0 position inside of your world. If 0,0,0 is in the middle of your screen it will face that direction. Otherwise you have to find out which coordinate your middle of your screen has.
I'm not sure what you're asking, but you can do ballRigidbody.velocity = transform.foward*speed, to make it go in the current direction it is facing.
If you want a ball you spawn on the left side of the screen to move to the right only, then set velocity like rb.velocity = Vector3.right * speed, and so on with each direction.
In this case, you should first check which position the ball spawned at (Top, Bottom, Left, Right), then from that decide the movement direction. If the ball spawns at the bottom, the direction to go up should be Vector3.up for example.
After you get the force, you can use rigidBody.AddForce(direction * speed); to move the ball.
This is a school project. I have a big cube which is like a planet. I have a small cube that can move on every side of the cube planet. The player moves forward automatically on its local z axis and I rotate it by 90 or -90 degrees to move left or right- but the player can control it like it's an up-down-left-right movement (made a script so they don't have to rotate the cube with 2 keys). It's like a Tron game so if I press the up key, I can't press down immediately because I leave a trail so I have to press the left or right keys. I have a problem with my camera movement. The camera follows the little cube from above, but I want it to lean a little when the little cube player gets close to the edge of a side so it lets me see the other side - where I'm planning to go.
I have a script where I use the center of the cube planet and the player's center as the direction vector and multiply it with the camera-player distance.
Vector3 direction = (target.position - center.position).normalized;
transform.position = target.position + direction * distance;
Then I point my camera's forward vector to the player cube's direction. I tried two codes but none of them worked perfectly. First I tried to rotate the camera with:
transform.rotation = Quaternion.LookRotation(-direction);
Shown in video. The problem with this is that since I don't tell the program the Up and Right vectors (I think), it sets them for itself to some random numbers so the camera sometimes do its own thing like it does a pirouette.
Next I tried this:
Quaternion rot = Quaternion.FromToRotation(transform.forward, -direction);
transform.Rotate(rot.eulerAngles, Space.World);
Shown in video. It's almost good but as the little cube moves, the camera starts steering slightly in the beginning and it gets worse and worse.
Do you have any ideas how can I make it work? I hope you understand what I would like to achieve. I'm trying to set the camera as to always show that when I press Up, my cube moves upward, when I press Right my cube always goes right etc. and when I reach the edge of my side the camera leans a bit towards the side I'm moving to.
Use dot product to find which orthogonal direction of your cube is closest to the camera's current up.
Vector3 closestToUp;
float greatestDot = 0f;
foreach (Vector3 dir in new Vector3[]{
target.forward, target.right, -target.forward, -target.right})
{
float curDot = Vector3.Dot(dir,transform.up);
if (curDot > greatestDot)
{
greatestDot = curDot;
closestToUp = dir;
}
}
Than, use that direction as the second parameter of Quaternion.LookRotation. This will keep its local up direction as aligned with the cube's "top" as possible given whatever new forward direction:
transform.rotation = Quaternion.LookRotation(-direction, closestToUp);
I'm Using Unity 2d and I made it so that the camera turned with the mouse in the x axis no problem. But I want the camera to only turn a small amount. The mouse needs to have full freedom to move but the camera needs to stop at a certain point.
I tried making an empty game object and set it so if the camera position equals that gameobject position the camera would move slightly back but that resulted in a lot if camera clipping. Also tried altering speed but of course that doesn't work. Does anyone know how I can do this without camera clipping?
Sorry for the lack of code as my computer has no interest access. Currently my code basically is:
transform.position = newvector3.Movetowards(
Input.GetAxisRaw("mouse X") * speed * Time.DeltaTime,
0f,
Input.GetAxisRaw("mouse Y") * 0 * Time.DeltaTime
);
That might be a bit inaccurate but that's the basic of it
To prevent clipping while using limited camera movement try something like this
transform.position = new vector 3(Mathf.Clamp(transform.position.x, MIN_X, MAX_X), 0, 0);
Of course replace MIN_X and MAX_X with the numbers of the minimum and maximum position you want the camera to be able to rotate to. This is off the top of my head so the code might not be 100 percent accurate. You can find Mathf.Clamp in the Unity docs if you're having trouble.
I have a very simple model for a plane that can move around in the x and y directions, while an ocean scrolls by to make it look as though the plane is flying. Whenever the plane moves, I adjust its roll and pitch.
I compute and maintain the position, roll and pitch, inside the object script. Every update step I re-assign them to the Unity properties of the object.
The problem comes where I tried to add a barrel-roll effect. This code works fine:
transform.Translate(position - transform.position);
Vector3 rotChange = new Vector3 (-pitch, 0, -roll) -
transform.rotation.eulerAngles;
transform.Rotate (rotChange);
So long as I'm keeping all the rotation within +- 30 degrees. When the plane is doing a barrel roll, it updates each step with the following:
velocity = new Vector3 (barrelRollDirections.x * barrelRollXSpeed,
barrelRollDirections.y * barrelRollYSpeed, 0);
roll += barrelRollTurnSpeed * Time.deltaTime;
if (roll < -(fullRotation/2)) {
roll += fullRotation;
}
if (roll > (fullRotation/2)) {
roll -= fullRotation;
}
The funny thing is that spinning the plane around actually works properly if the plane isn't moving along the x or y axis when I do it. But if it is, it jumps all over the place and only reappears in the proper final position once the roll is over.
I tried a number of ways to fix this problem:
-Convert my desired orientation to a quaternion using Quaternion.Euler and assigning that directly to transform.rotate. This didn't solve anything, and it also causes the plane to jitter and shake while at the bounds of its movement.
-Save the initial orientation of the plane in a quaternion, then, every update step, reassign that initial rotation to the plane and THEN call Transform.Rotate(new Vector3(-pitch,0,-roll)). I thought this would solve my problem if it was something like gimbal lock, since then I would just, every step, be applying rotations that were less than 180 degrees. But no dice.
EDIT: I found it! After asking this question, I figured I'd go work on different objects since I was waiting for an answer. There I discovered that the transform.Translate function moves objects in a different direction based on their rotation. When I changed to simply reassigning the position, it worked fine. As per usual, the act of talking to someone else helped to resolve the issue.