PC-20230316NUNE\Administrator 2b467e56ad no message
2024-02-20 18:39:12 +08:00

160 lines
5.9 KiB
C#

using HPJ.Simulation;
using HPJ.Simulation.Enums;
using HPJ.Simulation.Map;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace HPJ.Presentation.Obstacle
{
// A Simple Obstacle based on a sphere or circle
public class NavigationObstacleSphere : NavigationObstacle
{
#region Unity
// Start is called before the first frame update
public override void Start()
{
if (!NavigationManager.Instance.Initialized)
{
Invoke(nameof(Start), 01f);
return;
}
MapTileRelationships = new Dictionary<MapSet, MapObstacleRelationshipData>();
_previousPosition = new Vector3(-1111111, -112321321321312, 233414212);
base.Start();
}
public virtual void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, _radius);
Gizmos.color = Color.blue;
Gizmos.DrawLine(transform.position, transform.position - Vector3.up * _checkMapHeight);
}
#endregion
#region Obstacle
[SerializeField]
protected float _radius = 1f;
public float Radius { get { return _radius; } set { _radius = value; } }
private Vector3 _previousPosition;
public override void UpdatePosition(Vector3 NewPosition, bool ForceCheck = false)
{
if (!NavigationManager.Instance.Initialized)
{
return;
}
// No need to update if no tiles need updating
if (PositionChanged(NewPosition))
{
_previousPosition = NewPosition;
foreach (MapObstacleRelationshipData Data in MapTileRelationships.Values)
{
Data.UnvalidateTiles();
}
foreach (MapSet Set in NavigationManager.Instance.MapSets)
{
if (transform.position.y - Set.SetSettings.MapSettings.Offset.y / 100f > _checkMapHeight)
{
//Debug.Log("Too high or Too low");
continue;
}
if (!NavigationManager.Instance.CircleOnMap(Set, NewPosition, Radius))
{
//Debug.Log("Not on Map");
continue;
}
MapObstacleRelationshipData RelationshipData;
if (MapTileRelationships.ContainsKey(Set))
{
RelationshipData = MapTileRelationships[Set];
}
else
{
RelationshipData = new MapObstacleRelationshipData(Set, this, _obstacleTileType);
MapTileRelationships.Add(Set, RelationshipData);
}
Vector3 RadiusVector = new Vector3(Radius, 0, Radius);
IntVector2 Center = Set.GetMapTileIndex(NavigationManager.Instance.GetTileWorldPosition(NewPosition));
IntVector2 HigherBound = Set.GetMapTileIndex(NavigationManager.Instance.GetTileWorldPosition(NewPosition + RadiusVector));
IntVector2 LowerBound = Set.GetMapTileIndex(NavigationManager.Instance.GetTileWorldPosition(NewPosition - RadiusVector));
float TileRadiusSqr = (HigherBound.y - LowerBound.y) / 2f;
TileRadiusSqr *= TileRadiusSqr;
for (int x = LowerBound.x; x <= HigherBound.x; x++)
{
for (int y = LowerBound.y; y <= HigherBound.y; y++)
{
int X_Distance = Center.x - x;
int Y_Distance = Center.y - y;
if (X_Distance * X_Distance + Y_Distance * Y_Distance > TileRadiusSqr)
{
//Debug.Log($"({X_Distance}, {Y_Distance}) Not In Bounds");
continue;
}
// Make sure its close enough to the ground to count as an obstacle
if (Set.GetTileType(x, y) != TileTypes.OutOfBounds)
{
//Debug.Log("Change Tile");
IntVector3 TileKey = new IntVector3(x, y, Set.InstanceID);
RelationshipData.AddOrValidateTile(TileKey);
}
}
}
}
foreach (MapObstacleRelationshipData Data in MapTileRelationships.Values)
{
ChangeMapJob GeneratedMapChangeJob = Data.GenerateMapChangeJob();
if (GeneratedMapChangeJob != null)
{
//Debug.Log("Change Map From Job");
Data.Map.ChangeMap(GeneratedMapChangeJob);
}
Data.SortRelatedTileData();
}
}
else
{
RevalidateTiles();
}
}
public override void RevalidateTiles()
{
foreach (MapObstacleRelationshipData Data in MapTileRelationships.Values)
{
Data.Revalidate();
}
}
protected override bool PositionChanged(Vector3 NewPosition)
{
return _previousPosition != NewPosition;
}
/// <summary>
/// Rotates the obstacle based on the desired Rotation. Basic NavigationObstacle will only swap the object size x and y values. Inherit to ovverride this behaviour
/// </summary>
/// <param name="Rotation"></param>
public override void Rotate(Quaternion Rotation)
{
}
#endregion
}
}