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

ready动画结束后游戏开始,开始计时,直到死亡或者胜利再暂停计时。

新建ClearTime脚本用来更新时间文本,开始动画过后再计时

public class ClearTime : MonoBehaviour
{
[SerializeField] Text timeText;
[SerializeField] VoidEventChannel levelStartedEventChannel;//开始游戏
[SerializeField] VoidEventChannel levelClearedEventChannel;//玩家过关
[SerializeField] StringEventChannel cleardTimeTextEventChannel;//带string参数的频道
[SerializeField] VoidEventChannel playerDefeatedEventChannel;//玩家失败
float clearTime;//时间
bool stop = true;//计时停止

private void OnEnable()
{
//游戏开始
levelStartedEventChannel.AddListener(LevelStart);
//玩家通关
levelClearedEventChannel.AddListener(levelCleared);
//玩家失败
playerDefeatedEventChannel.AddListener(HideUI);
}
private void OnDisable()
{
//游戏开始
levelStartedEventChannel.RemoveListener(LevelStart);
//玩家通关
levelClearedEventChannel.RemoveListener(levelCleared);
//玩家失败
playerDefeatedEventChannel.RemoveListener(HideUI);
}
private void FixedUpdate()
{//当计时停止时 返回.
if (stop)
return;
clearTime += Time.fixedDeltaTime;
//将clearTime转化为秒,按格式输出
timeText.text = System.TimeSpan.FromSeconds(clearTime).ToString(@"mm\:ss\:ff");
}
void LevelStart()
{//开始游戏
stop = false;//开始计时
}
void levelCleared()
{//过关
HideUI();
cleardTimeTextEventChannel.Broadcast(timeText.text);
}
void HideUI()
{
stop = true;//计时停止
GetComponent<Canvas>().enabled = false;//关闭ui显示
}
}

过关时间显示在Victory Screen

说明:为角色胜利镜头做特殊定制

image-20221026021132507

follow属性用玩家对象

image-20221026021156345

过关功能实现

说明:过关时开启ui,切换状态为vitory,落地后再播放动画。

VictoryScreen中增加代码:订阅按钮功能,唤出鼠标指针。

using UnityEngine;
using UnityEngine.UI;
public class VictoryScreen : MonoBehaviour
{
[SerializeField] VoidEventChannel levelClearedEventChannel;//获取事件频道
[SerializeField] Button nextLevelButton;
private void OnEnable()
{
levelClearedEventChannel.AddListener(ShowUI);
nextLevelButton.onClick.AddListener(SceneLoader.LoadNextScene);//订阅下一关按钮功能
}
private void OnDisable()
{
levelClearedEventChannel.RemoveListener(ShowUI);
nextLevelButton.onClick.RemoveListener(SceneLoader.LoadNextScene);//订阅下一关按钮功能
}
private void ShowUI()
{
GetComponent<Canvas>().enabled = true;
GetComponent<Animator>().enabled = true;
Cursor.lockState = CursorLockMode.None;
}
}

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

功能实现

尖刺碰撞

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

说明:开始游戏时播放ui动画,放完后摧毁红色闸门。游戏结束时(吃完红宝石),弹出用时、结束画面。

image-20220921170427534

image-20220921171040912

开始画面

常规方法:通过委托联系宝石与门(观察者模式)

流程是:

  • 在宝石脚本中创建委托,并在碰撞函数中调用(Invoke());
  • 在门脚本中创建函数(Open())摧毁对象,并且订阅宝石中的委托。
  • 当宝石碰撞,调用了委托,订阅委托的两个门就执行相应动作(摧毁)。

image-20220921125104646

说明:红宝石和蓝宝石是一次性的,所以拾取后要摧毁音效对象,而黄宝石是需要重复利用的,不需要摧毁。

为了整体音效更好管理,新建一个SoundEffectsPlayer类,附加在SFX Player对象上,SFX Player对象上要有AudioSource组件

image-20220919133724914

public class SoundEffectsPlayer : MonoBehaviour
{
public static AudioSource audioSource { get; private set; }
private void Awake()
{
audioSource = GetComponent<AudioSource>();
audioSource.playOnAwake = false;
}
}

功能实现

说明:未落地时按跳跃键,可被记录,并且落地后起跳。

  • 降落状态,并且无法二段跳时,开启缓冲输入
  • 从降落到落地之间只要一直按着空格,落地后会立马跳起。
  • 中间松开就会关闭缓冲输入
  • 落地关闭缓冲输入

PlayerInput中添加变量public bool HasJumpInputBuffer { get; set; }

土狼时间

人物在地面/平台边缘即将掉落的时候,仍有机会进行跳跃动作;

其原理是:在人物掉落判定时开始计时,在设置的土狼时间内,可以按键跳跃。

  • 新建一个状态脚本PlayerState_CoyoteTime,大部分代码可复制PlayerState_Run
  • RUN状态转向CoyoteTime,首先关闭刚体重力(需要在PlayerController脚本中添加方法获取参数),使角色在空中保持一段时间。状态结束再开启刚体重力。
  • 其中包含的下落状态处理逻辑,因此可以将PlayerState_Run中浮空切换下落状态改为切换为PlayerState_CoyoteTime

总章中间漏了点,最近懒得补。干脆做到哪写到哪吧,有时间再整理。

  • 跳跃在空中的状态是:跳起->下落;

  • 跳起之后松开空格就是下落状态,所以二段跳逻辑我们写在下落状态中;

实现空中多段跳

  • 新建一个空中跳跃状态(PlayerState_AirJump.cs),为他添加资产菜单(CreateAssetMenu);

  • 空中跳跃的逻辑和普通跳跃一样,所以直接复制代码即可。重要的地方在于,我们需要给二段跳进行限制。