提要:本次做的是关卡设计,创建玩家背包,设计钥匙卡、钥匙卡对应的滑动门。将用检测函数和集合类实现。
一、创建玩家背包类
1.创建集合List 记得要在Start函数中new一下,不然值为null
private List<int> keysArr;
private void Start()
{
keysArr = new List<int>();
}
2.定义在集合中添加钥匙卡ID的方法
.Contains(keyId):判断集合中是否包含此元素
.Add(keyId):在集合中添加此元素
public void AddKey(int keyId)
{
if(!keysArr.Contains(keyId))
keysArr.Add(keyId);
}
3.定义判断是否有对应钥匙ID的方法
public bool HasKey(int doorID)
{
if (keysArr.Contains(doorID))
return true;
return false;
}
二、创建拾取钥匙卡类
新建变量 初始化变量
public AudioClip keyGrab;
public int keyId;
private GameObject player;
private fps_PlayerInventory playerInventory;
private void Start()
{
player = GameObject.FindGameObjectWithTag(Tags.player);
playerInventory=player.GetComponent<fps_PlayerInventory>();
}
定义碰撞检测方法
检测到玩家物体后,将钥匙卡ID赋给玩家背包类中的AddKey函数,将ID添加进钥匙卡List
OnTriggerEnter():Unity自带函数,当本物体中的碰撞器检测到另一个碰撞器进入时即触发
OnTriggerStay():Unity自带函数,当本物体中的碰撞器检测到另一个碰撞器处于之中触发
private void OnTriggerEnter(Collider other)
{
if (other.gameObject == player)
{
AudioSource.PlayClipAtPoint(keyGrab,transform.position);
playerInventory.AddKey(keyId);
Destroy(this.gameObject);
}
}
三、创建门控制类
新建变量 初始化变量
要注意的是,定义计数器count,并用属性进行封装
当有玩家或敌人进入便播放一次开门音频,当玩家或敌人还未离开门碰撞检测区域,有另一玩家或敌人进入门碰撞检测,此时计数器++变为2,音频不符合播放要求,即不播放。这样设计符合现实。
public int doorId;//门ID 用于于钥匙卡关联
public Vector3 from;//门初始位置
public Vector3 to;//门移动位置
public float fadeSpeed = 5;//门移动速度
public bool requireKey;//此门打开是否需要钥匙卡
public AudioClip doorSwitchClip;//门移动音效
public AudioClip accessDeniedClip;//门不可打开音效
private Transform door;
private GameObject player;
private AudioSource audioSource;
private fps_PlayerInventory playerInventory;
private int count;//计数器
public int Count
{
get {return count; }
set
{
if (count == 0 && value == 1 || count == 1 && value == 0)
{
audioSource.clip = doorSwitchClip;
audioSource.Play();
}
count = value;
}
}
private void Start()
{
if(transform.childCount>0) door=transform.GetChild(0);
player = GameObject.FindGameObjectWithTag(Tags.player);
playerInventory=player.GetComponent<fps_PlayerInventory>();
audioSource= this.GetComponent<AudioSource>();
door.localPosition = from;
}
定义碰撞检测进入方法
当玩家进入,需有Key,有Key即Count++,后续在Update中判断,Count>0即改变门位置即开门;
当敌人进入,无需判断Key,即Count++,即开门。
private void OnTriggerEnter(Collider other)
{
if (other.gameObject == player)
{
if (requireKey)
{
if (playerInventory.HasKey(doorId))
Count++;
else
{
audioSource.clip = accessDeniedClip;
audioSource.Play();
}
}
else
Count++;
}
else if (other.gameObject.tag == Tags.enemy && other is CapsuleCollider)
Count++;
}
定义碰撞检测退出方法
private void OnTriggerExit(Collider other)
{
if(other.gameObject==player||(other.gameObject.tag==Tags.enemy && other is CapsuleCollider))
Count=Mathf.Max(0,Count-1);
}
在Update中判断Count,再实现开门
使用插值函数Vector3.Lerp,实现速度变化控制。
private void Update()
{
if (Count > 0)
door.localPosition = Vector3.Lerp(door.localPosition,to,fadeSpeed*Time.deltaTime);
else
door.localPosition = Vector3.Lerp(door.localPosition, from, fadeSpeed * Time.deltaTime);
}