i mean by that when you reach some point or archived a bonus
some other game objects might need this information you
will have to inform your UI or some other enemies ect.
Using it is very simple
first of all our example is a very simple scene we have tree
cubes Red,Blue and Gold Cubes
when player reachs Blue cube score increases on red cube score
dicreases
And gold cube gets this information and appiers on screen
when player reaches gold cube 100 more score adds to player and
player control willbe disabled
its a basic example for focusing on pattern;
Since we have 3 different behaved cubes we will have three different
Scripts;
=> Red Cube Event onCollisionentered Invokes redCubeReached to subscribers
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RedCubeEvent : MonoBehaviour
{
public static event Action redCubeReached;
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Player") // assume that you only looking for player
redCubeReached?.Invoke();
}
}
=> Blue Cube Event OnCollisionentered Invokes cubeReached to all subscribers
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BlueCubeEvent : MonoBehaviour
{
public static event Action cubeReached;
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Player") // assume that you only looking for player
{
Debug.Log($"cube has been breached", this.gameObject);
cubeReached?.Invoke();
}
}
}
=> Gold Cube Event
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GoldCubeEvent : MonoBehaviour
{
public static event Action goldUnlocked;
bool isRedCubeOk;
bool isBlueCubeOk;
MeshRenderer mesh;
BoxCollider collider;
private void Start()
{
mesh = this.GetComponent<MeshRenderer>();
collider = this.GetComponent<BoxCollider>();
BlueCubeEvent.cubeReached += CubeEvent_cubeReached;
RedCubeEvent.redCubeReached += RedCubeAdditionalEvent_redCubeReached;
mesh.enabled = false;
collider.enabled = false;
}
private void RedCubeAdditionalEvent_redCubeReached()
{
isRedCubeOk = true;
CheckStatsAndFireGoldEvent();
}
private void CubeEvent_cubeReached()
{
isBlueCubeOk = true;
CheckStatsAndFireGoldEvent();
}
private void CheckStatsAndFireGoldEvent()
{
if (isRedCubeOk && isBlueCubeOk) // i can fire my gold event
{
collider.enabled = true;
mesh.enabled = true;
}
}
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Player")
{
goldUnlocked?.Invoke();
}
}
}
=> Player Controller (simple for example)
Player controller is listening for goldUnlocked event and Subscribing it by GoldCube_goldUnlocked method its like reaction to an event
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[SerializeField]
float moveSpeed;
bool isGameFinished;
void Start()
{
isGameFinished = false;
GoldCubeEvent.goldUnlocked += GoldCube_goldUnlocked;
}
private void GoldCube_goldUnlocked()
{
isGameFinished = true;
Debug.Log("Player You have Reach the end of level Controls disabled now" );
}
///
/// Very basic movement system
///
void Update()
{
if (isGameFinished)
return;
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
Vector3 p = this.transform.position;
p.x += h * moveSpeed;
p.z += v * moveSpeed;
this.transform.position = p;
}
}
=> ScoreCounter
Score Controller observes three different events with AddScore,SubstractScore,GoldEvent
as you see Score changes based on action
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ScoreCounter : MonoBehaviour
{
[SerializeField]
Text scoreText;
int currentScore = 0;
private void OnEnable()
{
// setting up observetions
// subscriped methods
BlueCubeEvent.cubeReached += AddScore;
RedCubeEvent.redCubeReached += SubstractScore;
GoldCubeEvent.goldUnlocked += GoldEvent;
}
private void GoldEvent()
{
currentScore += 100;
Debug.Log($"This function is fired from gold Cube");
scoreText.text = $"Score:{currentScore}";
}
private void SubstractScore()
{
Debug.Log($"This function is fired by RedcubeReached Event The RedCube");
currentScore--;
currentScore = Mathf.Clamp(currentScore, 0, int.MaxValue);
scoreText.text = $"Score:{currentScore}";
}
private void AddScore()
{
Debug.Log($"This function is fired by cubeReached Event The BlueCube ");
currentScore++;
scoreText.text = $"Score:{currentScore}";
}
private void OnDisable()
{
// unsubscribe on disable to prevent errors
BlueCubeEvent.cubeReached -= AddScore;
RedCubeEvent.redCubeReached -= SubstractScore;
}
}
Observerpattern can be used in many different games by chaning events and combinig wiht differentscenarios many problems may be solved easlyi hope it helps everyone Happy coding :)
No comments:
Post a Comment