Unity3D学习笔记(十五):寻路系统


打开Navigation窗口在Bake栏下点Bake
烘焙数据:蓝色区域就是寻路平面,烘焙数据可以与显示数据分离
设置障碍物:障碍物勾选Navigation Static,重新烘焙,障碍物被添加
设置目标点,引用UnityEngine.AI,引用寻路系统
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.AI;//引用UnityEngine.AI
- public enum EnemySta
- {
- Move,
- Idle,
- Death
- }
- public class EnemyControl : MonoBehaviour {
- public Animation anim;
- public EnemySta enemySta;
- //因为我们需要经常用到目标的状态,所以把TransForm改成了PlayerControl
- public PlayerControl moveTarget;//设置目标点
- public NavMeshAgent navMeshAgent;//引用寻路系统
- public MonsterManager manager;//怪物属于那个管理器
- private int enemyHealth = ;//设置怪物生命值
- // Use this for initialization
- void Start () {
- enemySta = EnemySta.Move;
- }
- // Update is called once per frame
- void Update () {
- if (Input.GetKeyDown(KeyCode.Alpha1))
- {
- enemySta = EnemySta.Move;
- }
- if (Input.GetKeyDown(KeyCode.Alpha2))
- {
- enemySta = EnemySta.Idle;
- }
- if (Input.GetKeyDown(KeyCode.Alpha3))
- {
- enemySta = EnemySta.Death;
- }
- Action();
- }
- void Action()
- {
- switch (enemySta)
- {
- case EnemySta.Move:
- Move();
- break;
- case EnemySta.Idle:
- Idle();
- break;
- case EnemySta.Death:
- Death();
- break;
- }
- }
- void Move()
- {
- anim.CrossFade("Move", 0.2f);
- navMeshAgent.SetDestination(moveTarget.transform.position);//让对应组件调用一个SetDastination(目标点)方法
- //如果怪物的目标死了
- if (moveTarget.playSta == PlaySta.Death)
- {
- //寻路停止
- navMeshAgent.isStopped = true;
- //状态切换到闲置
- enemySta = EnemySta.Idle;
- }
- }
- void Idle()
- {
- anim.CrossFade("Idle", 0.2f);
- }
- public void Damage()
- {
- //受伤减血
- enemyHealth -= ;
- //Debug.Log("怪物生命"+enemyHealth);
- //如果血到了0
- if (enemyHealth <= )
- {
- //状态变成死亡状态
- enemySta = EnemySta.Death;//怪物死亡:停止寻路,失效碰撞体(防止实体造成伤害)
- navMeshAgent.isStopped = true;
- gameObject.GetComponent<MeshCollider>().enabled = false;
- //gameObject.tag = "Untagged";
- }
- }
- void Death()
- {
- anim.CrossFade("Death", 0.2f);
- }
- public void DeathEvent()
- {
- //在管理器列表中移除自己
- manager.monsterList.Remove(this);
- //销毁自己
- Destroy(this.gameObject);
- }
- }

- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- public class CameraFollow : MonoBehaviour {
- public Transform target;//目标点
- public Vector3 distance;//目标点的距离,和目标点保持一定距离
- public Vector3 lookAtOffSet;//看向点与目标点的偏移量
- private Vector3 targetPos;
- // Use this for initialization
- void Start () {
- distance = transform.position - target.position;
- }
- // Update is called once per frame
- void Update () {
- }
- private void LateUpdate()
- {
- //目标点加距离 = 摄像机的目标位置
- targetPos = target.position + distance;
- //向目标位置移动,每次百分之10
- transform.position = Vector3.Lerp(transform.position, targetPos, 0.1F);
- //看向目标点
- transform.LookAt(target.position + lookAtOffSet);
- }
- }

