﻿using UnityEngine;

public class TankMover : MonoBehaviour
{
    [SerializeField] //это атрибут, чтобы в инспекторе видно было переменную
    private Vector3 _centerOfMass;
    [SerializeField]
    private float _power = 100f;
    [SerializeField]
    private float _maxSpeed = 10f;
    [SerializeField]
    private float _rotationSpeed = 10f;
    [SerializeField]
    private float _trackSpeed = 1f;
    [SerializeField]
    private MeshRenderer[] _trackMeshes;

    private Transform _selfTrans;
    private Rigidbody _mainRB;

    private Vector3 _inputDirection;

    private void Start()
    {
        _selfTrans = transform;
        _mainRB = GetComponent<Rigidbody>();
    }

    public void SetInput(Vector3 inputDirection)
    {
        _inputDirection = inputDirection;
    }

    private void Update()
    {
        _mainRB.centerOfMass = _centerOfMass; //смещать центр тяжести надо каждый кадр, иначе поворот башни резкий все испортит

        for (int i = 0; i < _trackMeshes.Length; i++) //двигаем гусеницы
        {
            var oldOffset = _trackMeshes[i].material.GetTextureOffset("_MainTex");
            oldOffset.x -= (Mathf.Abs(_inputDirection.x) + Mathf.Abs(_inputDirection.z)) * Time.deltaTime * _trackSpeed;
            _trackMeshes[i].material.SetTextureOffset("_MainTex", oldOffset);
        }

        if (Mathf.Abs(_inputDirection.x) > 0.1f || Mathf.Abs(_inputDirection.z) > 0.1f) //поворачиваем танк в нужном направлении
        {
            var oldRot = _selfTrans.eulerAngles;
            _selfTrans.LookAt(_selfTrans.position + _inputDirection);

            oldRot.y = Mathf.LerpAngle(oldRot.y, _selfTrans.eulerAngles.y, Time.deltaTime * _rotationSpeed);
            _selfTrans.eulerAngles = oldRot;
        }

        var speed = _selfTrans.InverseTransformDirection(_mainRB.velocity);
        var force = _inputDirection * _power;
        if (!IsFly() && Mathf.Abs(speed.z) < _maxSpeed && Mathf.Abs(speed.x) < _maxSpeed) //проверяем на превышение скорости и на то, что танк на земле
        {
            _mainRB.AddForce(force);
        }
    }

    private bool IsFly()
    {
        var colls = Physics.RaycastAll(_selfTrans.position + Vector3.up * 0.5f, Vector3.down, 1f, Physics.AllLayers, QueryTriggerInteraction.Ignore);
        for (int i = 0; i < colls.Length; i++)
        {
            var collTrans = colls[i].transform;
            if (!collTrans.IsChildOf(_selfTrans))
                return false;
        }
        return true;
    }
}
