Added Navigation System. Added basic AI FSM #438
|
@ -1,13 +1,13 @@
|
||||||
0 StaticObject 1100000000000000
|
0 StaticObject 1101000000000000
|
||||||
1 Player 1100000000000000
|
1 Player 1101000000000000
|
||||||
2 Food 1000000000000000
|
2 Food 1000000000000000
|
||||||
3 Breakable 1100000000000000
|
3 Breakable 1100000000000000
|
||||||
4 ScoringWallCollider 0110000000000000
|
4 ScoringWallCollider 0110000000000000
|
||||||
5 Homeowner 1100000000000000
|
5 Homeowner 1100000000000000
|
||||||
6 Camera 0010000000000000
|
6 Camera 0010000000000000
|
||||||
7 StaticWithCameraCollision 1110000000000000
|
7 StaticWithCameraCollision 1111000000000000
|
||||||
8 9 0000000000000000
|
8 Floor 1100000000000000
|
||||||
9 10 0000000000000000
|
9 Navigation 0001000000000000
|
||||||
10 11 0000000000000000
|
10 11 0000000000000000
|
||||||
11 12 0000000000000000
|
11 12 0000000000000000
|
||||||
12 13 0000000000000000
|
12 13 0000000000000000
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,3 @@
|
||||||
|
Name: Level2_AITest
|
||||||
|
ID: 86300248
|
||||||
|
Type: 5
|
|
@ -530,7 +530,6 @@
|
||||||
Scripts:
|
Scripts:
|
||||||
- Type: SHADE_Scripting.UI.FadeInOnActive
|
- Type: SHADE_Scripting.UI.FadeInOnActive
|
||||||
Enabled: true
|
Enabled: true
|
||||||
alpha: 0
|
|
||||||
- EID: 19
|
- EID: 19
|
||||||
Name: Options Canvas
|
Name: Options Canvas
|
||||||
IsActive: false
|
IsActive: false
|
||||||
|
@ -1236,7 +1235,6 @@
|
||||||
Scripts:
|
Scripts:
|
||||||
- Type: SHADE_Scripting.UI.FadeInOnActive
|
- Type: SHADE_Scripting.UI.FadeInOnActive
|
||||||
Enabled: true
|
Enabled: true
|
||||||
alpha: 0
|
|
||||||
- EID: 46
|
- EID: 46
|
||||||
Name: Credits Canvas
|
Name: Credits Canvas
|
||||||
IsActive: false
|
IsActive: false
|
||||||
|
@ -1461,7 +1459,6 @@
|
||||||
Scripts:
|
Scripts:
|
||||||
- Type: SHADE_Scripting.UI.FadeInOnActive
|
- Type: SHADE_Scripting.UI.FadeInOnActive
|
||||||
Enabled: true
|
Enabled: true
|
||||||
alpha: 0
|
|
||||||
- EID: 441
|
- EID: 441
|
||||||
Name: Level Select Buttons
|
Name: Level Select Buttons
|
||||||
IsActive: true
|
IsActive: true
|
||||||
|
|
|
@ -0,0 +1,320 @@
|
||||||
|
- EID: 0
|
||||||
|
Name: Camera
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: 10.2736483, z: 0}
|
||||||
|
Rotate: {x: -1.48352981, y: 1.5, z: 0.5}
|
||||||
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 1
|
||||||
|
Name: Floor
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: 0, z: 0}
|
||||||
|
Rotate: {x: -0, y: 0, z: -0}
|
||||||
|
Scale: {x: 12.8000002, y: 1, z: 12.8000002}
|
||||||
|
IsActive: true
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 142686872
|
||||||
|
Material: 126223465
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 2
|
||||||
|
Name: Light
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Light Component:
|
||||||
|
Position: {x: 0, y: 0, z: 0}
|
||||||
|
Type: Directional
|
||||||
|
Direction: {x: 0, y: -1, z: 1}
|
||||||
|
Color: {x: 1, y: 1, z: 1, w: 1}
|
||||||
|
Layer: 4294967295
|
||||||
|
Strength: 0
|
||||||
|
Casting Shadows: false
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 3
|
||||||
|
Name: Wall
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 11, y: 0, z: 0}
|
||||||
|
Rotate: {x: -0, y: 1.57079637, z: -0}
|
||||||
|
Scale: {x: 10.6225176, y: 1, z: 1}
|
||||||
|
IsActive: true
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 142652392
|
||||||
|
Material: 126223465
|
||||||
|
IsActive: true
|
||||||
|
Collider Component:
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Collision Tag: 0
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 2.5, y: 1, z: 1.60000002}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0, z: 0}
|
||||||
|
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 4
|
||||||
|
Name: Wall
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: 0, z: -11.2958097}
|
||||||
|
Rotate: {x: -0, y: 0, z: -0}
|
||||||
|
Scale: {x: 10.6225176, y: 1, z: 1}
|
||||||
|
IsActive: true
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 142652392
|
||||||
|
Material: 126223465
|
||||||
|
IsActive: true
|
||||||
|
Collider Component:
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Collision Tag: 0
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 2.5, y: 1, z: 1.60000002}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0, z: 0}
|
||||||
|
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 5
|
||||||
|
Name: Wall
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: 0, z: 11}
|
||||||
|
Rotate: {x: -0, y: 0, z: -0}
|
||||||
|
Scale: {x: 10.6225176, y: 1, z: 1}
|
||||||
|
IsActive: true
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 142652392
|
||||||
|
Material: 126223465
|
||||||
|
IsActive: true
|
||||||
|
Collider Component:
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Collision Tag: 0
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 2.5, y: 1, z: 1.60000002}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0, z: 0}
|
||||||
|
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 6
|
||||||
|
Name: Wall
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 6.06437206, y: 0, z: -5.60716629}
|
||||||
|
Rotate: {x: -0, y: 1.57079601, z: -0}
|
||||||
|
Scale: {x: 4.99989605, y: 1, z: 0.999986947}
|
||||||
|
IsActive: true
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 142652392
|
||||||
|
Material: 126223465
|
||||||
|
IsActive: true
|
||||||
|
Collider Component:
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Collision Tag: 0
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 2.5, y: 1, z: 1.60000002}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0, z: 0}
|
||||||
|
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 7
|
||||||
|
Name: Wall
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: -11, y: 0, z: 0}
|
||||||
|
Rotate: {x: -0, y: 1.57079637, z: -0}
|
||||||
|
Scale: {x: 10.6225176, y: 1, z: 1}
|
||||||
|
IsActive: true
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 142652392
|
||||||
|
Material: 126223465
|
||||||
|
IsActive: true
|
||||||
|
Collider Component:
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Collision Tag: 0
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 2.5, y: 1, z: 1.60000002}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0, z: 0}
|
||||||
|
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 8
|
||||||
|
Name: Wall
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: -4.70212746, y: 0, z: -0.00226712227}
|
||||||
|
Rotate: {x: -0, y: 1.57079601, z: -0}
|
||||||
|
Scale: {x: 4.99982977, y: 1, z: 0.999978602}
|
||||||
|
IsActive: true
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 142652392
|
||||||
|
Material: 126223465
|
||||||
|
IsActive: true
|
||||||
|
Collider Component:
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Collision Tag: 0
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 2.5, y: 1, z: 1.60000002}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0, z: 0}
|
||||||
|
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 9
|
||||||
|
Name: Wall
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 1.46194017, y: 0, z: 0.71579361}
|
||||||
|
Rotate: {x: -0, y: 0, z: -0}
|
||||||
|
Scale: {x: 4.99985838, y: 1, z: 0.999982238}
|
||||||
|
IsActive: true
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 142652392
|
||||||
|
Material: 126223465
|
||||||
|
IsActive: true
|
||||||
|
Collider Component:
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Collision Tag: 0
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 2.5, y: 1, z: 1.60000002}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0, z: 0}
|
||||||
|
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 10
|
||||||
|
Name: Wall
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: -2.30867815, y: 0, z: -6.02849674}
|
||||||
|
Rotate: {x: -0, y: 0, z: -0}
|
||||||
|
Scale: {x: 4, y: 1, z: 0.999974966}
|
||||||
|
IsActive: true
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 142652392
|
||||||
|
Material: 126223465
|
||||||
|
IsActive: true
|
||||||
|
Collider Component:
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Collision Tag: 0
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 2.5, y: 1, z: 1.60000002}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0, z: 0}
|
||||||
|
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 11
|
||||||
|
Name: TestAI
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 8.5, y: -1, z: -6.41661787}
|
||||||
|
Rotate: {x: -0, y: 0, z: -0}
|
||||||
|
Scale: {x: 5, y: 5, z: 5}
|
||||||
|
IsActive: true
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 140639624
|
||||||
|
Material: 131956078
|
||||||
|
IsActive: true
|
||||||
|
Navigation Component:
|
||||||
|
Target: {x: 0, y: 0, z: 0}
|
||||||
|
Forward: {x: 0, y: 0, z: 0}
|
||||||
|
Recalculate Path: true
|
||||||
|
Unreachable Target: false
|
||||||
|
Acceptance threshold: 1
|
||||||
|
IsActive: true
|
||||||
|
Scripts:
|
||||||
|
- Type: SHADE_Scripting.Gameplay.AIBehaviour.AIRework.NavigationTestScript
|
||||||
|
Enabled: true
|
||||||
|
endPoint: 12
|
||||||
|
speed: 3
|
||||||
|
- EID: 12
|
||||||
|
Name: EndPoint
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: -0.853474855, y: -1, z: 0.354041398}
|
||||||
|
Rotate: {x: -0, y: 0, z: -0}
|
||||||
|
Scale: {x: 5, y: 5, z: 5}
|
||||||
|
IsActive: true
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 140639624
|
||||||
|
Material: 131956078
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 13
|
||||||
|
Name: Camera
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: 10.2736483, z: 0}
|
||||||
|
Rotate: {x: -1.48352981, y: 0, z: 0}
|
||||||
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
|
IsActive: true
|
||||||
|
Camera Component:
|
||||||
|
Position: {x: 0, y: 0, z: 0}
|
||||||
|
Pitch: -85
|
||||||
|
Yaw: 0
|
||||||
|
Roll: 0
|
||||||
|
Width: 1920
|
||||||
|
Near: 0.00999999978
|
||||||
|
Far: 10000
|
||||||
|
Perspective: true
|
||||||
|
FOV: 90
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: NavigationTest
|
||||||
|
ID: 100246336
|
||||||
|
Type: 5
|
|
@ -0,0 +1,107 @@
|
||||||
|
using SHADE;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SHADE_Scripting.Gameplay.AIBehaviour.AIRework
|
||||||
|
{
|
||||||
|
public class AILineOfSight:Script
|
||||||
|
{
|
||||||
|
public GameObject player;
|
||||||
|
|
||||||
|
public float range = 2.0f;
|
||||||
|
[Tooltip("Angle between player and forward to be within sight")]
|
||||||
|
public float angle = 30.0f;
|
||||||
|
|
||||||
|
[Tooltip("For debug")]
|
||||||
|
public float angleBetween = 0.0f;
|
||||||
|
|
||||||
|
[Tooltip("For debug")]
|
||||||
|
public float distance = 0.0f;
|
||||||
|
|
||||||
|
public float heightLimit = 1.0f;
|
||||||
|
|
||||||
|
public Vector3 rayOffset;
|
||||||
|
|
||||||
|
|
||||||
|
public bool withinRange;
|
||||||
|
public bool withinSight;
|
||||||
|
|
||||||
|
|
||||||
|
public Vector3 lastFoundPos;
|
||||||
|
public float lastFoundTimer = 0.0f;
|
||||||
|
|
||||||
|
protected override void update()
|
||||||
|
{
|
||||||
|
if (player == GameObject.Null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Transform transform = GetComponent<Transform>();
|
||||||
|
Transform playerTransform = player.GetComponent<Transform>();
|
||||||
|
Collider playerCollider = player.GetComponent<Collider>();
|
||||||
|
|
||||||
|
withinRange = false;
|
||||||
|
withinSight = false;
|
||||||
|
|
||||||
|
|
||||||
|
if(transform && playerTransform && playerCollider)
|
||||||
|
{
|
||||||
|
Vector3 pos = transform.GlobalPosition + rayOffset;
|
||||||
|
Vector3 playerPos = playerTransform.GlobalPosition ;
|
||||||
|
Vector3 d = playerPos - pos;
|
||||||
|
distance = d.GetMagnitude();
|
||||||
|
if(distance < range)
|
||||||
|
{
|
||||||
|
Vector3 fwdHorizontal = transform.Forward;
|
||||||
|
fwdHorizontal.y = 0;
|
||||||
|
fwdHorizontal.Normalise();
|
||||||
|
|
||||||
|
Vector3 dHorizontal = d;
|
||||||
|
dHorizontal.y = 0;
|
||||||
|
|
||||||
|
|
||||||
|
float dot = Vector3.Dot(fwdHorizontal, dHorizontal);
|
||||||
|
angleBetween = SHADE.Math.Rad2Deg * MathF.Acos(dot / (dHorizontal.GetMagnitude()));
|
||||||
|
if (angleBetween < angle && playerPos.y < pos.y + heightLimit)
|
||||||
|
{
|
||||||
|
withinRange = true;
|
||||||
|
withinSight = true;
|
||||||
|
Ray sightRay = new Ray(pos, d.GetNormalised());
|
||||||
|
List<RaycastHit> hitResults = Physics.Raycast(sightRay, distance,false, (ushort)65535);
|
||||||
|
|
||||||
|
foreach(RaycastHit hit in hitResults)
|
||||||
|
{
|
||||||
|
if (hit.Hit && hit.Other != player)
|
||||||
|
{
|
||||||
|
Debug.Log("AI LOS: HIT OTHER");
|
||||||
|
withinSight = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (withinSight == true)
|
||||||
|
{
|
||||||
|
lastFoundPos = playerTransform.GlobalPosition;
|
||||||
|
lastFoundTimer = 0.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lastFoundTimer += Time.DeltaTimeF;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: AILineOfSight
|
||||||
|
ID: 152074687
|
||||||
|
Type: 9
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: BaseState
|
||||||
|
ID: 167091082
|
||||||
|
Type: 9
|
|
@ -0,0 +1,105 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Reflection.PortableExecutable;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using SHADE;
|
||||||
|
using SHADE_Scripting.Gameplay.AIBehaviour.AIRework.States;
|
||||||
|
|
||||||
|
namespace SHADE_Scripting.Gameplay.AIBehaviour.AIRework
|
||||||
|
{
|
||||||
|
public class HomeOwnerAI:Script
|
||||||
|
{
|
||||||
|
public float idleDuration = 1.0f;
|
||||||
|
public float timeoutDuration = 2.0f;
|
||||||
|
public GameObject patrolPointParent;
|
||||||
|
|
||||||
|
public float patrolSpeed = 2.0f;
|
||||||
|
public float chaseSpeed = 3.0f;
|
||||||
|
|
||||||
|
public float alertCooldown = 0.0f;
|
||||||
|
|
||||||
|
public GameObject player;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[NonSerialized]
|
||||||
|
public IEnumerable<Transform> patrolPointPool;
|
||||||
|
|
||||||
|
|
||||||
|
protected override void awake()
|
||||||
|
{
|
||||||
|
StateMachine machine = GetScript<StateMachine>();
|
||||||
|
if(machine)
|
||||||
|
{
|
||||||
|
Dictionary<Type, BaseState> dictionary = new Dictionary<Type, BaseState>();
|
||||||
|
dictionary.Add(typeof(IdleState), new IdleState(machine));
|
||||||
|
dictionary.Add(typeof(PatrolState), new PatrolState(machine));
|
||||||
|
dictionary.Add(typeof(TimeoutState), new TimeoutState(machine));
|
||||||
|
dictionary.Add(typeof(ChaseState), new ChaseState(machine));
|
||||||
|
dictionary.Add(typeof(AlertState), new AlertState(machine));
|
||||||
|
|
||||||
|
machine.InitStateMachine(dictionary);
|
||||||
|
}
|
||||||
|
|
||||||
|
patrolPointPool = patrolPointParent.GetComponentsInChildren<Transform>();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override void update()
|
||||||
|
{
|
||||||
|
if(alertCooldown > 0.0f)
|
||||||
|
{
|
||||||
|
alertCooldown -= Time.DeltaTimeF;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
alertCooldown = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
RigidBody rigid = GetComponent<RigidBody>();
|
||||||
|
if(rigid)
|
||||||
|
{
|
||||||
|
rigid.AngularVelocity = Vector3.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ShouldTransitAlert()
|
||||||
|
{
|
||||||
|
AILineOfSight los = GetScript<AILineOfSight>();
|
||||||
|
if (los)
|
||||||
|
{
|
||||||
|
if (los.withinSight && alertCooldown <= 0.0f)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RotateToPlayer()
|
||||||
|
{
|
||||||
|
|
||||||
|
//Transform playerTransform = player.GetComponent<Transform>();
|
||||||
|
|
||||||
|
////Rotate to face player.
|
||||||
|
//Transform aiTransform = GetComponent<Transform>();
|
||||||
|
//if(playerTransform && aiTransform)
|
||||||
|
//{
|
||||||
|
// Vector3 direction = playerTransform.GlobalPosition - aiTransform.GlobalPosition;
|
||||||
|
// Quaternion currentRotation = aiTransform.LocalRotation;
|
||||||
|
// Quaternion targetRotation = Quaternion.Euler(0.0f, MathF.Atan2(direction.x, direction.z), 0.0f);
|
||||||
|
// aiTransform.LocalRotation = Quaternion.Slerp(currentRotation, targetRotation, 5.0f * (float)Time.FixedDeltaTime);
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: HomeOwnerAI
|
||||||
|
ID: 162553450
|
||||||
|
Type: 9
|
|
@ -0,0 +1,52 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using SHADE;
|
||||||
|
|
||||||
|
namespace SHADE_Scripting.Gameplay.AIBehaviour.AIRework
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class NavigationTestScript :Script
|
||||||
|
{
|
||||||
|
public GameObject endPoint;
|
||||||
|
|
||||||
|
public float speed = 1.0f;
|
||||||
|
float timer = 0.0f;
|
||||||
|
|
||||||
|
protected override void start()
|
||||||
|
{
|
||||||
|
|
||||||
|
Navigation nav = GetComponent<Navigation>();
|
||||||
|
Transform endTransform = endPoint.GetComponent<Transform>();
|
||||||
|
if (endTransform)
|
||||||
|
nav.MoveTo(endTransform.GlobalPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void update()
|
||||||
|
{
|
||||||
|
timer += Time.DeltaTimeF;
|
||||||
|
Navigation nav = GetComponent<Navigation>();
|
||||||
|
Transform transform = GetComponent<Transform>();
|
||||||
|
if (timer >= 1.0f)
|
||||||
|
{
|
||||||
|
timer = 0.0f;
|
||||||
|
|
||||||
|
Transform endTransform = endPoint.GetComponent<Transform>();
|
||||||
|
if (endTransform)
|
||||||
|
nav.MoveTo(endTransform.GlobalPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (nav && transform)
|
||||||
|
{
|
||||||
|
transform.LocalPosition = transform.LocalPosition + ( nav.GetForward() * Time.DeltaTimeF * speed);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: NavigationTestScript
|
||||||
|
ID: 162476480
|
||||||
|
Type: 9
|
|
@ -0,0 +1,40 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using SHADE;
|
||||||
|
|
||||||
|
namespace SHADE_Scripting.Gameplay.AIBehaviour.AIRework
|
||||||
|
{
|
||||||
|
public class RotateToVelocity : Script
|
||||||
|
{
|
||||||
|
public float rotationPerSecond = 2.0f;
|
||||||
|
|
||||||
|
protected override void update()
|
||||||
|
{
|
||||||
|
RigidBody rigid = GetComponent<RigidBody>();
|
||||||
|
Transform transform = GetComponent<Transform>();
|
||||||
|
|
||||||
|
if(rigid && transform)
|
||||||
|
{
|
||||||
|
Vector3 vel = rigid.LinearVelocity;
|
||||||
|
|
||||||
|
if(vel.GetSqrMagnitude() > 1.0f)
|
||||||
|
{
|
||||||
|
Quaternion currentRotation = transform.LocalRotation;
|
||||||
|
Quaternion targetRotation = Quaternion.Euler(0.0f, MathF.Atan2(vel.x, vel.z), 0.0f);
|
||||||
|
transform.LocalRotation = Quaternion.Slerp(currentRotation, targetRotation, rotationPerSecond * (float)Time.FixedDeltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: RotateToVelocity
|
||||||
|
ID: 163814533
|
||||||
|
Type: 9
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: StateMachine
|
||||||
|
ID: 165140157
|
||||||
|
Type: 9
|
|
@ -0,0 +1,22 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SHADE_Scripting.Gameplay.AIBehaviour.AIRework.States
|
||||||
|
{
|
||||||
|
public abstract class AIBaseState: BaseState
|
||||||
|
{
|
||||||
|
|
||||||
|
protected HomeOwnerAI ai;
|
||||||
|
|
||||||
|
public AIBaseState(StateMachine stateMachine): base(stateMachine, "")
|
||||||
|
{
|
||||||
|
stateName = "AI Base State";
|
||||||
|
ai = stateMachine.GetScript<HomeOwnerAI>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: AIBaseState
|
||||||
|
ID: 160233845
|
||||||
|
Type: 9
|
|
@ -0,0 +1,42 @@
|
||||||
|
using SHADE;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SHADE_Scripting.Gameplay.AIBehaviour.AIRework.States
|
||||||
|
{
|
||||||
|
public class AlertState: AIBaseState
|
||||||
|
{
|
||||||
|
const float alertDuration = 2.0f;
|
||||||
|
float alertTimer = alertDuration;
|
||||||
|
|
||||||
|
|
||||||
|
public AlertState(StateMachine machine): base(machine)
|
||||||
|
{
|
||||||
|
stateName = "Alert";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnEnter()
|
||||||
|
{
|
||||||
|
alertTimer = alertDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void update()
|
||||||
|
{
|
||||||
|
alertTimer -= Time.DeltaTimeF;
|
||||||
|
if (alertTimer <= 0.0f)
|
||||||
|
{
|
||||||
|
machine.SetState(typeof(ChaseState));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override void fixedUpdate()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: AlertState
|
||||||
|
ID: 159828775
|
||||||
|
Type: 9
|
|
@ -0,0 +1,77 @@
|
||||||
|
using SHADE;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SHADE_Scripting.Gameplay.AIBehaviour.AIRework.States
|
||||||
|
{
|
||||||
|
public class ChaseState :AIBaseState
|
||||||
|
{
|
||||||
|
|
||||||
|
float giveUpDuration = 10.0f;
|
||||||
|
float giveUpTimer = 0.0f;
|
||||||
|
|
||||||
|
|
||||||
|
public ChaseState(StateMachine machine): base(machine)
|
||||||
|
{
|
||||||
|
stateName = "Chase";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnEnter()
|
||||||
|
{
|
||||||
|
giveUpTimer = giveUpDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void update()
|
||||||
|
{
|
||||||
|
Navigation nav = machine.GetComponent<Navigation>();
|
||||||
|
AILineOfSight los = ai.GetScript<AILineOfSight>();
|
||||||
|
if(los && nav)
|
||||||
|
{
|
||||||
|
Transform playerTransform = los.player.GetComponent<Transform>();
|
||||||
|
if (los.withinSight)
|
||||||
|
{
|
||||||
|
nav.MoveTo(playerTransform.GlobalPosition);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nav.MoveTo(los.lastFoundPos);
|
||||||
|
giveUpTimer -= Time.DeltaTimeF;
|
||||||
|
}
|
||||||
|
if(los.lastFoundTimer>= 10.0f || giveUpTimer <= 0.0f)
|
||||||
|
{
|
||||||
|
machine.SetState(typeof(TimeoutState));
|
||||||
|
}
|
||||||
|
|
||||||
|
RigidBody rigid = machine.GetComponent<RigidBody>();
|
||||||
|
if(rigid)
|
||||||
|
{
|
||||||
|
if (los.withinSight)
|
||||||
|
rigid.LinearVelocity = nav.GetForward() * ai.chaseSpeed;
|
||||||
|
else
|
||||||
|
rigid.LinearVelocity = nav.GetForward() * ai.patrolSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nav.ReachedTarget())
|
||||||
|
{
|
||||||
|
giveUpTimer -= Time.DeltaTimeF;
|
||||||
|
|
||||||
|
ai.RotateToPlayer();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void fixedUpdate()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: ChaseState
|
||||||
|
ID: 166357249
|
||||||
|
Type: 9
|
|
@ -0,0 +1,47 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using SHADE;
|
||||||
|
|
||||||
|
namespace SHADE_Scripting.Gameplay.AIBehaviour.AIRework.States
|
||||||
|
{
|
||||||
|
public class IdleState: AIBaseState
|
||||||
|
{
|
||||||
|
|
||||||
|
float timer = 0.0f;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public IdleState(StateMachine machine): base(machine)
|
||||||
|
{
|
||||||
|
stateName = "Idle";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override void OnEnter()
|
||||||
|
{
|
||||||
|
timer = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void update()
|
||||||
|
{
|
||||||
|
timer += Time.DeltaTimeF;
|
||||||
|
if(timer >= ai.idleDuration)
|
||||||
|
{
|
||||||
|
machine.SetState(typeof(PatrolState));
|
||||||
|
}
|
||||||
|
if(ai.ShouldTransitAlert())
|
||||||
|
{
|
||||||
|
machine.SetState(typeof(AlertState));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void fixedUpdate()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: IdleState
|
||||||
|
ID: 164902316
|
||||||
|
Type: 9
|
|
@ -0,0 +1,88 @@
|
||||||
|
using SHADE;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SHADE_Scripting.Gameplay.AIBehaviour.AIRework.States
|
||||||
|
{
|
||||||
|
public class PatrolState: AIBaseState
|
||||||
|
{
|
||||||
|
|
||||||
|
Random rand;
|
||||||
|
Vector3 lastFramePos;
|
||||||
|
|
||||||
|
float stuckTimer ;
|
||||||
|
|
||||||
|
|
||||||
|
public PatrolState(StateMachine machine) : base(machine)
|
||||||
|
{
|
||||||
|
stateName = "Patrol";
|
||||||
|
rand = new Random();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnEnter()
|
||||||
|
{
|
||||||
|
Navigation nav = machine.GetComponent<Navigation>();
|
||||||
|
Transform transform = machine.GetComponent<Transform>();
|
||||||
|
if (nav && transform)
|
||||||
|
{
|
||||||
|
|
||||||
|
int index = rand.Next(0, ai.patrolPointPool.Count() - 1);
|
||||||
|
Transform dest = ai.patrolPointPool.ElementAt(index);
|
||||||
|
if (dest)
|
||||||
|
{
|
||||||
|
nav.MoveTo(dest.GlobalPosition);
|
||||||
|
Debug.Log("Moving to" + dest.GlobalPosition.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
lastFramePos = transform.GlobalPosition;
|
||||||
|
|
||||||
|
stuckTimer = 0.0f;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void update()
|
||||||
|
{
|
||||||
|
Navigation nav = machine.GetComponent<Navigation>();
|
||||||
|
Transform transform = machine.GetComponent<Transform>();
|
||||||
|
RigidBody rigid = machine.GetComponent<RigidBody>();
|
||||||
|
if(nav && transform && rigid)
|
||||||
|
{
|
||||||
|
rigid.LinearVelocity = nav.GetForward() * ai.patrolSpeed;
|
||||||
|
Vector3 d = lastFramePos - transform.GlobalPosition;
|
||||||
|
if (d.GetSqrMagnitude() < 0.001f)
|
||||||
|
{
|
||||||
|
stuckTimer += Time.DeltaTimeF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (nav.ReachedTarget())
|
||||||
|
{
|
||||||
|
machine.SetState(typeof(IdleState));
|
||||||
|
}
|
||||||
|
lastFramePos = transform.GlobalPosition;
|
||||||
|
|
||||||
|
}
|
||||||
|
if(stuckTimer >= 0.5f)
|
||||||
|
{
|
||||||
|
machine.SetState(typeof(IdleState));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ai.ShouldTransitAlert())
|
||||||
|
{
|
||||||
|
machine.SetState(typeof(AlertState));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void fixedUpdate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: PatrolState
|
||||||
|
ID: 155844701
|
||||||
|
Type: 9
|
|
@ -0,0 +1,47 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using SHADE;
|
||||||
|
|
||||||
|
namespace SHADE_Scripting.Gameplay.AIBehaviour.AIRework.States
|
||||||
|
{
|
||||||
|
public class TimeoutState : AIBaseState
|
||||||
|
{
|
||||||
|
float timer = 0.0f;
|
||||||
|
float alertCooldown = 10.0f;
|
||||||
|
|
||||||
|
public TimeoutState(StateMachine machine) : base(machine)
|
||||||
|
{
|
||||||
|
stateName = "Timeout";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override void OnEnter()
|
||||||
|
{
|
||||||
|
timer = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void update()
|
||||||
|
{
|
||||||
|
timer += Time.DeltaTimeF;
|
||||||
|
if (timer >= ai.timeoutDuration)
|
||||||
|
{
|
||||||
|
machine.SetState(typeof(PatrolState));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void fixedUpdate()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnExit()
|
||||||
|
{
|
||||||
|
ai.alertCooldown = alertCooldown;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: TimeoutState
|
||||||
|
ID: 167077719
|
||||||
|
Type: 9
|
|
@ -35,6 +35,7 @@
|
||||||
#include "Scripting/SHScriptEngine.h"
|
#include "Scripting/SHScriptEngine.h"
|
||||||
#include "UI/SHUISystem.h"
|
#include "UI/SHUISystem.h"
|
||||||
#include "Animation/SHAnimationSystem.h"
|
#include "Animation/SHAnimationSystem.h"
|
||||||
|
#include "Navigation/SHNavigationSystem.h"
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
|
@ -89,6 +90,7 @@ namespace Sandbox
|
||||||
SHSystemManager::CreateSystem<SHAudioSystem>();
|
SHSystemManager::CreateSystem<SHAudioSystem>();
|
||||||
SHSystemManager::CreateSystem<SHCameraSystem>();
|
SHSystemManager::CreateSystem<SHCameraSystem>();
|
||||||
SHSystemManager::CreateSystem<SHUISystem>();
|
SHSystemManager::CreateSystem<SHUISystem>();
|
||||||
|
SHSystemManager::CreateSystem<SHNavigationSystem>();
|
||||||
|
|
||||||
//std::system("FontCompiler.exe ../../Assets/Fonts/SegoeUI.ttf");
|
//std::system("FontCompiler.exe ../../Assets/Fonts/SegoeUI.ttf");
|
||||||
//std::system("FontCompiler.exe ../../Assets/Fonts/ALGER.ttf");
|
//std::system("FontCompiler.exe ../../Assets/Fonts/ALGER.ttf");
|
||||||
|
@ -127,7 +129,9 @@ namespace Sandbox
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
SHSystemManager::RegisterRoutine<SHPhysicsDebugDrawSystem, SHPhysicsDebugDrawSystem::PhysicsDebugDraw>();
|
SHSystemManager::RegisterRoutine<SHPhysicsDebugDrawSystem, SHPhysicsDebugDrawSystem::PhysicsDebugDraw>();
|
||||||
|
SHSystemManager::RegisterRoutine<SHNavigationSystem, SHNavigationSystem::NavigationSystemGenerateRoutine>();
|
||||||
#endif
|
#endif
|
||||||
|
SHSystemManager::RegisterRoutine<SHNavigationSystem, SHNavigationSystem::UpdateNavigationRoutine>();
|
||||||
|
|
||||||
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
|
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
|
||||||
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
|
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
|
||||||
|
|
|
@ -16,3 +16,4 @@
|
||||||
#include "AudioSystem/SHAudioListenerComponent.h"
|
#include "AudioSystem/SHAudioListenerComponent.h"
|
||||||
#include "Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h"
|
#include "Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h"
|
||||||
#include "Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h"
|
#include "Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h"
|
||||||
|
#include "Navigation/SHNavigationComponent.h"
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "AudioSystem/SHAudioListenerComponent.h"
|
#include "AudioSystem/SHAudioListenerComponent.h"
|
||||||
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
|
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
|
||||||
#include "Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h"
|
#include "Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h"
|
||||||
|
#include "Navigation/SHNavigationComponent.h"
|
||||||
#include "Camera/SHCameraSystem.h"
|
#include "Camera/SHCameraSystem.h"
|
||||||
#include "FRC/SHFramerateController.h"
|
#include "FRC/SHFramerateController.h"
|
||||||
|
|
||||||
|
@ -193,6 +194,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
DrawComponent(particleComponent);
|
DrawComponent(particleComponent);
|
||||||
}
|
}
|
||||||
|
if (auto navigationComponent = SHComponentManager::GetComponent_s<SHNavigationComponent>(eid))
|
||||||
|
{
|
||||||
|
DrawComponent(navigationComponent);
|
||||||
|
}
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
// Render Scripts
|
// Render Scripts
|
||||||
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
@ -219,6 +224,7 @@ namespace SHADE
|
||||||
DrawAddComponentWithEnforcedComponentButton<SHTextRenderableComponent, SHTransformComponent>(eid);
|
DrawAddComponentWithEnforcedComponentButton<SHTextRenderableComponent, SHTransformComponent>(eid);
|
||||||
DrawAddComponentWithEnforcedComponentButton<SHAnimatorComponent, SHTransformComponent, SHRenderable>(eid);
|
DrawAddComponentWithEnforcedComponentButton<SHAnimatorComponent, SHTransformComponent, SHRenderable>(eid);
|
||||||
DrawAddComponentWithEnforcedComponentButton<SHAudioListenerComponent, SHTransformComponent>(eid);
|
DrawAddComponentWithEnforcedComponentButton<SHAudioListenerComponent, SHTransformComponent>(eid);
|
||||||
|
DrawAddComponentWithEnforcedComponentButton<SHNavigationComponent, SHTransformComponent>(eid);
|
||||||
//DrawAddComponentWithEnforcedComponentButton<SHParticleEmitterComponent, SHTransformComponent>(eid);
|
//DrawAddComponentWithEnforcedComponentButton<SHParticleEmitterComponent, SHTransformComponent>(eid);
|
||||||
|
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHNavigationComponent.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
uint16_t NavigationGridIndex::numColumns = 8;
|
||||||
|
|
||||||
|
|
||||||
|
SHNavigationComponent::SHNavigationComponent()
|
||||||
|
:target{ 0.0f }, path{}, threshold{ 0.1f }, recalculatePath{ false }, unreachableTarget{ false }, forward{0.0f}, tolerance{0}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHVec3 SHNavigationComponent::GetTarget() const noexcept
|
||||||
|
{
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHVec3 SHNavigationComponent::GetForward() const noexcept
|
||||||
|
{
|
||||||
|
return forward;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHNavigationComponent::GetRecalculatePath() const noexcept
|
||||||
|
{
|
||||||
|
return recalculatePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHNavigationComponent::GetUnreachableTarget() const noexcept
|
||||||
|
{
|
||||||
|
return unreachableTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHNavigationComponent::ReachedTarget() const noexcept
|
||||||
|
{
|
||||||
|
return path.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SHNavigationComponent::SetTarget(SHVec3 value) noexcept
|
||||||
|
{
|
||||||
|
recalculatePath = true;
|
||||||
|
target = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SHNavigationComponent::EmptySetForward(SHVec3 value) noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHNavigationComponent::EmptySetBool(bool value) noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}//namespace SHADE
|
||||||
|
|
||||||
|
|
||||||
|
RTTR_REGISTRATION
|
||||||
|
{
|
||||||
|
using namespace SHADE;
|
||||||
|
using namespace rttr;
|
||||||
|
|
||||||
|
registration::class_<SHNavigationComponent>("Navigation Component")
|
||||||
|
.property("Target", &SHNavigationComponent::GetTarget, &SHNavigationComponent::SetTarget)
|
||||||
|
.property("Forward", &SHNavigationComponent::GetForward, &SHNavigationComponent::EmptySetForward)
|
||||||
|
.property("Recalculate Path", &SHNavigationComponent::GetRecalculatePath, &SHNavigationComponent::EmptySetBool)
|
||||||
|
.property("Unreachable Target", &SHNavigationComponent::GetUnreachableTarget, &SHNavigationComponent::EmptySetBool)
|
||||||
|
.property("Tolerance", &SHNavigationComponent::tolerance)
|
||||||
|
.property("Acceptance threshold", &SHNavigationComponent::threshold)
|
||||||
|
;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,123 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <rttr/registration>
|
||||||
|
|
||||||
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
|
#include "Math/Vector/SHVec2.h"
|
||||||
|
#include "Math/Vector/SHVec3.h"
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct NavigationGridIndex
|
||||||
|
{
|
||||||
|
uint16_t row;
|
||||||
|
uint16_t column;
|
||||||
|
|
||||||
|
static uint16_t numColumns;
|
||||||
|
|
||||||
|
bool operator==(NavigationGridIndex const& rhs) const noexcept
|
||||||
|
{
|
||||||
|
return row == rhs.row && column == rhs.column;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(NavigationGridIndex const& rhs) const noexcept
|
||||||
|
{
|
||||||
|
return row != rhs.row || column != rhs.column;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(NavigationGridIndex const& rhs) const noexcept
|
||||||
|
{
|
||||||
|
return (row * numColumns + column) < (rhs.row * numColumns + rhs.column);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define NullGridIndex 9999;
|
||||||
|
|
||||||
|
class SH_API SHNavigationComponent final: public SHComponent
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
//Target to move to
|
||||||
|
SHVec3 target;
|
||||||
|
//Direction to mvoe towards to get to the target position.
|
||||||
|
SHVec3 forward;
|
||||||
|
//The path to follow to reach the target.
|
||||||
|
std::queue<NavigationGridIndex> path;
|
||||||
|
|
||||||
|
//The flag to check against to indicate whether to recalculate path
|
||||||
|
bool recalculatePath;
|
||||||
|
//The flag to set if the target is unreachable.
|
||||||
|
bool unreachableTarget;
|
||||||
|
public:
|
||||||
|
friend class SHNavigationSystem;
|
||||||
|
|
||||||
|
//The distance threshold that indicates when the entity has reached the navigation grid.
|
||||||
|
float threshold;
|
||||||
|
//Number of grid cells surrounding colliding cells to also mark as colliding.
|
||||||
|
uint16_t tolerance;
|
||||||
|
|
||||||
|
SHNavigationComponent();
|
||||||
|
virtual ~SHNavigationComponent() = default;
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* \brief
|
||||||
|
* Getter for the target position. This should be in world position.
|
||||||
|
* \return
|
||||||
|
* SHVec3
|
||||||
|
********************************************************************/
|
||||||
|
SHVec3 GetTarget() const noexcept;
|
||||||
|
/********************************************************************
|
||||||
|
* \brief
|
||||||
|
* Getter for the forward vector. This shows the direction to move
|
||||||
|
* in order to reach the target.
|
||||||
|
* \return
|
||||||
|
* SHVec3
|
||||||
|
********************************************************************/
|
||||||
|
SHVec3 GetForward() const noexcept;
|
||||||
|
|
||||||
|
bool GetRecalculatePath() const noexcept;
|
||||||
|
|
||||||
|
bool GetUnreachableTarget() const noexcept;
|
||||||
|
|
||||||
|
bool ReachedTarget() const noexcept;
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* \brief
|
||||||
|
* Setter for the target variable. Also sets recalculatePath boolean
|
||||||
|
* to true.
|
||||||
|
* \param value
|
||||||
|
* The target world location. The y-axis will be ignored.
|
||||||
|
* \return
|
||||||
|
* void
|
||||||
|
********************************************************************/
|
||||||
|
void SetTarget(SHVec3 value) noexcept;
|
||||||
|
/********************************************************************
|
||||||
|
* \brief
|
||||||
|
* An empty setter so we can see this variable in inspector but
|
||||||
|
* can't set it.
|
||||||
|
* \param value
|
||||||
|
* value to set to.
|
||||||
|
* \return
|
||||||
|
* void
|
||||||
|
********************************************************************/
|
||||||
|
void EmptySetForward(SHVec3 value) noexcept;
|
||||||
|
|
||||||
|
void EmptySetBool(bool value) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
RTTR_ENABLE()
|
||||||
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,671 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHNavigationSystem.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "Physics/System/SHPhysicsSystem.h"
|
||||||
|
#include "Math/Geometry/SHAABB.h"
|
||||||
|
#include "Input/SHInputManager.h"
|
||||||
|
#include "Editor/SHEditor.h"
|
||||||
|
#include "Scene/SHSceneManager.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <stack>
|
||||||
|
#include <map>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
#define DRAW_NAVIGATION_DATA
|
||||||
|
#define DRAW_NAVIGATION_PATH
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
void SHNavigationSystem::Init()
|
||||||
|
{
|
||||||
|
auto id = ComponentFamily::GetID<SHNavigationComponent>();
|
||||||
|
SHComponentManager::CreateComponentSparseSet<SHNavigationComponent>();
|
||||||
|
SystemID i = SystemFamily::GetID<SHNavigationSystem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHNavigationSystem::Exit()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t SHNavigationSystem::GetIndex(uint16_t row, uint16_t col) noexcept
|
||||||
|
{
|
||||||
|
size_t rowOffset = numRows / NumGridDataTypeBits;
|
||||||
|
return row * rowOffset + (col / NumGridDataTypeBits );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool SHNavigationSystem::GetNavigationData(uint16_t row, uint16_t col) noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
size_t index = GetIndex(row, col);
|
||||||
|
|
||||||
|
GridDataType bitMask = 1 << (col % NumGridDataTypeBits);
|
||||||
|
|
||||||
|
if ( index < navigationGrid.size())
|
||||||
|
{
|
||||||
|
return navigationGrid[index] & bitMask;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHNavigationSystem::GetNavigationData(NavigationGridIndex index) noexcept
|
||||||
|
{
|
||||||
|
return GetNavigationData(index.row, index.column);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHVec2 SHNavigationSystem::GetGridSize() noexcept
|
||||||
|
{
|
||||||
|
return SHVec2{size.x / numCols, size.z / numRows};
|
||||||
|
}
|
||||||
|
|
||||||
|
NavigationGridIndex SHNavigationSystem::GetNavigationGridIndex(SHVec3 const& worldPosition) noexcept
|
||||||
|
{
|
||||||
|
NavigationGridIndex result;
|
||||||
|
SHVec3 topleft{ origin.x - (size.x / 2.0f), origin.y, origin.z - (size.z / 2.0f) };
|
||||||
|
SHVec3 pos = worldPosition - topleft;
|
||||||
|
SHVec2 gridSize = GetGridSize();
|
||||||
|
|
||||||
|
result.row = (pos.z )/ gridSize.y;
|
||||||
|
result.column = (pos.x )/ gridSize.x;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHVec3 SHNavigationSystem::GetGridWorldPos(NavigationGridIndex index) noexcept
|
||||||
|
{
|
||||||
|
SHVec3 result{0.0f};
|
||||||
|
SHVec3 topleft{ origin.x - (size.x / 2.0f), origin.y, origin.z - (size.z / 2.0f) };
|
||||||
|
SHVec2 gridSize = GetGridSize();
|
||||||
|
result.x = (index.column * gridSize.x);
|
||||||
|
result.z = (index.row * gridSize.y) ;
|
||||||
|
|
||||||
|
result += topleft;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void SHNavigationSystem::GenerateNavigationGridData(SHVec3 origin, SHVec3 size, uint16_t nr, uint16_t nc) noexcept
|
||||||
|
{
|
||||||
|
if (size.x <= 0.0f || size.y <= 0.0f || size.z <= 0.0f || nr == 0 || nc == 0 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this->origin = origin;
|
||||||
|
this->size = size;
|
||||||
|
numRows = nr;
|
||||||
|
numCols = nc;
|
||||||
|
navigationGrid.clear();
|
||||||
|
|
||||||
|
|
||||||
|
GridDataType temp = 0;
|
||||||
|
|
||||||
|
for (size_t r = 0; r < numRows; ++r)
|
||||||
|
{
|
||||||
|
for (size_t c = 0; c < numCols; ++c)
|
||||||
|
{
|
||||||
|
GridDataType bitmask = 1 << (c % NumGridDataTypeBits);
|
||||||
|
auto physics = SHSystemManager::GetSystem<SHPhysicsSystem>();
|
||||||
|
|
||||||
|
//Does the AABB calculation
|
||||||
|
if (physics != nullptr)
|
||||||
|
{
|
||||||
|
//Get the top left position
|
||||||
|
SHVec3 topleft{ origin.x - (size.x / 2.0f), origin.y, origin.z - (size.z / 2.0f) };
|
||||||
|
SHVec2 halfGridSize = GetGridSize() * 0.5f;
|
||||||
|
|
||||||
|
//offset it by row and column and center it with half grid size.
|
||||||
|
topleft += SHVec3{ c * GetGridSize().x, 0.0f, r * GetGridSize().y} + SHVec3{halfGridSize.x,0.0f,halfGridSize.y};
|
||||||
|
|
||||||
|
//Get half extents.
|
||||||
|
|
||||||
|
SHVec3 halfExtents{ halfGridSize.x, size.y, halfGridSize.y };
|
||||||
|
|
||||||
|
SHAABB aabb{ topleft,halfExtents };
|
||||||
|
|
||||||
|
if (physics->TestAABBOverlap(aabb, (uint16_t)(SHCollisionTagMatrix::GetTag("Navigation")->GetMask())))
|
||||||
|
{
|
||||||
|
temp |= bitmask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((c % NumGridDataTypeBits) == NumGridDataTypeBits - 1)
|
||||||
|
{
|
||||||
|
navigationGrid.push_back(temp);
|
||||||
|
temp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//if the number of column dont fit perfectly to the NumGridDataTypeBits. We push in what we have with the rest as 0s.
|
||||||
|
if (numCols % NumGridDataTypeBits != 0)
|
||||||
|
{
|
||||||
|
navigationGrid.push_back(temp);
|
||||||
|
temp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void SHNavigationSystem::NavigationSystemGenerateRoutine::Execute(double dt) noexcept
|
||||||
|
{
|
||||||
|
#ifdef SHEDITOR
|
||||||
|
SHVec3 navigationAreaSize{ 10.5f, 1.0f, 10.5f };
|
||||||
|
|
||||||
|
auto editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
if (editor->editorState != SHEditor::State::PLAY)
|
||||||
|
{
|
||||||
|
SHNavigationSystem* system = static_cast<SHNavigationSystem*>(GetSystem());
|
||||||
|
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::H))
|
||||||
|
{
|
||||||
|
system->GenerateNavigationGridData(SHVec3{ 0.0f }, navigationAreaSize, 80, 80);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto debugDrawSystem = SHSystemManager::GetSystem<SHDebugDrawSystem>();
|
||||||
|
if (debugDrawSystem)
|
||||||
|
{
|
||||||
|
SHTransform trans;
|
||||||
|
trans.position = SHVec3{ 0.0f };
|
||||||
|
trans.scale = navigationAreaSize;
|
||||||
|
trans.ComputeTRS();
|
||||||
|
debugDrawSystem->DrawWireCube(trans.trs, SHColour::YELLOW, false);
|
||||||
|
|
||||||
|
#ifdef DRAW_NAVIGATION_DATA
|
||||||
|
for (uint16_t r = 0; r < system->numRows; ++r)
|
||||||
|
{
|
||||||
|
for (uint16_t c = 0; c < system->numCols; ++c)
|
||||||
|
{
|
||||||
|
if (system->GetNavigationData(r, c) == true)
|
||||||
|
{
|
||||||
|
SHVec3 topleft{ system->origin.x - (system->size.x / 2.0f), system->origin.y, system->origin.z - (system->size.z / 2.0f) };
|
||||||
|
SHVec2 halfGridSize = system->GetGridSize() * 0.5f;
|
||||||
|
|
||||||
|
//offset it by row and column and center it with half grid size.
|
||||||
|
topleft += SHVec3{ c * system->GetGridSize().x, 0.0f, r * system->GetGridSize().y } + SHVec3{ halfGridSize.x,0.0f,halfGridSize.y };
|
||||||
|
SHTransform t;
|
||||||
|
t.position = system->GetGridWorldPos({r,c});
|
||||||
|
t.scale = SHVec3{ halfGridSize.x * 2.0f, 1.0f, halfGridSize.y * 2.0f};
|
||||||
|
t.ComputeTRS();
|
||||||
|
debugDrawSystem->DrawCube(t.trs, SHColour::RED, true);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHVec3 topleft{ system->origin.x - (system->size.x / 2.0f), system->origin.y, system->origin.z - (system->size.z / 2.0f) };
|
||||||
|
SHVec2 halfGridSize = system->GetGridSize() * 0.5f;
|
||||||
|
|
||||||
|
//offset it by row and column and center it with half grid size.
|
||||||
|
topleft += SHVec3{ c * system->GetGridSize().x, 0.0f, r * system->GetGridSize().y } + SHVec3{ halfGridSize.x,0.0f,halfGridSize.y };
|
||||||
|
SHTransform t;
|
||||||
|
t.position = system->GetGridWorldPos({ r,c });
|
||||||
|
t.scale = SHVec3{ halfGridSize.x * 2.0f, 1.0f, halfGridSize.y * 2.0f };
|
||||||
|
t.ComputeTRS();
|
||||||
|
debugDrawSystem->DrawCube(t.trs, SHColour::WHITE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHNavigationSystem::UpdateNavigationRoutine::Execute(double dt) noexcept
|
||||||
|
{
|
||||||
|
SHNavigationSystem* system = static_cast<SHNavigationSystem*>(GetSystem());
|
||||||
|
auto& dense = SHComponentManager::GetDense<SHNavigationComponent>();
|
||||||
|
|
||||||
|
for (auto& comp : dense)
|
||||||
|
{
|
||||||
|
if (SHSceneManager::CheckNodeAndComponentsActive<SHNavigationComponent>(comp.GetEID()))
|
||||||
|
{
|
||||||
|
if (comp.recalculatePath)
|
||||||
|
system->GeneratePath(comp);
|
||||||
|
|
||||||
|
system->UpdateNavigationComponent(comp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SHNavigationSystem::UpdateNavigationComponent(SHNavigationComponent& comp) noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
if (comp.unreachableTarget == true || comp.path.empty())
|
||||||
|
{
|
||||||
|
comp.forward = SHVec3::Zero;
|
||||||
|
return; // no point continuing because target can't be reached / path is empty.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHTransformComponent* transform = SHComponentManager::GetComponent_s<SHTransformComponent>(comp.GetEID());
|
||||||
|
if (transform)
|
||||||
|
{
|
||||||
|
NavigationGridIndex nxtPoint = comp.path.front();
|
||||||
|
SHVec3 nxtPointPos = GetGridWorldPos(nxtPoint);
|
||||||
|
|
||||||
|
SHVec3 direction = nxtPointPos - transform->GetWorldPosition();
|
||||||
|
direction.y = 0.0f;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (direction.LengthSquared() <= comp.threshold * comp.threshold || direction.LengthSquared() <= GetGridSize().LengthSquared() * 0.5f)
|
||||||
|
{
|
||||||
|
comp.path.pop();
|
||||||
|
//Rerun this function
|
||||||
|
UpdateNavigationComponent(comp);
|
||||||
|
//return so we don't run the parts after this twice.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
comp.forward = SHVec3::Normalise(direction);
|
||||||
|
|
||||||
|
#ifdef DRAW_NAVIGATION_PATH
|
||||||
|
|
||||||
|
auto debugDrawSystem = SHSystemManager::GetSystem<SHDebugDrawSystem>();
|
||||||
|
|
||||||
|
auto queue = comp.path;
|
||||||
|
|
||||||
|
while (!queue.empty())
|
||||||
|
{
|
||||||
|
uint16_t r = queue.front().row;
|
||||||
|
uint16_t c = queue.front().column;
|
||||||
|
|
||||||
|
{
|
||||||
|
SHVec3 topleft{ origin.x - (size.x / 2.0f), origin.y, origin.z - (size.z / 2.0f) };
|
||||||
|
SHVec2 halfGridSize = GetGridSize() * 0.5f;
|
||||||
|
|
||||||
|
//offset it by row and column and center it with half grid size.
|
||||||
|
topleft += SHVec3{ c * GetGridSize().x, 0.0f, r * GetGridSize().y } + SHVec3{ halfGridSize.x,0.0f,halfGridSize.y };
|
||||||
|
SHTransform t;
|
||||||
|
t.position = GetGridWorldPos({ r,c });
|
||||||
|
t.scale = SHVec3{ halfGridSize.x * 2.0f, 1.0f, halfGridSize.y * 2.0f };
|
||||||
|
t.ComputeTRS();
|
||||||
|
debugDrawSystem->DrawCube(t.trs, SHColour::YELLOW, true);
|
||||||
|
|
||||||
|
}
|
||||||
|
queue.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void SHNavigationSystem::GeneratePath(SHNavigationComponent& comp) noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
//Check that the entity has a transform.
|
||||||
|
if (SHComponentManager::HasComponent<SHTransformComponent>(comp.GetEID()) == false)
|
||||||
|
{
|
||||||
|
comp.unreachableTarget = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::list<NavigationNode> openList;
|
||||||
|
std::map<NavigationGridIndex, NavigationNode> closedList;
|
||||||
|
closedList.clear();
|
||||||
|
|
||||||
|
NavigationGridIndex::numColumns = numCols;
|
||||||
|
|
||||||
|
//Check if ending position is set to true in navigation data.
|
||||||
|
NavigationGridIndex endIndex = GetNavigationGridIndex(comp.target);
|
||||||
|
//if (GetNavigationData(endIndex) == true)
|
||||||
|
//{
|
||||||
|
// //Target position is unreachable.
|
||||||
|
// SHLOG_WARNING("Navigation System: GeneratePath() target position is unreachable EID: {}", comp.GetEID())
|
||||||
|
// comp.unreachableTarget = true;
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(comp.GetEID());
|
||||||
|
|
||||||
|
NavigationNode startingNode;
|
||||||
|
startingNode.index = GetNavigationGridIndex(transform->GetWorldPosition());
|
||||||
|
|
||||||
|
startingNode.parent.row = NullGridIndex;
|
||||||
|
startingNode.parent.column = NullGridIndex;
|
||||||
|
startingNode.h = std::numeric_limits<uint32_t>::max();
|
||||||
|
startingNode.g = 0;
|
||||||
|
startingNode.f = 0;
|
||||||
|
|
||||||
|
openList.push_back(startingNode);
|
||||||
|
|
||||||
|
|
||||||
|
NavigationNode endNode;
|
||||||
|
endNode.index.row = NullGridIndex;
|
||||||
|
endNode.index.column = NullGridIndex;
|
||||||
|
endNode.g = std::numeric_limits<uint32_t>::max();
|
||||||
|
endNode.h = std::numeric_limits<uint32_t>::max();
|
||||||
|
endNode.f = std::numeric_limits<uint32_t>::max();
|
||||||
|
|
||||||
|
while (!openList.empty())
|
||||||
|
{
|
||||||
|
NavigationNode currNode;
|
||||||
|
std::list<NavigationNode>::iterator lowestNode = openList.end();
|
||||||
|
uint32_t lowestFValue = std::numeric_limits<uint32_t>::max();
|
||||||
|
uint32_t lowestHValue = std::numeric_limits<uint32_t>::max();
|
||||||
|
for (std::list<NavigationNode>::iterator node = openList.begin(); node != openList.end(); ++node)
|
||||||
|
{
|
||||||
|
if (node->f < lowestFValue)
|
||||||
|
{
|
||||||
|
lowestNode = node;
|
||||||
|
lowestHValue = node->h;
|
||||||
|
lowestFValue = node->f;
|
||||||
|
}
|
||||||
|
if (node->f == lowestFValue && node->h < lowestHValue)
|
||||||
|
{
|
||||||
|
lowestNode = node;
|
||||||
|
lowestHValue = node->h;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
currNode = *lowestNode;
|
||||||
|
openList.erase(lowestNode);
|
||||||
|
closedList.emplace(currNode.index, currNode);
|
||||||
|
|
||||||
|
if (currNode.index == endIndex)
|
||||||
|
{
|
||||||
|
endNode = currNode;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add the surrounding 8 tiles into the open list
|
||||||
|
{
|
||||||
|
//Top
|
||||||
|
if (currNode.index.column > 0)
|
||||||
|
{
|
||||||
|
NavigationNode topNode;
|
||||||
|
topNode.index = currNode.index;
|
||||||
|
topNode.index.column -= 1;
|
||||||
|
topNode.parent = currNode.index;
|
||||||
|
topNode.g = currNode.g + 10;
|
||||||
|
topNode.h = HCostCalculation(topNode.index, endIndex);
|
||||||
|
topNode.f = topNode.g + topNode.h;
|
||||||
|
AddNodeToOpenList(topNode, openList, closedList, comp.tolerance);
|
||||||
|
|
||||||
|
//TopLeft
|
||||||
|
if (currNode.index.row > 0)
|
||||||
|
{
|
||||||
|
NavigationNode newNode;
|
||||||
|
newNode.index = currNode.index;
|
||||||
|
newNode.index.column -= 1;
|
||||||
|
newNode.index.row -= 1;
|
||||||
|
newNode.parent = currNode.index;
|
||||||
|
newNode.g = currNode.g + 14;
|
||||||
|
newNode.h = HCostCalculation(newNode.index, endIndex);
|
||||||
|
newNode.f = newNode.g + newNode.h;
|
||||||
|
AddNodeToOpenList(newNode, openList, closedList, comp.tolerance);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//Bottom
|
||||||
|
if (currNode.index.column < numCols - 1)
|
||||||
|
{
|
||||||
|
NavigationNode btmNode;
|
||||||
|
btmNode.index = currNode.index;
|
||||||
|
btmNode.index.column += 1;
|
||||||
|
btmNode.parent = currNode.index;
|
||||||
|
btmNode.g = currNode.g + 10;
|
||||||
|
btmNode.h = HCostCalculation(btmNode.index, endIndex);
|
||||||
|
btmNode.f = btmNode.g + btmNode.h;
|
||||||
|
AddNodeToOpenList(btmNode, openList, closedList, comp.tolerance);
|
||||||
|
|
||||||
|
//BottomRight
|
||||||
|
if (currNode.index.row < numRows - 1)
|
||||||
|
{
|
||||||
|
NavigationNode newNode;
|
||||||
|
newNode.index = currNode.index;
|
||||||
|
newNode.index.column += 1;
|
||||||
|
newNode.index.row += 1;
|
||||||
|
newNode.parent = currNode.index;
|
||||||
|
newNode.g = currNode.g + 14;
|
||||||
|
newNode.h = HCostCalculation(newNode.index, endIndex);
|
||||||
|
newNode.f = newNode.g + newNode.h;
|
||||||
|
AddNodeToOpenList(newNode, openList, closedList, comp.tolerance);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//Left
|
||||||
|
if (currNode.index.row > 0)
|
||||||
|
{
|
||||||
|
NavigationNode leftNode;
|
||||||
|
leftNode.index = currNode.index;
|
||||||
|
leftNode.index.row -= 1;
|
||||||
|
leftNode.parent = currNode.index;
|
||||||
|
leftNode.g = currNode.g + 10;
|
||||||
|
leftNode.h = HCostCalculation(leftNode.index, endIndex);
|
||||||
|
leftNode.f = leftNode.g + leftNode.h;
|
||||||
|
AddNodeToOpenList(leftNode, openList, closedList, comp.tolerance);
|
||||||
|
|
||||||
|
|
||||||
|
//BottomLeft
|
||||||
|
if (currNode.index.column < numCols - 1)
|
||||||
|
{
|
||||||
|
NavigationNode newNode;
|
||||||
|
newNode.index = currNode.index;
|
||||||
|
newNode.index.column += 1;
|
||||||
|
newNode.index.row -= 1;
|
||||||
|
newNode.parent = currNode.index;
|
||||||
|
newNode.g = currNode.g + 14;
|
||||||
|
newNode.h = HCostCalculation(newNode.index, endIndex);
|
||||||
|
newNode.f = newNode.g + newNode.h;
|
||||||
|
AddNodeToOpenList(newNode, openList, closedList, comp.tolerance);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
//Right
|
||||||
|
if (currNode.index.row < numRows - 1)
|
||||||
|
{
|
||||||
|
NavigationNode rightNode;
|
||||||
|
rightNode.index = currNode.index;
|
||||||
|
rightNode.index.row += 1;
|
||||||
|
rightNode.parent = currNode.index;
|
||||||
|
rightNode.g = currNode.g + 10;
|
||||||
|
rightNode.h = HCostCalculation(rightNode.index, endIndex);
|
||||||
|
rightNode.f = rightNode.g + rightNode.h;
|
||||||
|
AddNodeToOpenList(rightNode, openList, closedList, comp.tolerance);
|
||||||
|
|
||||||
|
//TopRight
|
||||||
|
if (currNode.index.column > 0)
|
||||||
|
{
|
||||||
|
NavigationNode newNode;
|
||||||
|
newNode.index = currNode.index;
|
||||||
|
newNode.index.column -= 1;
|
||||||
|
newNode.index.row += 1;
|
||||||
|
newNode.parent = currNode.index;
|
||||||
|
newNode.g = currNode.g + 14;
|
||||||
|
newNode.h = HCostCalculation(newNode.index, endIndex);
|
||||||
|
newNode.f = newNode.g + newNode.h;
|
||||||
|
AddNodeToOpenList(newNode, openList, closedList, comp.tolerance);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//Check if there is a path.
|
||||||
|
if (endNode.g == std::numeric_limits<uint32_t>::max() || endNode.h == std::numeric_limits<uint32_t>::max() || endNode.f == std::numeric_limits<uint32_t>::max())
|
||||||
|
{
|
||||||
|
//SHLOG_WARNING("Navigation System: End Node not found after running through algo EID: {}", comp.GetEID())
|
||||||
|
//comp.unreachableTarget = true;
|
||||||
|
uint32_t lowestH = std::numeric_limits<uint32_t>::max();
|
||||||
|
|
||||||
|
for (std::map<NavigationGridIndex, NavigationNode>::iterator it = closedList.begin(); it != closedList.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->second.h < lowestH)
|
||||||
|
{
|
||||||
|
lowestH = it->second.h;
|
||||||
|
endNode = (it->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Generate the path using end node.
|
||||||
|
std::stack<NavigationGridIndex> reversePath;
|
||||||
|
NavigationNode pathNode = endNode;
|
||||||
|
|
||||||
|
while (pathNode.index != startingNode.index)
|
||||||
|
{
|
||||||
|
reversePath.push(pathNode.index);
|
||||||
|
if (closedList.find(pathNode.parent) == closedList.end())
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Navigation System: GeneratePath() reverse path parent not in closed list EID: {}", comp.GetEID())
|
||||||
|
comp.unreachableTarget = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pathNode = closedList.find(pathNode.parent)->second;
|
||||||
|
|
||||||
|
}
|
||||||
|
//Clear the queue.
|
||||||
|
while (!comp.path.empty())
|
||||||
|
{
|
||||||
|
comp.path.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!reversePath.empty())
|
||||||
|
{
|
||||||
|
comp.path.push(reversePath.top());
|
||||||
|
reversePath.pop();
|
||||||
|
}
|
||||||
|
comp.recalculatePath = false;
|
||||||
|
comp.unreachableTarget = false;
|
||||||
|
}//End GeneratePath
|
||||||
|
|
||||||
|
|
||||||
|
bool SHNavigationSystem::AddNodeToOpenList(NavigationNode node, std::list<NavigationNode>& openList, std::map<NavigationGridIndex, NavigationNode>& closedList, uint16_t tolerance) noexcept
|
||||||
|
{
|
||||||
|
if (closedList.find(node.index) != closedList.end())
|
||||||
|
{
|
||||||
|
//Node is already in closed list.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if the node is pointing to a non movable tile.
|
||||||
|
if (GetNavigationData(node.index) == true)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check that node surrounding this is also movable. (Controlled by tolerance).
|
||||||
|
for (uint16_t i = 0; i < tolerance; ++i)
|
||||||
|
{
|
||||||
|
NavigationGridIndex tolCheckIndex = node.index;
|
||||||
|
tolCheckIndex.row += i;
|
||||||
|
if (GetNavigationData(tolCheckIndex) == true)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tolCheckIndex = node.index;
|
||||||
|
tolCheckIndex.row -= i;
|
||||||
|
if (GetNavigationData(tolCheckIndex) == true)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tolCheckIndex = node.index;
|
||||||
|
tolCheckIndex.column += i;
|
||||||
|
if (GetNavigationData(tolCheckIndex) == true)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tolCheckIndex = node.index;
|
||||||
|
tolCheckIndex.column -= i;
|
||||||
|
if (GetNavigationData(tolCheckIndex) == true)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tolCheckIndex = node.index;
|
||||||
|
tolCheckIndex.row += i;
|
||||||
|
tolCheckIndex.column += i;
|
||||||
|
if (GetNavigationData(tolCheckIndex) == true)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tolCheckIndex = node.index;
|
||||||
|
tolCheckIndex.row -= i;
|
||||||
|
tolCheckIndex.column -= i;
|
||||||
|
if (GetNavigationData(tolCheckIndex) == true)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tolCheckIndex = node.index;
|
||||||
|
tolCheckIndex.row -= i;
|
||||||
|
tolCheckIndex.column += i;
|
||||||
|
if (GetNavigationData(tolCheckIndex) == true)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tolCheckIndex = node.index;
|
||||||
|
tolCheckIndex.row += i;
|
||||||
|
tolCheckIndex.column -= i;
|
||||||
|
if (GetNavigationData(tolCheckIndex) == true)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Check if node exist in open list already
|
||||||
|
for (auto& n : openList)
|
||||||
|
{
|
||||||
|
if (n.index == node.index )
|
||||||
|
{
|
||||||
|
if (n.f > node.f)
|
||||||
|
{
|
||||||
|
n = node;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
openList.push_back(node);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t SHNavigationSystem::HCostCalculation(NavigationGridIndex first, NavigationGridIndex second) noexcept
|
||||||
|
{
|
||||||
|
uint16_t rDiff = (first.row > second.row)?first.row - second.row: second.row - first.row;
|
||||||
|
uint16_t cDiff = (first.column > second.column) ? first.column - second.column : second.column - first.column;
|
||||||
|
|
||||||
|
if (rDiff > cDiff)
|
||||||
|
{
|
||||||
|
return (cDiff * 14) + ((rDiff - cDiff) * 10);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (rDiff * 14 )+ ((cDiff - rDiff) * 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ECS_Base/System/SHSystem.h"
|
||||||
|
#include "ECS_Base/System/SHSystemRoutine.h"
|
||||||
|
#include "SHNavigationComponent.h"
|
||||||
|
#include "Math/Vector/SHVec2.h"
|
||||||
|
#include "Math/Vector/SHVec3.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
struct SH_API NavigationNode
|
||||||
|
{
|
||||||
|
NavigationGridIndex index;
|
||||||
|
NavigationGridIndex parent;
|
||||||
|
uint32_t g;
|
||||||
|
uint32_t h;
|
||||||
|
uint32_t f;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class SH_API SHNavigationSystem final: public SHSystem
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
using GridDataType = uint8_t;
|
||||||
|
|
||||||
|
const size_t NumGridDataTypeBits = sizeof(GridDataType) * CHAR_BIT;
|
||||||
|
|
||||||
|
std::vector<uint8_t> navigationGrid;
|
||||||
|
|
||||||
|
//Number of subdivision on the x axis
|
||||||
|
uint16_t numRows{0};
|
||||||
|
//Number of subdivision on the z axis
|
||||||
|
uint16_t numCols{0};
|
||||||
|
|
||||||
|
//The center of the navigation area.
|
||||||
|
SHVec3 origin{0.0f};
|
||||||
|
|
||||||
|
//Size of the navigation area
|
||||||
|
SHVec3 size{0.0f};
|
||||||
|
|
||||||
|
SHVec2 GetGridSize() noexcept;
|
||||||
|
uint16_t GetIndex(uint16_t row, uint16_t col) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t HCostCalculation(NavigationGridIndex first, NavigationGridIndex second) noexcept; //TO DO
|
||||||
|
bool AddNodeToOpenList(NavigationNode node, std::list<NavigationNode>& openList, std::map<NavigationGridIndex, NavigationNode>& closedList, uint16_t tolerance) noexcept;
|
||||||
|
void UpdateNavigationComponent(SHNavigationComponent& comp) noexcept;
|
||||||
|
SHVec3 GetGridWorldPos(NavigationGridIndex index) noexcept;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SHNavigationSystem() = default;
|
||||||
|
virtual ~SHNavigationSystem() = default;
|
||||||
|
|
||||||
|
virtual void Init();
|
||||||
|
virtual void Exit();
|
||||||
|
|
||||||
|
|
||||||
|
void GenerateNavigationGridData(SHVec3 origin, SHVec3 size, uint16_t numRow, uint16_t numCol) noexcept;
|
||||||
|
void GeneratePath(SHNavigationComponent& comp) noexcept;
|
||||||
|
|
||||||
|
bool GetNavigationData(uint16_t row, uint16_t col) noexcept;
|
||||||
|
bool GetNavigationData(NavigationGridIndex index) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
NavigationGridIndex GetNavigationGridIndex(SHVec3 const& worldPosition) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class SH_API NavigationSystemGenerateRoutine final: public SHSystemRoutine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NavigationSystemGenerateRoutine() : SHSystemRoutine("Navigation System Generate", true) {};
|
||||||
|
virtual void Execute(double dt)noexcept override final;
|
||||||
|
};
|
||||||
|
friend class NavigationSystemGenerateRoutine;
|
||||||
|
|
||||||
|
class SH_API UpdateNavigationRoutine final: public SHSystemRoutine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UpdateNavigationRoutine() : SHSystemRoutine("Update Navigation Routine", false) {};
|
||||||
|
virtual void Execute(double dt)noexcept override final;
|
||||||
|
};
|
||||||
|
friend class UpdateNavigationRoutine;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -243,6 +243,8 @@ namespace SHADE
|
||||||
AddComponentToComponentNode<SHToggleButtonComponent>(components, eid);
|
AddComponentToComponentNode<SHToggleButtonComponent>(components, eid);
|
||||||
AddComponentToComponentNode<SHSliderComponent>(components, eid);
|
AddComponentToComponentNode<SHSliderComponent>(components, eid);
|
||||||
|
|
||||||
|
AddComponentToComponentNode<SHNavigationComponent>(components, eid);
|
||||||
|
|
||||||
AddComponentToComponentNode<SHTextRenderableComponent>(components, eid);
|
AddComponentToComponentNode<SHTextRenderableComponent>(components, eid);
|
||||||
AddComponentToComponentNode<SHAnimatorComponent>(components, eid);
|
AddComponentToComponentNode<SHAnimatorComponent>(components, eid);
|
||||||
AddComponentToComponentNode<SHUIComponent>(components, eid);
|
AddComponentToComponentNode<SHUIComponent>(components, eid);
|
||||||
|
@ -306,6 +308,9 @@ namespace SHADE
|
||||||
AddComponentID<SHButtonComponent>(componentIDList, componentsNode);
|
AddComponentID<SHButtonComponent>(componentIDList, componentsNode);
|
||||||
AddComponentID<SHToggleButtonComponent>(componentIDList, componentsNode);
|
AddComponentID<SHToggleButtonComponent>(componentIDList, componentsNode);
|
||||||
AddComponentID<SHSliderComponent>(componentIDList, componentsNode);
|
AddComponentID<SHSliderComponent>(componentIDList, componentsNode);
|
||||||
|
|
||||||
|
AddComponentID<SHNavigationComponent>(componentIDList, componentsNode);
|
||||||
|
|
||||||
AddComponentID<SHTextRenderableComponent>(componentIDList, componentsNode);
|
AddComponentID<SHTextRenderableComponent>(componentIDList, componentsNode);
|
||||||
AddComponentID<SHAnimatorComponent>(componentIDList, componentsNode);
|
AddComponentID<SHAnimatorComponent>(componentIDList, componentsNode);
|
||||||
AddComponentID<SHUIComponent>(componentIDList, componentsNode);
|
AddComponentID<SHUIComponent>(componentIDList, componentsNode);
|
||||||
|
@ -394,6 +399,9 @@ namespace SHADE
|
||||||
SHSerializationHelper::InitializeComponentFromNode<SHButtonComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHButtonComponent>(componentsNode, eid);
|
||||||
SHSerializationHelper::InitializeComponentFromNode<SHToggleButtonComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHToggleButtonComponent>(componentsNode, eid);
|
||||||
SHSerializationHelper::InitializeComponentFromNode<SHSliderComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHSliderComponent>(componentsNode, eid);
|
||||||
|
|
||||||
|
SHSerializationHelper::InitializeComponentFromNode<SHNavigationComponent>(componentsNode, eid);
|
||||||
|
|
||||||
SHSerializationHelper::InitializeComponentFromNode<SHTextRenderableComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHTextRenderableComponent>(componentsNode, eid);
|
||||||
SHSerializationHelper::InitializeComponentFromNode<SHLightComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHLightComponent>(componentsNode, eid);
|
||||||
SHSerializationHelper::InitializeComponentFromNode<SHAnimatorComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHAnimatorComponent>(componentsNode, eid);
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
|
||||||
|
#include "Navigation.hxx"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "Navigation/SHNavigationSystem.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
Navigation::Navigation(Entity entity)
|
||||||
|
:Component(entity)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
float Navigation::Threshold::get()
|
||||||
|
{
|
||||||
|
return GetNativeComponent()->threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Navigation::Threshold::set(float val)
|
||||||
|
{
|
||||||
|
GetNativeComponent()->threshold = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 Navigation::Target::get()
|
||||||
|
{
|
||||||
|
return Convert::ToCLI(GetNativeComponent()->GetTarget());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Navigation::Target::set(Vector3 val)
|
||||||
|
{
|
||||||
|
GetNativeComponent()->SetTarget(Convert::ToNative(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Vector3 Navigation::GetForward()
|
||||||
|
{
|
||||||
|
return Convert::ToCLI(GetNativeComponent()->GetForward());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Navigation::GetUnreachableTarget()
|
||||||
|
{
|
||||||
|
return GetNativeComponent()->GetUnreachableTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Navigation::MoveTo(Vector3 val)
|
||||||
|
{
|
||||||
|
GetNativeComponent()->SetTarget(Convert::ToNative(val));
|
||||||
|
auto system = SHSystemManager::GetSystem<SHNavigationSystem>();
|
||||||
|
if (system)
|
||||||
|
{
|
||||||
|
system->GeneratePath(*GetNativeComponent());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Navigation::ReachedTarget()
|
||||||
|
{
|
||||||
|
return GetNativeComponent()->ReachedTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Components/Component.hxx"
|
||||||
|
#include "Math/Vector3.hxx"
|
||||||
|
|
||||||
|
//External Dependencies
|
||||||
|
#include "Navigation/SHNavigationComponent.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
public ref class Navigation : public Component<SHNavigationComponent>
|
||||||
|
{
|
||||||
|
internal:
|
||||||
|
Navigation(Entity entity);
|
||||||
|
|
||||||
|
public:
|
||||||
|
property float Threshold
|
||||||
|
{
|
||||||
|
float get();
|
||||||
|
void set(float val);
|
||||||
|
}
|
||||||
|
property Vector3 Target
|
||||||
|
{
|
||||||
|
Vector3 get();
|
||||||
|
void set(Vector3 val);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 GetForward();
|
||||||
|
bool GetUnreachableTarget();
|
||||||
|
bool ReachedTarget();
|
||||||
|
|
||||||
|
void MoveTo(Vector3 val);
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
|
@ -52,7 +52,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Components\TrajectoryRenderable.hxx"
|
#include "Components\TrajectoryRenderable.hxx"
|
||||||
#include "Components\Animator.hxx"
|
#include "Components\Animator.hxx"
|
||||||
#include "Components\ParticleEmitter.hxx"
|
#include "Components\ParticleEmitter.hxx"
|
||||||
|
#include "Components\Navigation.hxx"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -344,6 +344,7 @@ namespace SHADE
|
||||||
componentMap.Add(createComponentSet<SHTrajectoryRenderableComponent, TrajectoryRenderable>());
|
componentMap.Add(createComponentSet<SHTrajectoryRenderableComponent, TrajectoryRenderable>());
|
||||||
componentMap.Add(createComponentSet<SHAnimatorComponent, Animator>());
|
componentMap.Add(createComponentSet<SHAnimatorComponent, Animator>());
|
||||||
componentMap.Add(createComponentSet<SHParticleEmitterComponent, ParticleEmitter>());
|
componentMap.Add(createComponentSet<SHParticleEmitterComponent, ParticleEmitter>());
|
||||||
|
componentMap.Add(createComponentSet<SHNavigationComponent, Navigation>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
Loading…
Reference in New Issue