第一人称射击游戏实战——玩家背包及生命
玩家背包
编程思路:本游戏中,玩家背包主要是存放能够开门的钥匙。而钥匙的ID是与门的ID相对应的。
创建PlayerInventory脚本,挂载到FP_Player上。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class fps_PlayerInventory:MonoBehaviour
{
private List<int> keyArr;
void Start()
{
keyArr=new List<int>();
}
public void AddKey(int keyID)
{
if(!keyArr.Contains(keyID))
keyArr.Add(keyID);
}
public bool HasKey(int doorID)
{
if(keysArr.Contains(keyID))
return true;
return false;
}
}
玩家生命
编程思路:首先,一定是定义玩家的生命;玩家会受到伤害,当受到伤害小的时候,需要有对应屏幕变血红色的特效,也会有对应的音效。血红的特效会随着当前血量以及受到的伤害,变成加深或者变浅。
另外。如果玩家死了,那么需要考虑三件事:1.玩家的输入操作需要全部屏蔽,因此不能继续控制人物或者相机了。2.屏蔽以后不久,会有音效,提示即将重启3.有对应的淡出效果,屏幕先变成灰白色(类似于黑白电视的效果,就是将镜头增加滤镜效果),之后屏幕变黑(用之前定义或的EndScene),原本会跳入下一场景,但是因为我们只有一个场景,因此就相当于重启。因为第一章中我用了SceneManager.LoadSceneAsync(“Demo”),本场景的名字就是Demo,所以循环调用。
创建fps_PlayerHealth脚本,给FP_Player。
注意:1. 实现血红色屏幕的效果,我们是利用的资源包中的BleedBehavior脚本实现,该脚本中通过BloodAmount来控制,【0,1】,0表示全屏没有血渍,而1表示有血渍最多。(该方法不是通用方法)**2.**屏幕增加滤镜效果,不同于场景的淡入淡出,用到了postprocessing组件,挂载到了主相机上。我们可以使用postprocessing ProfileV3中的Camera_BW_High Profile文件挂载到postprocessing Volume上。
知识点
postprocessing Volume中有Weight可以调控滤镜的程度,(0,1),0表示没有滤镜,1表示滤镜最深。
第二点,之前出过访问组件的方法集合,这里我们要用到访问游戏对象的方法
1.transform.Find(string name)
特点:可以查找隐藏的对象,也支持路径查找,当然,查找隐藏对象的前提是根节点active.这个是专门针对子物体查找的,因此注意路径查找的时候不用包含根节点。
2.GameOject.Find(string name)
适用于整个游戏场景,甚至是不同场景中名字为name的所有没有被隐藏的对象(active),若找到多个,则返回创建时间最短的游戏对象。但是效率非常低,一般只用于查找上层的对象。如果不是上层的话,建议使用路径查找。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class fps_PlayerHealth:Monobehaviour{
public bool isDead;
public float hp=100;
public float Hp=100;
public AudioClip damageClip;
public AudioClip deathClip;
public float recoverSpeed=1.0f;
public float resetTime=5.0f;
private float timer=0;
private FadeInOut fader;
private PostProcessingVolume volume;//挂载到了FP_Camera上
public void TakeDamage(float damage)
{
if(isDead)
return;
hp-=damage;
BleedBehavior.BloodAmount+=Mathf.clamp01(damage/hp);
AudioSource.PlayClipAtPoint(damageClip,transform.position);
}
public void DisableInput()
{
this.GetComponent<fps_PlayControl>().enabled=false;
this.GetComponent<fps_FPInput>().enabled=false;
this.GetComponent<AudioSource>().enabled=false;
transform.Find("FP_Camera/Weapon_Camera").gameObject.SetActive(false);//武器相机全部禁用
volume.gameObject.GetComponent<fps_FPCamera>().enabled=false;//将子物体的组件禁用
if(GameObject.Find("Canvas_Weapon")!=null)
GameObject.Find("Canvas_Weapon").SetActive(false);//禁用用于绘制武器的UI。淡入淡出的是Canvas,不能禁用,不然实现不出效果。
}
public void PlayerDead()
{
isDead=true;
DisableInput();
AudioSource.PlayClipAtPoint(deathClip,transform,position);
volume.enabled=true;//默认是不开滤镜的,只有玩家死了可以开
}
public void LevelReset()
{
timer+=Time.deltaTime;
volume.weight+=(Time.deltaTime);
volume.weight=Mathf.Min(volume.weight,1);//注意控件增加有上限
if(timer>=resetTime)
fader.EndScene();
}
void Update()
{
if(!isDead)
{
hp+=recoverSpeed*Time.deltaTime;//加操作需要考虑上限
if(hp>maxHp)
hp=maxHp;
}
if(hp<0)
{
if(!isDead)
PlayerDead();
else
LevelReset();
}
}
}