日志2025.2.18

日志2025.2.18
1.完善了远程敌人的遮蔽系统
public class Cover : MonoBehaviour
{
    [SerializeField] private GameObject coverPointPrefab;
    public List<CoverPoint> coverPoints = new List<CoverPoint>();
    [SerializeField] private Vector3 offset = new Vector3(1f, 0f, 1f);

    private Transform playerTransform;

    private void Awake()
    {
        playerTransform = FindFirstObjectByType<Player>().transform;
    }

    private void Start()
    {
        GenarateCoverPoints();
    }

    private void GenarateCoverPoints()
    {
        Vector3[] localCoverPoints =
        {
            new Vector3(0, offset.y, offset.z), //前
            new Vector3(0, offset.y, -offset.z), //后
            new Vector3(offset.x, offset.y, 0), //右
            new Vector3(-offset.x, offset.y, 0) //左
        };

        foreach (Vector3 localPoint in localCoverPoints)
        { 
            Vector3 worldPoint = transform.TransformPoint(localPoint);

            CoverPoint coverPoint = 
                Instantiate(coverPointPrefab, worldPoint, Quaternion.identity, transform).GetComponent<CoverPoint>();

            coverPoints.Add(coverPoint);
        }
    }

    public List<CoverPoint> GetValidCoverPoints(Transform EnemyTransform)
    {
        List<CoverPoint> validCoverPoints = new List<CoverPoint>();

        foreach (CoverPoint coverPoint in coverPoints)
        {
            if(IsValidCoverPoint(coverPoint, EnemyTransform))
                validCoverPoints.Add(coverPoint);
        }

        return validCoverPoints;
    }

    private bool IsValidCoverPoint(CoverPoint coverPoint, Transform EnemyTransform)
    {
        if(coverPoint.occupied)
            return false;

        if(IsFurthestCoverPoint(coverPoint) == false)
            return false;

        if(IsCoverPointBehindPlayer(coverPoint, EnemyTransform)) 
            return false;

        return true;
    }


    private bool IsFurthestCoverPoint(CoverPoint coverPoint)
    {
        CoverPoint furthestPoint = null;
        float furthestDistance = 0f;

        foreach(CoverPoint point in coverPoints)
        {
            float distance = Vector3.Distance(point.transform.position, playerTransform.position);

            if(distance > furthestDistance)
            {
                furthestDistance = distance;
                furthestPoint = point;
            }
        }

        return furthestPoint == coverPoint;
    }


    //判断遮蔽点是否在玩家身后
    private bool IsCoverPointBehindPlayer(CoverPoint coverPoint, Transform enemyTransform)
    {
        float distanceToPlayer = Vector3.Distance(coverPoint.transform.position, playerTransform.position);
        float distanceToEnemy = Vector3.Distance(coverPoint.transform.position, enemyTransform.position);

        return distanceToPlayer < distanceToEnemy;
    }

}

    #region Cover System

    public bool CanRunToCover()
    {
        if (canUseCovers == false) 
            return false;

        AttemptFindCoverPoint();

        if(currentCoverPoint == null)
            return false;

        return true;
    }

    public Transform AttemptFindCoverPoint()
    {
        List<CoverPoint> collectedCoverPoints = new List<CoverPoint>();

        foreach (Cover cover in allCovers)
        {
            collectedCoverPoints.AddRange(cover.GetValidCoverPoints(transform));
        }

        CoverPoint lastestCoverPoint = null; //最近的有效的遮蔽点
        float minDistance = float.MaxValue;

        foreach (CoverPoint coverPoint in collectedCoverPoints) 
        { 
            float distance = Vector3.Distance(transform.position, coverPoint.transform.position);

            if(distance < minDistance)
            {
                minDistance = distance;
                lastestCoverPoint = coverPoint;
            }
        }

        if(lastestCoverPoint != null)
        {
            lastCoverPoint = currentCoverPoint;
            lastCoverPoint?.SetOccupied(false);

            currentCoverPoint = lastestCoverPoint;
            currentCoverPoint.SetOccupied(true);

            return currentCoverPoint.transform;
        }

        return null;
    }


    private List<Cover> CollectNearCovers()
    {
        Collider[] colliders = Physics.OverlapSphere(transform.position, checkCoverRadius);
        List<Cover> collectedCovers = new List<Cover>();

        foreach (Collider collider in colliders)
        {
            Cover cover = collider.GetComponent<Cover>();

            //collectedCovers.Contains(cover) == false 是为了防止一个物体有多个碰撞体而导致的重复计入
            if (cover != null && collectedCovers.Contains(cover) == false)
            {
                collectedCovers.Add(cover);
            }
        }

        return collectedCovers;
    }
    #endregion

    private void ShouldRunToCover()
    {
        checkCoverTimer -= Time.deltaTime;

        if (checkCoverTimer <= 0)
        {
            checkCoverTimer = 0.5f;

            if (IsPlayerInClearSight())
            {
                if (enemy.CanRunToCover())
                {
                    stateMachine.ChangeState(enemy.runToCoverState);
                }
            }
        } 
    }

    private bool IsPlayerInClearSight()
    {
        if(Physics.Raycast(enemy.transform.position, enemy.DirectionToPlayer(), out RaycastHit hit))
        {
            return hit.collider.GetComponentInParent<Player>();
        }

        return false;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值