This commit is contained in:
SoulliesOfficial
2026-01-03 18:19:39 -05:00
parent 3bcd7c1cf8
commit 33b1795c1f
7387 changed files with 2762819 additions and 716926 deletions

View File

@@ -1,52 +0,0 @@
/// ---------------------------------------------
/// Behavior Designer
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.BehaviorDesigner.Samples.SceneManagers
{
using Opsive.BehaviorDesigner.Runtime;
using UnityEngine;
using System.Collections.Generic;
/// <summary>
/// Manages the Events scene.
/// </summary>
public class EventsSceneManager : MonoBehaviour
{
[Tooltip("A prefab of the behavior tree agent.")]
[SerializeField] protected GameObject m_AgentPrefab;
[Tooltip("The number of agents that should be spawned.")]
[SerializeField] protected int m_SpawnCount;
[Tooltip("The center of the spawn.")]
[SerializeField] protected GameObject m_SpawnCenter;
[Tooltip("The spawn area.")]
[SerializeField] protected Vector2 m_SpawnSize;
[Tooltip("The location the agent should move to. The agent will randomly choose one destination.")]
[SerializeField] protected GameObject[] m_Destinations;
[Tooltip("A reference to the turret.")]
[SerializeField] protected Turret m_Turret;
/// <summary>
/// Spawns the agents.
/// </summary>
public void Awake()
{
var agentHealths = new List<Health>();
for (int i = 0; i < m_SpawnCount; ++i) {
var position = m_SpawnCenter.transform.position + new Vector3(Random.Range(-m_SpawnSize.x, m_SpawnSize.x), 0, Random.Range(-m_SpawnSize.y, m_SpawnSize.y));
var agent = Object.Instantiate(m_AgentPrefab, position, m_SpawnCenter.transform.rotation);
agent.name = m_AgentPrefab.name + (i + 1);
// Set the scene variables.
var behaviorTree = agent.GetComponent<BehaviorTree>();
var destinationVariable = behaviorTree.GetVariable<GameObject>("Destination");
destinationVariable.Value = m_Destinations[Random.Range(0, m_Destinations.Length)];
agentHealths.Add(agent.GetComponent<Health>());
}
m_Turret.Targets = agentHealths;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 448076947215b3b41b197c0774afc9ce
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,75 +0,0 @@
/// ---------------------------------------------
/// Behavior Designer
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.BehaviorDesigner.Samples.SceneManagers
{
using Opsive.BehaviorDesigner.Runtime;
using UnityEngine;
using UnityEngine.AI;
/// <summary>
/// Manages the Hide and Seek scene.
/// </summary>
public class HideSeekSceneManager : MonoBehaviour
{
[Tooltip("A reference to the agent prefab.")]
[SerializeField] protected GameObject m_AgentPrefab;
[Tooltip("The locations that the agent should spawn.")]
[SerializeField] protected GameObject[] m_SpawnLocations;
[Tooltip("The locations the agents should patrol.")]
[SerializeField] protected GameObject[] m_PatrolWaypoints;
[Tooltip("A reference to the player.")]
[SerializeField] protected GameObject m_Player;
[Tooltip("The objects that should be reset.")]
[SerializeField] protected GameObject[] m_ResetObjects;
private GameObject[] m_SpawnedAgents;
private Vector3[] m_ResetPositions;
private Quaternion[] m_ResetRotations;
/// <summary>
/// Spawn the agents.
/// </summary>
private void Awake()
{
m_SpawnedAgents = new GameObject[m_SpawnLocations.Length];
for (int i = 0; i < m_SpawnLocations.Length; ++i) {
m_SpawnedAgents[i] = Object.Instantiate(m_AgentPrefab, m_SpawnLocations[i].transform.position, m_SpawnLocations[i].transform.rotation);
var behaviorTree = m_SpawnedAgents[i].GetComponent<BehaviorTree>();
var playerVariable = behaviorTree.GetVariable<GameObject>("Player");
playerVariable.Value = m_Player;
var waypointsVariable = behaviorTree.GetVariable<GameObject[]>("Waypoints");
waypointsVariable.Value = m_PatrolWaypoints;
}
m_ResetPositions = new Vector3[m_ResetObjects.Length];
m_ResetRotations = new Quaternion[m_ResetObjects.Length];
for (int i = 0; i < m_ResetPositions.Length; ++i) {
m_ResetPositions[i] = m_ResetObjects[i].transform.position;
m_ResetRotations[i] = m_ResetObjects[i].transform.rotation;
}
}
/// <summary>
/// Restarts the scene.
/// </summary>
public void Restart()
{
for (int i = 0; i < m_ResetPositions.Length; ++i) {
m_ResetObjects[i].transform.SetPositionAndRotation(m_ResetPositions[i], m_ResetRotations[i]);
Animator animator;
if ((animator = m_ResetObjects[i].GetComponent<Animator>()) != null) {
animator.SetFloat("Forward", 0);
}
}
for (int i = 0; i < m_SpawnedAgents.Length; ++i) {
m_SpawnedAgents[i].transform.SetPositionAndRotation(m_SpawnLocations[i].transform.position, m_SpawnLocations[i].transform.rotation);
m_SpawnedAgents[i].GetComponent<NavMeshAgent>().Warp(m_SpawnLocations[i].transform.position);
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 5888c01490b944d4ebeb7e9468f0adb0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,37 +0,0 @@
/// ---------------------------------------------
/// Behavior Designer
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.BehaviorDesigner.Samples.SceneManagers
{
using Opsive.BehaviorDesigner.Runtime;
using UnityEngine;
/// <summary>
/// Manages the melee combat scene.
/// </summary>
public class MeleeCombatSceneManager : MonoBehaviour
{
[Header("Agent")]
[Tooltip("A reference to the behavior tree agent.")]
[SerializeField] protected GameObject m_Agent;
[Header("Opponent")]
[Tooltip("A reference to the behavior tree opponent.")]
[SerializeField] protected GameObject m_Opponent;
/// <summary>
/// Initializes the default values.
/// </summary>
private void Awake()
{
var behaviorTree = m_Agent.GetComponent<BehaviorTree>();
var sharedVariable = behaviorTree.GetVariable<GameObject>("Opponent");
sharedVariable.Value = m_Opponent;
behaviorTree = m_Opponent.GetComponent<BehaviorTree>();
sharedVariable = behaviorTree.GetVariable<GameObject>("Opponent");
sharedVariable.Value = m_Agent;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 23934332dea978a4682a32e6ca24e113
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,75 +0,0 @@
/// ---------------------------------------------
/// Behavior Designer
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.BehaviorDesigner.Samples.SceneManagers
{
using Opsive.BehaviorDesigner.Runtime;
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
/// <summary>
/// Switches to the next scene after a random amount of time.
/// </summary>
public class PersistentScenesManager : MonoBehaviour
{
[Tooltip("A reference to the behavior tree agent prefab.")]
[SerializeField] protected GameObject m_Agent;
[Tooltip("The waypoints within the scene.")]
[SerializeField] protected GameObject[] m_Waypoints;
[Tooltip("The name of the next scene.")]
[SerializeField] protected string m_NextSceneName;
[Tooltip("The minimum seconds for changing to the next scene.")]
[SerializeField] protected int m_MinimumNextSceneChangeRange = 5;
[Tooltip("The maximum seconds for changing to the next scene.")]
[SerializeField] protected int m_MaximumNextSceneChangeRange = 9;
[Tooltip("A reference to the visual countdown until the scene is changed.")]
[SerializeField] protected UnityEngine.UI.Text m_CountdownText;
/// <summary>
/// Initializes the default values.
/// </summary>
public void Awake()
{
#if UNITY_2022
var behaviorTree = Object.FindObjectOfType<BehaviorTree>();
#else
var behaviorTree = Object.FindFirstObjectByType<BehaviorTree>();
#endif
// The behavior tree will be found if it has already been marked as DontDestroyOnLoad.
if (behaviorTree == null) {
var agent = Object.Instantiate(m_Agent);
behaviorTree = agent.GetComponent<BehaviorTree>();
DontDestroyOnLoad(agent);
}
// Update the waypoints to the new scene. The behavior tree will stay active across scene changes.
var waypoints = behaviorTree.GetVariable<GameObject[]>("Waypoints");
if (waypoints == null) {
Debug.LogError("Error: Unable to find the Waypoints variable.");
return;
}
waypoints.Value = m_Waypoints;
StartCoroutine(LoadNextScene());
}
/// <summary>
/// Loads the next scene.
/// </summary>
private IEnumerator LoadNextScene()
{
var duration = Random.Range(m_MinimumNextSceneChangeRange, m_MaximumNextSceneChangeRange);
var startTime = Time.time;
while (startTime + duration > Time.time) {
m_CountdownText.text = $"Changing scenes in {Mathf.RoundToInt(startTime + duration - Time.time)} seconds";
yield return new WaitForEndOfFrame();
}
m_CountdownText.text = "Changing scenes";
SceneManager.LoadScene(m_NextSceneName);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 2f9a0bff653ee0341827e4046c1b5e58
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,210 +0,0 @@
/// ---------------------------------------------
/// Behavior Designer
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.BehaviorDesigner.Samples
{
using Opsive.BehaviorDesigner.Runtime;
using Opsive.GraphDesigner.Runtime.Variables;
using Opsive.Shared.Events;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// Manages the runtime behavior scene.
/// </summary>
public class RuntimeBehaviorSceneManager : MonoBehaviour
{
[Header("Agent")]
[Tooltip("A reference to the behavior tree agent.")]
[SerializeField] protected GameObject m_Agent;
[Tooltip("The location that the agent should train strength.")]
[SerializeField] protected GameObject m_StrengthLocation;
[Tooltip("The location that the agent should train speed.")]
[SerializeField] protected GameObject m_SpeedLocation;
[Tooltip("The location that the agent should fight.")]
[SerializeField] protected GameObject m_FightLocation;
[Tooltip("The left and right dumbbells.")]
[SerializeField] protected GameObject[] m_Dumbbells;
[Tooltip("The location the dumbbells should be equipped to.")]
[SerializeField] protected GameObject[] m_DumbbellParents;
[Tooltip("The location the dumbbells should be unequipped to.")]
[SerializeField] protected GameObject[] m_DumbbellStorage;
[Tooltip("The left and right boxing gloves.")]
[SerializeField] protected GameObject[] m_BoxingGloves;
[Header("Opponent")]
[Tooltip("A reference to the behavior tree opponent.")]
[SerializeField] protected GameObject m_Opponent;
[Tooltip("The location that the opponent should fight.")]
[SerializeField] protected GameObject m_OpponentFightLocation;
[Tooltip("The left and right boxing gloves.")]
[SerializeField] protected GameObject[] m_OpponentBoxingGloves;
[Header("Camera")]
[Tooltip("Specifies the camera locations.")]
[SerializeField] protected GameObject[] m_CameraLocations;
[Header("UI")]
[Tooltip("A reference to the fight button.")]
[SerializeField] protected GameObject m_FightButton;
[Tooltip("A reference to the agent speed display.")]
[SerializeField] protected Text m_AgentSpeed;
[Tooltip("A reference to the agent strength display.")]
[SerializeField] protected Text m_AgentStrength;
[Tooltip("A reference to the agent health display.")]
[SerializeField] protected Text m_AgentHealth;
[Tooltip("A reference to the opponent health display.")]
[SerializeField] protected Text m_OpponentHealth;
private BehaviorTree m_AgentBehaviorTree;
private BehaviorTree m_OpponentBehaviorTree;
private SharedVariable<int> m_AgentSpeedVariable;
private SharedVariable<int> m_AgentStrengthVariable;
private SharedVariable<float> m_AgentHealthVariable;
private SharedVariable<float> m_OpponentHealthVariable;
/// <summary>
/// Initializes the default values.
/// </summary>
private void Awake()
{
m_AgentBehaviorTree = m_Agent.GetComponent<BehaviorTree>();
SetVariableValue(m_AgentBehaviorTree, "StrengthLocation", m_StrengthLocation);
SetVariableValue(m_AgentBehaviorTree, "SpeedLocation", m_SpeedLocation);
SetVariableValue(m_AgentBehaviorTree, "LeftDumbbell", m_Dumbbells[0]);
SetVariableValue(m_AgentBehaviorTree, "RightDumbbell", m_Dumbbells[1]);
SetVariableValue(m_AgentBehaviorTree, "LeftHand", m_DumbbellParents[0]);
SetVariableValue(m_AgentBehaviorTree, "RightHand", m_DumbbellParents[1]);
SetVariableValue(m_AgentBehaviorTree, "LeftDumbbellStorage", m_DumbbellStorage[0]);
SetVariableValue(m_AgentBehaviorTree, "RightDumbbellStorage", m_DumbbellStorage[1]);
SetVariableValue(m_AgentBehaviorTree, "LeftGlove", m_BoxingGloves[0]);
SetVariableValue(m_AgentBehaviorTree, "RightGlove", m_BoxingGloves[1]);
SetVariableValue(m_AgentBehaviorTree, "FightLocation", m_FightLocation);
EventHandler.RegisterEvent(m_AgentBehaviorTree, "OnChangeToStrengthLocation", () => { SetCameraLocation(CameraLocations.Dumbbells); });
EventHandler.RegisterEvent(m_AgentBehaviorTree, "OnChangeToSpeedLocation", () => { SetCameraLocation(CameraLocations.HeavyBag); });
m_OpponentBehaviorTree = m_Opponent.GetComponent<BehaviorTree>();
SetVariableValue(m_OpponentBehaviorTree, "FightLocation", m_OpponentFightLocation);
SetVariableValue(m_OpponentBehaviorTree, "LeftGlove", m_OpponentBoxingGloves[0]);
SetVariableValue(m_OpponentBehaviorTree, "RightGlove", m_OpponentBoxingGloves[1]);
m_AgentHealth.gameObject.SetActive(false);
m_OpponentHealth.gameObject.SetActive(false);
// Bind the health variable value to the health display.
#if UNITY_2022
var sceneVariables = Object.FindAnyObjectByType<SceneSharedVariables>();
#else
var sceneVariables = Object.FindFirstObjectByType<SceneSharedVariables>();
#endif
m_AgentSpeedVariable = sceneVariables.GetVariable<int>("AgentSpeed");
m_AgentSpeedVariable.OnValueChange += OnAgentSpeedChanged;
m_AgentStrengthVariable = sceneVariables.GetVariable<int>("AgentStrength");
m_AgentStrengthVariable.OnValueChange += OnAgentStrengthChanged;
m_AgentHealthVariable = sceneVariables.GetVariable<float>("AgentHealth");
m_AgentHealthVariable.OnValueChange += OnAgentHealthChanged;
m_OpponentHealthVariable = sceneVariables.GetVariable<float>("OpponentHealth");
m_OpponentHealthVariable.OnValueChange += OnOpponentHealthChanged;
}
/// <summary>
/// Sets the variable value on the specified tree.
/// </summary>
/// <param name="behaviorTree">The behavior tree that should be set.</param>
/// <param name="variableName">The name of the variable.</param>
/// <param name="value">The value of the variable.</param>
private void SetVariableValue<T>(BehaviorTree behaviorTree, string variableName, T value)
{
var sharedVariable = behaviorTree.GetVariable<T>(variableName);
sharedVariable.Value = value;
}
/// <summary>
/// The agent's speed value changed.
/// </summary>
private void OnAgentSpeedChanged()
{
m_AgentSpeed.text = "Agent Speed: " + m_AgentSpeedVariable.Value;
}
/// <summary>
/// The agent's strength value changed.
/// </summary>
private void OnAgentStrengthChanged()
{
m_AgentStrength.text = "Agent Strength: " + m_AgentStrengthVariable.Value;
}
/// <summary>
/// The agent's health value changed.
/// </summary>
private void OnAgentHealthChanged()
{
m_AgentHealth.text = "Agent Health: " + Mathf.Max(m_AgentHealthVariable.Value, 0);
}
/// <summary>
/// The agent's health value changed.
/// </summary>
private void OnOpponentHealthChanged()
{
m_OpponentHealth.text = "Opponent Health: " + Mathf.Max(m_OpponentHealthVariable.Value, 0);
}
/// <summary>
/// Training is done. Update the subtree references so the fight tree is used.
/// </summary>
public void Fight()
{
// The dumbbells should be unequipped.
m_Dumbbells[0].SetActive(false);
m_Dumbbells[1].SetActive(false);
m_FightButton.SetActive(false);
m_AgentSpeed.gameObject.SetActive(false);
m_AgentStrength.gameObject.SetActive(false);
m_AgentHealth.gameObject.SetActive(true);
m_OpponentHealth.gameObject.SetActive(true);
// The SubtreeReferenceSelector will use the SubtreeIndex in order to determine which subtree should be chosen.
SetVariableValue(m_AgentBehaviorTree, "SubtreeIndex", 1);
SetVariableValue(m_OpponentBehaviorTree, "SubtreeIndex", 1);
// Swap out the subtrees.
m_AgentBehaviorTree.ReevaluateSubtreeReferences();
m_OpponentBehaviorTree.ReevaluateSubtreeReferences();
SetCameraLocation(CameraLocations.BoxingRing);
}
/// <summary>
/// Specifies where the camera should be placed.
/// </summary>
public enum CameraLocations
{
HeavyBag, // The camera should look at the heavy rack.
Dumbbells, // The camera should look at the dumbbell rack.
BoxingRing, // The camera should look at the boxing ring.
}
/// <summary>
/// Changes the camera location.
/// </summary>
/// <param name="cameraLocation">The location the camera should be placed.</param>
private void SetCameraLocation(CameraLocations cameraLocation)
{
var index = (int)cameraLocation;
Camera.main.transform.SetPositionAndRotation(m_CameraLocations[index].transform.position, m_CameraLocations[index].transform.rotation);
}
/// <summary>
/// The agent has changed training locations.
/// </summary>
/// <param name="locationIndex"></param>
private void OnChangeTrainingLocations(object locationIndex)
{
SetCameraLocation((CameraLocations)locationIndex);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 73e9263674878d74f9d7a9d01a51ed2b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,185 +0,0 @@
/// ---------------------------------------------
/// Behavior Designer
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.BehaviorDesigner.Samples.SceneManagers
{
using Opsive.BehaviorDesigner.Runtime;
using System.IO;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.UI;
using static Opsive.BehaviorDesigner.Runtime.Utility.SaveManager;
/// <summary>
/// Saves and loads the behavior tree state.
/// </summary>
public class SaveLoadSceneManager : MonoBehaviour
{
[Tooltip("A reference to the behavior tree agent.")]
[SerializeField] protected GameObject m_Agent;
[Tooltip("The location that the behavior tree data should be saved.")]
[SerializeField] protected string m_SaveLocation = "Assets/Opsive/BehaviorDesigner/Samples/SaveLoad.save";
[Tooltip("A reference to the load button.")]
[SerializeField] protected Button m_LoadButton;
[Tooltip("A reference to the enemy agents.")]
[SerializeField] protected GameObject[] m_EnemyAgents;
[Tooltip("The location the enemies should move towards.")]
[SerializeField] protected GameObject[] m_EnemyDestinations;
private Transform m_Transform;
private BehaviorTree m_BehaviorTree;
private Animator m_Animator;
/// <summary>
/// Cache the variables and start moving the enemies.
/// </summary>
private void Awake()
{
m_Transform = m_Agent.transform;
m_BehaviorTree = m_Agent.GetComponent<BehaviorTree>();
m_Animator = m_Agent.GetComponent<Animator>();
m_BehaviorTree.SetVariableValue<GameObject[]>("Enemies", m_EnemyAgents);
if (!File.Exists(m_SaveLocation)) {
m_LoadButton.interactable = false;
}
for (int i = 0; i < m_EnemyAgents.Length; ++i) {
m_EnemyAgents[i].GetComponent<NavMeshAgent>().SetDestination(m_EnemyDestinations[Random.Range(0, m_EnemyDestinations.Length)].transform.position);
}
}
/// <summary>
/// Stores all of the agent save data in one structure.
/// </summary>
private struct AgentSaveData
{
public SaveData BehaviorTreeSaveData; // The behavior tree save data.
public int TargetIndex; // The index of the Target SharedVariable.
public int AnimationStateHash; // The current Animator state.
public int AnimationParameter; // The Animator "State" parameter value.
public Vector3[] EnemyPositions; // The enemy's position.
public Quaternion[] EnemyRotations; // The enemy's rotation.
public int[] EnemyAnimationStateHashes; // The enemy's Animator state.
public float[] EnemyAnimationNormalizedTimes; // The enemy's Animator playback time.
public float[] EnemyAnimationForwardParameters; // The enemy's Animator "Forward" parameter value.
public int[] EnemyAnimationStateParameters; // The enemy's Animator "State" parameter value.
public bool[] EnemyIsStopped; // True if the enemy's NavmeshAgent is stopped.
public Vector3[] EnemyDestinations; // The destination of the enemy.
public float CameraAnimationTime; // The camera's current animation time.
}
/// <summary>
/// Save the agent state.
/// </summary>
public void Save()
{
var saveData = m_BehaviorTree.Save(); // Don't use BehaviorTree.Save(FilePath) because it will only save the BehaviorTree data to the file path.
if (!saveData.HasValue) {
return;
}
var target = m_BehaviorTree.GetVariable<GameObject>("Target");
var targetIndex = -1;
for (int i = 0; i < m_EnemyAgents.Length; ++i) {
if (target.Value == m_EnemyAgents[i]) {
targetIndex = i;
break;
}
}
var enemyPositions = new Vector3[m_EnemyAgents.Length];
var enemyRotations = new Quaternion[m_EnemyAgents.Length];
var enemyAnimationStateHashes = new int[m_EnemyAgents.Length];
var enemyAnimationNormalizedTimes = new float[m_EnemyAgents.Length];
var enemyAnimationForwardParameters = new float[m_EnemyAgents.Length];
var enemyAnimationStateParameters = new int[m_EnemyAgents.Length];
var enemyIsStopped = new bool[m_EnemyAgents.Length];
var enemyDestinations = new Vector3[m_EnemyAgents.Length];
for (int i = 0; i < m_EnemyAgents.Length; ++i) {
enemyPositions[i] = m_EnemyAgents[i].transform.position;
enemyRotations[i] = m_EnemyAgents[i].transform.rotation;
enemyAnimationStateHashes[i] = m_EnemyAgents[i].GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).fullPathHash;
enemyAnimationNormalizedTimes[i] = m_EnemyAgents[i].GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).normalizedTime;
enemyAnimationForwardParameters[i] = m_EnemyAgents[i].GetComponent<Animator>().GetFloat("Forward");
enemyAnimationStateParameters[i] = m_EnemyAgents[i].GetComponent<Animator>().GetInteger("State");
enemyDestinations[i] = m_EnemyAgents[i].GetComponent<NavMeshAgent>().destination;
enemyIsStopped[i] = m_EnemyAgents[i].GetComponent<NavMeshAgent>().isStopped;
}
// Create the data structure which contains all of the values that should be saved.
var agentSaveData = new AgentSaveData() { BehaviorTreeSaveData = saveData.Value, TargetIndex = targetIndex,
AnimationStateHash = m_Animator.GetCurrentAnimatorStateInfo(0).fullPathHash, AnimationParameter = m_Animator.GetInteger("State"),
EnemyPositions = enemyPositions, EnemyRotations = enemyRotations, EnemyAnimationStateHashes = enemyAnimationStateHashes,
EnemyAnimationNormalizedTimes = enemyAnimationNormalizedTimes, EnemyAnimationForwardParameters = enemyAnimationForwardParameters,
EnemyAnimationStateParameters = enemyAnimationStateParameters, EnemyIsStopped = enemyIsStopped,
EnemyDestinations = enemyDestinations, CameraAnimationTime = Camera.main.GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).normalizedTime };
if (File.Exists(m_SaveLocation)) {
File.Delete(m_SaveLocation);
}
try {
if (!Directory.Exists(Path.GetDirectoryName(m_SaveLocation))) {
Directory.CreateDirectory(Path.GetDirectoryName(m_SaveLocation));
}
var fileStream = File.Create(m_SaveLocation);
using (var streamWriter = new StreamWriter(fileStream)) {
streamWriter.Write(JsonUtility.ToJson(agentSaveData));
}
fileStream.Close();
} catch (System.Exception e) {
Debug.LogException(e);
return;
}
m_LoadButton.interactable = true;
}
/// <summary>
/// Load the agent state.
/// </summary>
public void Load()
{
if (!File.Exists(m_SaveLocation)) {
return;
}
AgentSaveData agentSaveData;
var fileStream = File.Open(m_SaveLocation, FileMode.Open);
using (var streamReader = new StreamReader(fileStream)) {
var fileData = streamReader.ReadToEnd();
agentSaveData = JsonUtility.FromJson<AgentSaveData>(fileData);
}
fileStream.Close();
// Restore the values.
m_BehaviorTree.Load(agentSaveData.BehaviorTreeSaveData, (BehaviorTree tree) =>
{
// Scene objects cannot be persisted to a file. Restore the scene values before the tasks are restored.
m_BehaviorTree.SetVariableValue<GameObject[]>("Enemies", m_EnemyAgents);
if (agentSaveData.TargetIndex != -1) {
m_BehaviorTree.SetVariableValue("Target", m_EnemyAgents[agentSaveData.TargetIndex]);
}
});
m_Animator.Play(agentSaveData.AnimationStateHash, 0);
m_Animator.SetInteger("State", agentSaveData.AnimationParameter);
// Restore the enemy agent values.
for (int i = 0; i < m_EnemyAgents.Length; ++i) {
m_EnemyAgents[i].transform.SetPositionAndRotation(agentSaveData.EnemyPositions[i], agentSaveData.EnemyRotations[i]);
m_EnemyAgents[i].GetComponent<Animator>().Play(agentSaveData.EnemyAnimationStateHashes[i], 0, agentSaveData.EnemyAnimationNormalizedTimes[i]);
m_EnemyAgents[i].GetComponent<Animator>().SetFloat("Forward", agentSaveData.EnemyAnimationForwardParameters[i]);
m_EnemyAgents[i].GetComponent<Animator>().SetInteger("State", agentSaveData.EnemyAnimationStateParameters[i]);
m_EnemyAgents[i].GetComponent<NavMeshAgent>().isStopped = agentSaveData.EnemyIsStopped[i];
if (!agentSaveData.EnemyIsStopped[i]) {
m_EnemyAgents[i].GetComponent<NavMeshAgent>().SetDestination(agentSaveData.EnemyDestinations[i]);
}
m_EnemyAgents[i].GetComponent<Health>().Value = agentSaveData.EnemyIsStopped[i] ? 0 : 100;
}
Camera.main.GetComponent<Animator>().Play(Camera.main.GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).fullPathHash, 0, agentSaveData.CameraAnimationTime);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: d5511cc8b2a73f54b872a290ed0e0585
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,101 +0,0 @@
/// ---------------------------------------------
/// Behavior Designer
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.BehaviorDesigner.Samples.SceneManagers
{
using Opsive.BehaviorDesigner.Runtime;
using UnityEngine;
/// <summary>
/// Manually ticks the behavior tree when it is the agent's turn.
/// </summary>
public class TurnBasedSceneManager : MonoBehaviour
{
[Tooltip("The player GameObject.")]
[SerializeField] protected GameObject m_Player;
[Tooltip("The agents against the player.")]
[SerializeField] protected GameObject[] m_Agents;
[Tooltip("Specifies the amount of time to wait in between turns.")]
[SerializeField] protected float m_TurnDelay = 3;
[Tooltip("The player instructions.")]
[SerializeField] protected GameObject m_InstructionsUI;
public GameObject Player { get => m_Player; }
public GameObject[] Agents { get => m_Agents; }
private bool m_PlayersTurn = false;
private bool m_CanAttack = false;
private BehaviorTree m_BehaviorTree;
private TurnBaseCharacterController m_PlayerController;
/// <summary>
/// Initializes the default values.
/// </summary>
public void Awake()
{
m_BehaviorTree = GetComponent<BehaviorTree>();
m_PlayerController = m_Player.GetComponent<TurnBaseCharacterController>();
enabled = false; // Enable when it is the agent's turn.
StartTurn();
}
/// <summary>
/// Alternates the turn between the player and the agent.
/// </summary>
public void StartTurn()
{
m_PlayersTurn = !m_PlayersTurn;
if (m_PlayersTurn) {
m_InstructionsUI.SetActive(true);
m_CanAttack = true;
} else {
enabled = true;
}
}
/// <summary>
/// The specified character has been selected by the player.
/// </summary>
/// <param name="character">The selected character.</param>
public void SelectedCharacter(GameObject character)
{
// Wait for the player's turn.
if (!m_PlayersTurn || !m_CanAttack) {
return;
}
// The player can't shoot themself.
if (character == m_Player) {
return;
}
m_PlayerController.Attack(character);
m_CanAttack = false;
Invoke("StartTurn", m_TurnDelay);
m_InstructionsUI.SetActive(false);
}
/// <summary>
/// Ticks the behavior tree.
/// </summary>
public void Update()
{
m_BehaviorTree.Tick();
}
/// <summary>
/// The AI is done with their turn.
/// </summary>
public void EndAgentTurn()
{
enabled = false;
Invoke("StartTurn", m_TurnDelay);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: c41c950d96cabdc458c094b787c3ec69
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: