抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

说明:玩家碰到尖刺或者被黑球撞到就会死亡

功能实现

尖刺碰撞

首先选中所有尖刺,为他们添加脚本Spike

image-20220922130103417

using UnityEngine;
public class Spike : MonoBehaviour
{
private void OnTriggerEnter(Collider other)
{
if (other.TryGetComponent(out PlayerController player))
{//如果碰撞的是挂载PlayerController的对象
player.OnDefeated();//游戏失败,玩家身上相关功能禁用
}
}
}

角色属性调整(关闭功能)

通过问题修复功能,自动在PlayerController脚本中生成**OnDefeated()**函数;

同样地,在input类中生成DisableGamePlayInputs();

public void OnDefeated()
{//游戏失败
input.DisableGamePlayInputs();//关闭输入
rigidBody.velocity = Vector3.zero;//速度清零
rigidBody.useGravity = false;//关闭重力对刚体的影响
rigidBody.detectCollisions = false;//关闭刚体碰撞检测
//状态机切换到失败状态
GetComponent<StateMachine>().SwitchState(typeof(PlayerState_Defeated));
}

DisableGamePlayInputs();只有一行代码:禁用当前输入动作表。playerInputAction.GamePlay.Disable();

小球碰撞

为球Ball添加脚本Ball,如果球撞到玩家,则执行玩家死亡游戏失败逻辑。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Ball : MonoBehaviour
{
[SerializeField] Collider gameplayer;//获取玩家碰撞体
[SerializeField] PlayerController player;//获取玩家控制器
private void OnCollisionEnter(Collision other)
{
//Debug.Log(other.collider);
//Debug.Log(gameplayer);
if (other.collider == gameplayer)
{
player.OnDefeated();
}
}
}

更简便的写法:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Ball : MonoBehaviour
{
// [SerializeField] Collider gameplayer;//获取玩家碰撞体
// [SerializeField] PlayerController player;//获取玩家控制器
private void OnCollisionEnter(Collision other)
{
if (other.gameObject.TryGetComponent(out PlayerController player))
{
player.OnDefeated();
}
// if (other.collider == gameplayer)
// {
// player.OnDefeated();
// }
}
}

给小球加上消失功能,大约6s摧毁自身

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Ball : MonoBehaviour
{
[SerializeField] VoidEventChannel ballTriggeredEventChannel;
private void OnEnable()
{
ballTriggeredEventChannel.AddListener(EliminateBall);
}
private void OnDisable()
{
ballTriggeredEventChannel.RemoveListener(EliminateBall);
}
private void OnCollisionEnter(Collision other)
{
if (other.gameObject.TryGetComponent(out PlayerController player))
{
player.OnDefeated();
}
}
private void EliminateBall()
{
Destroy(gameObject, 6f);
}
}

对状态的操作

新建状态PlayerState_Defeated

image-20220922131642449

用来玩家生成死亡时的音效、特效

using System;
using UnityEngine;
[CreateAssetMenu(menuName = "Data/StateMachine/PlayerState/Defeated", fileName = "PlayerState_Defeated")]
public class PlayerState_Defeated : PlayerState
{
[SerializeField] ParticleSystem Deathvfx;//死亡特效
[SerializeField] AudioClip[] voice;//音效集合
public override void Enter()
{
base.Enter();
Instantiate(Deathvfx, player.transform.position, Quaternion.identity);//生成特效
AudioClip deathVoice = voice[UnityEngine.Random.Range(0, voice.Length)];//随机选中一个音效
player.voicePlayer.PlayOneShot(deathVoice);//播放音效
}
}

UI相关

新建SceneLoader脚本用来管理场景的切换,用来实现ui中按钮功能

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneLoader
{
public static void ReloadScene()
{//重开
int sceneIndex = SceneManager.GetActiveScene().buildIndex;//获取场景下标
SceneManager.LoadScene(sceneIndex);//切换为当前场景(重进)
}
public static void QuitGame()
{//退出游戏
//如果在编辑器中运行
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;//判断当前是否处于游戏状态
#else
Application.Quie();//退出应用
#endif
}
public static void LoadNextScene()
{//下一关
int sceneIndex = SceneManager.GetActiveScene().buildIndex + 1;//获取下一关场景下标
if (sceneIndex >= SceneManager.sceneCount)
{//如果下标大于场景总数
ReloadScene();//返回当前关
return;
}
SceneManager.LoadScene(sceneIndex);//切换为下一关
}
}

UI中新建DefeatScreen同名脚本

image-20220923122705802

OnEnableOnDisable中订阅、退订按钮功能。

PlayerShot中实现随机播放失败bgm。这里有个问题,我在玩家失败状态类中实现这个功能的时候,最终运行时音效呈现的效果是若干音乐叠加 而且音调更低,排查了很久找不到原因,所以我把这个功能改成了动画事件触发。动画里事件大概在这个位置

image-20220923150710067

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DefeatScreen : MonoBehaviour
{
[SerializeField] VoidEventChannel playerDefeatedEventChannel;//获取事件频道
[SerializeField] AudioClip[] voice;//加油音效合集
[SerializeField] Button retryButton;
[SerializeField] Button quitButton;
private void OnEnable()
{
playerDefeatedEventChannel.AddListener(ShowUI);//订阅展示ui函数
retryButton.onClick.AddListener(SceneLoader.ReloadScene);//订阅重置按钮功能
quitButton.onClick.AddListener(SceneLoader.QuitGame);//订阅退出按钮功能
}
private void OnDisable()
{
playerDefeatedEventChannel.RemoveListener(ShowUI);
retryButton.onClick.RemoveListener(SceneLoader.ReloadScene);
quitButton.onClick.RemoveListener(SceneLoader.QuitGame);
}
private void ShowUI()
{
GetComponent<Canvas>().enabled = true;
GetComponent<Animator>().enabled = true;
Cursor.lockState = CursorLockMode.None;//显示鼠标光标
}
void PlayerShot()
{
AudioClip retryVoice = voice[UnityEngine.Random.Range(0, voice.Length)];//随机播放加油音效
//游戏错误失败音效 许可:CC-BY 作者:GabrielAraujo 来源:耳聆网 https://www.ear0.com/sound/13207
SoundEffectsPlayer.audioSource.PlayOneShot(retryVoice);//播放音效
}
}

评论