using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Playables;
using RPGTALK.Snippets;
[AddComponentMenu("Seize Studios/RPGTalk/RPGTalk Area")]
public class RPGTalkArea : MonoBehaviour {
///
/// The RPGTalk to be played. Can be left null if you only need to play a timeline director, for instance
///
public RPGTalk rpgtalkTarget;
///
/// Should the Talk start only when the player hit a button?
///
public bool shouldInteractWithButton;
///
/// When the player can interact, show/hide any GameObjects. Useful for something like 'Press A to talk'
///
public GameObject[] showWhenInteractionIsPossible;
///
/// What is the key that should be used to interact? You can override the Update function and write your
/// own conditions, if needed
///
public KeyCode interactionKey = KeyCode.None;
///
/// What button, set in the Input Settings, should interact with the area
///
public string interactionButton;
///
/// Should the are interact when the player clicks with the left button of the mouse?
///
public bool interactWithMouse;
bool canInteract;
///
/// The talk will only begin if someone with this tag hits it. Leave blank to accept anyone
///
public string checkIfColliderHasTag = "";
///
/// A series of events to be called before the talk starts
///
public UnityEvent callbackBeforeTalk;
///
/// What line to start the talk
///
public string lineToStart = "1";
///
/// What line to finish the talk (leave -1 to read the file until the end)
///
public string lineToBreak = "-1";
///
/// The text file to be parsed into the talks. Leave empty if it is the same as the rpgtalkTarget
///
public TextAsset txtToParse;
///
/// Overwrite the variable callback on RPGTalk. Leave empty if no ovewrite is wanted
///
public UnityEvent overwriteCallbackAfterTalk;
///
/// Should this talk/interaction be available only once?
///
public bool happenOnlyOnce;
[HideInInspector]
///
/// This talk already happened before?
///
public bool alreadyHappened;
///
/// Activate talk on trigger enter? (ignored if shouldInteractWithButton is true)
///
public bool triggerEnter = true;
///
/// Activate talk on trigger exit? (ignored if shouldInteractWithButton is true)
///
public bool triggerExit = false;
///
/// After the talk finishes, the canvas shold stay on the screen?
///
public bool shouldStayOnScreen;
///
/// Forbids the talk to be initialized if the rpgtalkTarget is already showing something else.
///
public bool forbidPlayIfRpgtalkIsPlaying;
///
/// The timeline director can be played with the same rules as the talk.
///
public PlayableDirector timelineDirectorToPlay;
///
/// Save (With RPGTAlkSaveInstance on RPGTalk Holder), if this area has already happened. The name of the object will be the saveData value.
///
public bool saveAlreadyHappened;
///
/// Should the talk pass itself?
///
public bool autoPass = false;
///
/// How many seconds should RPGTalk wait after the animation stopped to autoPass
///
public float secondsAutoPass = 3f;
///
/// If it has a RPGTalkFollowCharacter, should it be contained inside the screen?
///
public bool containInsideScreen;
///
/// Hide anything that shouldn't be showing upon the start
///
protected virtual void Start () {
HideInteractionInstruction ();
if (saveAlreadyHappened)
{
if (rpgtalkTarget.saveInstance)
{
alreadyHappened = rpgtalkTarget.saveInstance.GetSavedData(name, 1);
}
}
}
///
/// Check for the interaction. Override this method to implement your own rules
///
protected virtual void Update () {
if (shouldInteractWithButton && canInteract) {
if ((interactionKey != KeyCode.None && Input.GetKeyDown (interactionKey)) ||
(interactionButton != "" && Input.GetButtonDown(interactionButton)) ||
(interactWithMouse && Input.GetMouseButtonDown(0)) ) {
StartTalk ();
}
}
}
///
/// Check the rules and put it into rpgtalkTarget, initializing a new talk.
///
protected virtual void NewTalk(){
if (rpgtalkTarget == null || (happenOnlyOnce && alreadyHappened) || (forbidPlayIfRpgtalkIsPlaying && rpgtalkTarget.isPlaying)) {
return;
}
alreadyHappened = true;
if (saveAlreadyHappened)
{
if (rpgtalkTarget.saveInstance)
{
rpgtalkTarget.saveInstance.SaveData(name, 1);
}
}
callbackBeforeTalk.Invoke();
TextAsset newTxt = rpgtalkTarget.txtToParse;
if (txtToParse != null) {
newTxt = txtToParse;
}
rpgtalkTarget.shouldStayOnScreen = shouldStayOnScreen;
rpgtalkTarget.autoPass = autoPass;
rpgtalkTarget.secondsAutoPass = secondsAutoPass;
RPGTalkFollowCharacter followCharacter = rpgtalkTarget.GetComponent();
if (followCharacter)
{
followCharacter.containInsideScreen = containInsideScreen;
}
rpgtalkTarget.NewTalk (lineToStart, lineToBreak, newTxt, overwriteCallbackAfterTalk);
}
///
/// Show anything in the showWhenInteractionIsPossible array
///
protected virtual void ShowInteractionInstruction(){
if (happenOnlyOnce && alreadyHappened) {
return;
}
foreach (GameObject GO in showWhenInteractionIsPossible) {
GO.SetActive (true);
}
}
///
/// Hides anything in the showWhenInteractionIsPossible array
///
protected virtual void HideInteractionInstruction(){
foreach (GameObject GO in showWhenInteractionIsPossible) {
GO.SetActive (false);
}
}
///
/// Prepare the variables for the interaction or just call a new talk
///
/// Should only work with specifc tag?
/// Was called from an OnTriggerExite?
protected virtual void PrepareInteraction(string tagName, bool gettingOut = false){
if(tagName == checkIfColliderHasTag || checkIfColliderHasTag == ""){
if (shouldInteractWithButton) {
if (!gettingOut) {
canInteract = true;
ShowInteractionInstruction ();
} else {
canInteract = false;
HideInteractionInstruction ();
}
} else {
if((gettingOut && triggerExit) || (!gettingOut && triggerEnter)){
StartTalk ();
}
}
}
}
protected virtual void OnTriggerEnter(Collider col){
PrepareInteraction (col.tag);
}
protected virtual void OnTriggerExit(Collider col){
PrepareInteraction (col.tag,true);
}
protected virtual void OnTriggerEnter2D(Collider2D col){
PrepareInteraction (col.tag);
}
protected virtual void OnTriggerExit2D(Collider2D col){
PrepareInteraction (col.tag,true);
}
///
/// Hide anything that should be showing, starts a new talk and plays the timeline director
///
protected virtual void StartTalk(){
HideInteractionInstruction ();
if (rpgtalkTarget != null) {
NewTalk ();
}
if (timelineDirectorToPlay != null) {
timelineDirectorToPlay.Play ();
}
}
}