using Unity.FPS.Game;using UnityEngine;namespace Unity.FPS.Gameplay
{publicclassObjectiveKillEnemies:Objective{[Tooltip("Chose whether you need to kill every enemies or only a minimum amount")]publicbool MustKillAllEnemies =true;[Tooltip("If MustKillAllEnemies is false, this is the amount of enemy kills required")]publicint KillsToCompleteObjective =5;[Tooltip("Start sending notification about remaining enemies when this amount of enemies is left")]publicint NotificationEnemiesRemainingThreshold =3;int m_KillTotal;protectedoverridevoidStart(){base.Start();
EventManager.AddListener<EnemyKillEvent>(OnEnemyKilled);// set a title and description specific for this type of objective, if it hasn't oneif(string.IsNullOrEmpty(Title))
Title ="Eliminate "+(MustKillAllEnemies ?"all the": KillsToCompleteObjective.ToString())+" enemies";if(string.IsNullOrEmpty(Description))
Description =GetUpdatedCounterAmount();}voidOnEnemyKilled(EnemyKillEvent evt){if(IsCompleted)return;
m_KillTotal++;if(MustKillAllEnemies)
KillsToCompleteObjective = evt.RemainingEnemyCount + m_KillTotal;int targetRemaining = MustKillAllEnemies ? evt.RemainingEnemyCount : KillsToCompleteObjective - m_KillTotal;// update the objective text according to how many enemies remain to killif(targetRemaining ==0){CompleteObjective(string.Empty,GetUpdatedCounterAmount(),"Objective complete : "+ Title);}elseif(targetRemaining ==1){string notificationText = NotificationEnemiesRemainingThreshold >= targetRemaining
?"One enemy left":string.Empty;UpdateObjective(string.Empty,GetUpdatedCounterAmount(), notificationText);}else{// create a notification text if needed, if it stays empty, the notification will not be createdstring notificationText = NotificationEnemiesRemainingThreshold >= targetRemaining
? targetRemaining +" enemies to kill left":string.Empty;UpdateObjective(string.Empty,GetUpdatedCounterAmount(), notificationText);}}stringGetUpdatedCounterAmount(){return m_KillTotal +" / "+ KillsToCompleteObjective;}voidOnDestroy(){
EventManager.RemoveListener<EnemyKillEvent>(OnEnemyKilled);}}}
2. Objective
using System;using UnityEngine;namespace Unity.FPS.Game
{publicabstractclassObjective:MonoBehaviour{[Tooltip("Name of the objective that will be shown on screen")]publicstring Title;[Tooltip("Short text explaining the objective that will be shown on screen")]publicstring Description;[Tooltip("Whether the objective is required to win or not")]publicbool IsOptional;[Tooltip("Delay before the objective becomes visible")]publicfloat DelayVisible;publicbool IsCompleted {get;privateset;}publicboolIsBlocking()=>!(IsOptional || IsCompleted);publicstaticevent Action<Objective> OnObjectiveCreated;publicstaticevent Action<Objective> OnObjectiveCompleted;protectedvirtualvoidStart(){
OnObjectiveCreated?.Invoke(this);DisplayMessageEvent displayMessage = Events.DisplayMessageEvent;
displayMessage.Message = Title;
displayMessage.DelayBeforeDisplay =0.0f;
EventManager.Broadcast(displayMessage);}publicvoidUpdateObjective(string descriptionText,string counterText,string notificationText){ObjectiveUpdateEvent evt = Events.ObjectiveUpdateEvent;
evt.Objective =this;
evt.DescriptionText = descriptionText;
evt.CounterText = counterText;
evt.NotificationText = notificationText;
evt.IsComplete = IsCompleted;
EventManager.Broadcast(evt);}publicvoidCompleteObjective(string descriptionText,string counterText,string notificationText){
IsCompleted =true;ObjectiveUpdateEvent evt = Events.ObjectiveUpdateEvent;
evt.Objective =this;
evt.DescriptionText = descriptionText;
evt.CounterText = counterText;
evt.NotificationText = notificationText;
evt.IsComplete = IsCompleted;
EventManager.Broadcast(evt);
OnObjectiveCompleted?.Invoke(this);}}}
3.Event
using UnityEngine;namespace Unity.FPS.Game
{// The Game Events used across the Game.// Anytime there is a need for a new event, it should be added here.publicstaticclassEvents{publicstaticObjectiveUpdateEvent ObjectiveUpdateEvent =newObjectiveUpdateEvent();publicstaticAllObjectivesCompletedEvent AllObjectivesCompletedEvent =newAllObjectivesCompletedEvent();publicstaticGameOverEvent GameOverEvent =newGameOverEvent();publicstaticPlayerDeathEvent PlayerDeathEvent =newPlayerDeathEvent();publicstaticEnemyKillEvent EnemyKillEvent =newEnemyKillEvent();publicstaticPickupEvent PickupEvent =newPickupEvent();publicstaticAmmoPickupEvent AmmoPickupEvent =newAmmoPickupEvent();publicstaticDamageEvent DamageEvent =newDamageEvent();publicstaticDisplayMessageEvent DisplayMessageEvent =newDisplayMessageEvent();}publicclassObjectiveUpdateEvent:GameEvent{publicObjective Objective;publicstring DescriptionText;publicstring CounterText;publicbool IsComplete;//合并到EnemyKillEvent里头publicstring NotificationText;}/*
*/publicclassAllObjectivesCompletedEvent:GameEvent{}publicclassGameOverEvent:GameEvent{publicbool Win;}publicclassPlayerDeathEvent:GameEvent{}publicclassEnemyKillEvent:GameEvent{publicGameObject Enemy;publicint RemainingEnemyCount;//把这里的int改为从碰撞器传来的bool}publicclassPickupEvent:GameEvent{publicGameObject Pickup;}publicclassAmmoPickupEvent:GameEvent{publicWeaponController Weapon;}publicclassDamageEvent:GameEvent{publicGameObject Sender;publicfloat DamageValue;}publicclassDisplayMessageEvent:GameEvent{publicstring Message;publicfloat DelayBeforeDisplay;}}