using UnityEngine;
using System.Collections;
using UnityEngine.Events;
using MalbersAnimations.Scriptables;
using UnityEngine.SceneManagement;
using UnityEngine.Serialization;
using MalbersAnimations.Events;
namespace MalbersAnimations.Controller
{
/// Use this Script's Transform as the Respawn Point
[AddComponentMenu("Malbers/Animal Controller/Respawner NPC")]
public class MRespawnerNPC : MonoBehaviour
{
#region Respawn
[Tooltip("Animal Prefab to Swpawn")]
public MAnimal NPC;
public StateID RespawnState;
public FloatReference RespawnTime = new FloatReference(10f);
[Tooltip("If True: it will destroy the MainPlayer GameObject and Respawn a new One")]
public BoolReference DestroyAfterRespawn = new BoolReference(true);
/// Active Animal
private MAnimal ActiveAnimal;
#endregion
[FormerlySerializedAs("OnRestartGame")]
public GameObjectEvent OnRespawned = new GameObjectEvent();
private bool Respawned;
void OnLevelFinishedLoading(Scene scene, LoadSceneMode mode)
{
FindNPCAnimal();
}
public virtual void DontDestroyOnLoad_GameObject(GameObject gameObject) => DontDestroyOnLoad(gameObject);
void OnEnable()
{
if (!isActiveAndEnabled) return;
DontDestroyOnLoad(gameObject);
gameObject.name = gameObject.name + " Instance";
SceneManager.sceneLoaded += OnLevelFinishedLoading;
FindNPCAnimal();
}
private void OnDisable()
{
SceneManager.sceneLoaded -= OnLevelFinishedLoading;
if (ActiveAnimal != null)
ActiveAnimal.OnStateChange.RemoveListener(OnCharacterDead); //Listen to the Animal changes of states
}
void FindNPCAnimal()
{
if (Respawned) return; //meaning the animal was already respawned.
if (NPC != null)
{
if (NPC.gameObject.IsPrefab())
{
ActiveAnimal = Instantiate(NPC);
}
else
{
ActiveAnimal = NPC;
}
SceneAnimal();
}
else
{
Debug.LogWarning("[Respawner Removed]. There's no Character assigned", this);
Destroy(gameObject); //Destroy This GO since is already a Spawner in the scene
}
}
private void SceneAnimal()
{
ActiveAnimal.OverrideStartState = RespawnState;
ActiveAnimal.ResetController();
ActiveAnimal.enabled = true;
ActiveAnimal.OnStateChange.AddListener(OnCharacterDead); //Listen to the Animal changes of states
ActiveAnimal.Teleport_Internal(transform.position); //Move the Animal to is Start Position
ActiveAnimal.transform.rotation = (transform.rotation); //Move the Animal to is Start Position
ActiveAnimal.isPlayer.Value = false;
Respawned = true;
// Debug.Log("Placed");
}
/// Listen to the Animal States
public void OnCharacterDead(int StateID)
{
if (!Respawned) return;
if (StateID == StateEnum.Death) //Means Death
{
// Debug.Log("OnCharacterDead" + StateID);
ActiveAnimal.OnStateChange.RemoveListener(OnCharacterDead); //Remove listener from the Animal
Respawned = false;
if (NPC != null) //If the Player is a Prefab then then instantiate it on the created scene
{
if (NPC.gameObject.IsPrefab())
{
this.Delay_Action(RespawnTime, () =>
{
DestroyCurrentDeathAnimal();
this.Delay_Action(() => FindNPCAnimal());
}
);
}
else
{
var DeathS = ActiveAnimal.activeState as Death; //make sure the Death does not disable all things... since where reusing the same animal
DeathS.disableAnimal = false;
DeathS.DisableAllComponents = false;
DeathS.RemoveAllColliders = false;
DeathS.RemoveAllTriggers = false;
this.Delay_Action(RespawnTime, () => SceneAnimal());
}
}
}
}
void DestroyCurrentDeathAnimal()
{
if (ActiveAnimal != null)
{
if (DestroyAfterRespawn)
Destroy(ActiveAnimal.gameObject);
else
DestroyAllComponents(ActiveAnimal);
}
}
/// Destroy all the components on Animal and leaves the mesh and bones
private void DestroyAllComponents(MAnimal target)
{
if (!target) return;
var components = target.GetComponentsInChildren();
foreach (var comp in components) Destroy(comp);
var colliders = target.GetComponentsInChildren();
if (colliders != null)
{
foreach (var col in colliders) Destroy(col);
}
var rb = target.GetComponentInChildren();
if (rb != null) Destroy(rb);
var anim = target.GetComponentInChildren();
if (anim != null) Destroy(anim);
}
}
}