mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-12-09 22:39:06 +00:00
no message
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HPJ.Presentation.Agents
|
||||
{
|
||||
/// <summary>
|
||||
/// A example ground cast that connects a agent to the ground
|
||||
/// </summary>
|
||||
public class AgentGroundCast : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private LayerMask _groundLayers;
|
||||
[SerializeField]
|
||||
private Transform _raycastSpot;
|
||||
[SerializeField]
|
||||
private float _rayCastDistance;
|
||||
public float RayCastDistance { get { return _rayCastDistance; } set { _rayCastDistance = value; } }
|
||||
[SerializeField]
|
||||
private float _rayCastElevatedDistance;
|
||||
public float RayCastElevatedDistance { get { return _rayCastElevatedDistance; } set { _rayCastElevatedDistance = value; } }
|
||||
[SerializeField]
|
||||
[Range(1, 10)]
|
||||
private int _rayCastEveryXFrames = 3;
|
||||
public int RayCastEveryXFrames { get { return _rayCastEveryXFrames; } set { _rayCastEveryXFrames = value; } }
|
||||
[SerializeField]
|
||||
private Transform _effectTransform;
|
||||
[SerializeField]
|
||||
private float _floatAmount;
|
||||
public float FloatAmount { get { return _floatAmount; } set { _floatAmount = value; } }
|
||||
[SerializeField]
|
||||
private Vector3 _raycastDirection = Vector3.down;
|
||||
public Vector3 RaycastDirection { get { return _raycastDirection; } set { _raycastDirection = value; } }
|
||||
[SerializeField]
|
||||
private bool AttemptTeleportUpOnFail = false;
|
||||
|
||||
private RaycastHit _rayHit;
|
||||
private int _physicsCheckCounter = 0;
|
||||
// Update is called once per frame
|
||||
public void PhysicsCheck()
|
||||
{
|
||||
_physicsCheckCounter++;
|
||||
if (_physicsCheckCounter >= _rayCastEveryXFrames)
|
||||
{
|
||||
_physicsCheckCounter = 0;
|
||||
if (Physics.Raycast(_raycastSpot.position - _raycastDirection * _rayCastElevatedDistance, _raycastDirection, out _rayHit, _rayCastDistance + _rayCastElevatedDistance, _groundLayers))
|
||||
{
|
||||
//Debug.Log("Move");
|
||||
_effectTransform.transform.position = _rayHit.point - FloatAmount * _raycastDirection;
|
||||
}
|
||||
else if (Physics.Raycast(transform.position - _raycastDirection * _rayCastElevatedDistance, _raycastDirection, out _rayHit, _rayCastDistance + _rayCastElevatedDistance, _groundLayers))
|
||||
{
|
||||
//Debug.Log("Move 2");
|
||||
_effectTransform.transform.position = _rayHit.point - FloatAmount * _raycastDirection;
|
||||
}
|
||||
else if (AttemptTeleportUpOnFail)
|
||||
{
|
||||
TeleportUp();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void TeleportUp()
|
||||
{
|
||||
if (Physics.Raycast(_raycastSpot.position - _raycastDirection * 30, _raycastDirection, out _rayHit, _rayCastDistance * 60, _groundLayers))
|
||||
{
|
||||
//Debug.Log("Teleport");
|
||||
_effectTransform.transform.position = _rayHit.point - FloatAmount * _raycastDirection;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e31c7a1c22f26de4698459dd6ccada5b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,89 @@
|
||||
using HPJ.Presentation.Agents;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HPJ.Presentation
|
||||
{
|
||||
/// <summary>
|
||||
/// Displays a line of the Navigation Agents Remaining Path
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(LineRenderer))]
|
||||
[RequireComponent(typeof(NavigationAgent))]
|
||||
public class AgentLine : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// How Often the line is updated
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
private float _updateInterval = 0.1f;
|
||||
private float _updateTime = 0;
|
||||
|
||||
private LineRenderer _line;
|
||||
private NavigationAgent _agent;
|
||||
private List<Vector3> _linePoints;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_agent = GetComponent<NavigationAgent>();
|
||||
_line = GetComponent<LineRenderer>();
|
||||
_linePoints = new List<Vector3>();
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
_updateTime += Time.deltaTime;
|
||||
if (_updateTime > _updateInterval)
|
||||
{
|
||||
_updateTime = 0;
|
||||
UpdateLine();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the Line Renderer to the navigation agent remaining path
|
||||
/// </summary>
|
||||
public void UpdateLine()
|
||||
{
|
||||
_linePoints.Clear();
|
||||
|
||||
if (_agent.Path.Count <= 0)
|
||||
{
|
||||
_line.positionCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_agent.CurrentPathingIndex + 1 >= _agent.Path.Count)
|
||||
{
|
||||
Vector3 EndPoint = _agent.Path[_agent.Path.Count - 1];
|
||||
_linePoints.Add(EndPoint);
|
||||
|
||||
EndPoint.x = transform.position.x;
|
||||
EndPoint.z = transform.position.z;
|
||||
_linePoints.Add(EndPoint);
|
||||
|
||||
_line.positionCount = 2;
|
||||
_line.SetPositions(_linePoints.ToArray());
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 StartPoint = _agent.Path[_agent.CurrentPathingIndex + 1];
|
||||
StartPoint.x = transform.position.x;
|
||||
StartPoint.z = transform.position.z;
|
||||
_linePoints.Add(StartPoint);
|
||||
int PathCount = 1;
|
||||
|
||||
|
||||
for(int i = _agent.CurrentPathingIndex + 1; i < _agent.Path.Count; i++)
|
||||
{
|
||||
PathCount++;
|
||||
Vector3 NextPoint = _agent.Path[i];
|
||||
_linePoints.Add(NextPoint);
|
||||
}
|
||||
|
||||
_line.positionCount = PathCount;
|
||||
_line.SetPositions(_linePoints.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c649545522b2ab4b95a1fb7d7ef8974
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c2dd48d02935c94a83797754f33fe7c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,415 @@
|
||||
using HPJ.Simulation;
|
||||
using HPJ.Simulation.Enums;
|
||||
using HPJ.Simulation.Map;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HPJ.Presentation.Agents
|
||||
{
|
||||
[System.Serializable]
|
||||
public class SimAgent
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID for each simulation Agent
|
||||
/// </summary>
|
||||
public static ushort SimIDCounter = 1; // SimID of zero means no agent
|
||||
public ushort SimID { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// The corresponding Navigation Agent for this Simulation Agent
|
||||
/// </summary>
|
||||
public SimNavigationAgent NavAgent { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Position of the simulation agent
|
||||
/// </summary>
|
||||
public Vector3 Position { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether agent avoidance is active
|
||||
/// </summary>
|
||||
public bool AgentAvoidenceActive { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the base agent should call the on moving complete call
|
||||
/// </summary>
|
||||
public bool CallOnMovingComplete { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the base agent should call the on recieved path call
|
||||
/// </summary>
|
||||
public bool CallOnRecievePath { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Updates to the Core Agents position
|
||||
/// </summary>
|
||||
public bool UpdateToUnity { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tile owned by the Agent
|
||||
/// </summary>
|
||||
public IntVector2 OwnedTile { get; internal set; }
|
||||
|
||||
public static IntVector2 NullTile = -IntVector2.One;
|
||||
|
||||
/// <summary>
|
||||
/// Creates and Initializes the Agent
|
||||
/// </summary>
|
||||
/// <param name="Agent"></param>
|
||||
public SimAgent(SimNavigationAgent Agent, bool UseAgentAvoidence)
|
||||
{
|
||||
SimID = SimIDCounter;
|
||||
SimIDCounter++;
|
||||
|
||||
AgentAvoidenceActive = UseAgentAvoidence;
|
||||
NavAgent = Agent;
|
||||
UpdatePositionFromAgent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the agent simuliarily the unity version of Navigaiton Agent gets updated
|
||||
/// </summary>
|
||||
public void Update()
|
||||
{
|
||||
if (UpdateToUnity)
|
||||
{
|
||||
UpdateToUnity = false;
|
||||
UpdatePosition(NavAgent.DesiredPosition);
|
||||
}
|
||||
|
||||
if (NavAgent.State == AgentStates.Moving)
|
||||
{
|
||||
NavAgent._lerpPercentage += NavigationManager.Instance.HelperDeltaTime * NavAgent.MovementSpeed / NavAgent._lerpTotal;
|
||||
UpdatePosition(Vector3.Lerp(NavAgent.Path[NavAgent.CurrentPathingIndex], NavAgent.Path[NavAgent.CurrentPathingIndex + 1], NavAgent._lerpPercentage));
|
||||
|
||||
// Make sure the current tile for this agent is Valid
|
||||
if (NavAgent.ValidateCurrentTile)
|
||||
{
|
||||
if (!NavAgent.ValidateStandingTile())
|
||||
{
|
||||
// This Path is invalid, so needs to be recalculated
|
||||
if (NavAgent.CurrentOrder.NavJob.CurrentPath != null)
|
||||
{
|
||||
lock (NavAgent.CurrentOrder.NavJob.CurrentPath)
|
||||
{
|
||||
NavAgent.CurrentOrder.NavJob.CurrentPath.ValidPath = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Move to closest Valid Tile and repath
|
||||
NavAgent.CurrentTileIndex = NavAgent.CurrentOrder.StartingMap.GetClosestValidIndex(NavAgent.CurrentTileIndex, NavAgent.TraversableTiles, SimID);
|
||||
NavAgent.CurrentTileType = NavigationManager.Instance.GetTileTypeForMap(NavAgent.CurrentTileIndex, NavAgent.CurrentOrder.StartingMap);
|
||||
UpdatePosition(NavigationManager.Instance.GetTileCenterWorldPosition(NavAgent.CurrentTileIndex, NavAgent.CurrentOrder.StartingMap));
|
||||
if (NavAgent.Settings.OnFailAttemptToNearestPoint)
|
||||
{
|
||||
NavAgent.ReadjustToNearestPoint();
|
||||
}
|
||||
else
|
||||
{
|
||||
NavAgent.SetDestination(NavAgent.WantedDestination);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (NavAgent._lerpPercentage >= 1f)
|
||||
{
|
||||
// Go to NEXT index
|
||||
NavAgent.CurrentPathingIndex++;
|
||||
UpdatePosition(NavAgent.Path[NavAgent.CurrentPathingIndex]);
|
||||
if (NavAgent.CurrentPathingIndex >= NavAgent.Path.Count - 1)
|
||||
{
|
||||
// Completed
|
||||
if (NavAgent.CurrentOrder.Destination == NavAgent.CurrentOrder.CheckPointDestination)
|
||||
{
|
||||
//Debug.Log("At Destination");
|
||||
CallOnMovingComplete = true;
|
||||
NavAgent.State = AgentStates.Idle;
|
||||
}
|
||||
// Find Destination
|
||||
else
|
||||
{
|
||||
//Debug.Log("At Current Destination");
|
||||
NavAgent.SetDestination(NavAgent.CurrentOrder.Destination);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NavAgent.CurrentDirection = NavAgent.Path[NavAgent.CurrentPathingIndex + 1] - NavAgent.Path[NavAgent.CurrentPathingIndex];
|
||||
NavAgent.CurrentDirection = new Vector3(NavAgent.CurrentDirection.x, 0, NavAgent.CurrentDirection.z);
|
||||
NavAgent._lerpPercentage = 0;
|
||||
NavAgent._lerpTotal = NavAgent.CurrentDirection.magnitude;
|
||||
}
|
||||
}
|
||||
|
||||
// Local Advoidance
|
||||
if (NavAgent.AutoValidateCurrentPath)
|
||||
{
|
||||
NavAgent._autoValidateTimer += NavigationManager.Instance.HelperDeltaTime;
|
||||
if (NavAgent._autoValidateTimer > NavAgent.AutoValidateTime)
|
||||
{
|
||||
// By this point the pathing may be over
|
||||
if (NavAgent.State == AgentStates.Moving)
|
||||
{
|
||||
if (!NavAgent.CurrentPathIsValid(NavAgent.LocalAvoidanceRange))
|
||||
{
|
||||
NavAgent._autoValidateTimer = 0;
|
||||
if (NavAgent.CurrentOrder != null && NavAgent.CurrentOrder.NavJob != null)
|
||||
{
|
||||
if (NavAgent.CurrentOrder.NavJob.CurrentPath != null)
|
||||
{
|
||||
lock (NavAgent.CurrentOrder.NavJob.CurrentPath)
|
||||
{
|
||||
NavAgent.CurrentOrder.NavJob.CurrentPath.ValidPath = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
NavAgent.ReadjustToNearestPoint();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (NavAgent.CurrentOrder.PathfindingStep == PathfindingCalculationStep.Complete)
|
||||
{
|
||||
CallOnRecievePath = true;
|
||||
}
|
||||
else if (NavAgent.State != AgentStates.Paused && NavAgent.State != AgentStates.Stopped)
|
||||
{
|
||||
// Keep the agent in a valid position
|
||||
if (NavAgent.CurrentOrder.StartingMap == null)
|
||||
{
|
||||
NavAgent.CurrentOrder.StartingMap = NavigationManager.Instance.GetCurrentMap(Position);
|
||||
NavAgent.CurrentMap = NavAgent.CurrentOrder.StartingMap;
|
||||
}
|
||||
if (NavAgent.CurrentOrder.StartingMap == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (NavAgent.ValidateCurrentTile)
|
||||
{
|
||||
if (!NavAgent.ValidateStandingTile())
|
||||
{
|
||||
// Move to closest Valid Tile and repath
|
||||
NavAgent.CurrentTileIndex = NavAgent.CurrentOrder.StartingMap.GetClosestValidIndex(NavAgent.CurrentTileIndex, NavAgent.TraversableTiles, SimID);
|
||||
NavAgent.CurrentTileType = NavigationManager.Instance.GetTileTypeForMap(NavAgent.CurrentTileIndex, NavAgent.CurrentOrder.StartingMap);
|
||||
UpdatePosition(NavigationManager.Instance.GetTileCenterWorldPosition(NavAgent.CurrentTileIndex, NavAgent.CurrentOrder.StartingMap));
|
||||
}
|
||||
}
|
||||
|
||||
if (NavAgent.FailedLastPath)
|
||||
{
|
||||
if (NavAgent.KeepAttemptingOnFail)
|
||||
{
|
||||
NavAgent._keepAttemptingTimer += NavigationManager.Instance.HelperDeltaTime;
|
||||
if (NavAgent._keepAttemptingTimer >= NavAgent.KeepAttemptingTime)
|
||||
{
|
||||
NavAgent._keepAttemptingTimer = 0;
|
||||
|
||||
if (NavAgent.Settings.OnFailAttemptToNearestPoint)
|
||||
{
|
||||
NavAgent.ReadjustToNearestPoint();
|
||||
}
|
||||
else
|
||||
{
|
||||
NavAgent.SetDestination(NavAgent.WantedDestination);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (AgentAvoidenceActive)
|
||||
{
|
||||
if (OwnedTile == NullTile)
|
||||
{
|
||||
RecheckOwnership();
|
||||
}
|
||||
}
|
||||
|
||||
if (NavAgent.Settings.KeepTryingToReadjustToWantedPosition)
|
||||
{
|
||||
if (NavAgent.WantedDestination != Position)
|
||||
{
|
||||
NavAgent.ReadjustToNearestPoint();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the position to the position of the Agent
|
||||
/// </summary>
|
||||
internal void UpdatePositionFromAgent()
|
||||
{
|
||||
UpdatePosition(NavAgent.transform.position);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal way to update position and tile ownership for the agent
|
||||
/// </summary>
|
||||
protected void UpdatePosition(Vector3 NewPosition)
|
||||
{
|
||||
if (AgentAvoidenceActive)
|
||||
{
|
||||
if (NavAgent.CurrentMap != null)
|
||||
{
|
||||
IntVector2 NewTilePosition = NavigationManager.Instance.GetTileIndexForMap(NewPosition, NavAgent.CurrentMap);
|
||||
if (NavAgent.CurrentMap.OutOfRange(NewTilePosition))
|
||||
{
|
||||
MapSet NewMap = NavigationManager.Instance.GetMapAtWorldPosition(NewPosition);
|
||||
if (NewMap != null)
|
||||
{
|
||||
NewTilePosition = NavigationManager.Instance.GetTileIndexForMap(NewPosition, NewMap);
|
||||
NavAgent.SetCurrentMap(NewMap);
|
||||
if (NewTilePosition != OwnedTile || NavAgent.CurrentMap.BaseMap.AgentOwnershipMap.Tiles[OwnedTile.x, OwnedTile.y] != SimID)
|
||||
{
|
||||
NavAgent.CurrentMap.DisownClaim(OwnedTile, SimID);
|
||||
if (NavAgent.CurrentMap.AttemptClaim(NewTilePosition, SimID))
|
||||
{
|
||||
OwnedTile = NewTilePosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
OwnedTile = NullTile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unown previous tile
|
||||
if (OwnedTile != NullTile)
|
||||
{
|
||||
if (NewTilePosition != OwnedTile || NavAgent.CurrentMap.BaseMap.AgentOwnershipMap.Tiles[OwnedTile.x, OwnedTile.y] != SimID)
|
||||
{
|
||||
NavAgent.CurrentMap.DisownClaim(OwnedTile, SimID);
|
||||
if (NavAgent.CurrentMap.AttemptClaim(NewTilePosition, SimID))
|
||||
{
|
||||
OwnedTile = NewTilePosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
OwnedTile = NullTile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MapSet NewMap = NavigationManager.Instance.GetMapAtWorldPosition(NewPosition);
|
||||
if (NewMap != null)
|
||||
{
|
||||
NavAgent.SetCurrentMap(NewMap);
|
||||
IntVector2 NewTilePosition = NavigationManager.Instance.GetTileIndexForMap(NewPosition, NewMap);
|
||||
if (NavAgent.CurrentMap.AttemptClaim(NewTilePosition, SimID))
|
||||
{
|
||||
OwnedTile = NewTilePosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
OwnedTile = NullTile;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OwnedTile = NullTile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Position = NewPosition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rechecks the ownership of the tile
|
||||
/// </summary>
|
||||
public void RecheckOwnership()
|
||||
{
|
||||
if (AgentAvoidenceActive)
|
||||
{
|
||||
if (NavAgent.CurrentMap != null)
|
||||
{
|
||||
IntVector2 NewTilePosition = NavigationManager.Instance.GetTileIndexForMap(Position, NavAgent.CurrentMap);
|
||||
if (NavAgent.CurrentMap.OutOfRange(NewTilePosition))
|
||||
{
|
||||
MapSet NewMap = NavigationManager.Instance.GetMapAtWorldPosition(Position);
|
||||
if (NewMap != null)
|
||||
{
|
||||
NewTilePosition = NavigationManager.Instance.GetTileIndexForMap(Position, NewMap);
|
||||
NavAgent.SetCurrentMap(NewMap);
|
||||
if (NewTilePosition != OwnedTile || NavAgent.CurrentMap.BaseMap.AgentOwnershipMap.Tiles[OwnedTile.x, OwnedTile.y] == 0)
|
||||
{
|
||||
if (OwnedTile != NullTile)
|
||||
{
|
||||
NavAgent.CurrentMap.DisownClaim(OwnedTile, SimID);
|
||||
}
|
||||
if (NavAgent.CurrentMap.AttemptClaim(NewTilePosition, SimID))
|
||||
{
|
||||
OwnedTile = NewTilePosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
OwnedTile = NullTile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NewTilePosition != OwnedTile || NavAgent.CurrentMap.BaseMap.AgentOwnershipMap.Tiles[OwnedTile.x, OwnedTile.y] == 0)
|
||||
{
|
||||
if (OwnedTile != NullTile)
|
||||
{
|
||||
NavAgent.CurrentMap.DisownClaim(OwnedTile, SimID);
|
||||
}
|
||||
if (NavAgent.CurrentMap.AttemptClaim(NewTilePosition, SimID))
|
||||
{
|
||||
OwnedTile = NewTilePosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
OwnedTile = NullTile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MapSet NewMap = NavigationManager.Instance.GetMapAtWorldPosition(Position);
|
||||
if (NewMap != null)
|
||||
{
|
||||
NavAgent.SetCurrentMap(NewMap);
|
||||
IntVector2 NewTilePosition = NavigationManager.Instance.GetTileIndexForMap(Position, NewMap);
|
||||
if (NavAgent.CurrentMap.AttemptClaim(NewTilePosition, SimID))
|
||||
{
|
||||
OwnedTile = NewTilePosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
OwnedTile = NullTile;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OwnedTile = NullTile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make sure to remove this agent when it's destroyed
|
||||
/// </summary>
|
||||
internal void OnDestroy()
|
||||
{
|
||||
if (NavAgent.CurrentMap != null)
|
||||
{
|
||||
NavAgent.CurrentMap.DisownClaim(OwnedTile, SimID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc363d003b9fc02438defff04aa53423
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,482 @@
|
||||
using HPJ.Simulation;
|
||||
using HPJ.Simulation.Enums;
|
||||
using HPJ.Simulation.Map;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HPJ.Presentation.Agents
|
||||
{
|
||||
public class SimNavigationAgent : NavigationAgent
|
||||
{
|
||||
/// <summary>
|
||||
/// Simulation Counterpart of this agent
|
||||
/// </summary>
|
||||
public SimAgent SimulationAgent { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether sim agents are using Agent Avoidence
|
||||
/// </summary>
|
||||
public bool UsingAgentAvoidence { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Adds the Agent to the Navigation Manager as a simulation agent
|
||||
/// </summary>
|
||||
protected override void AddToManager()
|
||||
{
|
||||
if (NavigationManager.Instance == null)
|
||||
{
|
||||
Invoke(nameof(AddToManager), 0.1f);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!NavigationManager.Instance)
|
||||
{
|
||||
Invoke(nameof(AddToManager), 0.1f);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NavigationManager.Instance.MapSets.Count <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UsingAgentAvoidence = NavigationManager.Instance.ManagerSettings.SimulationSettings.UseAgentAvoidance;
|
||||
IntVector3 StartPosition = NavigationManager.Instance.GetTileWorldPosition(transform.position);
|
||||
CurrentMap = NavigationManager.Instance.GetMapAtTileWorldPosition(StartPosition);
|
||||
StartingMap = NavigationManager.Instance.GetMapAtTileWorldPosition(StartPosition);
|
||||
|
||||
SimulationAgent.AgentAvoidenceActive = NavigationManager.Instance.ManagerSettings.SimulationSettings.UseAgentAvoidance;
|
||||
NavigationManager.Instance.AddSimAgent(this);
|
||||
UpdateAgentPosition(transform.position);
|
||||
}
|
||||
|
||||
public override void UpdateAgentState()
|
||||
{
|
||||
if (transform.position != SimulationAgent.Position)
|
||||
{
|
||||
transform.position = SimulationAgent.Position;
|
||||
}
|
||||
|
||||
if (SimulationAgent.CallOnMovingComplete)
|
||||
{
|
||||
SimulationAgent.CallOnMovingComplete = false;
|
||||
OnMovingComplete?.Invoke(this);
|
||||
}
|
||||
|
||||
if (SimulationAgent.CallOnRecievePath)
|
||||
{
|
||||
SimulationAgent.CallOnRecievePath = false;
|
||||
RecievePathingInfoCallback();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDrawGizmosSelected()
|
||||
{
|
||||
base.OnDrawGizmosSelected();
|
||||
|
||||
if (GizmosSettings.ShowClosestValidTileToWantedPosition)
|
||||
{
|
||||
if (NavigationManager.Instance != null && CurrentMap != null)
|
||||
{
|
||||
Gizmos.color = Color.blue;
|
||||
Vector3 SquareSize = Vector3.one * CurrentMap.SetSettings.MapSettings.TileSize / 100;
|
||||
SquareSize.x -= 0.05f;
|
||||
SquareSize.y = 0.1f;
|
||||
SquareSize.z -= 0.05f;
|
||||
|
||||
IntVector2 WantedIndex = NavigationManager.Instance.GetTileIndexForMap(WantedDestination, CurrentMap);
|
||||
WantedIndex = CurrentMap.GetClosestValidIndex(WantedIndex, _settings.TraversableTiles, SimulationAgent.SimID);
|
||||
|
||||
Vector3 TilePosition = NavigationManager.Instance.GetTileCenterWorldPosition(WantedIndex, CurrentMap);
|
||||
Gizmos.DrawCube(TilePosition, SquareSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Callback for when the agent recieves its path
|
||||
/// </summary>
|
||||
protected override void RecievePathingInfoCallback()
|
||||
{
|
||||
if (State == AgentStates.Stopped)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore Previous orders if there is a duplication or previous uncompleted order
|
||||
CurrentOrder.SetPath(Path);
|
||||
if (CurrentOrder.NavJob.CurrentPath != null && CurrentOrder.NavJob.CurrentPath.ValidPath)
|
||||
{
|
||||
State = AgentStates.SucceededPathing;
|
||||
}
|
||||
else if (CurrentOrder.DestinationState == DestinationStates.NextMap_FromBridge || CurrentOrder.DestinationState == DestinationStates.NextMap_FromSeam)
|
||||
{
|
||||
State = AgentStates.SucceededPathing;
|
||||
}
|
||||
else
|
||||
{
|
||||
State = AgentStates.FailedPathing;
|
||||
}
|
||||
|
||||
FailedLastPath = false;
|
||||
CurrentOrder.PathfindingStep = PathfindingCalculationStep.Finalized;
|
||||
if (State == AgentStates.SucceededPathing)
|
||||
{
|
||||
OnPathfindingSucceed?.Invoke(this);
|
||||
_currentMovementPathIndex = 0;
|
||||
SetInitialPositionToPath();
|
||||
if (CurrentOrder.Recenter)
|
||||
{
|
||||
UpdateAgentPosition(Path[_currentMovementPathIndex]);
|
||||
}
|
||||
if (_settings.GroundCheck)
|
||||
{
|
||||
GroundCast?.PhysicsCheck();
|
||||
}
|
||||
_currentDirection = Path[_currentMovementPathIndex + 1] - Path[_currentMovementPathIndex];
|
||||
_currentDirection.y = 0;
|
||||
_lerpPercentage = 0;
|
||||
_lerpTotal = _currentDirection.magnitude;
|
||||
if (PreviousState != AgentStates.Paused)
|
||||
{
|
||||
State = AgentStates.Moving;
|
||||
}
|
||||
else
|
||||
{
|
||||
State = AgentStates.Paused;
|
||||
}
|
||||
}
|
||||
else if (State == AgentStates.FailedPathing)
|
||||
{
|
||||
FailedLastPath = true;
|
||||
State = AgentStates.Idle;
|
||||
OnPathfindingFailed?.Invoke(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Position you want to update the agent to
|
||||
/// </summary>
|
||||
public Vector3 DesiredPosition { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used to adjust the agent position in the simulation. Note make sure that the state is not moving or the agent will teleport back to it's simulated position
|
||||
/// </summary>
|
||||
public void UpdateAgentPosition(Vector3 NewPosition, bool AutocancelPathing = false)
|
||||
{
|
||||
if (AutocancelPathing)
|
||||
{
|
||||
Idle();
|
||||
}
|
||||
|
||||
DesiredPosition = NewPosition;
|
||||
SimulationAgent.UpdateToUnity = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tells you if the current tile the unit is on is valid
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override bool ValidateStandingTile()
|
||||
{
|
||||
if (CurrentOrder.DestinationState == DestinationStates.NextMap_FromBridge || CurrentOrder.DestinationState == DestinationStates.NextMap_FromSeam)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (CurrentMap != null)
|
||||
{
|
||||
CurrentTileIndex = NavigationManager.Instance.GetTileIndexForMap(SimulationAgent.Position, CurrentMap);
|
||||
CurrentTileType = NavigationManager.Instance.GetTileTypeForMap(CurrentTileIndex, CurrentMap);
|
||||
if (!TraversableTiles.Contains(CurrentTileType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (SimulationAgent.AgentAvoidenceActive)
|
||||
{
|
||||
IntVector2 TilePosition = CurrentMap.GetMapTileIndex(NavigationManager.Instance.GetTileWorldPosition(SimulationAgent.Position));
|
||||
if (!CurrentMap.BaseMap.AgentOwnershipMap.ValidTileForAgent(SimulationAgent.SimID, TilePosition.x, TilePosition.y))
|
||||
{
|
||||
if (SimulationAgent.OwnedTile == TilePosition)
|
||||
{
|
||||
SimulationAgent.OwnedTile = -IntVector2.One;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks the tiles in the path to see if they are still valid
|
||||
/// </summary>
|
||||
/// <param name="Range"></param>
|
||||
/// <returns></returns>
|
||||
public override bool CurrentPathIsValid(int Range = -1)
|
||||
{
|
||||
// You are on a bridge, so it will automatically be true
|
||||
if (CurrentOrder.DestinationState == DestinationStates.NextMap_FromBridge || CurrentOrder.DestinationState == DestinationStates.NextMap_FromSeam)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (CurrentOrder.DestinationState == DestinationStates.SameMap || CurrentOrder.DestinationState == DestinationStates.Bridge || CurrentOrder.DestinationState == DestinationStates.ClosestPoint)
|
||||
{
|
||||
// Reaffirm current Index
|
||||
if (!ValidateStandingTile())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// This is to keep track of the path
|
||||
int validationPathIndex = _currentMovementPathIndex + 1;
|
||||
if (Range == -1)
|
||||
{
|
||||
Range = int.MaxValue;
|
||||
}
|
||||
int RangeCounter = 0;
|
||||
|
||||
// Calculate this section
|
||||
IntVector2 NextDestinationIndexPosition = NavigationManager.Instance.GetTileIndexForMap(Path[validationPathIndex], CurrentOrder.StartingMap);
|
||||
IntVector2 Direction = new IntVector2();
|
||||
if (CurrentTileIndex.x < NextDestinationIndexPosition.x)
|
||||
{
|
||||
Direction.x = 1;
|
||||
}
|
||||
else if (CurrentTileIndex.x > NextDestinationIndexPosition.x)
|
||||
{
|
||||
Direction.x = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Direction.x = 0;
|
||||
}
|
||||
if (CurrentTileIndex.y < NextDestinationIndexPosition.y)
|
||||
{
|
||||
Direction.y = 1;
|
||||
}
|
||||
else if (CurrentTileIndex.y > NextDestinationIndexPosition.y)
|
||||
{
|
||||
Direction.y = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Direction.y = 0;
|
||||
}
|
||||
|
||||
// Set the tracking tile
|
||||
IntVector2 TrackingTile = CurrentTileIndex;
|
||||
while (TrackingTile != NextDestinationIndexPosition)
|
||||
{
|
||||
TrackingTile += Direction;
|
||||
if (!ValidateTileIndex(TrackingTile, CurrentOrder.StartingMap))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RangeCounter++;
|
||||
if (RangeCounter > Range)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check the next sections of the path
|
||||
validationPathIndex++;
|
||||
while (validationPathIndex < Path.Count)
|
||||
{
|
||||
NextDestinationIndexPosition = NavigationManager.Instance.GetTileIndexForMap(Path[validationPathIndex], CurrentOrder.StartingMap);
|
||||
if (TrackingTile.x < NextDestinationIndexPosition.x)
|
||||
{
|
||||
Direction.x = 1;
|
||||
}
|
||||
else if (TrackingTile.x > NextDestinationIndexPosition.x)
|
||||
{
|
||||
Direction.x = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Direction.x = 0;
|
||||
}
|
||||
if (TrackingTile.y < NextDestinationIndexPosition.y)
|
||||
{
|
||||
Direction.y = 1;
|
||||
}
|
||||
else if (TrackingTile.y > NextDestinationIndexPosition.y)
|
||||
{
|
||||
Direction.y = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Direction.y = 0;
|
||||
}
|
||||
|
||||
// Set the tracking tile
|
||||
while (TrackingTile != NextDestinationIndexPosition)
|
||||
{
|
||||
TrackingTile += Direction;
|
||||
if (!ValidateTileIndex(TrackingTile, CurrentOrder.StartingMap))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RangeCounter++;
|
||||
if (RangeCounter > Range)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
validationPathIndex++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This tells you if the current tile index is valid for this unit
|
||||
/// </summary>
|
||||
/// <param name="TileIndex"></param>
|
||||
/// <returns></returns>
|
||||
public override bool ValidateTileIndex(IntVector2 TileIndex, MapSet Map)
|
||||
{
|
||||
if (!TraversableTiles.Contains(NavigationManager.Instance.GetTileTypeForMap(TileIndex, Map)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (UsingAgentAvoidence)
|
||||
{
|
||||
if (Map == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!Map.BaseMap.AgentOwnershipMap.ValidTileForAgent(SimulationAgent.SimID, TileIndex.x, TileIndex.y))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the destination to the nearest valid point near the desired destination
|
||||
/// </summary>
|
||||
/// <param name="Destination"></param>
|
||||
/// <param name="RecenterOnTile"></param>
|
||||
/// <param name="SetWantedDestination"></param>
|
||||
public override void SetDestinationToNearestPoint(Vector3 Destination, bool RecenterOnTile = false)
|
||||
{
|
||||
if (CurrentOrder.PathfindingStep == PathfindingCalculationStep.Pathfinding)
|
||||
{
|
||||
return;
|
||||
}
|
||||
State = AgentStates.Pathfinding;
|
||||
CurrentOrder.SetPrevious();
|
||||
CurrentOrder.Clear();
|
||||
|
||||
IntVector3 WorldTilePosition = NavigationManager.Instance.GetTileWorldPosition(Destination);
|
||||
MapSet EndingMap = NavigationManager.Instance.GetMapAtTileWorldPosition(NavigationManager.Instance.GetTileWorldPosition(Destination));
|
||||
if (NavigationManager.Instance.ManagerSettings.SimulationSettings.UseAgentAvoidance)
|
||||
{
|
||||
IntVector2 TileIndex = EndingMap.GetMapTileIndex(WorldTilePosition);
|
||||
if (!_settings.TraversableTiles.Contains(EndingMap.GetTileType(TileIndex)) || !EndingMap.BaseMap.AgentOwnershipMap.ValidTileForAgent(SimulationAgent.SimID, TileIndex.x, TileIndex.y))
|
||||
{
|
||||
SetDestination(EndingMap.GetWorldTileIndex(EndingMap.GetClosestValidIndex(TileIndex, _settings.TraversableTiles, SimulationAgent.SimID)), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetDestination(Destination);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_settings.TraversableTiles.Contains(EndingMap.GetTileType(WorldTilePosition)))
|
||||
{
|
||||
SetDestination(EndingMap.GetWorldTileIndex(EndingMap.GetClosestValidIndex(EndingMap.GetMapTileIndex(WorldTilePosition), _settings.TraversableTiles)), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetDestination(Destination);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the destination to the nearest valid point near the desired destination
|
||||
/// </summary>
|
||||
/// <param name="Destination"></param>
|
||||
/// <param name="RecenterOnTile"></param>
|
||||
/// <param name="SetWantedDestination"></param>
|
||||
protected override void SetDestinationToNearestPoint(IntVector3 Destination, bool RecenterOnTile = false)
|
||||
{
|
||||
if (CurrentOrder.PathfindingStep == PathfindingCalculationStep.Pathfinding)
|
||||
{
|
||||
return;
|
||||
}
|
||||
State = AgentStates.Pathfinding;
|
||||
CurrentOrder.SetPrevious();
|
||||
CurrentOrder.Clear();
|
||||
|
||||
MapSet EndingMap = NavigationManager.Instance.GetMapAtTileWorldPosition(Destination);
|
||||
|
||||
if (NavigationManager.Instance.ManagerSettings.SimulationSettings.UseAgentAvoidance)
|
||||
{
|
||||
IntVector2 TileIndex = EndingMap.GetMapTileIndex(Destination);
|
||||
if (!_settings.TraversableTiles.Contains(EndingMap.GetTileType(TileIndex)) || !EndingMap.BaseMap.AgentOwnershipMap.ValidTileForAgent(SimulationAgent.SimID, TileIndex.x, TileIndex.y))
|
||||
{
|
||||
SetDestination(EndingMap.GetWorldTileIndex(EndingMap.GetClosestValidIndex(TileIndex, _settings.TraversableTiles, SimulationAgent.SimID)), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetDestination(Destination);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_settings.TraversableTiles.Contains(EndingMap.GetTileType(Destination)))
|
||||
{
|
||||
SetDestination(EndingMap.GetWorldTileIndex(EndingMap.GetClosestValidIndex(EndingMap.GetMapTileIndex(Destination), _settings.TraversableTiles)), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetDestination(Destination);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helps get the current position for this agent. Sim agents override this to use the simagent position
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
internal override Vector3 GetCurrentPosition()
|
||||
{
|
||||
return SimulationAgent.Position;
|
||||
}
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
SimulationAgent = new SimAgent(this, false);
|
||||
CurrentOrder.NavJob.AgentID = SimulationAgent.SimID;
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
if (NavigationManager.Instance != null && NavigationManager.Instance.Running)
|
||||
{
|
||||
SimulationAgent?.OnDestroy();
|
||||
NavigationManager.Instance?.RemoveSimAgent(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53cb4b6f50173b44dbb35bd1007d19d0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c4d0b4f704fd2524b9c526c68324c99c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user