Added Camera Collision WIP #278
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,3 @@
|
||||||
|
Name: MainGameWithAIFixed
|
||||||
|
ID: 89830755
|
||||||
|
Type: 5
|
|
@ -40,15 +40,7 @@ namespace SHADE_Scripting.AIBehaviour.BehaviourTree
|
||||||
|
|
||||||
//awake and update functions
|
//awake and update functions
|
||||||
//the only segment in the entire AI that is dependent on the engine
|
//the only segment in the entire AI that is dependent on the engine
|
||||||
|
|
||||||
private bool test = false;
|
|
||||||
|
|
||||||
protected override void awake()
|
protected override void awake()
|
||||||
{
|
|
||||||
AwakeCall();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void start()
|
|
||||||
{
|
{
|
||||||
_root = CreateTree();
|
_root = CreateTree();
|
||||||
_root.InitialiseNode(this);
|
_root.InitialiseNode(this);
|
||||||
|
@ -59,7 +51,7 @@ namespace SHADE_Scripting.AIBehaviour.BehaviourTree
|
||||||
_root?.Evaluate();
|
_root?.Evaluate();
|
||||||
Tick();
|
Tick();
|
||||||
}
|
}
|
||||||
protected abstract void AwakeCall();
|
|
||||||
protected abstract void Initialise();
|
protected abstract void Initialise();
|
||||||
protected abstract void Tick();
|
protected abstract void Tick();
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,14 +28,13 @@ public partial class Homeowner1 : BehaviourTree
|
||||||
private BehaviourTreeEvents _events { get; set; }
|
private BehaviourTreeEvents _events { get; set; }
|
||||||
public override BehaviourTreeEvents events { get => _events; }
|
public override BehaviourTreeEvents events { get => _events; }
|
||||||
|
|
||||||
[Tooltip("The player the AI should chase and attempt to capture")]
|
|
||||||
public GameObject player;
|
|
||||||
|
|
||||||
//PATROL FIELDS///////////////////////////////////////////////////////////////
|
//PATROL FIELDS///////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
[Tooltip("The list of waypoints for the AI to cycle around")]
|
[Tooltip("The list of waypoints for the AI to cycle around")]
|
||||||
private List<Vector3> waypoints = new List<Vector3>();
|
private GameObject waypointsPool;
|
||||||
|
|
||||||
|
private List<GameObject> waypoints;
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
[Tooltip("The AI will patrol at this speed")]
|
[Tooltip("The AI will patrol at this speed")]
|
||||||
|
@ -79,32 +78,18 @@ public partial class Homeowner1 : BehaviourTree
|
||||||
//AI tree
|
//AI tree
|
||||||
public partial class Homeowner1 : BehaviourTree
|
public partial class Homeowner1 : BehaviourTree
|
||||||
{
|
{
|
||||||
Transform _thisTransform = null;
|
|
||||||
RigidBody _thisRigidbody = null;
|
|
||||||
GameObject _playerObject;
|
|
||||||
private LeafPatrol leafPatrol;
|
|
||||||
|
|
||||||
protected override void AwakeCall()
|
|
||||||
{
|
|
||||||
_thisTransform = GetComponent<Transform>();
|
|
||||||
if (!_thisTransform)
|
|
||||||
Debug.LogError("EMPTY TRANSFORM");
|
|
||||||
|
|
||||||
_thisRigidbody = GetComponent<RigidBody>();
|
|
||||||
if (!_thisRigidbody)
|
|
||||||
Debug.LogError("EMPTY RIGIDBODY");
|
|
||||||
|
|
||||||
if (!player)
|
|
||||||
Debug.Log("PLAYER MISSING!");
|
|
||||||
|
|
||||||
//_playerObject = GameObject.Find("Player").GetValueOrDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Called at the start
|
//Called at the start
|
||||||
protected override void Initialise()
|
protected override void Initialise()
|
||||||
{
|
{
|
||||||
_events = new Homeowner1Events(this);
|
_events = new Homeowner1Events(this);
|
||||||
events.Initialise();
|
events.Initialise();
|
||||||
|
|
||||||
|
//Initialise the waypoints here
|
||||||
|
if (waypointsPool)
|
||||||
|
{
|
||||||
|
waypoints = (List<GameObject>)waypointsPool.GetChildren();
|
||||||
|
SetData("waypoints", waypoints);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Called every tick
|
//Called every tick
|
||||||
|
@ -112,8 +97,8 @@ public partial class Homeowner1 : BehaviourTree
|
||||||
{
|
{
|
||||||
events.Tick();
|
events.Tick();
|
||||||
|
|
||||||
|
//Footsteps SFX, move them somewhere else soon
|
||||||
float velocity = GetComponent<RigidBody>().LinearVelocity.GetMagnitude();
|
float velocity = GetComponent<RigidBody>().LinearVelocity.GetMagnitude();
|
||||||
leafPatrol.waypoints = waypoints;
|
|
||||||
|
|
||||||
footstepTimeRemaining -= velocity * Time.DeltaTimeF;
|
footstepTimeRemaining -= velocity * Time.DeltaTimeF;
|
||||||
if (footstepTimeRemaining < 0.0f)
|
if (footstepTimeRemaining < 0.0f)
|
||||||
|
@ -128,22 +113,20 @@ public partial class Homeowner1 : BehaviourTree
|
||||||
//The tree is called from the root every tick
|
//The tree is called from the root every tick
|
||||||
protected override BehaviourTreeNode CreateTree()
|
protected override BehaviourTreeNode CreateTree()
|
||||||
{
|
{
|
||||||
leafPatrol = new LeafPatrol("Patrol", _thisTransform, waypoints, patrolSpeed, turningSpeed, _thisRigidbody);
|
|
||||||
//Start from the root, structure it like this to make it look like a tree
|
//Start from the root, structure it like this to make it look like a tree
|
||||||
BehaviourTreeNode root = new BehaviourTreeSelector("Root", new List<BehaviourTreeNode>
|
BehaviourTreeNode root = new BehaviourTreeSelector("Root", new List<BehaviourTreeNode>
|
||||||
{
|
{
|
||||||
/* new BehaviourTreeSequence("Alerted", new List<BehaviourTreeNode>
|
new BehaviourTreeSequence("Alerted", new List<BehaviourTreeNode>
|
||||||
{
|
{
|
||||||
new LeafSearch("SearchFOV", _thisTransform, eyeOffset, sightDistance),
|
new LeafSearch("SearchFOV", GetComponent<Transform>(), eyeOffset, sightDistance),
|
||||||
new BehaviourTreeSequence("CatchPlayer", new List<BehaviourTreeNode>
|
new BehaviourTreeSequence("CatchPlayer", new List<BehaviourTreeNode>
|
||||||
{
|
{
|
||||||
new LeafChase("Chasing", _thisTransform, _thisRigidbody, chaseSpeed, turningSpeed, distanceToCapture, captureTime),
|
new LeafChase("Chasing", GetComponent<Transform>(), GetComponent<RigidBody>(), chaseSpeed, turningSpeed, distanceToCapture, captureTime),
|
||||||
new LeafAttack("Attacking")
|
new LeafAttack("Attacking", GameObject.Find("Player").GetValueOrDefault())
|
||||||
})
|
})
|
||||||
}),*/
|
}),
|
||||||
leafPatrol
|
new LeafPatrol("Patrol", GetComponent<Transform>(), patrolSpeed, turningSpeed, GetComponent<RigidBody>())
|
||||||
});
|
});
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -28,22 +28,13 @@ public partial class LeafAttack : BehaviourTreeNode
|
||||||
//FUNCTIONS
|
//FUNCTIONS
|
||||||
public partial class LeafAttack : BehaviourTreeNode
|
public partial class LeafAttack : BehaviourTreeNode
|
||||||
{
|
{
|
||||||
public LeafAttack(string name) : base (name)
|
public LeafAttack(string name, GameObject p) : base (name)
|
||||||
{
|
{
|
||||||
//player = p;
|
player = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override BehaviourTreeNodeStatus Evaluate()
|
public override BehaviourTreeNodeStatus Evaluate()
|
||||||
{
|
{
|
||||||
{
|
|
||||||
if (!player)
|
|
||||||
{
|
|
||||||
player = GameObject.Find("Player").GetValueOrDefault();
|
|
||||||
Debug.Log("HERE2");
|
|
||||||
if (!player) { return BehaviourTreeNodeStatus.FAILURE; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Debug.LogWarning("LeafAttack");
|
//Debug.LogWarning("LeafAttack");
|
||||||
//Fail if no target in blackboard?
|
//Fail if no target in blackboard?
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,10 @@ public partial class LeafPatrol : BehaviourTreeNode
|
||||||
{
|
{
|
||||||
//Waypoints and movement
|
//Waypoints and movement
|
||||||
private Transform transform;
|
private Transform transform;
|
||||||
public List<Vector3> waypoints;
|
private List<GameObject> waypoints;
|
||||||
private RigidBody rb;
|
private RigidBody rb;
|
||||||
private float patrolSpeed = 1.0f;
|
private float patrolSpeed;
|
||||||
private float turningSpeed = 5.0f;
|
private float turningSpeed;
|
||||||
private float retreatTimer = 0.0f;
|
private float retreatTimer = 0.0f;
|
||||||
private int currentWaypointIndex = 0;
|
private int currentWaypointIndex = 0;
|
||||||
private bool retreatState = false;
|
private bool retreatState = false;
|
||||||
|
@ -42,10 +42,9 @@ public partial class LeafPatrol : BehaviourTreeNode
|
||||||
//Constructor, establish values here
|
//Constructor, establish values here
|
||||||
//Despite inheriting from BehaviourTreeNode, we don't have children to this
|
//Despite inheriting from BehaviourTreeNode, we don't have children to this
|
||||||
//node, and hence we do not need to inherit its constructors
|
//node, and hence we do not need to inherit its constructors
|
||||||
public LeafPatrol(string name, Transform t, List<Vector3> wps, float patrolSpeed, float turnSpeed, RigidBody rb) : base(name)
|
public LeafPatrol(string name, Transform t, float patrolSpeed, float turnSpeed, RigidBody rb) : base(name)
|
||||||
{
|
{
|
||||||
transform = t;
|
transform = t;
|
||||||
waypoints = wps;
|
|
||||||
this.patrolSpeed = patrolSpeed;
|
this.patrolSpeed = patrolSpeed;
|
||||||
turningSpeed = turnSpeed;
|
turningSpeed = turnSpeed;
|
||||||
this.rb = rb;
|
this.rb = rb;
|
||||||
|
@ -59,6 +58,10 @@ public partial class LeafPatrol : BehaviourTreeNode
|
||||||
{
|
{
|
||||||
//Debug.LogWarning("LeafPatrol");
|
//Debug.LogWarning("LeafPatrol");
|
||||||
onEnter(BehaviourTreeNodeStatus.RUNNING);
|
onEnter(BehaviourTreeNodeStatus.RUNNING);
|
||||||
|
if(GetNodeData("currentWaypointIndex") == null)
|
||||||
|
{
|
||||||
|
SetNodeData("currentWaypointIndex", 0);
|
||||||
|
}
|
||||||
if (isWaiting) DelayAtWaypoint();
|
if (isWaiting) DelayAtWaypoint();
|
||||||
else MoveToWaypoint();
|
else MoveToWaypoint();
|
||||||
|
|
||||||
|
@ -80,27 +83,25 @@ public partial class LeafPatrol : BehaviourTreeNode
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 remainingDistance = Vector3.Zero;
|
waypoints = (List<GameObject>)GetNodeData("waypoints");
|
||||||
Debug.Log($"{waypoints.Count}");
|
Vector3 targetPosition = waypoints[currentWaypointIndex].GetComponent<Transform>().GlobalPosition;
|
||||||
if (currentWaypointIndex > 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
Vector3 targetPosition = waypoints[currentWaypointIndex];
|
//Reach waypoint by X and Z being near enough
|
||||||
|
//Do not consider Y of waypoints yet
|
||||||
//Reach waypoint by X and Z being near enough
|
Vector3 remainingDistance = targetPosition - transform.GlobalPosition;
|
||||||
//Do not consider Y of waypoints yet
|
remainingDistance.y = 0.0f;
|
||||||
remainingDistance = targetPosition - transform.GlobalPosition;
|
|
||||||
remainingDistance.y = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Reached waypoint, cycle
|
//Reached waypoint, cycle
|
||||||
if (remainingDistance.GetSqrMagnitude() < 0.1f)
|
if (remainingDistance.GetSqrMagnitude() < 0.1f)
|
||||||
{
|
{
|
||||||
//Cycle waypoints
|
//Cycle waypoints
|
||||||
++currentWaypointIndex;
|
++currentWaypointIndex;
|
||||||
if (currentWaypointIndex >= waypoints.Count)
|
if (currentWaypointIndex >= waypoints.Count())
|
||||||
currentWaypointIndex = 0;
|
currentWaypointIndex = 0;
|
||||||
|
|
||||||
|
//Write to blackboard
|
||||||
|
SetNodeData("currentWaypointIndex", currentWaypointIndex);
|
||||||
|
|
||||||
waitCounter = 0.0f;
|
waitCounter = 0.0f;
|
||||||
isWaiting = true;
|
isWaiting = true;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +116,7 @@ public partial class LeafPatrol : BehaviourTreeNode
|
||||||
//Get the difference vector to the waypoint
|
//Get the difference vector to the waypoint
|
||||||
//Debug.Log("Current Waypoint " + waypoints[currentWaypointIndex].x.ToString() + " " + waypoints[currentWaypointIndex].y.ToString() + " " + waypoints[currentWaypointIndex].z.ToString());
|
//Debug.Log("Current Waypoint " + waypoints[currentWaypointIndex].x.ToString() + " " + waypoints[currentWaypointIndex].y.ToString() + " " + waypoints[currentWaypointIndex].z.ToString());
|
||||||
//Debug.Log("AI is at " + transform.GlobalPosition.x.ToString() + " " + transform.GlobalPosition.y.ToString() + " " + transform.GlobalPosition.z.ToString());
|
//Debug.Log("AI is at " + transform.GlobalPosition.x.ToString() + " " + transform.GlobalPosition.y.ToString() + " " + transform.GlobalPosition.z.ToString());
|
||||||
Vector3 normalisedDifference = waypoints[currentWaypointIndex] - transform.GlobalPosition;
|
Vector3 normalisedDifference = targetPosition - transform.GlobalPosition;
|
||||||
normalisedDifference.y = 0.0f; //Do not move vertically
|
normalisedDifference.y = 0.0f; //Do not move vertically
|
||||||
normalisedDifference /= normalisedDifference.GetMagnitude();
|
normalisedDifference /= normalisedDifference.GetMagnitude();
|
||||||
//Debug.Log("Normalised Difference x " + normalisedDifference.x.ToString() + " z " + normalisedDifference.z.ToString());
|
//Debug.Log("Normalised Difference x " + normalisedDifference.x.ToString() + " z " + normalisedDifference.z.ToString());
|
||||||
|
|
|
@ -21,11 +21,10 @@ using System.Threading.Tasks;
|
||||||
//VARIABLES HERE
|
//VARIABLES HERE
|
||||||
public partial class LeafSearch : BehaviourTreeNode
|
public partial class LeafSearch : BehaviourTreeNode
|
||||||
{
|
{
|
||||||
private GameObject player;
|
|
||||||
private Transform transform;
|
private Transform transform;
|
||||||
private Vector3 eyeOffset;
|
private Vector3 eyeOffset;
|
||||||
private float sightDistance;
|
private float sightDistance;
|
||||||
|
private GameObject? player; //To be searched for and marked
|
||||||
}
|
}
|
||||||
|
|
||||||
//FUNCTIONS HERE
|
//FUNCTIONS HERE
|
||||||
|
@ -33,111 +32,143 @@ public partial class LeafSearch : BehaviourTreeNode
|
||||||
{
|
{
|
||||||
public LeafSearch(string name, Transform t, Vector3 eo, float sDist) : base(name)
|
public LeafSearch(string name, Transform t, Vector3 eo, float sDist) : base(name)
|
||||||
{
|
{
|
||||||
Debug.Log($"===============================PLAYER: {t}");
|
|
||||||
// player = p;
|
|
||||||
transform = t;
|
transform = t;
|
||||||
eyeOffset = eo;
|
eyeOffset = eo;
|
||||||
sightDistance = sDist;
|
sightDistance = sDist;
|
||||||
|
player = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Helper, find the nearest unobstructed waypoint to return to when chase is over
|
||||||
|
private void reevaluateWaypoint()
|
||||||
|
{
|
||||||
|
Debug.Log("Reevaluating Waypoints");
|
||||||
|
List<GameObject> waypoints = (List<GameObject>)GetNodeData("waypoints");
|
||||||
|
|
||||||
|
if (waypoints == null)
|
||||||
|
{
|
||||||
|
SetNodeData("currentWaypointIndex", 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nearestWaypointIndex = 0;
|
||||||
|
for (int i = 0; i < waypoints.Count; ++i)
|
||||||
|
{
|
||||||
|
if ((transform.GlobalPosition - waypoints[i].GetComponent<Transform>().GlobalPosition).GetSqrMagnitude() <
|
||||||
|
(transform.GlobalPosition - waypoints[nearestWaypointIndex].GetComponent<Transform>().GlobalPosition).GetSqrMagnitude())
|
||||||
|
{
|
||||||
|
nearestWaypointIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetNodeData("currentWaypointIndex", nearestWaypointIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override BehaviourTreeNodeStatus Evaluate()
|
public override BehaviourTreeNodeStatus Evaluate()
|
||||||
{
|
{
|
||||||
{
|
|
||||||
if (!player)
|
|
||||||
{
|
|
||||||
player = GameObject.Find("Player").GetValueOrDefault();
|
|
||||||
if (!player) { Debug.Log("HERE1"); return BehaviourTreeNodeStatus.FAILURE; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Debug.LogWarning("LeafSearch");
|
//Debug.LogWarning("LeafSearch");
|
||||||
onEnter(BehaviourTreeNodeStatus.RUNNING);
|
onEnter(BehaviourTreeNodeStatus.RUNNING);
|
||||||
|
|
||||||
//Fail if unable to find a player
|
//Search for player
|
||||||
//Get player's transform
|
player = GameObject.Find("Player");
|
||||||
Transform plrT = player.GetComponent<Transform>();
|
|
||||||
|
|
||||||
//DELETE THIS
|
//Automatically fail if no player is found
|
||||||
//Debug.Log("X " + MathF.Sin(transform.LocalEulerAngles.y).ToString() + " Z " + MathF.Cos(transform.LocalEulerAngles.y).ToString());
|
if (player == null)
|
||||||
//Debug.Log("Looking at: " + transform.LocalRotation.y.ToString() + " To player is: " + temporary.ToString());
|
|
||||||
//Debug.Log("Look difference is: " + (transform.LocalRotation.y - differenceDirection.y).ToString());
|
|
||||||
//Debug.Log("Dot: " + Quaternion.Dot(differenceDirection, transform.GlobalRotation));
|
|
||||||
|
|
||||||
//Fail if too far from vision range
|
|
||||||
if ((plrT.GlobalPosition - transform.GlobalPosition).GetMagnitude() > sightDistance)
|
|
||||||
{
|
{
|
||||||
//Debug.Log("Failure: Too far");
|
|
||||||
if (GetNodeData("isAlert") != null && (bool)GetNodeData("isAlert") == true)
|
|
||||||
{
|
|
||||||
Debug.Log("AI play unalert hmm");
|
|
||||||
}
|
|
||||||
SetNodeData("isAlert", false);
|
SetNodeData("isAlert", false);
|
||||||
status = BehaviourTreeNodeStatus.FAILURE;
|
status = BehaviourTreeNodeStatus.FAILURE;
|
||||||
onExit(BehaviourTreeNodeStatus.FAILURE);
|
onExit(BehaviourTreeNodeStatus.FAILURE);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
//Fail if player is out of FOV
|
|
||||||
//TODO currently a simple dot product against negative is done, this makes it essentially be a semicircle in front at which AI can see
|
|
||||||
Vector3 difference = plrT.GlobalPosition - transform.GlobalPosition;
|
|
||||||
difference.y = 0.0f; //Disregard Y axis
|
|
||||||
Vector3 lookDirection = new Vector3(MathF.Sin(transform.LocalEulerAngles.y), 0.0f, MathF.Cos(transform.LocalEulerAngles.y));
|
|
||||||
//Debug.Log("Dot: " + Vector3.Dot(difference, lookDirection));
|
|
||||||
if (Vector3.Dot(difference, lookDirection) < 0.0f)
|
|
||||||
{
|
{
|
||||||
//Debug.Log("Failure: Out of FOV");
|
//Fail if unable to find a player
|
||||||
if (GetNodeData("isAlert") != null && (bool)GetNodeData("isAlert") == true)
|
//Get player's transform
|
||||||
|
Transform plrT = player.GetValueOrDefault().GetComponent<Transform>();
|
||||||
|
|
||||||
|
//DELETE THIS
|
||||||
|
//Debug.Log("X " + MathF.Sin(transform.LocalEulerAngles.y).ToString() + " Z " + MathF.Cos(transform.LocalEulerAngles.y).ToString());
|
||||||
|
//Debug.Log("Looking at: " + transform.LocalRotation.y.ToString() + " To player is: " + temporary.ToString());
|
||||||
|
//Debug.Log("Look difference is: " + (transform.LocalRotation.y - differenceDirection.y).ToString());
|
||||||
|
//Debug.Log("Dot: " + Quaternion.Dot(differenceDirection, transform.GlobalRotation));
|
||||||
|
|
||||||
|
//Fail if too far from vision range
|
||||||
|
if ((plrT.GlobalPosition - transform.GlobalPosition).GetMagnitude() > sightDistance)
|
||||||
{
|
{
|
||||||
Debug.Log("AI play unalert hmm");
|
//Debug.Log("Failure: Too far");
|
||||||
|
if (GetNodeData("isAlert") != null && (bool)GetNodeData("isAlert") == true)
|
||||||
|
{
|
||||||
|
Debug.Log("AI play unalert hmm");
|
||||||
|
reevaluateWaypoint();
|
||||||
|
}
|
||||||
|
SetNodeData("isAlert", false);
|
||||||
|
status = BehaviourTreeNodeStatus.FAILURE;
|
||||||
|
onExit(BehaviourTreeNodeStatus.FAILURE);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
SetNodeData("isAlert", false);
|
|
||||||
status = BehaviourTreeNodeStatus.FAILURE;
|
//Fail if player is out of FOV
|
||||||
onExit(BehaviourTreeNodeStatus.FAILURE);
|
//TODO currently a simple dot product against negative is done, this makes it essentially be a semicircle in front at which AI can see
|
||||||
|
Vector3 difference = plrT.GlobalPosition - transform.GlobalPosition;
|
||||||
|
difference.y = 0.0f; //Disregard Y axis
|
||||||
|
Vector3 lookDirection = new Vector3(MathF.Sin(transform.LocalEulerAngles.y), 0.0f, MathF.Cos(transform.LocalEulerAngles.y));
|
||||||
|
//Debug.Log("Dot: " + Vector3.Dot(difference, lookDirection));
|
||||||
|
if (Vector3.Dot(difference, lookDirection) < 0.0f)
|
||||||
|
{
|
||||||
|
//Debug.Log("Failure: Out of FOV");
|
||||||
|
if (GetNodeData("isAlert") != null && (bool)GetNodeData("isAlert") == true)
|
||||||
|
{
|
||||||
|
Debug.Log("AI play unalert hmm");
|
||||||
|
reevaluateWaypoint();
|
||||||
|
}
|
||||||
|
SetNodeData("isAlert", false);
|
||||||
|
status = BehaviourTreeNodeStatus.FAILURE;
|
||||||
|
onExit(BehaviourTreeNodeStatus.FAILURE);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//LocalRotation is between -1 and 1, which are essentially the same.
|
||||||
|
//0 and -1/1 are 180 deg apart
|
||||||
|
//Quaternion differenceDirection = Quaternion.FromToRotation(Vector3.Forward, plrT.GlobalPosition - transform.GlobalPosition);
|
||||||
|
//Debug.Log("Looking at: " + transform.LocalRotation.y.ToString() + " To player is: " + differenceDirection.y.ToString());
|
||||||
|
|
||||||
|
//Draw a ray, succeed if ray is unobstructed
|
||||||
|
Vector3 eyePosition = transform.GlobalPosition + eyeOffset;
|
||||||
|
Ray sightRay = new Ray(eyePosition, plrT.GlobalPosition - eyePosition);
|
||||||
|
RaycastHit sightRayHit = Physics.Raycast(sightRay);
|
||||||
|
//As of November 2022, RaycastHit contains only the FIRST object hit by
|
||||||
|
//the ray in the Other GameObject data member
|
||||||
|
//Diren may likely add ALL objects hit by the ray over December
|
||||||
|
if (sightRayHit.Hit && sightRayHit.Other != player)
|
||||||
|
{
|
||||||
|
//Debug.Log("Failure: Ray hit obstacle named " + sightRayHit.Other.GetValueOrDefault().Name + " ID" + sightRayHit.Other.GetValueOrDefault().EntityId);
|
||||||
|
if (GetNodeData("isAlert") != null && (bool)GetNodeData("isAlert") == true)
|
||||||
|
{
|
||||||
|
Debug.Log("AI play unalert hmm");
|
||||||
|
reevaluateWaypoint();
|
||||||
|
}
|
||||||
|
SetNodeData("isAlert", false);
|
||||||
|
status = BehaviourTreeNodeStatus.FAILURE;
|
||||||
|
onExit(BehaviourTreeNodeStatus.FAILURE);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
else if (sightRayHit.Hit && sightRayHit.Other == player)
|
||||||
|
{
|
||||||
|
//Debug.Log("Ray hit player");
|
||||||
|
}
|
||||||
|
|
||||||
|
//All checks for now succeeded
|
||||||
|
//Debug.Log("Success: Homeowner has sighted player");
|
||||||
|
//Write player's transform into the blackboard
|
||||||
|
SetNodeData("target", plrT);
|
||||||
|
|
||||||
|
if (GetNodeData("isAlert") != null && (bool)GetNodeData("isAlert") == false)
|
||||||
|
{
|
||||||
|
Debug.Log("AI Play Alerted Yell here");
|
||||||
|
}
|
||||||
|
SetNodeData("isAlert", true);
|
||||||
|
|
||||||
|
status = BehaviourTreeNodeStatus.SUCCESS;
|
||||||
|
onExit(BehaviourTreeNodeStatus.SUCCESS);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
//LocalRotation is between -1 and 1, which are essentially the same.
|
|
||||||
//0 and -1/1 are 180 deg apart
|
|
||||||
//Quaternion differenceDirection = Quaternion.FromToRotation(Vector3.Forward, plrT.GlobalPosition - transform.GlobalPosition);
|
|
||||||
//Debug.Log("Looking at: " + transform.LocalRotation.y.ToString() + " To player is: " + differenceDirection.y.ToString());
|
|
||||||
|
|
||||||
//Draw a ray, succeed if ray is unobstructed
|
|
||||||
Vector3 eyePosition = transform.GlobalPosition + eyeOffset;
|
|
||||||
Ray sightRay = new Ray(eyePosition, plrT.GlobalPosition - eyePosition);
|
|
||||||
RaycastHit sightRayHit = Physics.Raycast(sightRay);
|
|
||||||
//As of November 2022, RaycastHit contains only the FIRST object hit by
|
|
||||||
//the ray in the Other GameObject data member
|
|
||||||
//Diren may likely add ALL objects hit by the ray over December
|
|
||||||
if (sightRayHit.Hit && sightRayHit.Other != player)
|
|
||||||
{
|
|
||||||
//Debug.Log("Failure: Ray hit obstacle named " + sightRayHit.Other.GetValueOrDefault().Name + " ID" + sightRayHit.Other.GetValueOrDefault().EntityId);
|
|
||||||
if (GetNodeData("isAlert") != null && (bool)GetNodeData("isAlert") == true)
|
|
||||||
{
|
|
||||||
Debug.Log("AI play unalert hmm");
|
|
||||||
}
|
|
||||||
SetNodeData("isAlert", false);
|
|
||||||
status = BehaviourTreeNodeStatus.FAILURE;
|
|
||||||
onExit(BehaviourTreeNodeStatus.FAILURE);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
else if (sightRayHit.Hit && sightRayHit.Other == player)
|
|
||||||
{
|
|
||||||
//Debug.Log("Ray hit player");
|
|
||||||
}
|
|
||||||
|
|
||||||
//All checks for now succeeded
|
|
||||||
//Debug.Log("Success: Homeowner has sighted player");
|
|
||||||
//Write player's transform into the blackboard
|
|
||||||
SetNodeData("target", plrT);
|
|
||||||
|
|
||||||
if (GetNodeData("isAlert") != null && (bool)GetNodeData("isAlert") == false)
|
|
||||||
{
|
|
||||||
Debug.Log("AI Play Alerted Yell here");
|
|
||||||
}
|
|
||||||
SetNodeData("isAlert", true);
|
|
||||||
|
|
||||||
status = BehaviourTreeNodeStatus.SUCCESS;
|
|
||||||
onExit(BehaviourTreeNodeStatus.SUCCESS);
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -74,7 +74,9 @@ namespace Sandbox
|
||||||
SHSystemManager::CreateSystem<SHScriptEngine>();
|
SHSystemManager::CreateSystem<SHScriptEngine>();
|
||||||
SHSystemManager::CreateSystem<SHTransformSystem>();
|
SHSystemManager::CreateSystem<SHTransformSystem>();
|
||||||
SHSystemManager::CreateSystem<SHPhysicsSystem>();
|
SHSystemManager::CreateSystem<SHPhysicsSystem>();
|
||||||
|
#ifndef _PUBLISH
|
||||||
SHSystemManager::CreateSystem<SHPhysicsDebugDrawSystem>();
|
SHSystemManager::CreateSystem<SHPhysicsDebugDrawSystem>();
|
||||||
|
#endif
|
||||||
|
|
||||||
SHSystemManager::CreateSystem<SHAudioSystem>();
|
SHSystemManager::CreateSystem<SHAudioSystem>();
|
||||||
SHSystemManager::CreateSystem<SHCameraSystem>();
|
SHSystemManager::CreateSystem<SHCameraSystem>();
|
||||||
|
@ -114,7 +116,9 @@ namespace Sandbox
|
||||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>();
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>();
|
||||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
|
||||||
|
|
||||||
|
#ifndef _PUBLISH
|
||||||
SHSystemManager::RegisterRoutine<SHPhysicsDebugDrawSystem, SHPhysicsDebugDrawSystem::PhysicsDebugDrawRoutine>();
|
SHSystemManager::RegisterRoutine<SHPhysicsDebugDrawSystem, SHPhysicsDebugDrawSystem::PhysicsDebugDrawRoutine>();
|
||||||
|
#endif
|
||||||
|
|
||||||
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
|
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
|
||||||
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
|
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
|
||||||
|
@ -189,6 +193,13 @@ namespace Sandbox
|
||||||
SHSystemManager::RunRoutines(false, SHFrameRateController::GetRawDeltaTime());
|
SHSystemManager::RunRoutines(false, SHFrameRateController::GetRawDeltaTime());
|
||||||
#endif
|
#endif
|
||||||
// TODO: Move into an Editor menu
|
// TODO: Move into an Editor menu
|
||||||
|
static bool drawContacts = false;
|
||||||
|
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F9))
|
||||||
|
{
|
||||||
|
drawContacts = !drawContacts;
|
||||||
|
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACT_POINTS, drawContacts);
|
||||||
|
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACT_NORMALS, drawContacts);
|
||||||
|
}
|
||||||
static bool drawColliders = false;
|
static bool drawColliders = false;
|
||||||
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F10))
|
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F10))
|
||||||
{
|
{
|
||||||
|
@ -201,13 +212,7 @@ namespace Sandbox
|
||||||
drawRays = !drawRays;
|
drawRays = !drawRays;
|
||||||
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::RAYCASTS, drawRays);
|
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::RAYCASTS, drawRays);
|
||||||
}
|
}
|
||||||
static bool drawContacts = false;
|
|
||||||
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F9))
|
|
||||||
{
|
|
||||||
drawContacts = !drawContacts;
|
|
||||||
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACT_POINTS, drawContacts);
|
|
||||||
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACT_NORMALS, drawContacts);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Finish all graphics jobs first
|
// Finish all graphics jobs first
|
||||||
graphicsSystem->AwaitGraphicsExecution();
|
graphicsSystem->AwaitGraphicsExecution();
|
||||||
|
|
|
@ -84,14 +84,27 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
const SHCollisionInfo& C_INFO = *eventIter;
|
const SHCollisionInfo& C_INFO = *eventIter;
|
||||||
|
|
||||||
const bool CLEAR_EVENT = C_INFO.GetCollisionState() == SHCollisionInfo::State::EXIT || C_INFO.GetCollisionState() == SHCollisionInfo::State::INVALID;
|
|
||||||
const bool INVALID_ENTITY = !SHEntityManager::IsValidEID(C_INFO.GetEntityA()) || !SHEntityManager::IsValidEID(C_INFO.GetEntityB());
|
const bool INVALID_ENTITY = !SHEntityManager::IsValidEID(C_INFO.GetEntityA()) || !SHEntityManager::IsValidEID(C_INFO.GetEntityB());
|
||||||
const bool INACTIVE_OBJECT = !SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(C_INFO.GetEntityA()) || !SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(C_INFO.GetEntityB());
|
if (INVALID_ENTITY)
|
||||||
|
{
|
||||||
if (CLEAR_EVENT || INVALID_ENTITY || INACTIVE_OBJECT)
|
|
||||||
eventIter = container.erase(eventIter);
|
eventIter = container.erase(eventIter);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
++eventIter;
|
{
|
||||||
|
const bool CLEAR_EVENT = C_INFO.GetCollisionState() == SHCollisionInfo::State::EXIT || C_INFO.GetCollisionState() == SHCollisionInfo::State::INVALID;
|
||||||
|
|
||||||
|
const bool INACTIVE_OBJECT = !SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(C_INFO.GetEntityA())
|
||||||
|
|| !SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(C_INFO.GetEntityB());
|
||||||
|
|
||||||
|
if (CLEAR_EVENT || INACTIVE_OBJECT)
|
||||||
|
{
|
||||||
|
eventIter = container.erase(eventIter);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
++eventIter;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ namespace SHADE
|
||||||
raycasts.clear();
|
raycasts.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
SHPhysicsRaycastResult SHPhysicsRaycaster::Raycast(const SHRay& ray, float distance) noexcept
|
SHPhysicsRaycastResult SHPhysicsRaycaster::Raycast(const SHRay& ray, float distance, const SHCollisionTag& collisionTag) noexcept
|
||||||
{
|
{
|
||||||
// Reset temp
|
// Reset temp
|
||||||
temp = SHPhysicsRaycastResult{};
|
temp = SHPhysicsRaycastResult{};
|
||||||
|
@ -78,13 +78,13 @@ namespace SHADE
|
||||||
// If distance in infinity, cast to the default max distance of 2 km.
|
// If distance in infinity, cast to the default max distance of 2 km.
|
||||||
if (distance == std::numeric_limits<float>::infinity())
|
if (distance == std::numeric_limits<float>::infinity())
|
||||||
{
|
{
|
||||||
world->raycast(ray, this);
|
world->raycast(ray, this, collisionTag);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const SHVec3 END_POINT = ray.position + ray.direction * distance;
|
const SHVec3 END_POINT = ray.position + ray.direction * distance;
|
||||||
const rp3d::Ray RP3D_RAY{ ray.position, END_POINT };
|
const rp3d::Ray RP3D_RAY{ ray.position, END_POINT };
|
||||||
world->raycast(RP3D_RAY, this);
|
world->raycast(RP3D_RAY, this, collisionTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a hit was found, populate temp info for return.
|
// If a hit was found, populate temp info for return.
|
||||||
|
@ -98,7 +98,7 @@ namespace SHADE
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHPhysicsRaycastResult SHPhysicsRaycaster::Linecast(const SHVec3& start, const SHVec3& end) noexcept
|
SHPhysicsRaycastResult SHPhysicsRaycaster::Linecast(const SHVec3& start, const SHVec3& end, const SHCollisionTag& collisionTag) noexcept
|
||||||
{
|
{
|
||||||
temp = SHPhysicsRaycastResult{};
|
temp = SHPhysicsRaycastResult{};
|
||||||
temp.distance = SHVec3::Distance(start, end);
|
temp.distance = SHVec3::Distance(start, end);
|
||||||
|
@ -110,7 +110,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
const rp3d::Ray RP3D_RAY{ start, end };
|
const rp3d::Ray RP3D_RAY{ start, end };
|
||||||
world->raycast(RP3D_RAY, this);
|
world->raycast(RP3D_RAY, this, collisionTag);
|
||||||
|
|
||||||
if (temp.hit)
|
if (temp.hit)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "Physics/PhysicsObject/SHPhysicsObjectManager.h"
|
#include "Physics/PhysicsObject/SHPhysicsObjectManager.h"
|
||||||
#include "Physics/SHPhysicsWorld.h"
|
#include "Physics/SHPhysicsWorld.h"
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
|
#include "SHCollisionTags.h"
|
||||||
#include "SHPhysicsRaycastResult.h"
|
#include "SHPhysicsRaycastResult.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -67,44 +68,46 @@ namespace SHADE
|
||||||
|
|
||||||
SHPhysicsRaycastResult Raycast
|
SHPhysicsRaycastResult Raycast
|
||||||
(
|
(
|
||||||
const SHRay& ray
|
const SHRay& ray
|
||||||
, float distance = std::numeric_limits<float>::infinity()
|
, float distance = std::numeric_limits<float>::infinity()
|
||||||
|
, const SHCollisionTag& collisionTag = SHCollisionTag{}
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
|
||||||
SHPhysicsRaycastResult Linecast
|
SHPhysicsRaycastResult Linecast
|
||||||
(
|
(
|
||||||
const SHVec3& start
|
const SHVec3& start
|
||||||
, const SHVec3& end
|
, const SHVec3& end
|
||||||
|
, const SHCollisionTag& collisionTag = SHCollisionTag{}
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
|
||||||
SHPhysicsRaycastResult ColliderRaycast
|
SHPhysicsRaycastResult ColliderRaycast
|
||||||
(
|
(
|
||||||
EntityID eid
|
EntityID eid
|
||||||
, const SHRay& ray
|
, const SHRay& ray
|
||||||
, float distance = std::numeric_limits<float>::infinity()
|
, float distance = std::numeric_limits<float>::infinity()
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
|
||||||
SHPhysicsRaycastResult ColliderRaycast
|
SHPhysicsRaycastResult ColliderRaycast
|
||||||
(
|
(
|
||||||
EntityID eid
|
EntityID eid
|
||||||
, int shapeIndex
|
, int shapeIndex
|
||||||
, const SHRay& ray
|
, const SHRay& ray
|
||||||
, float distance = std::numeric_limits<float>::infinity()
|
, float distance = std::numeric_limits<float>::infinity()
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
|
||||||
SHPhysicsRaycastResult ColliderLinecast
|
SHPhysicsRaycastResult ColliderLinecast
|
||||||
(
|
(
|
||||||
EntityID eid
|
EntityID eid
|
||||||
, const SHVec3& start
|
, const SHVec3& start
|
||||||
, const SHVec3& end
|
, const SHVec3& end
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
|
||||||
SHPhysicsRaycastResult ColliderLinecast
|
SHPhysicsRaycastResult ColliderLinecast
|
||||||
(
|
(
|
||||||
EntityID eid
|
EntityID eid
|
||||||
, int shapeIndex
|
, int shapeIndex
|
||||||
, const SHVec3& start
|
, const SHVec3& start
|
||||||
, const SHVec3& end
|
, const SHVec3& end
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
|
||||||
rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo& raycastInfo) override;
|
rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo& raycastInfo) override;
|
||||||
|
|
|
@ -206,7 +206,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the half extents relative to world scale
|
// Set the half extents relative to world scale
|
||||||
const SHVec3 WORLD_EXTENTS = correctedHalfExtents * COLLIDER->GetScale() * 0.5f;
|
const SHVec3 WORLD_EXTENTS = correctedHalfExtents * COLLIDER->GetScale();
|
||||||
|
|
||||||
if (type != Type::BOX)
|
if (type != Type::BOX)
|
||||||
{
|
{
|
||||||
|
|
|
@ -120,21 +120,25 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
rp3d::DebugRenderer* rp3dRenderer = nullptr;
|
rp3d::DebugRenderer* rp3dRenderer = nullptr;
|
||||||
#ifdef SHEDITOR
|
if (system->physicsSystem->worldState.world)
|
||||||
const auto* EDITOR = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
if (EDITOR && EDITOR->editorState != SHEditor::State::STOP)
|
|
||||||
{
|
|
||||||
rp3dRenderer = &system->physicsSystem->worldState.world->getDebugRenderer();
|
rp3dRenderer = &system->physicsSystem->worldState.world->getDebugRenderer();
|
||||||
rp3dRenderer->setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::CONTACT_POINT, false);
|
|
||||||
rp3dRenderer->setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::CONTACT_NORMAL, false);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (int i = 0; i < SHUtilities::ConvertEnum(DebugDrawFlags::NUM_FLAGS); ++i)
|
for (int i = 0; i < SHUtilities::ConvertEnum(DebugDrawFlags::NUM_FLAGS); ++i)
|
||||||
{
|
{
|
||||||
const bool DRAW = (system->debugDrawFlags & (1U << i)) > 0;
|
const bool DRAW = (system->debugDrawFlags & (1U << i)) > 0;
|
||||||
if (DRAW)
|
if (DRAW)
|
||||||
|
{
|
||||||
drawFunctions[i](debugDrawSystem, rp3dRenderer);
|
drawFunctions[i](debugDrawSystem, rp3dRenderer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (rp3dRenderer && (i == 3 || i == 4))
|
||||||
|
{
|
||||||
|
rp3dRenderer->setIsDebugItemDisplayed(reactphysics3d::DebugRenderer::DebugItem::CONTACT_POINT, false);
|
||||||
|
rp3dRenderer->setIsDebugItemDisplayed(reactphysics3d::DebugRenderer::DebugItem::CONTACT_NORMAL, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Automatically clear the container of raycasts despite debug drawing state
|
// Automatically clear the container of raycasts despite debug drawing state
|
||||||
|
@ -180,6 +184,7 @@ namespace SHADE
|
||||||
void SHPhysicsDebugDrawSystem::drawContactPoints(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept
|
void SHPhysicsDebugDrawSystem::drawContactPoints(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept
|
||||||
{
|
{
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
|
|
||||||
const auto* EDITOR = SHSystemManager::GetSystem<SHEditor>();
|
const auto* EDITOR = SHSystemManager::GetSystem<SHEditor>();
|
||||||
if (EDITOR && EDITOR->editorState != SHEditor::State::STOP)
|
if (EDITOR && EDITOR->editorState != SHEditor::State::STOP)
|
||||||
{
|
{
|
||||||
|
@ -192,6 +197,18 @@ namespace SHADE
|
||||||
for (int i = 0; i < NUM_TRIS; ++i)
|
for (int i = 0; i < NUM_TRIS; ++i)
|
||||||
debugRenderer->DrawTri(SHColour::RED, TRI_ARRAY[i].point1, TRI_ARRAY[i].point2, TRI_ARRAY[i].point3);
|
debugRenderer->DrawTri(SHColour::RED, TRI_ARRAY[i].point1, TRI_ARRAY[i].point2, TRI_ARRAY[i].point3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
rp3dRenderer->setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::CONTACT_POINT, true);
|
||||||
|
const int NUM_TRIS = static_cast<int>(rp3dRenderer->getNbTriangles());
|
||||||
|
if (NUM_TRIS == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto& TRI_ARRAY = rp3dRenderer->getTrianglesArray();
|
||||||
|
for (int i = 0; i < NUM_TRIS; ++i)
|
||||||
|
debugRenderer->DrawTri(SHColour::RED, TRI_ARRAY[i].point1, TRI_ARRAY[i].point2, TRI_ARRAY[i].point3);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,6 +227,18 @@ namespace SHADE
|
||||||
for (int i = 0; i < NUM_LINES; ++i)
|
for (int i = 0; i < NUM_LINES; ++i)
|
||||||
debugRenderer->DrawLine(SHColour::RED, LINE_ARRAY[i].point1, LINE_ARRAY[i].point2);
|
debugRenderer->DrawLine(SHColour::RED, LINE_ARRAY[i].point1, LINE_ARRAY[i].point2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
rp3dRenderer->setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::CONTACT_NORMAL, true);
|
||||||
|
const int NUM_LINES = static_cast<int>(rp3dRenderer->getNbLines());
|
||||||
|
if (NUM_LINES == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto& LINE_ARRAY = rp3dRenderer->getLinesArray();
|
||||||
|
for (int i = 0; i < NUM_LINES; ++i)
|
||||||
|
debugRenderer->DrawLine(SHColour::RED, LINE_ARRAY[i].point1, LINE_ARRAY[i].point2);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -163,8 +163,6 @@ namespace SHADE
|
||||||
// Destroy an existing world
|
// Destroy an existing world
|
||||||
if (worldState.world != nullptr)
|
if (worldState.world != nullptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
objectManager.RemoveAllObjects();
|
objectManager.RemoveAllObjects();
|
||||||
objectManager.SetWorld(nullptr);
|
objectManager.SetWorld(nullptr);
|
||||||
|
|
||||||
|
@ -174,12 +172,12 @@ namespace SHADE
|
||||||
worldState.DestroyWorld(factory);
|
worldState.DestroyWorld(factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
worldState.CreateWorld(factory);
|
worldState.CreateWorld(factory);
|
||||||
#ifdef _PUBLISH
|
#ifdef _PUBLISH
|
||||||
worldState.world->setIsDebugRenderingEnabled(false);
|
worldState.world->setIsDebugRenderingEnabled(false);
|
||||||
#else
|
#else
|
||||||
worldState.world->setIsDebugRenderingEnabled(true);
|
worldState.world->setIsDebugRenderingEnabled(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Link Collision Listener & Raycaster
|
// Link Collision Listener & Raycaster
|
||||||
collisionListener.BindToWorld(worldState.world);
|
collisionListener.BindToWorld(worldState.world);
|
||||||
|
@ -260,14 +258,14 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SHPhysicsRaycastResult SHPhysicsSystem::Raycast(const SHRay& ray, float distance) noexcept
|
SHPhysicsRaycastResult SHPhysicsSystem::Raycast(const SHRay& ray, float distance, const SHCollisionTag& collisionTag) noexcept
|
||||||
{
|
{
|
||||||
return raycaster.Raycast(ray, distance);
|
return raycaster.Raycast(ray, distance, collisionTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHPhysicsRaycastResult SHPhysicsSystem::Linecast(const SHVec3& start, const SHVec3& end) noexcept
|
SHPhysicsRaycastResult SHPhysicsSystem::Linecast(const SHVec3& start, const SHVec3& end, const SHCollisionTag& collisionTag) noexcept
|
||||||
{
|
{
|
||||||
return raycaster.Linecast(start, end);
|
return raycaster.Linecast(start, end, collisionTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHPhysicsRaycastResult SHPhysicsSystem::ColliderRaycast(EntityID eid, const SHRay& ray, float distance) noexcept
|
SHPhysicsRaycastResult SHPhysicsSystem::ColliderRaycast(EntityID eid, const SHRay& ray, float distance) noexcept
|
||||||
|
@ -444,11 +442,11 @@ namespace SHADE
|
||||||
return onPlayEvent->handle;
|
return onPlayEvent->handle;
|
||||||
|
|
||||||
worldState.CreateWorld(factory);
|
worldState.CreateWorld(factory);
|
||||||
#ifdef _PUBLISH
|
#ifdef _PUBLISH
|
||||||
worldState.world->setIsDebugRenderingEnabled(false);
|
worldState.world->setIsDebugRenderingEnabled(false);
|
||||||
#else
|
#else
|
||||||
worldState.world->setIsDebugRenderingEnabled(true);
|
worldState.world->setIsDebugRenderingEnabled(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Link Collision Listener & Raycaster
|
// Link Collision Listener & Raycaster
|
||||||
collisionListener.BindToWorld(worldState.world);
|
collisionListener.BindToWorld(worldState.world);
|
||||||
|
|
|
@ -85,24 +85,28 @@ namespace SHADE
|
||||||
* @brief Casts a ray into the world.
|
* @brief Casts a ray into the world.
|
||||||
* @param ray The ray to cast.
|
* @param ray The ray to cast.
|
||||||
* @param distance The distance to cast the ray. Defaults to infinity.
|
* @param distance The distance to cast the ray. Defaults to infinity.
|
||||||
|
* @param collisionTag The collision tag to use for filtering the raycast.
|
||||||
* @return The result of the raycast.
|
* @return The result of the raycast.
|
||||||
*/
|
*/
|
||||||
SHPhysicsRaycastResult Raycast
|
SHPhysicsRaycastResult Raycast
|
||||||
(
|
(
|
||||||
const SHRay& ray
|
const SHRay& ray
|
||||||
, float distance = std::numeric_limits<float>::infinity()
|
, float distance = std::numeric_limits<float>::infinity()
|
||||||
|
, const SHCollisionTag& collisionTag = SHCollisionTag{}
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Casts a bounded ray into the world.
|
* @brief Casts a bounded ray into the world.
|
||||||
* @param start The starting point of the ray.
|
* @param start The starting point of the ray.
|
||||||
* @param end The end point of the ray.
|
* @param end The end point of the ray.
|
||||||
|
* @param collisionTag The collision tag to use for filtering the bounded raycast.
|
||||||
* @return The result of the raycast.
|
* @return The result of the raycast.
|
||||||
*/
|
*/
|
||||||
SHPhysicsRaycastResult Linecast
|
SHPhysicsRaycastResult Linecast
|
||||||
(
|
(
|
||||||
const SHVec3& start
|
const SHVec3& start
|
||||||
, const SHVec3& end
|
, const SHVec3& end
|
||||||
|
, const SHCollisionTag& collisionTag = SHCollisionTag{}
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "Scripting/SHScriptEngine.h"
|
#include "Scripting/SHScriptEngine.h"
|
||||||
|
|
||||||
#include "Input/SHInputManager.h"
|
#include "Input/SHInputManager.h"
|
||||||
|
#include "Physics/Collision/SHCollisionTagMatrix.h"
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------------*/
|
||||||
/* Local Functions */
|
/* Local Functions */
|
||||||
|
@ -334,10 +335,6 @@ namespace SHADE
|
||||||
if (physicsObject.GetRigidBody()->isActive())
|
if (physicsObject.GetRigidBody()->isActive())
|
||||||
physicsObject.prevTransform = CURRENT_TF;
|
physicsObject.prevTransform = CURRENT_TF;
|
||||||
|
|
||||||
// Skip sleeping objects
|
|
||||||
if (physicsObject.GetRigidBody()->isSleeping())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Sync with rigid bodies
|
// Sync with rigid bodies
|
||||||
if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive<SHRigidBodyComponent>(physicsObject.entityID))
|
if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive<SHRigidBodyComponent>(physicsObject.entityID))
|
||||||
{
|
{
|
||||||
|
@ -369,7 +366,7 @@ namespace SHADE
|
||||||
colliderComponent->orientation = CURRENT_TF.getOrientation();
|
colliderComponent->orientation = CURRENT_TF.getOrientation();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set transform for rendering
|
// Set transform for rendering
|
||||||
if (transformComponent)
|
if (transformComponent)
|
||||||
{
|
{
|
||||||
transformComponent->SetWorldPosition(renderPos);
|
transformComponent->SetWorldPosition(renderPos);
|
||||||
|
@ -407,4 +404,13 @@ void testFunction()
|
||||||
rb->AddForce(SHVec3::UnitX * forceModifier);
|
rb->AddForce(SHVec3::UnitX * forceModifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cast rays
|
||||||
|
auto* tag = SHCollisionTagMatrix::GetTag(1);
|
||||||
|
tag->SetLayerState(SHCollisionTag::Layer::_1, false);
|
||||||
|
tag->SetLayerState(SHCollisionTag::Layer::_2, true);
|
||||||
|
|
||||||
|
SHRay ray { SHVec3{3.0f, 3.5f, 0.0f}, -SHVec3::UnitX };
|
||||||
|
auto* physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
|
||||||
|
physicsSystem->Raycast(ray, std::numeric_limits<float>::infinity(), *tag);
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,12 +197,18 @@ namespace SHADE
|
||||||
if (BUILD_SUCCESS)
|
if (BUILD_SUCCESS)
|
||||||
{
|
{
|
||||||
// Copy to built dll to the working directory and replace
|
// Copy to built dll to the working directory and replace
|
||||||
std::filesystem::copy_file("./tmp/SHADE_Scripting.dll", "SHADE_Scripting.dll", std::filesystem::copy_options::overwrite_existing);
|
if (!copyFile("./tmp/SHADE_Scripting.dll", "SHADE_Scripting.dll", std::filesystem::copy_options::overwrite_existing))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("[ScriptEngine] Failed to replace scripts assembly. Scripts will remain outdated.");
|
||||||
|
}
|
||||||
|
|
||||||
// If debug, we want to copy the PDB so that we can do script debugging
|
// If debug, we want to copy the PDB so that we can do script debugging
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
std::filesystem::copy_file("./tmp/SHADE_Scripting.pdb", "SHADE_Scripting.pdb", std::filesystem::copy_options::overwrite_existing);
|
if (!copyFile("./tmp/SHADE_Scripting.pdb", "SHADE_Scripting.pdb", std::filesystem::copy_options::overwrite_existing))
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("[ScriptEngine] Breakpoint debugging will not work as PDB cannot be updated. If you are currently debugging, stop the debugger first.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
oss << "[ScriptEngine] Successfully built Managed Script Assembly (" << MANAGED_SCRIPT_LIB_NAME << ")!";
|
oss << "[ScriptEngine] Successfully built Managed Script Assembly (" << MANAGED_SCRIPT_LIB_NAME << ")!";
|
||||||
|
@ -591,6 +597,19 @@ namespace SHADE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SHScriptEngine::copyFile(const std::filesystem::path& from, const std::filesystem::path& to, const std::filesystem::copy_options options) noexcept
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return std::filesystem::copy_file(from, to, options);
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("[ScriptEngine] Failed to copy file {} ({})", to.string(), std::string(e.what()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DWORD SHScriptEngine::execProcess(const std::wstring& path, const std::wstring& args)
|
DWORD SHScriptEngine::execProcess(const std::wstring& path, const std::wstring& args)
|
||||||
{
|
{
|
||||||
STARTUPINFOW startInfo;
|
STARTUPINFOW startInfo;
|
||||||
|
|
|
@ -319,6 +319,7 @@ namespace SHADE
|
||||||
/// <param name="filePath">File path to the file to check.</param>
|
/// <param name="filePath">File path to the file to check.</param>
|
||||||
/// <returns> True if the file exists </returns>
|
/// <returns> True if the file exists </returns>
|
||||||
static bool fileExists(const std::filesystem::path& filePath);
|
static bool fileExists(const std::filesystem::path& filePath);
|
||||||
|
static bool copyFile(const std::filesystem::path& from, const std::filesystem::path& to, const std::filesystem::copy_options options) noexcept;
|
||||||
static DWORD execProcess(const std::wstring& path, const std::wstring& args);
|
static DWORD execProcess(const std::wstring& path, const std::wstring& args);
|
||||||
static std::wstring generateBuildCommand(bool debug);
|
static std::wstring generateBuildCommand(bool debug);
|
||||||
};
|
};
|
||||||
|
|
|
@ -107,7 +107,7 @@ namespace SHADE
|
||||||
|
|
||||||
Vector3 Transform::Forward::get()
|
Vector3 Transform::Forward::get()
|
||||||
{
|
{
|
||||||
const SHVec3 DIRECTION = SHVec3::Rotate(SHVec3::UnitZ, Convert::ToNative(GlobalRotation));
|
const SHVec3 DIRECTION = SHVec3::Rotate(-SHVec3::UnitZ, Convert::ToNative(GlobalRotation));
|
||||||
return Convert::ToCLI(DIRECTION);
|
return Convert::ToCLI(DIRECTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -200,7 +200,16 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (SHEditorUI::Button("Add Item"))
|
if (SHEditorUI::Button("Add Item"))
|
||||||
{
|
{
|
||||||
System::Object^ obj = System::Activator::CreateInstance(listType);
|
System::Object^ obj;
|
||||||
|
if (listType == System::String::typeid)
|
||||||
|
{
|
||||||
|
// Special case for string
|
||||||
|
obj = gcnew System::String("");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
obj = System::Activator::CreateInstance(listType);
|
||||||
|
}
|
||||||
iList->Add(obj);
|
iList->Add(obj);
|
||||||
registerUndoListAddAction(listType, iList, iList->Count - 1, obj);
|
registerUndoListAddAction(listType, iList, iList->Count - 1, obj);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,9 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "Math.hxx"
|
#include "Math.hxx"
|
||||||
|
#include "Quaternion.hxx"
|
||||||
|
#include "Math/Vector/SHVec3.h"
|
||||||
|
#include "Utility/Convert.hxx"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -148,21 +151,21 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
return vec - (Project(vec, normal.GetNormalised()) * 2.0f);
|
return vec - (Project(vec, normal.GetNormalised()) * 2.0f);
|
||||||
}
|
}
|
||||||
Vector3 Vector3::RotateRadians(Vector3 vec, float radians)
|
Vector3 Vector3::RotateX(Vector3 vec, float radians)
|
||||||
{
|
{
|
||||||
const float SINE = sin(radians);
|
return Convert::ToCLI(SHVec3::RotateX(Convert::ToNative(vec), radians));
|
||||||
const float COSINE = cos(radians);
|
|
||||||
|
|
||||||
return Vector3
|
|
||||||
(
|
|
||||||
vec.x * COSINE - vec.y * SINE,
|
|
||||||
vec.x * SINE + vec.y * COSINE,
|
|
||||||
vec.z
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Vector3 Vector3::RotateDegrees(Vector3 vec, float degrees)
|
Vector3 Vector3::RotateY(Vector3 vec, float radians)
|
||||||
{
|
{
|
||||||
return RotateRadians(vec, Math::DegreesToRadians(degrees));
|
return Convert::ToCLI(SHVec3::RotateY(Convert::ToNative(vec), radians));
|
||||||
|
}
|
||||||
|
Vector3 Vector3::RotateZ(Vector3 vec, float radians)
|
||||||
|
{
|
||||||
|
return Convert::ToCLI(SHVec3::RotateZ(Convert::ToNative(vec), radians));
|
||||||
|
}
|
||||||
|
Vector3 Vector3::Rotate(Vector3 vec, Vector3 axis, float radians)
|
||||||
|
{
|
||||||
|
return Convert::ToCLI(SHVec3::Rotate(Convert::ToNative(vec), Convert::ToNative(axis), radians));
|
||||||
}
|
}
|
||||||
Vector3 Vector3::Min(Vector3 lhs, Vector3 rhs)
|
Vector3 Vector3::Min(Vector3 lhs, Vector3 rhs)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,6 +19,8 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include "Vector2.hxx"
|
#include "Vector2.hxx"
|
||||||
|
|
||||||
|
value struct Quaternion;
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
///<summary>
|
///<summary>
|
||||||
|
@ -266,7 +268,7 @@ namespace SHADE
|
||||||
/// <returns>The Vector3 that represents vec reflected across normal.</returns>
|
/// <returns>The Vector3 that represents vec reflected across normal.</returns>
|
||||||
static Vector3 Reflect(Vector3 vec, Vector3 normal);
|
static Vector3 Reflect(Vector3 vec, Vector3 normal);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rotates a Vector3 on the Z-axis by a specified angle in an anti-clockwise
|
/// Rotates a Vector3 about the X-axis by a specified angle in an anti-clockwise
|
||||||
/// direction.
|
/// direction.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vec">A Vector3 to rotate.</param>
|
/// <param name="vec">A Vector3 to rotate.</param>
|
||||||
|
@ -274,17 +276,37 @@ namespace SHADE
|
||||||
/// Angle to rotate the vector by in an anti-clockwise direction in radians.
|
/// Angle to rotate the vector by in an anti-clockwise direction in radians.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <returns>The Vector3 that represents the rotated vector.</returns>
|
/// <returns>The Vector3 that represents the rotated vector.</returns>
|
||||||
static Vector3 RotateRadians(Vector3 vec, float radians);
|
static Vector3 RotateX(Vector3 vec, float radians);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rotates a Vector3 on the Z-axis by a specified angle in an anti-clockwise
|
/// Rotates a Vector3 about the Y-axis by a specified angle in an anti-clockwise
|
||||||
/// direction.
|
/// direction.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vec">A Vector3 to rotate.</param>
|
/// <param name="vec">A Vector3 to rotate.</param>
|
||||||
/// <param name="degrees">
|
/// <param name="radians">
|
||||||
/// Angle to rotate the vector by in an anti-clockwise direction in degrees.
|
/// Angle to rotate the vector by in an anti-clockwise direction in radians.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <returns>The Vector3 that represents the rotated vector.</returns>
|
/// <returns>The Vector3 that represents the rotated vector.</returns>
|
||||||
static Vector3 RotateDegrees(Vector3 vec, float degrees);
|
static Vector3 RotateY(Vector3 vec, float radians);
|
||||||
|
/// <summary>
|
||||||
|
/// Rotates a Vector3 about the Z-axis by a specified angle in an anti-clockwise
|
||||||
|
/// direction.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vec">A Vector3 to rotate.</param>
|
||||||
|
/// <param name="radians">
|
||||||
|
/// Angle to rotate the vector by in an anti-clockwise direction in radians.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>The Vector3 that represents the rotated vector.</returns>
|
||||||
|
static Vector3 RotateZ(Vector3 vec, float radians);
|
||||||
|
/// <summary>
|
||||||
|
/// Rotates a Vector3 about an arbitrary axis by a specified angle in an anti-clockwise
|
||||||
|
/// direction.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vec">A Vector3 to rotate.</param>
|
||||||
|
/// <param name="radians">
|
||||||
|
/// Angle to rotate the vector by in an anti-clockwise direction in radians.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>The Vector3 that represents the rotated vector.</returns>
|
||||||
|
static Vector3 Rotate(Vector3 vec, Vector3 axis, float radians);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Computes and returns a Vector3 that is made from the smallest components of
|
/// Computes and returns a Vector3 that is made from the smallest components of
|
||||||
/// the two specified Vector3s.
|
/// the two specified Vector3s.
|
||||||
|
|
|
@ -74,7 +74,7 @@ namespace SHADE
|
||||||
// Add the script in
|
// Add the script in
|
||||||
script->Initialize(GameObject(entity));
|
script->Initialize(GameObject(entity));
|
||||||
entityScriptList->Insert(System::Math::Clamp(index, 0, entityScriptList->Count), script);
|
entityScriptList->Insert(System::Math::Clamp(index, 0, entityScriptList->Count), script);
|
||||||
if (Application::IsPlaying && !SHSceneManager::HasSceneChanged())
|
if (Application::IsPlaying && !isDeserialising)
|
||||||
{
|
{
|
||||||
// Only call immediately if we are in game and is not loading another scene
|
// Only call immediately if we are in game and is not loading another scene
|
||||||
script->Awake();
|
script->Awake();
|
||||||
|
@ -423,6 +423,8 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
void ScriptStore::Init()
|
void ScriptStore::Init()
|
||||||
{
|
{
|
||||||
|
isDeserialising = false;
|
||||||
|
|
||||||
// Create an enumerable list of script types
|
// Create an enumerable list of script types
|
||||||
refreshScriptTypeList();
|
refreshScriptTypeList();
|
||||||
// Get stored methods for interop variants of functions
|
// Get stored methods for interop variants of functions
|
||||||
|
@ -724,6 +726,10 @@ namespace SHADE
|
||||||
bool ScriptStore::DeserialiseScripts(Entity entity, System::IntPtr yamlNodePtr)
|
bool ScriptStore::DeserialiseScripts(Entity entity, System::IntPtr yamlNodePtr)
|
||||||
{
|
{
|
||||||
SAFE_NATIVE_CALL_BEGIN
|
SAFE_NATIVE_CALL_BEGIN
|
||||||
|
|
||||||
|
// Flag that deserialization processs is ongoing
|
||||||
|
isDeserialising = true;
|
||||||
|
|
||||||
// Convert to pointer
|
// Convert to pointer
|
||||||
YAML::Node* yamlNode = reinterpret_cast<YAML::Node*>(yamlNodePtr.ToPointer());
|
YAML::Node* yamlNode = reinterpret_cast<YAML::Node*>(yamlNodePtr.ToPointer());
|
||||||
|
|
||||||
|
@ -765,9 +771,16 @@ namespace SHADE
|
||||||
Debug::LogWarning("[ScriptStore] Script with unloaded type detected, skipping.");
|
Debug::LogWarning("[ScriptStore] Script with unloaded type detected, skipping.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unset flag for deserialization process
|
||||||
|
isDeserialising = false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
|
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
|
||||||
|
|
||||||
|
// Unset flag for deserialization process
|
||||||
|
isDeserialising = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -337,6 +337,7 @@ namespace SHADE
|
||||||
static ScriptSet disposalQueue;
|
static ScriptSet disposalQueue;
|
||||||
static System::Collections::Generic::IEnumerable<System::Type^>^ scriptTypeList;
|
static System::Collections::Generic::IEnumerable<System::Type^>^ scriptTypeList;
|
||||||
static System::Reflection::MethodInfo^ addScriptMethod;
|
static System::Reflection::MethodInfo^ addScriptMethod;
|
||||||
|
static bool isDeserialising;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
|
|
|
@ -279,7 +279,15 @@ namespace SHADE
|
||||||
for (int i = 0; i < LIST_SIZE; ++i)
|
for (int i = 0; i < LIST_SIZE; ++i)
|
||||||
{
|
{
|
||||||
// Create the object
|
// Create the object
|
||||||
System::Object^ obj = System::Activator::CreateInstance(elemType);
|
System::Object^ obj;
|
||||||
|
if (elemType == System::String::typeid)
|
||||||
|
{
|
||||||
|
obj = gcnew System::String("");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
obj = System::Activator::CreateInstance(elemType);
|
||||||
|
}
|
||||||
|
|
||||||
// Set it's value
|
// Set it's value
|
||||||
if (varAssignYaml(obj, node[i]))
|
if (varAssignYaml(obj, node[i]))
|
||||||
|
|
|
@ -167,6 +167,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
valueObj = 0;
|
valueObj = 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -181,6 +185,10 @@ namespace SHADE
|
||||||
valueObj = FieldType();
|
valueObj = FieldType();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include "Engine/Entity.hxx"
|
#include "Engine/Entity.hxx"
|
||||||
#include "Math/Vector2.hxx"
|
#include "Math/Vector2.hxx"
|
||||||
#include "Math/Vector3.hxx"
|
|
||||||
#include "Math/Quaternion.hxx"
|
#include "Math/Quaternion.hxx"
|
||||||
#include "Math/Ray.hxx"
|
#include "Math/Ray.hxx"
|
||||||
#include "Physics/RaycastHit.hxx"
|
#include "Physics/RaycastHit.hxx"
|
||||||
|
@ -34,6 +33,8 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Graphics/Color.hxx"
|
#include "Graphics/Color.hxx"
|
||||||
#include "Physics/Collision/SHPhysicsRaycastResult.h"
|
#include "Physics/Collision/SHPhysicsRaycastResult.h"
|
||||||
|
|
||||||
|
value struct Vector3;
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
Loading…
Reference in New Issue