更新
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 448076947215b3b41b197c0774afc9ce
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5888c01490b944d4ebeb7e9468f0adb0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 23934332dea978a4682a32e6ca24e113
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2f9a0bff653ee0341827e4046c1b5e58
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73e9263674878d74f9d7a9d01a51ed2b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5511cc8b2a73f54b872a290ed0e0585
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c41c950d96cabdc458c094b787c3ec69
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user