Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question How to make the turret rotate with the mouse/camera?

Discussion in 'Scripting' started by HansSchmulge, Aug 17, 2023.

  1. HansSchmulge

    HansSchmulge

    Joined:
    Nov 29, 2022
    Posts:
    7
    Hello.
    I'm trying to make the weapon turn in the direction the camera is facing on the y-axis.
    Car.png
    However, all the solutions I've found so far are either not mouse-related or affect axes other than the Y (which is why I can often see the underside of the gun).
    Can someone point me in which direction to think?
    Here is my code so far (not very useful, but better than nothing)
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class GunBehaviour : MonoBehaviour
    6. {
    7.     /*
    8.     For Rotation A
    9.     [SerializeField] private float rotationSpeed = 0.5f;
    10.     [SerializeField] private bool isStatic = false;
    11.     [SerializeField] private Camera mainCamera = null;
    12.     private Quaternion initialRotation;
    13.     private Vector2 turn;
    14.     */
    15.     private Transform cameraTransform;
    16.     public float rotationSpeed = 15f;
    17.     public float rotationDegree = 35f;
    18.     private Camera mainCamera;
    19.     void Start()
    20.     {
    21.         cameraTransform = Camera.main.transform;
    22.         mainCamera = Camera.main;
    23.     }
    24.     void Update()
    25.     {
    26.         //Rotation using keys. Just for testing.
    27.         if(Input.GetKey(KeyCode.Q))
    28.         {
    29.             transform.Rotate(0, rotationSpeed * rotationDegree * (-1) * Time.deltaTime, 0);
    30.         }
    31.         else if(Input.GetKey(KeyCode.E))
    32.         {
    33.             transform.Rotate(0, rotationSpeed * rotationDegree * Time.deltaTime, 0);
    34.         }
    35.     }
    36.  
    37.     void RotateTower()
    38.     {
    39.         /* Rotation A - Rotates not only on the Y axis
    40.         initialRotation = transform.rotation;
    41.  
    42.         Ray rayToWorld = mainCamera.ScreenPointToRay(Input.mousePosition);
    43.         rayToWorld.origin = transform.position;
    44.         Quaternion targetRotation = Quaternion.LookRotation(rayToWorld.direction);
    45.         if(!isStatic)
    46.         {
    47.             Quaternion currentRotation = transform.rotation;
    48.             float angularDifference = Quaternion.Angle(currentRotation, targetRotation);
    49.             if (angularDifference > 0)
    50.                 transform.rotation = Quaternion.Slerp(currentRotation, targetRotation,(rotationSpeed * 180 * Time.deltaTime) / angularDifference );
    51.             else
    52.                 transform.rotation = targetRotation;
    53.         }
    54.         */
    55.         /* Rotation B - Rotates along the Y axis, but relative to the camera position -> bugs when the car is on a hill
    56.          Quaternion rotation = Quaternion.Euler(0, cameraTransform.eulerAngles.y, 0);
    57.          transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
    58.         */
    59.     }
    60. }
    Thank you in advance :3
     
  2. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    Most situations like this, the camera.forward direction is used to correlate any aiming parameter. And as far as rotating, or setting a rotation is based off the mouse.screenPosition, or just values of the mouse inputs.

    It's been awhile since I've done any first person camera(no good saved snippets), but what you want is very similar to that. I'm sure you can find several "first person shooter" tutorials that can help in this regard.
     
    HansSchmulge likes this.
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    If that gun is a child within the car hierarchy, only rotate it via the .localRotation property of the transform.

    - track your own notion of angle
    - adjust it due to input
    - clamp it to limits (if applicable)
    - drive the appropriate local axis, such as:

    Code (csharp):
    1. gunTurretTranform.locatlRotation = Quaternion.Euler (0, gunBearingAngle, 0);
    Here's some more general reading on turrets and such:

    Turret aiming/rotating:

    https://forum.unity.com/threads/vector-lookat-unprecise.858511/#post-5658304
     
    HansSchmulge likes this.
  4. HansSchmulge

    HansSchmulge

    Joined:
    Nov 29, 2022
    Posts:
    7
    Update:
    I made it so that the gun only rotates on the Y axis, but the turret barrel only points to the center of the screen if the car is in the starting position or driving straight ahead. If you turn to the side, then the sight will be wrong.
    Code (CSharp):
    1.         if (!Input.GetMouseButton(1))
    2.         {
    3.             Ray rayToWorld = mainCamera.ScreenPointToRay(Input.mousePosition);
    4.             var aimAt = rayToWorld.direction;
    5.             Quaternion newRotation = Quaternion.LookRotation(aimAt - transform.localPosition);
    6.             newRotation.z = 0f;
    7.             newRotation.x = 0f;
    8.             transform.localRotation = Quaternion.Slerp(transform.localRotation, newRotation, Time.deltaTime * rotationSpeed);
    9.         }
     
  5. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    I found a snippet of my turret rotate code for a tower defense game:
    Code (CSharp):
    1. void TurretTurnTowards(Vector3 pos)
    2.     {
    3.         Transform rotator = turret;
    4.         Vector3 direction = pos - rotator.position;
    5.         //direction.y = 0; // needed if not aiming up/down
    6.         Quaternion targetRotation = Quaternion.LookRotation(direction, trans.up);
    7.         rotator.rotation = Quaternion.RotateTowards(rotator.rotation, targetRotation, turnSpeed);
    8.     }
    But it should be pretty similar to that, if I understand your question correctly. :)
     
  6. HansSchmulge

    HansSchmulge

    Joined:
    Nov 29, 2022
    Posts:
    7
    It's sad, but it doesn't work in my case:,(
     
  7. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    Then I would play around with
    Debug.DrawRay
    or
    Debug.DrawLine
    and check all your positions and directions. Seeing a visualization of what each Vector3, and direction is doing, is a great way to debug rotation style problems.

    Can't remember if they show in game view, but as long as Gizmos are turned on, you can see the lines in Scene view. Also best to change the colors of each line, so you know what is what.
     
    HansSchmulge likes this.