CTIN 289 - Interactive Snippets Library

Powered by 🌱Roam Garden

Tank Turret

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


/*
 *  This class is responsible for rotating the tank turret to follow
 *  the player character, when the player character is visible and within
 *  the range specified by watchDistance.
 */
public class TankTurret : MonoBehaviour {

    [SerializeField]
    GameObject player;

    [SerializeField]
    float watchDistance;

    [SerializeField]
    float turretRotationSpeed;

    [SerializeField]
    LayerMask layerMask;

    Transform turret;


    void Start () {
        turret = transform.Find("turret");
    }
    
    void Update () {

        //To get a vector FROM this GO's position TO the player's position,
        //the pattern is
        //          TO - FROM
        Vector3 directionToPlayer = player.transform.position - transform.position;

        //BEWARE: Physics2D.Raycast returns a report about what happened, NOT an object
        //that the raycast hit. You will ALWAYS get back the report, even if the raycast
        //didn't hit anything.
        RaycastHit2D raycastHit2D;
        raycastHit2D = Physics2D.Raycast(
            gameObject.transform.position,
            directionToPlayer,
            watchDistance,
            layerMask
        );

        //Remember, normalizing a vector means that you keep its direction
        //but set its length to one.
        Vector3 dirToPlayerNormalized =
                      directionToPlayer.normalized;

        //Notice the arguments to DrawRay are subtly different from the arguments
        //to Physics2D.Raycast. See the documentation for details.
        Debug.DrawRay(
            gameObject.transform.position,
            dirToPlayerNormalized  *  watchDistance,
            Color.red
        );

        //REMEMBER! raycastHit2D will NEVER be null. So this is how to check
        //whether the raycast actually hit something.
        if (raycastHit2D.collider != null)
        {
            Debug.Log("Ray hit " + raycastHit2D.collider.name);
            if (raycastHit2D.collider.tag == "Player")
            {
                //It's not vital for this class, but this is the "proper" way to rotate
                //something in 2D. You may want to copy and paste this somewhere.

                //First, calculate the angle (here based on the direction to the player)
                float angle =
                  Mathf.Atan2(directionToPlayer.y, directionToPlayer.x)
                  * Mathf.Rad2Deg
                  - 90f;

                //Then use Quaternion.AngleAxis to rotate it around the z axis. Using
                //a quaternion to do rotation keeps the object from snapping weirdly
                //when it gets all the way back around to 360 degrees/0 degrees.

                //But you don't need to understand it, you can just copy and paste it
                //and it will work.
                turret.rotation = Quaternion.AngleAxis(
                                         angle,
                                         Vector3.forward
                                      );
            }
        } else
        {
            //Debug.Log("Ray didn't hit anything");
        }
    }
}