设置灯光动画
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- public enum PlaySta
- {
- Move,
- Idle,
- Death
- }
- public class PlayerControl : MonoBehaviour
- {
- public Animation anim;
- public PlaySta playSta;
- // Use this for initialization
- void Start()
- {
- playSta = PlaySta.Move;
- }
- // Update is called once per frame
- void Update()
- {
- float h = Input.GetAxis("Horizontal");
- float v = Input.GetAxis("Vertical");
- moveDir.x = h;
- moveDir.z = v;
- cd += Time.deltaTime;
- Action();
- }
- void Action()
- {
- switch (playSta)
- {
- case PlaySta.Move:
- Move();
- Attack();
- Rot();
- break;
- case PlaySta.Idle:
- Idle();
- Attack();
- Rot();
- break;
- case PlaySta.Death:
- Death();
- break;
- }
- }
- Vector3 moveDir;
- Vector3 lookPoint;
- RaycastHit hit;
- public float moveSpeed = ;
- void Move()
- {
- anim.Play("Move");
- transform.position += moveDir * moveSpeed * Time.deltaTime;
- if (moveDir.magnitude < 0.01f)
- {
- playSta = PlaySta.Idle;
- }
- }
- //把转向功能提炼出来
- void Rot()
- {
- if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, , << ))
- {
- lookPoint = hit.point;
- lookPoint.y = transform.position.y;
- transform.LookAt(lookPoint);
- }
- }
- void Idle()
- {
- anim.Play("Idle");
- if (moveDir.magnitude >= 0.01f)
- {
- playSta = PlaySta.Move;
- }
- }
- float cd;
- public void Damage()
- {
- cd = ;//无敌时间,受伤间隔
- playSta = PlaySta.Death;
- }
- void Death()
- {
- anim.Play("Death");
- }
- //触发器判定死亡
- //public void OnTriggerEnter(Collider other)
- //{
- // if (other.tag == "Monster")
- // {
- // if (cd > 0.5f)
- // {
- // Damage();
- // }
- // }
- //}
- //改良版:碰撞器判定死亡
- public void OnCollisionEnter(Collision other)
- {
- if (other.gameObject.tag == "Monster")
- if (cd > 0.5f)
- {
- Damage();
- }
- }
- public AudioSource fireAudio;
- public Animation fireAnim;
- public Transform firePos;
- public LineRenderer lineRenderer;
- private RaycastHit fireHit;
- void Attack()
- {
- if (Input.GetMouseButtonDown())
- {
- fireAudio.Play();
- fireAnim.Stop();//Stop避免前一动画未执行完,后一动画不会执行
- fireAnim.Play();
- if (Physics.Raycast(new Ray(firePos.position,firePos.forward),out fireHit,))
- {
- //如果我打中的目标是怪物
- if (fireHit.collider.tag == "Monster")
- {
- //这个目标受伤
- fireHit.collider.GetComponent<EnemyControl>().Damage();
- }
- SetFirePos(fireHit.point);
- }
- else
- {
- SetFirePos(firePos.transform.position + firePos.forward * );
- }
- }
- }
- void SetFirePos(Vector3 hitPos)
- {
- lineRenderer.SetPosition(, firePos.position);
- lineRenderer.SetPosition(, hitPos);
- }
- //还原射线到枪口位置
- public void ReSetFirePos()
- {
- lineRenderer.SetPosition(, firePos.position);
- lineRenderer.SetPosition(, firePos.position);
- }
- }
----射线



新建脚本FireEvent,调用父级Player的脚本
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- public class FireEvent : MonoBehaviour {
- public PlayerControl player;
- // Use this for initialization
- void Start () {
- }
- // Update is called once per frame
- void Update () {
- }
- public void Fire()
- {
- player.ReSetFirePos();
- }
- }
射线宽度调整:添加关键帧,调整曲线,效果先细后粗


怪物属于那个管理器
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- public class MonsterManager : MonoBehaviour {
- List<Transform> birthPoint;
- public GameObject monsterPreGo;
- public List<EnemyControl> monsterList;
- public int MaxMonsterCount = ;//最大怪物数
- public PlayerControl player;
- // Use this for initialization
- void Start () {
- birthPoint = new List<Transform>();
- monsterList = new List<EnemyControl>();
- for (int i = ; i < transform.childCount; i++)
- {
- birthPoint.Add(transform.GetChild(i));
- }
- }
- // Update is called once per frame
- void Update () {
- }
- private void FixedUpdate()
- {
- CheckMonster();
- }
- void CreateMonster()
- {
- //实例化一个怪物
- GameObject go = Instantiate<GameObject>(monsterPreGo);
- //怪物的位置设置任意出生点
- go.transform.position = birthPoint[Random.Range(,birthPoint.Count)].position;
- //取得怪物脚本
- EnemyControl monster = go.GetComponent<EnemyControl>();
- //把怪物放到管理器列表里
- monsterList.Add(monster);
- //指定怪物的目标
- monster.moveTarget = player;
- //指定怪物的管理者
- monster.manager = this;
- }
- void CheckMonster()
- {
- if (monsterList.Count < MaxMonsterCount)
- {
- CreateMonster();
- }
- }
- }

