I would like to have a Gameobject point to another only on the Local X-axis.
void FixedUpdate()
{
if(started){
Vector3 targetPosition = target.position;
Vector3 direction = Vector3.ProjectOnPlane(targetPosition - transform.position, transform.right);
Quaternion lookRot = Quaternion.LookRotation(direction, transform.right);
transform.rotation = Quaternion.RotateTowards(transform.rotation, lookRot, Time.fixedDeltaTime * 45);
}
On the y-axis it worked with transform.up instead of transform.right, but on the x-axis the Gameobject only rotates permanently around the z-axis.
You could do something like this:
Vector3 beforeRot = transform.eulerAngles;
transform.LookAt(gameObjectToLookAt.transform);
transform.localEulerAngles = new Vector3(transform.localEulerAngles.x, beforeRot.y, beforeRot.z);
This will take a record of the position before looking at the object.
Make it look at the object.
Reset rotation back to its original except the X rotation
Related
How to convert from direction and rotation around y-axis to Quaternion in Unity.
I want to rotate the object that is up-wards.
The object rotate certain direction and then rotate around an axis (object's local up-wards).
I implemented it as follows, and pressed the A button and the B button.
However, obj (button B) sometimes becomes a different quaternion (button A).
Why is this? Is there a solution?
if (Input.GetKeyUp(KeyCode.A)){
obj.transform.rotation = Quaternion.EulerAngles((float)Random.Range(0,359), (float)Random.Range(0,359), (float)Random.Range(0,359));
}
if (Input.GetKeyUp(KeyCode.B)){
// decomposition of vector and rotation around axis
Vector3 up_axis = new Vector3(0f, 1f, 0f);
Vector3 fwd = obj.transform.rotation * up_axis;
Quaternion q = obj.transform.rotation;
// create quaternion
Quaternion objective_rot_wo_w = Quaternion.FromToRotation(up_axis, fwd);
Quaternion diff = objective_rot_wo_w * Quaternion.Inverse(q);
diff.ToAngleAxis(out float _tmpAngle, out Vector3 _tmpAxis);
float around_y_angle = _tmpAngle;
// set
Quaternion rot = objective_rot_wo_w;
Quaternion rot_z = Quaternion.AngleAxis(around_y_angle, up_axis);
obj.transform.rotation = rot * rot_z;
}
Thank you for your cooperation.
I have been experimenting with trying to recreate a 3rd person character controller from a Brackeys tutorial, but using the new input system and rigid body physics.
The rotation works properly, but moving forward or back moves me forward compared to the camera, and moving left or right moves me backward.
The desired effect is changing the input should change my rotation to match the input direction relative to the camera and then move in the direction the player model is facing
Here is where I'm at:
private Vector3 GetMoveInput()
{
return new Vector3(_input.MoveInput.x, 0f, _input.MoveInput.y); //convert input Vector2 into a Vector3
}
private void PlayerMove()
{
if (_playerMoveInput.magnitude > 0.01f){ //only update rotation if player is moving
float targetAngle = Mathf.Atan2(_playerMoveInput.x, _playerMoveInput.z) * Mathf.Rad2Deg + _mainCamera.eulerAngles.y;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
//down here is where the problem lies I believe
_playerMoveInput = new Vector3(_playerMoveInput.x * _movementMultiplier * _rigidBody.mass,
_playerMoveInput.y,
_playerMoveInput.z * _movementMultiplier * _rigidBody.mass);
_rigidBody.AddRelativeForce(_playerMoveInput, ForceMode.Force);
}
}
I have tried setting y and z to 0f, multiplying by transform.forward, setting _playerMoveInput to transform.forward, and Quaternion.Euler(0f, angle, 0f) * transform.forward but no positive results.
I am trying to create a 3rd person movement script using Cinemachine as camera, I followed Brackeys "THIRD PERSON MOVEMENT in Unity" YouTube tutorial. I then Changed the base of it from character controller to rigidbody and the movement works perfectly fine. However my code sets the velocity of the rigidbody's y axis to 0 when I move the player which fights the gravity making the player jitter slowly to the ground when I move. The Character however does drop to the ground when the player stops moving. All I need is for the script to ignore the y axis and simply listen to unity's gravity.
void Update()
{
if (!photonView.isMine)
{
Destroy(GetComponentInChildren<Camera>().gameObject);
Destroy(GetComponentInChildren<Cinemachine.CinemachineFreeLook>().gameObject);
return;
}
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
isGrounded = Physics.CheckSphere(new Vector3(transform.position.x, transform.position.y - 1, transform.position.z), 0.01f, layerMask);
Vector3 inputVector = new Vector3(horizontal, 0f, vertical).normalized;
if (inputVector.magnitude >= 0.1f)
{
float targetAngle = Mathf.Atan2(inputVector.x, inputVector.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
rb.velocity = moveDir.normalized * speed;
}
if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
rb.AddForce(Vector3.up * jumpForce);
}
}
The player jitters because, in your movement section, you set the y velocity to 0, since Vector3.forward returns new Vector3(0, 0, 1) and you only rotate the vector around the y axis. Instead of this, consider doing:
Vector3 moveDir = new Vector3(transform.forward.x, rb.velocity.y, transform.forward.z);
This will preserve the velocity as it was, removing the jittering.
Note: transform.forward automatically gets the forward vector for the player.
I'm trying to make a cube to look at the mouse i found the following code:
RaycastHit hit;
if(Physics.Raycast(ray, out hit))
{
Vector3 targetPosition = new Vector3(hit.point.x, transform.position.y, hit.point.z);
Quaternion rotation = Quaternion.LookRotation(targetPosition - transform.position);
transform.rotation = Quaternion.Lerp(transform.rotation, rotation, Time.deltaTime * 10.0f);
}
I don't get it why did he subtract targetPosition from transform.position ?
Documentation LookRotation(Vector3 forward, Vector3 upwards = Vector3.up)
LookRotation transforms a direction vector into a Quaternion. In this example, he wants the angle between the two points. By subtracting the two position vectors, you can get the distance between the points and transform that distance vector into a Quaternion.
upwards is simply used as a reference. You can set it to anything you like, but if you leave it blank (as it is in this case) it will default to Vector3.up.
i have start a project in unity 3d.I want to make a spaceship that moving forward,but when i pressed the ArrowUp then i want to change its y postion to
( currentpos+ 1.5 ) but i want this smoothly.
this is my code
transform.position += transform.forward * Time.deltaTime * 10f;
if (Input.GetKey (KeyCode.UpArrow))
transform.position = new Vector3 (transform.position.x, 5f,
transform.position.z);
through the above code the Y position of object can b changed but it work so fast and i want to make it smooth.
so please help me.
I think the best solution to your problem is to use Mathf.SmoothDamp.
Example:
private float targetY = 0f;
private float verticalVelocity = 0f;
private const float smoothTime = 1f;
private void Update()
{
transform.position += transform.forward * Time.deltaTime * 10f;
if (Input.GetKey(KeyCode.UpArrow))
{
targetY = 5f;
}
float y = Mathf.SmoothDamp(transform.position.y, targetY, ref verticalVelocity, smoothTime);
transform.position = new Vector3 (transform.position.x, y, transform.position.z);
}
This example will smoothly change the y coordinate to 5 over the course of 1 second (you can change the smoothTime constant for a different time).
Based in your own code the easiest way for you to work it out could be something like this
//this sets the X position
transform.position += transform.forward * Time.deltaTime * 10f;
//if the button is pressed then modify Y
if (Input.GetKey (KeyCode.UpArrow))
transform.position += new Vector3 (0, 5f * Time.deltaTime * y_speed,0);
y_speed could be a public float y_speed = 1.0f in your script so you could modify it from the inspector to get the effect you want to achieve.
Hope it helps!
Assuming your spaceship is a rigidbody, you should take a look at Rigidbody.AddForce
https://docs.unity3d.com/ScriptReference/Rigidbody.AddForce.html
By working with forces, you can get a smooth movement in all directions very easily, and tweak it within the Rigidbody's parameters (like mass) without fiddling in the script again. It's part of the Unity physics model.
If you only want to move in y-direction, input a vector like (0,1,0) but you can also input the Transform.forward vector of your spaceship's Gameobject. That way, it will always move the direction it is facing in.