I have two cubes. One of them must rotate towards the other one all the time. The things is that the other cube always changes its position. Here is an image that explains what i need.
I tried to AddTorque to the direction between them but it did not work.
transform.GetComponent<Rigidbody>().AddTorque(transform.position - OtherCube.transform.position * 10f * Time.smoothDeltaTime);
Any help appreciated!
EDIT:
The rotating cube's face not always looking to other cube so it should rotate without looking to the other cube. (I meant it should rotate from closest face or edge or anywhere. does not matter).
You can use a cross product to find the axis you're interested in, taking into account the direction of the ground:
private Rigidbody rb;
void Start() { rb = GetComponent<Rigidbody>(); } // cache results of GetComponent
void TurnTowards()
{
Vector3 groundDirection = Vector3.down;
Vector3 towardsOther = (OtherCube.transform.position - transform.position).normalized;
Vector3 rotateAxis = Vector3.Cross(towardsOther, groundDirection);
float rotateMagnitude = 500f; // tune as necessary
rb.AddTorque(rotateMagnitude * Time.smoothDeltaTime * rotateAxis);
}
I think it is easier if you use an empty object as the father of the cube, freezing movement in the cube.
With that, you can make the parent just LookAt the other cube, and the cube just AddTorque on his X axis, the code will be simple like this:
private Transform parent;
private Rigidbody rb;
void Start() {
parent = transform.parent;
rb = GetComponent<Rigidbody>();
}
void Update()
{
Quaternion rot = transform.rotation;
parent.LookAt(otherCube.transform);
transform.rotation = rot;
rb.AddTorque(rotateMagnitude * parent.right);
}
Related
trying for 2 days to rotate a gun around a player in a 2d platfromer and i have 3 problems
1: the item or rotate uncontrolebly (my grammer isnt the best my mother language isnt even latin base)
around the player even if i dont move my mouse .or its rotate on its self like a wheel.
2:its seems phisycs some how work on the gun even though its dosnt has a rigibid body. givin in rb on kinimatic halped but not fully.
3: its rotate way to quickly . little movment will cause it to fly
4(bonus) the sqauer module i gave it strach and band in a really weird way.
heres the code:your text
[SerializeField] float fireRate = 0.3f;
[SerializeField] float rocketSpeed = 20f;
[SerializeField] GameObject rocketType;
[SerializeField] Transform firePoint;
Player player;
Vector3 mousePos;
Camera mainCam;
void Start()
{
player = FindObjectOfType<Player>();
mainCam = FindObjectOfType<Camera>().GetComponent<Camera>();
}
// Update is called once per frame
void Update()
{
mousePos = mainCam.ScreenToWorldPoint(Input.mousePosition);
}
private void FixedUpdate()
{
Vector3 aimDirection = mousePos - transform.position;
float aimAngle = Mathf.Atan2(aimDirection.y, aimDirection.x) * Mathf.Rad2Deg ;
// Quaternion rotation = Quaternion.AngleAxis(aimAngle, Vector3.forward);
// transform.rotation = rotation;
transform.rotation = Quaternion.Euler(0, 0, aimAngle);
// transform.RotateAround(player.transform.position, Vector3.forward, aimAngle);
}
here a picture of the componets:
enter image description here
wanted a gun obj to rotate around my charcter whan its move or still, wanted to shoot stuff while i jump.
Mathf.Atan2 returns the value in Radians, but Quaternion.Euler uses Degrees. You'll have to multiply the value by Mathf.Rad2Deg first.
It also sounds like the parent of the gun has a rigidbody which is causing it to Rotate. Remove the rigidbody you put on the gun and toggle on "Freeze Rotation" on the parent's rigidbody.
using UnityEngine;
public class ThirdPersonMovement : MonoBehaviour
{
Rigidbody rb;
private Animator animator;
public float speed = 5f;
void Start() {
animator = GetComponent<Animator>();
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
//Get player input based on world space.
float playerHorizontalInput = Input.GetAxisRaw("Horizontal");
float playerVerticalInput = Input.GetAxisRaw("Vertical");
//Get camera-normalized directional vectors
Vector3 forward = Camera.main.transform.forward;
Vector3 right = Camera.main.transform.right;
//Create direction-relative input vectors
Vector3 forwardRelativeVerticalInput = playerVerticalInput * forward;
Vector3 rightRelativeHorizontalInput = playerHorizontalInput * right;
Vector3 cameraRelativeMovement = forwardRelativeVerticalInput + rightRelativeHorizontalInput;
Vector3 movement = cameraRelativeMovement * speed * Time.deltaTime;
rb.MovePosition(transform.position + movement);
transform.forward = cameraRelativeMovement;
if (cameraRelativeMovement != Vector3.zero)
{
animator.SetBool("IsMoving", true);
}
else {
animator.SetBool("IsMoving", false);
}
}
}
I know similar questions have been posted before but I haven't been able to find a solution to what I'm experiencing.
I have the code above and it is linked to a character with a rigidbody component and 'is kinematic' checked. When I try to move, the character doesn't move for ages and then randomly jumps forward a random distance and doesn't do it again until I hit W again.
This has worked before when I used transform.Translate but obviously my character ran through the floor when the camera pointed down so I was trying to fix the issue.
A few things I notice about your code. You said this method used to work with transform.translate but not anymore, this tells me that your movement vectors are probably fine up until the point you changed them for this implementation (my guess is everything is the same except when you added tranform.position to your vector, since the function doesn't take speed, it takes position). You could try testing tranform.position + movement or just movement with a Debug.Log() statement, but that's probably not your issue.
Since you said this issue only started when you changed the function you use to move the player, I would try just inputting a non-changing Vector3 into the movement function: rb.movePosition(tranform.position + new Vector3(1,0,0)); or something like that, just to see if the movement function is even working.
I have the following script which should make the main camera follow and rotate with the player's movements.
public class FollowPlayer : MonoBehaviour
{
[SerializeField]
float mouseSensitivity;
public Vector3 cameraOffset;
public Transform Player;
public Transform mainCamera;
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
cameraOffset = transform.position - Player.transform.position;
}
void Update()
{
Rotate();
}
private void Rotate()
{
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
Player.Rotate(Vector3.up, mouseX);
mainCamera.Rotate(Vector3.up, mouseX); //shows abnormal rotation (hides the player as well)
}
private void LateUpdate()
{
Vector3 newPosition = Player.position + cameraOffset;
transform.position = newPosition;
}
}
The camera follows the player, however, but it does not rotate with the player's rotations. Please note that making the main camera the child of the player is not an option here, since I have to use this script on multiplayer. I want the mouse to be able to rotate both the main camera and the player at the same time.
The reason the camera is not rotating, is that you capture the initial offset on start, which is expressed in absolute (world space) position. This can be easily fixed using transform.TransformPoint method. What you then need to do is address camera rotation. In the simplest case you can just use 'LookAt' method
private void LateUpdate()
{
Vector3 newPosition = Player.position + Player.TransformPoint(cameraOffset);
mainCamera.position = newPosition;
mainCamera.LookAt(Player.position, Vector3.up);
}
I also noticed that you use transform.position (a transform from the object your script is attached to) but then you also use mainCamera transform as a seperate transform, mixing it like that might lead to confusion later. You should either always access the camera via mainCamera reference, or you could always keep the script attached to the camera and use transform reference.
I also noticed that you use one script to do two seperate things, it controls both player rotation and camera position/rotation while following the player. While there is nothing stoping you from doing that, its often a good idea to split it into doing two things each doing one logical thing
I currently am working on a game where I am using click to move in Unity. When I click on a spot on the map, I set that mouse's click to the destination and then use the rigidBody on the gameobject to move it using RigidBody.MovePosition(). When I do this, I am getting a lot of flicker when the gameobject reaches its destination. Any assistance is appreciated. Thanks.
// COMPONENTS
Rigidbody rigidBody;
// MOVEMENT
Vector3 destination;
Vector3 direction;
// Use this for initialization
void Start()
{
rigidBody = GetComponent<Rigidbody>();
destination = transform.position;
}
// Update is called once per frame
void Update()
{
DetectInput();
}
void FixedUpdate()
{
MoveControlledPlayer();
}
void MoveControlledPlayer()
{
transform.LookAt(destination);
Vector3 direction = (destination - transform.position).normalized;
rigidBody.MovePosition(transform.position + direction * 5 * Time.deltaTime);
}
void DetectInput()
{
if (Input.GetMouseButton(0))
{
SetDestination();
}
}
void SetDestination()
{
if (!EventSystem.current.IsPointerOverGameObject())
{
Plane field = new Plane(Vector3.up, transform.position);
Ray ray;
float point = 0;
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (field.Raycast(ray, out point))
destination = ray.GetPoint(point);
}
}
I do these kind of movements with temporary joints. They are extremely accurate / configurable / embeddable.
In 2D I use a DistanceJoint2D to control distance between rigidbody points, or between a body and a world point. In 3D you could use SpringJoint or ConfigurableJoint.
Then just tween the distance basically the same way you do per frame moving now (on FixedUpdate).
Reaching a point when using a velocity-based behavior is really hard, and often results in flickering: that's because the object is always passing over his destination.
A way to fix it is to stop the movement when the object is close enought to the target.
I am new to Unity trying to make my first game (a Third Person Shooter).
It's been now more than a week that I've tried again and again to get my character moving using a rigidbody component and NOT the Character Controller or the simple transform.Translate.
I have had about 30 web pages opened since a week browsing topics about it but I haven't found anything (almost made me feel like I am trying to do something impossible lol...).
So, I want to move my character just like in Splinter Cell Blacklist, and to have the camera with the crosshair controlled by the mouse (if I shoot, the character would rotate if not facing the target and then shoot).
For the movement, if it is not possible with the rigidbody then I'll use one of the others, it's just that I love the real feeling that the rigidbody has.
If there's even a tutorial that break it down to really understand, that would be great or just some code with comments (I have a C# background).
float moveSpeed = 6f; // Player's speed when walking.
float rotationSpeed = 6f;
float jumpHeight = 10f; // How high Player jumps
Vector3 moveDirection;
Rigidbody rb;
// Using the Awake function to set the references
void Awake()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
Move();
}
void Move ()
{
float hAxis = Input.GetAxis("Horizontal");
float vAxis = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(hAxis, 0f, vAxis);
rb.position += movement * moveSpeed * Time.deltaTime;
}
My idea.
If you want the real feel, you need the rigidbody.addforce to your character at the proper part of the character body. Not the rigidbody.position.
Hope help.