Search code examples
c#unity-game-enginerotationquaternionsdirection

Rotate rigidbody with moverotation in the direction of the camera


I want to use moverotation to rotate the object in the direction of the Main Camera, like a common third person shooter, but I don't know how to set the quaternion values or otherwise

`using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class movimento : MonoBehaviour
{

   [SerializeField] float walk = 1;
   [SerializeField] float run = 2;
    Vector3 movement = Vector3.zero;
    private Rigidbody rig;

    // Start is called before the first frame update
    void Start()
    {
      rig = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.LeftShift)) walk = (walk + run);
        if (Input.GetKeyUp(KeyCode.LeftShift)) walk = (walk - run);

        float Horizontal = Input.GetAxis("Horizontal");.
        float Vertical = Input.GetAxis("Vertical");
        movement = Camera.main.transform.forward * Vertical + Camera.main.transform.right * Horizontal;
        float origMagnitude = movement.magnitude;
        movement.y = 0f;
        movement = movement.normalized * origMagnitude;

    }

     private void FixedUpdate ()
    {
        rig.MovePosition(rig.position + movement * walk * Time.fixedDeltaTime);
        Quaternion rotation = Quaternion.Euler(???);
        rig.MoveRotation(rig.rotation * rotation);


    }
  }`

Solution

  • i use a coroutine to do smooth rotation. I use Quaternion.LookRotation for the job.

    so you indicate the position of object to look at and the duration of animation. Here you want to rotate face to the main camera

    StartCoroutine(SmoothRotation(Camera.main.transform, 3f));
    :
    :
    
    IEnumerator SmoothRotation(Transform target, float duration)
    {
        float currentDelta = 0;
        var startrotation = transform.rotation;//use your rigisbody if you want here i use the gameobject
        var LookPos = target.position - transform.position;
        var finalrot = Quaternion.LookRotation(LookPos);
    
    
        while (currentDelta <= 1f)
        {
            currentDelta += Time.deltaTime / duration;
            transform.rotation = Quaternion.Lerp(startrotation, finalrot, currentDelta);//
            yield return null;
        }
    
        transform.rotation = finalrot;
    }
    

    if you want to see (in scene when running) where your camera points just add this line of code in update():

        Debug.DrawRay(Camera.main.transform.position, Camera.main.transform.TransformDirection(Vector3.forward) * 10f, Color.black);
    

    if you want to point in same direction tha nthe Camera just change the line of finalrot in SmoothRotation Method:

    var finalrot = Camera.main.transform.rotation;
    

    you dont need to calculate the LookPos

    for your problem of crazy rotation, i suggest you to reset rotation x and z

    direction = hit.transform.position - transform.position;
    Quaternion rotation = Quaternion.LookRotation(direction);
    rotation.x = 0f;
    rotation.z = 0f;
    

    a tips to detect object what you want with the raycast inside spere : Physics.OverlapSphere: you could select what you want to cast when using the optional parameter layermask

    private void DetectEnemy(Vector3 center, float radius)
    {
    
        var hitColliders = Physics.OverlapSphere(center, radius );
    
        for (var i = 0; i < hitColliders.Length; i++)
        {
            print(hitColliders[i].name + "," + hitColliders[i].transform.position);
            // collect information on the hits here
        }
    }