update 1.2.5

This commit is contained in:
2025-07-20 10:18:13 +08:00
parent 5396d3e4b8
commit 9d22e1c192
17 changed files with 313 additions and 115 deletions
+10
View File
File diff suppressed because one or more lines are too long
+1
View File
@@ -27,3 +27,4 @@ MonoBehaviour:
OutlineEffect: 0
UseAnimateFontSize: 0
DefaultHeight: 1.75
VRSupport: 0
@@ -11,7 +11,9 @@ namespace EmeraldAI.SoundDetection.Utility
GUIStyle FoldoutStyle;
Texture SoundDetectionEditorIcon;
SerializedProperty CheckIncrementProp;
SerializedProperty TargetVelocityFactorProp;
SerializedProperty FalloffDealyProp;
SerializedProperty DistanceFactorProp;
SerializedProperty MinVelocityThresholdProp;
SerializedProperty AttentionRateProp;
SerializedProperty AttentionFalloffProp;
@@ -36,7 +38,9 @@ namespace EmeraldAI.SoundDetection.Utility
{
if (SoundDetectionEditorIcon == null) SoundDetectionEditorIcon = Resources.Load("Editor Icons/EmeraldSoundDetector") as Texture;
CheckIncrementProp = serializedObject.FindProperty("CheckIncrement");
TargetVelocityFactorProp = serializedObject.FindProperty("TargetVelocityFactor");
FalloffDealyProp = serializedObject.FindProperty("FalloffDealy");
DistanceFactorProp = serializedObject.FindProperty("DistanceFactor");
MinVelocityThresholdProp = serializedObject.FindProperty("MinVelocityThreshold");
AttentionRateProp = serializedObject.FindProperty("AttentionRate");
AttentionFalloffProp = serializedObject.FindProperty("AttentionFalloff");
@@ -98,23 +102,29 @@ namespace EmeraldAI.SoundDetection.Utility
CustomEditorProperties.BeginFoldoutWindowBox();
CustomEditorProperties.TextTitleWithDescription("Sound Detector Settings", "The Sound Detector component gives AI the ability to hear player targets and other sounds made by external sources. When these events happen, " +
"it will trigger Reaction Objects that will determine what the AI does. These Reaction Objects can be customized by the user.", false);
EditorGUILayout.HelpBox("AI will only listen for player targets. The tags and layers used for this are based on this AI's Emerald AI settings from its Detection Settings.", MessageType.Info); //TODO: Replace with CustomEditorProperties equivalent
EditorGUILayout.HelpBox("AI will only listen for player targets they have an Enemy Relation Type with. The tags and layers used for this are based on this AI's Emerald AI settings from its Detection Settings.", MessageType.Info); //TODO: Replace with CustomEditorProperties equivalent
GUILayout.Space(10);
DisplayThreatLevel(self);
CustomEditorProperties.CustomFloatSlider(new Rect(), new GUIContent(), CheckIncrementProp, "Check Increment", 0.0f, 1f);
CustomHelpLabelField("Controls how often sound detecting calculations are made.", true);
CustomEditorProperties.CustomFloatSlider(new Rect(), new GUIContent(), MinVelocityThresholdProp, "Min Velocity Threshold", 0.05f, 10f);
CustomHelpLabelField("Controls the minimum detected velocity 'sound'. Any amount lower than this will be handled by the Attention Falloff and will not be detected.", true);
CustomEditorProperties.CustomFloatSlider(new Rect(), new GUIContent(), AttentionRateProp, "Attention Rate", 0.0025f, 1.0f);
CustomHelpLabelField("Controls how quickly an AI's Current Threat Amount will increase, given that any detected targets' velocity is at or above the Min Velocity Threshold.", true);
CustomEditorProperties.CustomFloatSlider(new Rect(), new GUIContent(), AttentionFalloffProp, "Attention Fall off", 0.0025f, 1.0f);
CustomEditorProperties.CustomFloatSlider(new Rect(), new GUIContent(), MinVelocityThresholdProp, "Min Velocity Threshold", 0f, 10f);
CustomHelpLabelField("Controls the minimum detected velocity 'sound'. Any amount lower than this will be handled by the Attention Falloff and will not be detected.", true);
CustomEditorProperties.CustomFloatSlider(new Rect(), new GUIContent(), TargetVelocityFactorProp, "Target Velocity Factor", 0f, 1f);
CustomHelpLabelField("Controls how much a detected target's velocity influences the Attention Rate.", true);
CustomEditorProperties.CustomFloatSlider(new Rect(), new GUIContent(), DistanceFactorProp, "Target Distance Factor", 0f, 1f);
CustomHelpLabelField("Controls how much a detected target's distance influences the Attention Rate. The closer the target is, the more it will affect the Attention Rate.", true);
CustomEditorProperties.CustomFloatSlider(new Rect(), new GUIContent(), AttentionFalloffProp, "Attention Falloff", 0.0025f, 1.0f);
CustomHelpLabelField("Controls how quickly an AI's Current Threat Amount will decrease, given that all detected targets' velocity is below the Min Velocity Threshold.", true);
CustomEditorProperties.CustomFloatSlider(new Rect(), new GUIContent(), FalloffDealyProp, "Falloff Delay", 0, 10f);
CustomHelpLabelField("Controls how many seconds must pass before the Attention Falloff happens. This will only happen after all detected targets' velocity is below the Min Velocity Threshold.", true);
CustomEditorProperties.CustomFloatSlider(new Rect(), new GUIContent(), AttractModifierCooldownProp, "Attract Modifier Cooldown", 1f, 25f);
CustomHelpLabelField("Controls how many seconds need to pass before the AI can detect Attract Modifier again, after already detecting one.", true);
@@ -31,6 +31,7 @@ namespace EmeraldAI.SoundDetection.Utility
string MoveToLoudestTargetInfo = "Moves the AI directly to the loudest detected target. (If no loudest target is present, this reaction will be ignored)";
string MoveAroundCurrentPositionInfo = "Allows the AI to generate new waypoints from the AI's current position based on the user set waypoint amount and radius.";
string MoveAroundLoudestTargetInfo = "Allows the AI to generate new waypoints from the AI's loudest detected target based on the user set waypoint amount and radius. (If no loudest target is present, this reaction will be ignored)";
string SetLoudestTargetAsCombatTargetInfo = "Sets the loudest target as the AI's current target and puts the AI into Combat Mode. This bypasses the AI needing to see the target and will move to their position to attack them.";
string NoneInfo = "A None reaction is the default reaction. Nothing will happen when this reaction is triggered.";
private void OnEnable()
@@ -224,6 +225,12 @@ namespace EmeraldAI.SoundDetection.Utility
new GUIContent(" ", FleeFromLoudestTargetInfo));
element.FindPropertyRelative("ElementLineHeight").intValue = (int)Reaction.ElementLineHeights.One;
}
else if ((ReactionTypes)element.FindPropertyRelative("ReactionType").intValue == ReactionTypes.SetLoudestTargetAsCombatTarget)
{
EditorGUI.PrefixLabel(new Rect(rect.x, rect.y + 11, rect.width, EditorGUIUtility.singleLineHeight),
new GUIContent(" ", SetLoudestTargetAsCombatTargetInfo));
element.FindPropertyRelative("ElementLineHeight").intValue = (int)Reaction.ElementLineHeights.One;
}
//Two line elements
else if ((ReactionTypes)element.FindPropertyRelative("ReactionType").intValue == ReactionTypes.DebugLogMessage)
@@ -15,12 +15,13 @@ namespace EmeraldAI.SoundDetection
#region Sound Detector Variables
public GameObject DetectedAttractModifier;
public ThreatLevels CurrentThreatLevel = ThreatLevels.Unaware;
public LayerMask DetectableLayers = 1;
public float CurrentThreatAmount;
public float CheckIncrement = 0.25f;
public float MinVelocityThreshold = 0.5f;
public float AttentionRate = 0.1f;
public float MinVelocityThreshold = 0.5f;
public float TargetVelocityFactor = 0.3f;
public float DistanceFactor = 0.1f;
public float AttentionFalloff = 0.05f;
public float FalloffDealy = 3f;
public float DelayUnawareSeconds = 5f;
public float AttractModifierCooldown = 5;
public bool MovingTargetDetected;
@@ -48,15 +49,16 @@ namespace EmeraldAI.SoundDetection
//Private variables
float DelayUnawareTimer = 0;
float CheckIncrementTimer = 0;
EmeraldSystem EmeraldComponent;
EmeraldDetection EmeraldDetection;
EmeraldMovement EmeraldMovement;
bool ArrivedAtDestination;
Coroutine CurrentReactionCoroutine;
Coroutine CalculateMovementCoroutine;
Coroutine RotateTowardsCoroutine;
float TimeSinceLastAttractModifier;
bool SoundDetectorEnabled = true;
float FalloffDelayTimer;
[SerializeField]
public List<TargetDataClass> CurrentTargetData = new List<TargetDataClass>();
@@ -78,6 +80,7 @@ namespace EmeraldAI.SoundDetection
NoiseLevel = m_NoiseLevel;
}
}
#endregion
#region Editor Variables
@@ -89,6 +92,14 @@ namespace EmeraldAI.SoundDetection
#endregion
void Start()
{
InitializeSoundDetector();
}
/// <summary>
/// Initializes the Sound Detector script.
/// </summary>
void InitializeSoundDetector ()
{
CurrentThreatAmount = 0;
TimeSinceLastAttractModifier = AttractModifierCooldown;
@@ -126,24 +137,18 @@ namespace EmeraldAI.SoundDetection
return;
}
CheckIncrementTimer += Time.deltaTime;
if (CheckIncrementTimer >= CheckIncrement)
//Add each target from LineOfSightTargets to CurrentTargetData, given that it hasn't already been added and it has the EmeraldComponent.PlayerTag.
for (int i = 0; i < EmeraldDetection.LineOfSightTargets.Count; i++)
{
//Add each target from LineOfSightTargets to CurrentTargetData, given that it hasn't already been added and it has the EmeraldComponent.PlayerTag.
for (int i = 0; i < EmeraldDetection.LineOfSightTargets.Count; i++)
if (!CurrentTargetData.Exists(x => x.Target == EmeraldDetection.LineOfSightTargets[i].transform))
{
if (!CurrentTargetData.Exists(x => x.Target == EmeraldDetection.LineOfSightTargets[i].transform))
{
if (!EmeraldDetection.LineOfSightTargets[i].gameObject.CompareTag(EmeraldDetection.PlayerTag)) continue; //Skip non-player targets
float DistanceFromTarget = Vector3.Distance(transform.position, EmeraldDetection.LineOfSightTargets[i].transform.position);
CurrentTargetData.Add(new TargetDataClass(EmeraldDetection.LineOfSightTargets[i].transform, EmeraldDetection.LineOfSightTargets[i].transform.position, MinVelocityThreshold, DistanceFromTarget, 0));
}
if (!EmeraldDetection.LineOfSightTargets[i].gameObject.CompareTag(EmeraldDetection.PlayerTag)) continue; //Skip non-player targets
float DistanceFromTarget = Vector3.Distance(transform.position, EmeraldDetection.LineOfSightTargets[i].transform.position);
CurrentTargetData.Add(new TargetDataClass(EmeraldDetection.LineOfSightTargets[i].transform, EmeraldDetection.LineOfSightTargets[i].transform.position, MinVelocityThreshold, DistanceFromTarget, 0));
}
UpdateTargetData();
CheckIncrementTimer = 0;
}
UpdateTargetData();
}
private void Update()
@@ -153,11 +158,32 @@ namespace EmeraldAI.SoundDetection
if (!EmeraldComponent.AnimationComponent.IsDead && SoundDetectorEnabled)
{
TimeSinceLastAttractModifier += Time.deltaTime;
if (EmeraldDetection.LineOfSightTargets.Count > 0 || CurrentThreatLevel != ThreatLevels.Unaware)
if (EmeraldDetection.LineOfSightTargets.Count > 0)
{
CheckForSounds();
CheckEvents();
CalculateThreatLevel();
}
if (CurrentThreatAmount > 0 && EmeraldDetection.LineOfSightTargets.Count == 0)
{
if (CurrentTargetData.Count > 0)
{
SuspiciousTriggered = false;
AwareTriggered = false;
CurrentTargetData.Clear();
}
FalloffDelayTimer += Time.deltaTime; //Allow a brief resting period between when a moving target is detected and when it's not.
if (FalloffDelayTimer > FalloffDealy) CurrentThreatAmount = Mathf.MoveTowards(CurrentThreatAmount, 0, AttentionFalloff * Time.deltaTime);
CurrentThreatAmount = Mathf.Clamp(CurrentThreatAmount, 0f, 1f);
if (CurrentThreatAmount < 0.001f)
{
InvokeReactionList(UnawareReaction);
UnawareEvent.Invoke();
DelayUnawareTimer = 0;
ClearThreats();
}
}
}
}
@@ -169,20 +195,25 @@ namespace EmeraldAI.SoundDetection
{
for (int i = 0; i < CurrentTargetData.Count; i++)
{
//Calculate the velocity of each target by storing its previous distance and comparing it to its current distance (with each CheckIncrement).
float DistanceFromTarget = Vector3.Distance(transform.position, CurrentTargetData[i].Target.position);
float TargetVelocity = (CurrentTargetData[i].Target.position - CurrentTargetData[i].LastPosition).magnitude;
//float DistanceVariable = (EmeraldComponent.AttackDistance / DistanceFromTarget);
CurrentTargetData[i].LastPosition = CurrentTargetData[i].Target.position;
CurrentTargetData[i].NoiseLevel = TargetVelocity;
if (CurrentTargetData[i].Target != null)
{
//Calculate the velocity of each target by storing its previous distance and comparing it to its current distance (with each CheckIncrement).
float DistanceFromTarget = Vector3.Distance(transform.position, CurrentTargetData[i].Target.position);
float TargetVelocity = (CurrentTargetData[i].Target.position - CurrentTargetData[i].LastPosition).magnitude / Time.deltaTime;
float MitigationValue = (1f - Mathf.Clamp01(DistanceFromTarget / EmeraldComponent.DetectionComponent.DetectionRadius));
if (TargetVelocity >= MinVelocityThreshold)
{
MovingTargetDetected = true;
}
else if (CurrentThreatAmount > 0 && TargetVelocity < MinVelocityThreshold)
{
MovingTargetDetected = false;
CurrentTargetData[i].LastPosition = CurrentTargetData[i].Target.position;
CurrentTargetData[i].NoiseLevel = TargetVelocity;
CalculateThreatLevel(TargetVelocity, MitigationValue);
if (TargetVelocity > MinVelocityThreshold)
{
MovingTargetDetected = true;
}
else if (CurrentThreatAmount > 0 && TargetVelocity <= MinVelocityThreshold)
{
MovingTargetDetected = false;
}
}
}
}
@@ -190,15 +221,20 @@ namespace EmeraldAI.SoundDetection
/// <summary>
/// Simply increases or descreases the CurrentThreatLevel depending on whether or not detected targets are moving.
/// </summary>
void CalculateThreatLevel ()
void CalculateThreatLevel (float CurrentTargetVelocity, float MitigationValue)
{
if (MovingTargetDetected)
{
CurrentThreatAmount += Time.deltaTime * AttentionRate;
FalloffDelayTimer = 0;
float attentionEffect = AttentionRate * Time.deltaTime;
attentionEffect += (TargetVelocityFactor * CurrentTargetVelocity * 0.01f) * Time.deltaTime;
attentionEffect += (DistanceFactor * MitigationValue) * Time.deltaTime;
CurrentThreatAmount = Mathf.MoveTowards(CurrentThreatAmount, 1, attentionEffect);
}
else
{
CurrentThreatAmount -= Time.deltaTime * AttentionFalloff;
FalloffDelayTimer += Time.deltaTime; //Allow a brief resting period between when a moving target is detected and when it's not.
if (FalloffDelayTimer > FalloffDealy) CurrentThreatAmount = Mathf.MoveTowards(CurrentThreatAmount, 0, AttentionFalloff * Time.deltaTime);
}
CurrentThreatAmount = Mathf.Clamp(CurrentThreatAmount, 0f, 1f);
@@ -209,7 +245,11 @@ namespace EmeraldAI.SoundDetection
/// </summary>
void CancelAll ()
{
StopAllCoroutines();
if (CurrentReactionCoroutine != null) StopCoroutine(CurrentReactionCoroutine);
if (CalculateMovementCoroutine != null) StopCoroutine(CalculateMovementCoroutine);
if (RotateTowardsCoroutine != null) StopCoroutine(RotateTowardsCoroutine);
EmeraldComponent.MovementComponent.RotateTowardsTarget = false;
EmeraldComponent.m_NavMeshAgent.isStopped = false;
CurrentTargetData.Clear();
EmeraldComponent.MovementComponent.ChangeWanderType((EmeraldMovement.WanderTypes)EmeraldMovement.StartingWanderingType);
}
@@ -314,7 +354,7 @@ namespace EmeraldAI.SoundDetection
//Ensure the AI is using its Starting WanderType.
EmeraldComponent.MovementComponent.ChangeWanderType((EmeraldMovement.WanderTypes)EmeraldMovement.StartingWanderingType);
if (CurrentReactionCoroutine != null) { StopAllCoroutines(); }
if (CurrentReactionCoroutine != null) { StopCoroutine(CurrentReactionCoroutine); }
CurrentReactionCoroutine = StartCoroutine(InvokeReactionListInternal(SentReactionObject, SentByAttractModifier));
}
@@ -354,6 +394,11 @@ namespace EmeraldAI.SoundDetection
else if (SentReactionObject.ReactionList[i].ReactionType == ReactionTypes.LookAtLoudestTarget)
{
LookAtLoudestTarget();
yield return new WaitForSeconds(SentReactionObject.ReactionList[i].IntValue1);
}
else if (SentReactionObject.ReactionList[i].ReactionType == ReactionTypes.SetLoudestTargetAsCombatTarget)
{
SetLoudestTargetAsCombatTarget();
}
else if (SentReactionObject.ReactionList[i].ReactionType == ReactionTypes.ReturnToStartingPosition)
{
@@ -486,7 +531,16 @@ namespace EmeraldAI.SoundDetection
if (CurrentTargetData.Count == 0)
return;
EmeraldComponent.LookAtTarget = GetLoudestTarget(); //Assign the loudest detected target as the Look At Target.
if (RotateTowardsCoroutine != null) StopCoroutine(RotateTowardsCoroutine);
RotateTowardsCoroutine = StartCoroutine(RotateTowardsPosition(GetLoudestTarget().position)); //Have the AI rotate towards the loudest position
}
/// <summary>
/// Sets the loudest target as the AI's current target.
/// </summary>
public void SetLoudestTargetAsCombatTarget()
{
EmeraldAPI.Combat.SetCombatTarget(EmeraldComponent, GetLoudestTarget());
}
/// <summary>
@@ -659,6 +713,27 @@ namespace EmeraldAI.SoundDetection
EmeraldComponent.MovementComponent.ChangeWanderType((EmeraldMovement.WanderTypes)EmeraldMovement.StartingWanderingType);
}
IEnumerator RotateTowardsPosition(Vector3 TargetPosition)
{
if (EmeraldComponent.MovementComponent.RotateTowardsTarget) yield break; //Don't allow the AI to rotate towards the TargetPosition if it's already doing so
EmeraldComponent.MovementComponent.RotateTowardsTarget = true; //Stops certain functionality while in this state
EmeraldComponent.MovementComponent.LockTurning = false; //This is used for preventing an AI from getting stuck between two turn animations
EmeraldComponent.m_NavMeshAgent.isStopped = true; //Stop the AI's NavMesh
yield return new WaitForSeconds(0.1f); //Add a delay so the changes above aren't missed
while (!EmeraldComponent.MovementComponent.LockTurning)
{
Vector3 Direction = new Vector3(TargetPosition.x, 0, TargetPosition.z) - new Vector3(EmeraldComponent.transform.position.x, 0, EmeraldComponent.transform.position.z);
EmeraldComponent.MovementComponent.UpdateRotations(Direction);
EmeraldComponent.AnimationComponent.CalculateTurnAnimations(true);
yield return null;
}
EmeraldComponent.MovementComponent.RotateTowardsTarget = false;
EmeraldComponent.m_NavMeshAgent.isStopped = false;
}
/// <summary>
/// Sets the AI's flee target as the loudest detected target. (Cautious Coward AI Only)
/// </summary>
@@ -14,12 +14,13 @@
MoveAroundCurrentPosition = 200,
MoveAroundLoudestTarget = 225,
MoveToLoudestTarget = 250,
SetLoudestTargetAsCombatTarget = 260,
PlayEmoteAnimation = 275,
PlaySound = 300,
ResetAllToDefault = 325,
ResetDetectionDistance = 350,
ResetLookAtPosition = 375,
ReturnToStartingPosition = 400,
SetMovementState = 425,
SetMovementState = 425,
}
}
@@ -449,6 +449,7 @@ namespace EmeraldAI
public void PlayAttackAnimation ()
{
if (!EmeraldComponent.CombatComponent.CurrentAttackData.CooldownIgnored) EmeraldComponent.CombatComponent.CurrentAttackData.CooldownTimeStamp = Time.time;
if (!EmeraldComponent.CombatComponent.CurrentAttackData.AbilityObject.CooldownSettings.Enabled) EmeraldComponent.CombatComponent.CurrentAttackData.CooldownTimeStamp = 0; //Set cooldown values that are disabled to 0
AIAnimator.SetInteger("Attack Index", EmeraldComponent.CombatComponent.CurrentAnimationIndex + 1);
AIAnimator.SetTrigger("Attack");
@@ -832,6 +832,12 @@ namespace EmeraldAI
/// </summary>
public void MovementUpdate ()
{
if (m_NavMeshAgent.isOnOffMeshLink)
{
m_NavMeshAgent.speed = 1f;
return;
}
CanReachTarget = CanReachTargetInternal();
AIAgentActive = m_NavMeshAgent.enabled;
@@ -952,7 +958,6 @@ namespace EmeraldAI
/// </summary>
public void StopBackingUp()
{
if (BackupCoroutine != null) StopCoroutine(BackupCoroutine);
EmeraldComponent.AIAnimator.SetBool("Walk Backwards", false);
EmeraldComponent.m_NavMeshAgent.stoppingDistance = EmeraldComponent.CombatComponent.AttackDistance;
BackingUpTimer = 0;
@@ -973,7 +978,7 @@ namespace EmeraldAI
{
BackupTimer = 0;
if (m_NavMeshAgent.remainingDistance <= EmeraldComponent.CombatComponent.TooCloseDistance && !DefaultMovementPaused)
if (EmeraldComponent.CombatComponent.DistanceFromTarget <= EmeraldComponent.CombatComponent.TooCloseDistance && !DefaultMovementPaused)
{
if (DestinationAdjustedAngle <= 90 && !AIAnimator.GetBool("Blocking"))
{
+64 -9
View File
@@ -17,6 +17,7 @@ namespace EmeraldAI
public GameObject CombatTextCanvas;
[HideInInspector]
public EmeraldCombatTextData m_EmeraldAICombatTextData;
Transform m_CombatTextParent;
private void Awake()
@@ -29,6 +30,19 @@ namespace EmeraldAI
CombatTextObject = (GameObject)Resources.Load("Combat Text") as GameObject;
m_CombatTextParent = CombatTextCanvas.transform.GetChild(0);
m_EmeraldAICombatTextData = (EmeraldCombatTextData)Resources.Load("Combat Text Data") as EmeraldCombatTextData;
if (!m_EmeraldAICombatTextData.VRSupport)
{
CombatTextCanvas.transform.localScale = Vector3.one;
CombatTextCanvas.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
}
else
{
CombatTextCanvas.transform.localScale = Vector3.one * 0.01f;
CombatTextCanvas.GetComponent<Canvas>().renderMode = RenderMode.WorldSpace;
CombatTextCanvas.GetComponent<CanvasScaler>().dynamicPixelsPerUnit = 3;
CombatTextCanvas.GetComponent<Canvas>().worldCamera = Camera.main;
}
}
public void CreateCombatText(int amount, Vector3 TextPosition, bool CriticalHit, bool HealingText, bool PlayerTakingDamage)
@@ -49,6 +63,7 @@ namespace EmeraldAI
m_Text.text = amount.ToString();
m_Text.font = m_EmeraldAICombatTextData.TextFont;
m_Text.fontSize = m_EmeraldAICombatTextData.FontSize;
if (m_EmeraldAICombatTextData.VRSupport) m_Text.transform.localScale = Vector3.one * 0.6f;
Outline m_OutLine = t.GetComponent<Outline>();
if (m_EmeraldAICombatTextData.OutlineEffect == EmeraldCombatTextData.OutlineEffectEnum.Enabled)
@@ -87,11 +102,12 @@ namespace EmeraldAI
var t = EmeraldAI.Utility.EmeraldObjectPool.Spawn(CombatTextObject, TextPosition + Vector3.up, Quaternion.identity);
t.transform.SetParent(m_CombatTextParent);
t.transform.position = Vector3.zero;
Text m_Text = t.GetComponent<Text>();
m_Text.text = Amount.ToString();
m_Text.font = m_EmeraldAICombatTextData.TextFont;
m_Text.fontSize = m_EmeraldAICombatTextData.FontSize;
if (m_EmeraldAICombatTextData.VRSupport) m_Text.transform.localScale = Vector3.one * 0.6f;
Outline m_OutLine = t.GetComponent<Outline>();
if (m_EmeraldAICombatTextData.OutlineEffect == EmeraldCombatTextData.OutlineEffectEnum.Enabled)
@@ -162,8 +178,15 @@ namespace EmeraldAI
t += Time.deltaTime;
float r = 1.0f - (t / 1);
Vector3 m_TextPos = TargetPosition + new Vector3(r - RandomXPosition, Mathf.Sin(r * Mathf.PI), 0);
m_TextPos = Camera.main.WorldToScreenPoint(m_TextPos - Vector3.right + Vector3.up * m_EmeraldAICombatTextData.DefaultHeight / 2);
m_TextPos.z = 0.0f;
if (!m_EmeraldAICombatTextData.VRSupport)
{
m_TextPos = Camera.main.WorldToScreenPoint(m_TextPos - Vector3.right + Vector3.up * m_EmeraldAICombatTextData.DefaultHeight / 2);
m_TextPos.z = 0.0f;
}
else
{
m_TextPos = (m_TextPos - Vector3.right + Vector3.up * m_EmeraldAICombatTextData.DefaultHeight / 2);
}
if (m_EmeraldAICombatTextData.UseAnimateFontSize == EmeraldCombatTextData.UseAnimateFontSizeEnum.Enabled)
{
@@ -186,6 +209,7 @@ namespace EmeraldAI
}
m_Text.transform.position = m_TextPos;
if (m_EmeraldAICombatTextData.VRSupport) RotateTowardsCamera(m_Text.transform);
yield return null;
}
@@ -233,8 +257,15 @@ namespace EmeraldAI
t += Time.deltaTime*0.75f;
float r = 1.0f - (t / 1);
Vector3 m_TextPos = TargetPosition + new Vector3(RandomXPosition, -r * m_EmeraldAICombatTextData.DefaultHeight, 0);
m_TextPos = Camera.main.WorldToScreenPoint(m_TextPos + Vector3.up * m_EmeraldAICombatTextData.DefaultHeight);
m_TextPos.z = 0.0f;
if (!m_EmeraldAICombatTextData.VRSupport)
{
m_TextPos = Camera.main.WorldToScreenPoint(m_TextPos + Vector3.up * m_EmeraldAICombatTextData.DefaultHeight);
m_TextPos.z = 0.0f;
}
else
{
m_TextPos = (m_TextPos + Vector3.up * m_EmeraldAICombatTextData.DefaultHeight);
}
if (m_EmeraldAICombatTextData.UseAnimateFontSize == EmeraldCombatTextData.UseAnimateFontSizeEnum.Enabled)
{
@@ -257,6 +288,7 @@ namespace EmeraldAI
}
m_Text.transform.position = m_TextPos;
if (m_EmeraldAICombatTextData.VRSupport) RotateTowardsCamera(m_Text.transform);
yield return null;
}
@@ -321,9 +353,18 @@ namespace EmeraldAI
m_TextPos = TargetPosition + new Vector3(Mathf.Lerp(0, RandomXPosition, 1 - r), -r * m_EmeraldAICombatTextData.DefaultHeight + Mathf.Sin(r + RandomYPosition * Mathf.PI), 0);
}
m_TextPos = Camera.main.WorldToScreenPoint(m_TextPos+Vector3.up*RandomYPosition);
m_TextPos.z = 0.0f;
if (!m_EmeraldAICombatTextData.VRSupport)
{
m_TextPos = Camera.main.WorldToScreenPoint(m_TextPos + Vector3.up * RandomYPosition);
m_TextPos.z = 0.0f;
}
else
{
m_TextPos = (m_TextPos + Vector3.up * RandomYPosition);
}
m_Text.transform.position = m_TextPos;
if (m_EmeraldAICombatTextData.VRSupport) RotateTowardsCamera(m_Text.transform);
if (m_EmeraldAICombatTextData.UseAnimateFontSize == EmeraldCombatTextData.UseAnimateFontSizeEnum.Enabled)
{
@@ -392,8 +433,15 @@ namespace EmeraldAI
{
t += Time.deltaTime;
Vector3 m_TextPos = TargetPosition + new Vector3(RandomXPosition, RandomYPosition, 0);
m_TextPos = Camera.main.WorldToScreenPoint(m_TextPos - Vector3.up * 0.5f);
m_TextPos.z = 0.0f;
if (!m_EmeraldAICombatTextData.VRSupport)
{
m_TextPos = Camera.main.WorldToScreenPoint(m_TextPos - Vector3.up * 0.5f);
m_TextPos.z = 0.0f;
}
else
{
m_TextPos = (m_TextPos - Vector3.up * 0.5f);
}
if (m_EmeraldAICombatTextData.UseAnimateFontSize == EmeraldCombatTextData.UseAnimateFontSizeEnum.Enabled)
{
@@ -416,11 +464,18 @@ namespace EmeraldAI
}
m_Text.transform.position = m_TextPos;
if (m_EmeraldAICombatTextData.VRSupport) RotateTowardsCamera(m_Text.transform);
yield return null;
}
EmeraldAI.Utility.EmeraldObjectPool.Despawn(m_Text.gameObject);
}
void RotateTowardsCamera (Transform Source)
{
Vector3 directionAwayFromCamera = Source.position - Camera.main.transform.position;
Source.rotation = Quaternion.LookRotation(directionAwayFromCamera);
}
}
}
@@ -27,6 +27,7 @@ namespace EmeraldAI.Utility
SerializedProperty OutlineEffect;
SerializedProperty UseAnimateFontSize;
SerializedProperty TextHeight;
SerializedProperty VRSupport;
[MenuItem("Window/Emerald AI/Combat Text Manager #%c", false, 200)]
public static void ShowWindow()
@@ -61,6 +62,7 @@ namespace EmeraldAI.Utility
OutlineEffect = serializedObject.FindProperty("OutlineEffect");
UseAnimateFontSize = serializedObject.FindProperty("UseAnimateFontSize");
TextHeight = serializedObject.FindProperty("DefaultHeight");
VRSupport = serializedObject.FindProperty("VRSupport");
}
void OnGUI()
@@ -131,6 +133,12 @@ namespace EmeraldAI.Utility
GUI.backgroundColor = Color.white;
EditorGUILayout.Space();
EditorGUILayout.PropertyField(VRSupport, new GUIContent("VR Support"));
GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
EditorGUILayout.HelpBox("Changes the Combat Text System's canvas to World Space to allow it to work with VR (this setting cannot be changed during runtime as it's set up when the CTS is initialized).", MessageType.None, true);
GUI.backgroundColor = Color.white;
EditorGUILayout.Space();
EditorGUILayout.PropertyField(TextHeight, new GUIContent("Combat Text Height"));
GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
EditorGUILayout.HelpBox("Controls the overall height the Combat Text will spawn above targets.", MessageType.None, true);
@@ -45,7 +45,6 @@ namespace EmeraldAI.Utility
}
//If there are no available attacks, ignore the cooldowns and pick a random ability to avoid an error.
//if (AvailableAttacks.Count == 0 && SentAttackClass.AttackPickType != AttackPickTypes.Order)
if (AvailableAttacks.Count == 0)
{
SetAttackValues(EmeraldComponent, SentAttackClass.AttackDataList[Random.Range(0, SentAttackClass.AttackDataList.Count)], true);
@@ -169,7 +168,7 @@ namespace EmeraldAI.Utility
/// <summary>
/// Check each condition for the passed ability to see if they can be used.
/// </summary>
static bool CheckAbilityConditions (EmeraldSystem EmeraldComponent, AttackClass.AttackData AttackData)
static bool CheckAbilityConditions(EmeraldSystem EmeraldComponent, AttackClass.AttackData AttackData)
{
if (AttackData.AbilityObject.ConditionSettings.ConditionType == ConditionTypes.SelfLowHealth)
{
@@ -195,8 +194,14 @@ namespace EmeraldAI.Utility
}
else if (AttackData.AbilityObject.ConditionSettings.ConditionType == ConditionTypes.DistanceFromTarget)
{
return EmeraldComponent.CombatComponent.DistanceFromTarget <= AttackData.AbilityObject.ConditionSettings.DistanceFromTarget && AttackData.AbilityObject.ConditionSettings.ValueCompareType == AbilityData.ConditionData.ValueCompareTypes.LessThan ||
EmeraldComponent.CombatComponent.DistanceFromTarget >= AttackData.AbilityObject.ConditionSettings.DistanceFromTarget && AttackData.AbilityObject.ConditionSettings.ValueCompareType == AbilityData.ConditionData.ValueCompareTypes.GreaterThan;
if (AttackData.AbilityObject.ConditionSettings.ValueCompareType == AbilityData.ConditionData.ValueCompareTypes.LessThan)
{
return EmeraldComponent.CombatComponent.DistanceFromTarget <= AttackData.AbilityObject.ConditionSettings.DistanceFromTarget;
}
else if (AttackData.AbilityObject.ConditionSettings.ValueCompareType == AbilityData.ConditionData.ValueCompareTypes.GreaterThan)
{
return EmeraldComponent.CombatComponent.DistanceFromTarget >= AttackData.AbilityObject.ConditionSettings.DistanceFromTarget;
}
}
return false;
@@ -25,5 +25,6 @@ namespace EmeraldAI
public enum UseAnimateFontSizeEnum { Enabled, Disabled };
public UseAnimateFontSizeEnum UseAnimateFontSize = UseAnimateFontSizeEnum.Disabled;
public float DefaultHeight = 1.75f;
public bool VRSupport = false;
}
}
@@ -1099,8 +1099,6 @@ MonoBehaviour:
x: 1
y: 1
z: 1
m_SourceObjectsGUIToggle: 0
m_SettingsGUIToggle: 1
--- !u!1 &430677210
GameObject:
m_ObjectHideFlags: 0
@@ -2163,8 +2161,6 @@ MonoBehaviour:
x: 1
y: 1
z: 1
m_SourceObjectsGUIToggle: 0
m_SettingsGUIToggle: 1
--- !u!1 &854498951
GameObject:
m_ObjectHideFlags: 0
@@ -2513,8 +2509,6 @@ MonoBehaviour:
x: 1
y: 1
z: 1
m_SourceObjectsGUIToggle: 0
m_SettingsGUIToggle: 1
--- !u!1 &993205062
GameObject:
m_ObjectHideFlags: 0
@@ -3176,6 +3170,7 @@ MonoBehaviour:
m_NavMeshAgent: {fileID: 0}
AIBoxCollider: {fileID: 0}
AIAnimator: {fileID: 0}
TimeSinceEnabled: 0
DetectionComponent: {fileID: 0}
BehaviorsComponent: {fileID: 0}
MovementComponent: {fileID: 0}
@@ -3529,9 +3524,11 @@ MonoBehaviour:
DeathDelayTimer: 0
CurrentAnimationIndex: 0
TargetDetectionActive: 0
TargetOutOfHeightRange: 0
TooCloseDistance: 1
AttackDistance: 2.5
CurrentEmeraldAIAbility: {fileID: 0}
AvailableConditionAbilities: []
CurrentAttackData:
AbilityObject: {fileID: 0}
AttackAnimation: 0
@@ -3562,6 +3559,7 @@ MonoBehaviour:
CurrentHealth: 90
StartingHealth: 90
HealRate: 0
AttachHitEffects: 0
Immortal: 0
CurrentActiveEffects: []
HitEffectFoldout: 0
@@ -3691,6 +3689,8 @@ MonoBehaviour:
ObstructionType: 2
LineOfSightTargets: []
CurrentFollowers: []
NearbyAllies: []
LowHealthAllies: []
CurrentFaction: 0
FactionRelations:
FactionRelationsList:
@@ -3793,8 +3793,6 @@ MonoBehaviour:
MissingRuntimeController: 0
AnimationsUpdated: 0
AIAnimator: {fileID: 1223765695}
AnimatorCullingMode: 0
UseWarningAnimation: 0
AttackingTracker: 0
AttackTriggered: 0
WarningAnimationTriggered: 0
@@ -6890,8 +6888,6 @@ MonoBehaviour:
x: 1
y: 1
z: 1
m_SourceObjectsGUIToggle: 0
m_SettingsGUIToggle: 1
--- !u!4 &984178145003238945
Transform:
m_ObjectHideFlags: 0
@@ -7964,6 +7960,7 @@ MonoBehaviour:
m_NavMeshAgent: {fileID: 0}
AIBoxCollider: {fileID: 0}
AIAnimator: {fileID: 0}
TimeSinceEnabled: 0
DetectionComponent: {fileID: 0}
BehaviorsComponent: {fileID: 0}
MovementComponent: {fileID: 0}
@@ -8320,9 +8317,11 @@ MonoBehaviour:
DeathDelayTimer: 0
CurrentAnimationIndex: 0
TargetDetectionActive: 0
TargetOutOfHeightRange: 0
TooCloseDistance: 1
AttackDistance: 2.5
CurrentEmeraldAIAbility: {fileID: 0}
AvailableConditionAbilities: []
CurrentAttackData:
AbilityObject: {fileID: 0}
AttackAnimation: 0
@@ -8353,6 +8352,7 @@ MonoBehaviour:
CurrentHealth: 130
StartingHealth: 130
HealRate: 0
AttachHitEffects: 0
Immortal: 0
CurrentActiveEffects: []
HitEffectFoldout: 0
@@ -8482,6 +8482,8 @@ MonoBehaviour:
ObstructionType: 2
LineOfSightTargets: []
CurrentFollowers: []
NearbyAllies: []
LowHealthAllies: []
CurrentFaction: 1
FactionRelations:
FactionRelationsList:
@@ -8600,8 +8602,6 @@ MonoBehaviour:
MissingRuntimeController: 0
AnimationsUpdated: 0
AIAnimator: {fileID: 5834346861728704417}
AnimatorCullingMode: 0
UseWarningAnimation: 0
AttackingTracker: 0
AttackTriggered: 0
WarningAnimationTriggered: 0
@@ -3379,8 +3379,6 @@ MonoBehaviour:
x: 1
y: 1
z: 1
m_SourceObjectsGUIToggle: 0
m_SettingsGUIToggle: 1
--- !u!1 &1419757364
GameObject:
m_ObjectHideFlags: 0
@@ -4426,6 +4424,7 @@ MonoBehaviour:
m_NavMeshAgent: {fileID: 0}
AIBoxCollider: {fileID: 0}
AIAnimator: {fileID: 0}
TimeSinceEnabled: 0
DetectionComponent: {fileID: 0}
BehaviorsComponent: {fileID: 0}
MovementComponent: {fileID: 0}
@@ -4561,7 +4560,7 @@ Animator:
m_GameObject: {fileID: 1743903527}
m_Enabled: 1
m_Avatar: {fileID: 9000000, guid: e57e9b8cd5e115f4f8d7736473e5c7fd, type: 3}
m_Controller: {fileID: 9100000, guid: bdc0762e205db0345a5ea194ab3a480b, type: 2}
m_Controller: {fileID: 9100000, guid: 22e597addfc275e43a5b6bb4b051f7a0, type: 2}
m_CullingMode: 1
m_UpdateMode: 0
m_ApplyRootMotion: 1
@@ -4773,9 +4772,11 @@ MonoBehaviour:
DeathDelayTimer: 0
CurrentAnimationIndex: 0
TargetDetectionActive: 0
TargetOutOfHeightRange: 0
TooCloseDistance: 1
AttackDistance: 2.5
CurrentEmeraldAIAbility: {fileID: 0}
AvailableConditionAbilities: []
CurrentAttackData:
AbilityObject: {fileID: 0}
AttackAnimation: 0
@@ -4806,6 +4807,7 @@ MonoBehaviour:
CurrentHealth: 50
StartingHealth: 50
HealRate: 0
AttachHitEffects: 0
Immortal: 1
CurrentActiveEffects: []
HitEffectFoldout: 0
@@ -4872,8 +4874,6 @@ MonoBehaviour:
RotateTowardsTarget: 0
StationaryIdleSecondsMin: 3
StationaryIdleSecondsMax: 6
BackupType: 1
BackupOdds: 50
GeneratedBackupOdds: 0
StartingWanderingType: 0
ReturnToStationaryPosition: 0
@@ -4887,8 +4887,6 @@ MonoBehaviour:
BackupLayerMask:
serializedVersion: 2
m_Bits: 4294967295
BackingUpSecondsMin: 3
BackingUpSecondsMax: 4
LockTurning: 0
ReturningToStartInProgress: 0
AIAgentActive: 0
@@ -4937,6 +4935,8 @@ MonoBehaviour:
ObstructionType: 2
LineOfSightTargets: []
CurrentFollowers: []
NearbyAllies: []
LowHealthAllies: []
CurrentFaction: 0
FactionRelations:
FactionRelationsList:
@@ -5011,6 +5011,9 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 871be6a68bd875f49b5587968e1ac56c, type: 3}
m_Name:
m_EditorClassIdentifier:
InternalDodge: 0
InternalBlock: 0
InternalHit: 0
IsEmoting: 0
IsIdling: 0
IsAttacking: 0
@@ -5036,8 +5039,6 @@ MonoBehaviour:
MissingRuntimeController: 0
AnimationsUpdated: 0
AIAnimator: {fileID: 1743903532}
AnimatorCullingMode: 0
UseWarningAnimation: 0
AttackingTracker: 0
AttackTriggered: 0
WarningAnimationTriggered: 0
@@ -5065,14 +5066,13 @@ MonoBehaviour:
m_EditorClassIdentifier:
DetectedAttractModifier: {fileID: 0}
CurrentThreatLevel: 0
DetectableLayers:
serializedVersion: 2
m_Bits: 1
CurrentThreatAmount: 0
CheckIncrement: 0.25
MinVelocityThreshold: 0.5
AttentionRate: 0.1
MinVelocityThreshold: 0.5
TargetVelocityFactor: 0.3
DistanceFactor: 0.1
AttentionFalloff: 0.05
FalloffDealy: 3
DelayUnawareSeconds: 5
AttractModifierCooldown: 5
MovingTargetDetected: 0
@@ -5094,7 +5094,7 @@ MonoBehaviour:
CurrentTargetData: []
HideSettingsFoldout: 0
SoundDetectorFoldout: 1
UnawareFoldout: 0
UnawareFoldout: 1
SuspiciousFoldout: 0
AwareFoldout: 0
--- !u!4 &1743903545
@@ -5295,8 +5295,6 @@ MonoBehaviour:
x: 1
y: 1
z: 1
m_SourceObjectsGUIToggle: 0
m_SettingsGUIToggle: 1
--- !u!1 &1961984826
GameObject:
m_ObjectHideFlags: 0
@@ -23,9 +23,13 @@ MonoBehaviour:
Enabled: 0
CooldownLength: 1
ConditionSettings:
Foldout: 1
Enabled: 0
ConditionType: 0
OutnumberedThreshold: 3
ValueCompareType: 1
HighPriority: 0
DistanceFromTarget: 3
LowHealthPercentage: 60
ChargeSettings:
Enabled: 0
ChargeEffect: {fileID: 0}
@@ -2,16 +2,14 @@
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Ring
m_Shader: {fileID: 211, guid: 0000000000000000f000000000000000, type: 0}
m_ValidKeywords:
- _ALPHABLEND_ON
m_InvalidKeywords: []
m_ShaderKeywords: _ALPHABLEND_ON
m_LightmapFlags: 0
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
@@ -20,6 +18,7 @@ Material:
RenderType: Transparent
disabledShaderPasses:
- GRABPASS
- ALWAYS
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
@@ -59,7 +58,6 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _BlendOp: 0
- _BumpScale: 1
+34 -15
View File
@@ -30,19 +30,27 @@ namespace EmeraldAI.Example
{
if (Input.GetMouseButtonDown(1))
{
lastMouse = Input.mousePosition;
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
if (Input.GetMouseButtonUp(1))
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
if (Input.GetMouseButton(1))
{
lastMouse = Input.mousePosition - lastMouse;
lastMouse = new Vector3(-lastMouse.y * camSens, lastMouse.x * camSens, 0);
lastMouse = new Vector3(transform.eulerAngles.x + lastMouse.x, transform.eulerAngles.y + lastMouse.y, 0);
transform.eulerAngles = lastMouse;
lastMouse = Input.mousePosition;
float mouseX = Input.GetAxis("Mouse X") * camSens * 15;
float mouseY = Input.GetAxis("Mouse Y") * camSens * 15;
Vector3 newRotation = transform.eulerAngles;
newRotation.x -= mouseY;
newRotation.y += mouseX;
transform.eulerAngles = newRotation;
}
//Keyboard commands
Vector3 p = GetBaseLegacyInput();
if (Input.GetKey(KeyCode.LeftShift))
{
@@ -66,21 +74,32 @@ namespace EmeraldAI.Example
#if (ENABLE_INPUT_SYSTEM)
void NewInput()
{
if (!Mouse.current.rightButton.isPressed)
if (Mouse.current.rightButton.wasPressedThisFrame)
{
lastMouse = Mouse.current.position.ReadValue();
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
if (Mouse.current.rightButton.wasReleasedThisFrame)
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
if (Mouse.current.rightButton.isPressed)
{
lastMouse = (Vector3)Mouse.current.position.ReadValue() - lastMouse;
lastMouse = new Vector3(-lastMouse.y * camSens, lastMouse.x * camSens, 0);
lastMouse = new Vector3(transform.eulerAngles.x + lastMouse.x, transform.eulerAngles.y + lastMouse.y, 0);
transform.eulerAngles = lastMouse;
lastMouse = Mouse.current.position.ReadValue();
Vector2 mouseDelta = Mouse.current.delta.ReadValue();
float mouseX = mouseDelta.x * camSens;
float mouseY = mouseDelta.y * camSens;
Vector3 newRotation = transform.eulerAngles;
newRotation.x -= mouseY;
newRotation.y += mouseX;
transform.eulerAngles = newRotation;
}
//Keyboard commands
Vector3 p = GetBaseNewInput();
if (Keyboard.current.leftShiftKey.isPressed)
{