Unity射击类游戏,僵尸猎手~
<p>
Unity射击类的游戏,写完后做一个总结记录,方便以后回顾。
</p>
一、游戏功能组成
游戏主要包括:主角(一个呆萌的baby),敌人(三种类型的僵尸),敌人生成管理,以及UI界面。
主要的功能有:
主角,移动,射击僵尸,血量
敌人,三种类型的僵尸,在场景生成后可以追踪主角,靠近主角后可以进行攻击。
敌人生成管理,控制场景中三种僵尸的生成。
UI界面,主角血量的显示,游戏开始以及结束。
二、游戏组件
每个游戏对象包括的组件有:
主角:
player1.Animator 动画播放控制器,负责游戏中一些动画的控制;
2.Rigidbody 刚体,使主角可以受到物理力的控制,(游戏中使用到了刚体中的运动方法)
3.Capsule Collider 胶囊碰撞体,用来检测撞击的组件。
射击:
shoot射击效果放在枪口上:
1.Light 射击时控制灯光的闪烁。
2.LineRenderer 射击时控制弹痕的射线。
3.AudioSource 射击时的音效
敌人:
Enemy1.Animator 动画播放控制器,负责游戏中一些动画的控制;
2.Rigidbody 刚体,使主角可以受到物理力的控制,(游戏中使用到了刚体中的运动方法)
3.Capsule Collider 胶囊碰撞体,用来检测撞击的组件。
4.Nav Mesh Agent Unity自带的寻路系统,使用前需要对场景(场景需要设置为静态的)进行烘焙。
5.AudioSource 音频播放,用来控制游戏中的声音播放。(可以使用clip来播放不同的音频文件)
6.Sphere Collider 圆形碰撞体,用来做触发器,来检测主角是否在攻击范围内。使用时需要勾上istragger:
istragger
敌人生成管理:
Enemymanage包括3个刷新点,分别刷新3种类型的僵尸,由脚本统一控制生成。
三、代码主要构成
主角,主要包括血量(BabyHp)、移动(BabyMove)以及射击Shoot(射击脚本是挂在枪口处)。
敌人,主要包括血量(EnemyHp)、移动(EnemyWalk)以及攻(EnemyAtt)击。
敌人生成管理(EnemyManage),包括3个刷新点,以及每个类型的敌人的刷新时间。
相机跟随脚本(CameraFollow),挂载在Camera上,用来跟随主角移动。
四、注意要点
代码的逻辑都比较易懂,重点记录一下射线的使用,以及一些常用方法的应用:
1.插值运算
这种方法经常在一些渐变的过程,移动的平滑性中使用,这个游戏中,在主角收到攻击颜色变化,以及相机跟随主角移动,都使用到了插值运算,下面用相机跟随为例:
float smooth = 5;//控制相机跟随的平滑程度
//摄像机与玩家之间的间距
offsetPosition = transform.position-playerTransform.position;
void FixedUpdate () {
//通过插值来控制摄像机跟随玩家移动Lerp(a,b,t);t取值为0-1,在Updata中调用时,越大越快的靠近b点。
transform.position = Vector3.Lerp(transform.position,playerTransform.position+offsetPosition,Time.deltaTime*smooth);
}
2.射线检测
射线在游戏中两处用到了,一个是控制玩家的旋转,另外一个是射击。大致的使用步骤如下:
1.首先设置射线的长度:
2.获得地板层级:(floor)
3.取得射线(从摄像机打到屏幕鼠标位置。)
4.申明射线打到的点(这个值通过out参数来取得):
5.取得射线打到的位置:
Physics.Raycast(射线,射线打到的点(out修饰),射线长度,地板层级),返回的是一个bool类型的函数,通过if来判断得到碰撞点的位置信息。
//控制玩家旋转,在Updata中调用
private float rayLength = 100f; //射线长度
int layer; //射线碰撞的图层
RaycastHit rayHit; //射线碰撞到图层的点位
Ray camareRay; //声明射线
//取得摄像机和鼠标之间的一条射线
camareRay = Camera.main.ScreenPointToRay(Input.mousePosition);
//判断这条射线和图层是否有碰撞,有的话通过rayHit取得点位置信息
if (Physics.Raycast(camareRay,out rayHit,rayLength,layer))
{
Vector3 mousePosition = rayHit.point;
mousePosition.y = 0;
//transform控制旋转
transform.LookAt(mousePosition);
//刚体控制旋转,这个是通过四元数来控制
//Quaternion lookAt = Quaternion.LookRotation(mousePosition);
//playerRigid.MoveRotation(lookAt);
}
//射线射击
//声明射线(枪口处),第一个参数是起始位置,第二个参数是方向
Ray ray = new Ray(transform.position, transform.forward);
//声明碰撞点
RaycastHit hitInfo;
if(Physics.Raycast(ray,out hitInfo))
{
//碰撞上了物体,设置LineRenderer的终点为碰撞点
lineRenderer.SetPosition(1, hitInfo.point);
//判断碰撞上的是否是敌人
if (hitInfo.collider.GetComponent<EnemyHp>() != null)
{
hitInfo.collider.GetComponent<EnemyHp>().Damage(attack,hitInfo.point);
}
}
else
{
//如果没有碰撞上,则设置长度为100
lineRenderer.SetPosition(1,transform.position+transform.forward*100);
}
3.Invoke方法
这个方法在射击中使用,用来延时关闭射击的效果显示,有两个参数,第一个是调用的方法,第二个是延时时间。
Invoke("ShootStop", 1.2f*Time.deltaTime);
void ShootStop()
{
light.enabled = false;
lineRenderer.enabled = false;
}
}
4.敌人消失注意项
敌人在被打死后会自动下沉,完成到这里时需要注意,下沉的同时也要把自动追踪的组件(NavMeshAgent)给disable掉,不然不会下沉消失。