小言_互联网的博客

游戏开发记录--敌人追寻玩家

332人阅读  评论(0)

今天开始记录自己游戏开发的过程,算是自己的一个笔记吧。

首先让敌人追寻玩家的方法有三种。

第一种,玩家出现在敌人的视野内

简单的来说,就是当敌人“看见”玩家的时候(玩家出现在敌人的视野内),让敌人开始靠近玩家。

这种情况得先在敌人身上绑定一个摄像机,然后当摄像机内出现玩家,且出现的范围比较大的时候,让敌人开始追寻玩家。


(具体在unity中的体现,α为摄像机与玩家之间的夹角)
当α角大于摄像机视野角的一半的时候,就认为敌人看到了玩家,并且进行追寻。

第二种,玩家的声音被敌人所“听到”

这种我在unity中不好表示出来,我画图出来表示

第三种,玩家进入敌人的圆形侦测范围内


给敌人身上挂一个shere,然后取消掉Mesh Renderer组件,在OnTriggerEnter(Collider other)函数内进行判断和让敌人进行追寻

具体的实现代码片段如下

using UnityEngine;
using System.Collections;
using UnityEngine.AI;

public class EnemySight : MonoBehaviour {
   


private float seeAngle=120;//敌人视野角度
private bool isSeePlay = false;

private Vector3 lastPos;// 玩家的最后位置
    private Vector3 alermPos=Vector3.zero; //警报位置   

    private Animator anim;  //主角动画,作用是判断玩家是否在运动
    private SphereCollidersphereCollider;//敌人身上的碰撞器,该碰撞器是用来触发检测主角是否在敌人可见,可听范围内
    private NavMeshAgentnavMeshAgent; //AI组件  

    void Awake()
    {
   
        anim = GameObject.FindGameObjectWithTag(Tags.player).GetComponent<Animator>();
        lastPos = GameController._instance.lastPlayerPostion;
        navMeshAgent = GetComponent<NavMeshAgent>();
    }

    void Update()
    {
   
        //同步主角位置
        if (lastPos != GameController._instance.lastPlayerPostion)//触发警报后玩家位置改变
        {
   
            alermPos = GameController._instance.lastPlayerPostion; //更新警报位置
            lastPos = GameController._instance.lastPlayerPostion;
        }
        
    }

    void OnTriggleStay(Collider other)
    {
   
        if (other.tag==Tags.player)
        {
   
            //看玩家
            Vector3 startDir = transform.forward;//敌人开始朝向
            Vector3 currDir = other.transform.position - transform.position; //敌人看向玩家的向量
            float angle = Vector3.Angle(startDir, currDir);//敌人开始朝向与看见玩家朝向的夹角
            if (angle <seeAngle * 0.5f) //视野角度一半以内可见
            {
   
                //主角在敌人的视野之内
                isSeePlay = true;
                alermPos = other.transform.position;//把玩家的位置设置为警报位置
                GameController._instance.SeePlayer(other.transform);
            }
            else
            {
   
                isSeePlay = false;
            }


            //听脚步声音
            if (anim.GetCurrentAnimatorStateInfo(0).IsName("Locomotion"))//如果玩家在运动
            {
   
                NavMeshPath path = new NavMeshPath();
                if (navMeshAgent.CalculatePath(other.transform.position, path))
                {
   
                    Vector3[] wayPoints = new Vector3[path.corners.Length+2];
                    wayPoints[0] = transform.position;
                    wayPoints[wayPoints.Length - 1] = other.transform.position;
                    for (inti = 0; i<path.corners.Length; i++)
                    {
   
                        wayPoints[i + 1] = path.corners[i];  
                    }
                    float length = 0;
                    for (inti = 1; i<wayPoints.Length; i++)
                    {
   
                        length += (wayPoints[i] - wayPoints[i - 1]).magnitude; //所有节点连接的折线的总长度
                    }
                    if (length <= sphereCollider.radius) //在听力范围内
                    {
   
                        alermPos = other.transform.position;
                    }
                }
            }

        }
    }

    void OnTriggleExit(Collider other)
    {
   
        if (other.tag == Tags.player)
        {
   
            isSeePlay = false;
        }
    }

上面是前两种“看”和“听”所实现的代码

下面是实现进入到侦测范围的实现方法,部分内容与上面代码相似,这里仅显示思路和部分代码片段。

private void OnTriggerEnter(Collider other){
   
        if(other.tag == "Tag.Player")
        {
   
            //看玩家
            Vector3 startDir = transform.forward;//敌人开始朝向
            isSeePlay = true;
            alermPos = other.transform.position;//把玩家的位置设置为警报位置
            GameController._instance.SeePlayer(other.transform);
        }
        else
        {
   
                isSeePlay = false;
        }

}

最后,如果感兴趣的话,还可以加入我的技术交流小窝:1140238314


转载:https://blog.csdn.net/qq_39750907/article/details/116074283
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场