怪物死亡:移出列表,摧毁游戏物体,放在死亡动画最后一帧调用
- public void DeathEvent()
- {
- //在管理器列表中移除自己
- manager.monsterList.Remove(this);
- //销毁自己
- Destroy(this.gameObject);
- }
更换场景,重新烘焙,并添加floor和碰撞体
怪物管理器添加积分系统
Unity3D学习笔记(十五):寻路系统的更多相关文章
- python3.4学习笔记(十五) 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)
python3.4学习笔记(十五) 字符串操作(string替换.删除.截取.复制.连接.比较.查找.包含.大小写转换.分割等) python print 不换行(在后面加上,end=''),prin ...
- (转载)西门子PLC学习笔记十五-(数据块及数据访问方式)
一.数据块 数据块是在S7 CPU的存储器中定义的,用户可以定义多了数据块,但是CPU对数据块数量及数据总量是有限制的. 数据块与临时数据不同,当逻辑块执行结束或数据块关闭,数据块中的数据是会保留住的 ...
- (C/C++学习笔记) 十五. 构造数据类型
十五. 构造数据类型 ● 构造数据类型概念 Structured data types 构造数据类型 结构体(structure), 联合体/共用体 (union), 枚举类型(enumeration ...
- MySQL学习笔记十五:优化(2)
一.数据库性能评测关键指标 1.IOPS:每秒处理的IO请求次数,这跟磁盘硬件相关,DBA不能左右,但推荐使用SSD. 2.QPS:每秒查询次数,可以使用show status或mysqladmin ...
- MYSQL进阶学习笔记十五:MySQL 的账号权限赋予!(视频序号:进阶_33,34)
知识点十六:MySQL的账号权限赋予(33) 一.MySQL权限简介 关于mysql的权限简单的理解就是mysql允许你做你全力以内的事情,不可以越界.比如只允许你执行select操作,那么你就不能执 ...
- python 学习笔记十五 django基础
Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. ...
- Java基础学习笔记十五 集合、迭代器、泛型
Collection 集合,集合是java中提供的一种容器,可以用来存储多个数据. 在前面的学习中,我们知道数据多了,可以使用数组存放或者使用ArrayList集合进行存放数据.那么,集合和数组既然都 ...
- Python3学习笔记十五
---恢复内容开始--- 1. jquery的属性操作 $().attr(属性名) 取值 $().attr(属性名,属性值) 赋值 <!DOCTYPE html> &l ...
- angular学习笔记(十五)-module里的'服务'
本篇介绍angular中的模块:module 在笔记(二)http://www.cnblogs.com/liulangmao/p/3711047.html里已经讲到过模块,这篇主要讲模块的 '服务' ...
- Java学习笔记十五:Java中的成员变量和局部变量
Java中的成员变量和局部变量 一:成员变量: 成员变量在类中定义,用来描述对象将要有什么 成员变量可以被本类的方法使用,也可以被其他类的方法使用,成员变量的作用域在整个类内部都是可见的 二:局部变量 ...
随机推荐
- 共享访问在.NET中的编程实现
转载:http://blog.csdn.net/zhzuo/article/details/1732937 共享访问在.NET中的编程实现 发布日期:2007-08-08 | 更新日期:2009-03 ...
- SQL Server 学习博客分享列表(应用式学习 + 深入理解)
SQL Server 学习博客分享列表(应用式学习 + 深入理解) 转自:https://blog.csdn.net/tianjing0805/article/details/75047574 SQL ...
- Java-mybatis-一次执行多条SQL语句
mysql数据库 1.修改数据库连接参数加上allowMultiQueries=true,如: hikariConfig.security.jdbcUrl=jdbc:mysql://xx.xx.xx: ...
- ABP项目创建
第一种:1.在MyAbp.Migrator下面的appsettings.json里面的sql连接语句 MyAbp.Web.Host 下面的appsettings.json 里面的连接语句2.把MyAb ...
- HTTP头部信息解释分析(详细整理)
这篇文章为大家介绍了HTTP头部信息,中英文对比分析,还是比较全面的,若大家在使用过程中遇到不了解的,可以适当参考下 HTTP 头部解释 1. Accept:告诉WEB服务器自己接受什么介质类型,*/ ...
- 使用Navicat导入excel表
1:首先创建Navicat与数据库的连接 2:,从数据库中选择要导入的表 3:导入向导,选择要导入的数据类型 4:创创建excel表:一般第一行需要与表的属性相对应,这样就不需要手动设置对应栏位 不一 ...
- JSP表单提交与接收
JSP表单提交与接收 在Myeclipse中新建web project,在webroot中新建userRegist1.jsp,代码如下 <%@ page contentType="te ...
- Kettle定时抽取两个库中的两个表到目标库SYS_OPLOG表
A库a表(红色为抽取字段): 关联用户表: B库b表(红色为抽取字段): 关联用户表 C目标库SYS_OPLOG表(c表) 利用kettle抽取A库a表(具体名称见上图),B库b表的上面红色框起来 ...
- 蒙特卡罗(Monte Carlo)方法简介
蒙特卡罗(Monte Carlo)方法,也称为计算机随机模拟方法,是一种基于"随机数"的计算方法. 二 解决问题的基本思路 Monte Carlo方法的基本思想很早以前就被人们所发 ...
- Lintcode: k Sum II
Given n unique integers, number k (1<=k<=n) and target. Find all possible k integers where the ...