Hark-the-Moon-Men-Cometh / Assets / Scripts / Creatures / Enemy_Rifle.cs
Enemy_Rifle.cs
Raw
using System.Collections.Generic;
using UnityEngine;

public class Enemy_Rifle : Enemy, IDamageSource
{
    public List<GameObject> i_sources { get => m_sources; 
        set => m_sources = value; }
    public float i_damage { get => m_damage; set => m_damage = value; }

    //needs to be able to track the player
    public PlayerAvatar r_player;

    [SerializeField]
    private List<GameObject> m_sources;
    [SerializeField]
    private float m_damage;

    //These are for controlling how good a shot the enemy is
    public float m_turnSpeed;
    [Range(0f,45f)]
    public float m_innacuracyDegrees;
    public Vector3 m_aimPointOffset;
    
    //Draws laser beam, temporary
    public LineRenderer r_renderer;
    public float m_beamTTL;

    protected override void Start()
    {
        r_renderer.enabled = false;
        r_player = FindAnyObjectByType<PlayerAvatar>();
    }

    //Makes enemy turn to face the player, with max turn speed
    private void Look()
    {        
        Vector3 facing = transform.TransformDirection(Vector3.forward);
        Vector3 directionToPlayer = r_player.transform.position 
            - transform.position;
        float dy = Vector3.SignedAngle(facing, directionToPlayer, Vector3.up);
        dy *= m_turnSpeed * Time.deltaTime;
        transform.Rotate(0f, dy, 0f);
    }

    protected override void HandleWeapon()
    {
        if (m_attackTimer >= m_attackPeriod)
        {
            m_attackTimer = 0f;
            Attack();
        }
        m_attackTimer += Time.deltaTime;
    }

    //Enemy fires weapon in player's direction, with a random change in angle 
    //to simulate innacuracy
    //TODO: Tidy all this up
    protected override void Attack()
    {        
        Vector3 origin = transform.position + m_aimPointOffset;
        Vector3 facing = (r_player.transform.position
            - new Vector3(0f, r_player.transform.lossyScale.y / 2))
            - transform.position;
        facing = GetInaccuracyRotation() * facing;
        RaycastHit hit;
        /*bug.DrawRay(origin, facing * 100, 
            Random.ColorHSV(0f, 1f, 1f, 1f, 0.5f, 1f), 0.1f);*/
        Vector3 laserEndPoint = facing * 100;
        LayerMask layerMask = ~LayerMask.GetMask(new string[] { "Enemy" });
        if (Physics.Raycast(origin, facing, out hit, Mathf.Infinity,
            layerMask))
        {
            laserEndPoint = hit.point;
            IHarmable harmable = 
                hit.collider.gameObject.GetComponent<IHarmable>();
            if (harmable != null)
            {
                InflictDamage(harmable);
            }
        }
        r_renderer.SetPosition(0, origin);
        r_renderer.SetPosition(1, laserEndPoint);
        r_renderer.enabled = true;        
        if (m_attackTimer >= m_beamTTL)
        {
            r_renderer.enabled = false;
        }        
    }

    private Quaternion GetInaccuracyRotation()
    {
        float r = Random.Range(-1f, 1f);
        float rotX = (Mathf.Asin(r) * Mathf.Rad2Deg) * m_innacuracyDegrees/90f;
        r = Random.Range(-1f, 1f);
        float rotY = (Mathf.Asin(r) * Mathf.Rad2Deg) * m_innacuracyDegrees / 90f;
        Vector3 eulerRotation = new Vector3(rotX, rotY, 0f);
        Quaternion q = Quaternion.Euler(eulerRotation.x, eulerRotation.y, 0f);
        return q;
    }

    public void InflictDamage(IHarmable target)
    {
        target.TakeDamage(m_damage);
    }

    public override void SetIsAttacking(bool attacking)
    {
        //throw new System.NotImplementedException();
    }

    protected override void UpdateUIElements()
    {
        //throw new System.NotImplementedException();
    }

    protected override void DoAction()
    {
        //throw new System.NotImplementedException();
    }

    protected override void Move()
    {
        Look();
    }    
}