Unity3D-智能巡逻兵

本文详细介绍了使用Unity3D开发智能巡逻兵游戏的过程,包括游戏基本内容、编程方法、素材设置及小技巧。游戏涉及单例模式、工厂模式、订阅与发布模式,以及巡逻兵的智能行为和地图设计。此外,还分享了关于摄像机跟随、碰撞检测和事件管理的实现细节。
摘要由CSDN通过智能技术生成

智能巡逻兵

游戏基本内容

  1. 玩家

    • 玩家操控人物在地图中移动
    • 靠近巡逻兵一定距离会被追赶,摆脱后得1分
    • 被巡逻兵抓到游戏结束
    • 吃到蓝色水晶得2分
    • 吃到紫色水晶得5分
    • 每轮游戏开始玩家会在复活区域开始游戏
  2. 巡逻兵

    • 每个区域有2个巡逻兵
    • 巡逻兵无法跨越区域,当碰到每个区域的出入口时被消灭,在所属区域内重新生成新的的巡逻兵,进行巡逻
    • 以一个随机的四边形路线巡逻
    • 碰到墙壁后重新生成巡逻路线
    • 当玩家靠近到一定距离会追赶玩家,被摆脱后继续巡逻
    • 抓到玩家游戏结束
  3. 水晶

    • 有两种水晶,蓝色水晶2分,紫色水晶5分
    • 普通区域有1个紫水晶,3个蓝水晶
    • 特殊区域有3个紫水晶
    • 被玩家吃后,当局游戏不再重新生成
    • 每局游戏开局自动生成,出现位置确定
  4. 地图

    • 如图

    map

    • 最上端区域为安全区域,不会出现巡逻兵,玩家会在安全区域开始游戏
    • 中间区域为特殊区域,只有一个出入口。
    • 其余区域为普通区域

游戏编程方法

  • 单例模式
  • 工厂模式
  • 动作管理
  • 订阅与发布模式

游戏素材

  1. 玩家

    player

  2. 巡逻兵

    monster

  3. 天空盒

    skybox

  4. 墙贴图

    wall

  5. 水晶贴图

    diamond diamond

  6. 自制预制

    地图预制,Plane

当然素材下载下来之后还要进行各种调整来符合需求。

设置上的小技巧

  1. 出入口的设置

    出入口需要能通过且能感知到,因此可以用空游戏对象,加上触发器,并设置其标签为Gate。这样可以让角色通过,并且可以通过角色的触发器感知到出入口的存在

  2. 巡逻兵对出入口的感知

    巡逻兵的根节点上有一个触发器,用来感知玩家的。但这个触发器范围太广,会导致离出入口还很远就感知到出入口,然后被消灭掉。

    因此不要把感知出入口的函数放在根节点,可以放在子节点,调整该节点的触发器范围小一点,这样就可以让巡逻兵在足够靠近出入口时感知到,然后被消灭。

  3. 摄像机的跟随

    当将摄像机跟随的目标设为玩家角色时,发现怎么调整都不能得到令人满意的第三人称视角。

    我就在玩家角色中增加了一个子对象cube,去掉渲染,放在头顶合适的位置。让摄像跟随的目标变成这个cube,就可以实现满意的跟随效果。

UML图

uml

游戏主要代码分析

CamareFollow.cs

实现摄像机的跟随,平滑移动

public Transform target;
public float distanceH = 10f;
public float distanceV = 5f;
public float smoothSpeed = 10f; //平滑参数

void LateUpdate()
{
    Vector3 nextpos = target.forward * -1 * distanceH + target.up * distanceV + target.position;
    this.transform.position =Vector3.Lerp(this.transform.position, nextpos, smoothSpeed * Time.deltaTime); 
    this.transform.LookAt(target);
}

跟随效果:
follow

PatrolData.cs

巡逻兵的数据

public GameObject player;   //玩家
public float speed;         //速度
public bool isFollow = false;   //是否跟随玩家
public bool isGate = false;     //是否撞到区域的出入口
public bool isWall = false;     //是否撞到墙
public int area;            //所在的区域

PatrolFactory.cs

巡逻兵工厂,用于生成与回收巡逻兵

getPatrol,用于根据区域在该区域中随机生成巡逻兵

public GameObject getPatrol(int area){
    GameObject newPatrol = null;
    float baseX = 0;
    float baseZ = 0;

    //根据区域确定基本坐标
    switch (area) {
    case 0:
        baseX = -100;
        baseZ = -50;
        break;
    case 1:
        baseX = 80;
        baseZ = -180;
        break;
    case 2:
        baseX = 250;
        baseZ = -180;
        break;
    case 3:
        baseX = 250;
        baseZ = -50;
        break;
    case 4:
        baseX = 50;
        baseZ = -50;
        break;
    }

    //当巡逻兵有库存时
    if (free.Count > 0) {
        newPatrol = free [0].gameObject;

        //在基本坐标的基础上生成有随机的偏移坐标
        float dev = Random.Range(-20, 20);
        newPatrol.transform.position = new Vector3(baseX + dev, 0, baseZ + dev);
        free.Remove (free[0]);
    } else {

        //在基本坐标的基础上生成有随机的偏移坐标
        float dev = Random.Range(-20, 20);
        newPatrol = Instantiate<GameObject> (patrolPrefab, new Vector3(baseX + dev, 0, baseZ + dev), Quaternion.identity);
    }

    newPatrol.SetActive (true);
    newPatrol.GetComponent<PatrolData> ().area = area;

    //加入使用中队列
    used.Add (newPatrol.GetComponent<PatrolData>());
    return newPatrol;
}

freePatrol方法,回收巡逻兵,与Hit UFO中基本相同

public void freePatrol(GameObject oldPatrol){
    for (int i = 0; i < used.Count; i++) {
        if (used [i].gameObject == oldPatrol) {
            PatrolData move = used[i];
            used.Remove (move);
            free.Add (move);
            return;
        }
    }
    Debug.Log ("Exception: No such disk int used list");
}

Director.cs

单例的导演类

public ScenceController scence;     //场景控制器
private static Director instance;   //单例
public bool gameOver = false;       //游戏状态

public static Director getInstance(){
    if (instance == null) {
        instance = new Director ();
    }
    return instance;
}

//开始游戏
public void gameStart(){
    scence.gameStart ();
}

GameEventManager.cs

事件发布类,连接触发条件和响应方法

//游戏结束事件
public delegate void GameoverEvent();
public static event GameoverEvent GameoverChange;

//玩家逃脱事件
public delegate void AddscoreEvent();
public static event GameoverEvent Addscore;

//巡逻兵撞到出入口事件
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值