目录
一.内容以及步骤:
1.编写代码允许玩家向场景发射
①shoot方法,从摄像机的中心发射射线,将碰撞点作为射击点,产生一个小球,其实就是在碰撞点的位置生成一个sphere就有这种效果了
②OnGUI方法相当于创建最上层图层,类似贴纸,用来当准心
2.敌人被击中的简单后仰效果,以及敌人AI漫游
①当被子弹击中时,产生后仰,直接在子弹发生碰撞时进行检测,检测成功直接使碰撞物体倾倒。(利用rotate方法即可简单实现)
②敌人呆呆的在原地没有意思,这里用一种简单的方法来实现敌人漫游:移动很简单,直接使用translate就可以。但是怎样让它遇到墙自己转向呢?就是从敌人处发射射线,射线里包含很多信息包括发生碰撞的距离,当检测到距离过小时,也就是要撞墙了,此时产生一个随机的角度,利用rotate方法给它一个旋转就行了。
二.效果预览:
1.玩家向场景发射效果:
如图所示,从摄像机中心发射射线,射线如果与敌人发生碰撞则发射一个球模拟子弹
2.敌人被击中的简单后仰效果
3.敌人AI漫游效果
三.实现步骤:
1.步骤
(1)创建一个RayShooter脚本,附加到摄像机上
(2)RayShooter脚本内容:
shoot()方法实现:
private void shoot()
{
//_camera.enabled = false;理解GetComponent小例子
if (Input.GetMouseButtonDown(0))
{
Vector3 point = new Vector3(_camera.pixelWidth / 2, _camera.pixelHeight / 2,
0);//获取摄像机屏幕中心坐标
Ray ray = _camera.ScreenPointToRay(point);//ScreenPointToRay()返回从摄像机通过
屏幕点的光线,也就是产生一个
//ray对象,而不是Object对象
//Debug.DrawRay(ray.origin,
ray.direction * 10, Color.black);
RaycastHit hit;//RaycastHit关于射线交叉信息的包装,包括哪里交叉和与哪个对象发生
交叉
if (Physics.Raycast(ray, out hit))//Physics.Raycast():射线投射 类似于从空间中
的某个点朝特定方向发射一条光束。
//在该过程中,可以检测并报告与光束接触的任何对
象
//out关键字,使一个数据结构在命令内操作和命令
外都是同一对象而不是,
//那些在不同函数作用域中被反复复制的对象
{
GameObject hitObject = hit.transform.gameObject;//获取碰撞对象
//击中信息不会返回击中对象,而是指向所击中的Transform组件,所以可以通过
Transform来访问gameObject
//使用对象的GetComponent方法检查它是否是一个反应的目标(如果有ReactiveTarget
就是)
//GetComponent()方法返回附加到GameObject上的指定类型组件,如果对象没有添加这
个类型组件,
//则GetComponent不会返回任何东西
ReactiveTarget target = hitObject.GetComponent<ReactiveTarget>();//将碰撞
对象组件引用给
//攻击对
象:ReactiveTarget
if(target == null)//击中对象是一个反应目标,则发射小球
{
Debug.Log("啥也不是!!");
}
else
{
//Debug.Log("Hit" + hit.point);
StartCoroutine(SphereIndicator(hit.point));//运行协程需要使用
StartCoroutine()方法调用
}
}
}
}
协程:当需要产生一些慢慢消失的物体时采用协程
private IEnumerator SphereIndicator(Vector3 pos)//球指示器,使用协程发射一个球到碰撞体上
{
GameObject sphere =
GameObject.CreatePrimitive(PrimitiveType.Sphere);//CreatePrimitive:
//创建一个具有原始网格渲染器和相应碰撞体的游戏对象。
sphere.transform.position = pos;
yield return new WaitForSeconds(10);
Destroy(sphere);
}
(3) 敌人类:
单独写一个脚本:命名为ReactiveTarget(这里注意,如果这里命名更改或是未创建都会引起报错),将其附加到enemy上,这样就能达到只射击中方块而墙壁不会被影响的效果,当然这种效果也可以使用tag。
2.敌人受攻击倾斜效果
(1)重新创建一个脚本命名为ReactiveTarget,将其挂在enemy上
(2)打开脚本写一个公开可以被外部调用的ReactiveToHit方法,传入一个攻击值,调用RotateEnemy协程方法产生倾斜,并且减血量,当血量小于或等于0时,调用协程死亡方法。
ReactiveTarget类整体代码:
public class ReactiveTarget : MonoBehaviour
{
private int Hp = 100;
public void ReactiveToHit(int attract )
{
StartCoroutine(RotateEnemy());
Hp -= attract;
if (Hp <= 0)
{
StartCoroutine(Die());//协程的调用
}
}
private IEnumerator Die()
{
yield return null;//new WaitForSeconds(1.5f);//等待1.5秒
Destroy(this.gameObject);
}
private IEnumerator RotateEnemy()
{
this.transform.Rotate(-75, 0, 0);
yield return new WaitForSeconds(0.5f);
this.transform.Rotate(75, 0, 0);
}
}
3.敌人AI漫游实现
(1)创造一个新脚本WangderingAI,也将其挂在enemy上
public class WangderingAI : MonoBehaviour
{
public float speed = 3.0f;
public float obstacleRange = 5.0f;
private void Update()
{
divergentRay();
move();
}
private void move()
{
transform.Translate(0, 0, speed * Time.deltaTime);
}
private void divergentRay()
{
Ray ray = new Ray(this.transform.position, this.transform.forward);//创建一个在这个物体位置和前方
//为起点和方向的射线
RaycastHit hitInfo;
if(Physics.SphereCast(ray,0.75f,out hitInfo))
{
if(hitInfo.distance < obstacleRange)
{
float angle = Random.Range(-110, 110);
transform.Rotate(0, angle, 0);
}
}
}
}