public static void DrawDebugLine(GameObject from, GameObject hit, GameObject target, Vector3 fromRaycastPosition, Vector3 hitPosition, Vector3 targetRaycastPosition, Color positive, Color negative, float time = 0.1f) { #if UNITY_EDITOR if (LosUtility.IsValidTarget(target, hit)) { DrawDebugLine(fromRaycastPosition, targetRaycastPosition, targetRaycastPosition, positive, negative, time); } else { DrawDebugLine(fromRaycastPosition, hitPosition, targetRaycastPosition, positive, negative, time); } #endif }
public bool IsHearable(IListener listener, IAudioSource source, AudioSourceInfo info) { if (info.volume >= listener.config.minHearingVolume) { var raycastPosition = new Vector3[] { new Vector3(0f, 0f), // Middle new Vector3(0f, 1f), // Up new Vector3(0f, -1f), // Down new Vector3(-1f, 0f), // Left side new Vector3(1f, 0f), // Right side }; const int levels = 1; const float scaling = 1.5f; for (int i = 1; i < levels + 1; i++) { foreach (var pos in raycastPosition) { var raycastToPosition = listener.transform.position + (pos * i * scaling); RaycastHit hitInfo; bool hit = _raycaster.Linecast(source.transform.position, raycastToPosition, out hitInfo, _config.raycastLayer); // If nothing was hit the object is visible. if (hit == false) { hitInfo.gameObject = listener.gameObject; hitInfo.point = raycastToPosition; hitInfo.normal = Vector3.zero; } // Direct path from audio source to listener. if (_config.debug) { LosDebugUtility.DrawDebugLine(source.gameObject, hitInfo.gameObject, listener.gameObject, source.transform.position, hitInfo.point, raycastToPosition, Color.magenta, Color.black); } // If we did hit something, is it the target? if (LosUtility.IsValidTarget(listener.gameObject, hitInfo.gameObject) || hit == false) { return(true); } } } } return(false); }
protected virtual void OnTargetEnter(GameObject target) { var listener = target.GetComponentInParent <IListener>(); if (listener != null && LosUtility.IsValidTarget(listener.gameObject, target)) { if (audioSource.IsHeardBy(listener)) { // Prevent objects with multiple colliders to invoke events more than once. return; } if (((listener.config.targetCategoryMask & audioSource.emitterCategory) == 0) || audioSource.emitterCategory == 0) { return; } var dist = Vector3.Distance(transform.position, listener.gameObject.transform.position); var info = new AudioSourceInfo() { volume = Mathf.Clamp01((audioSource.maxGrowthSize - dist) / audioSource.maxGrowthSize), lastHeardAtPosition = new AudioSourceSampleData() { position = transform.position, time = LosUtility.time }, audioSource = audioSource, listener = listener }; if (listener.hearableValidators.Length == 0) { HeardBy(ref info); } else { foreach (var validator in listener.hearableValidators) { if (validator.IsHearable(listener, audioSource, info)) { HeardBy(ref info); break; } } } } }
/// <summary> /// /// </summary> /// <returns>Returns True when the raycasting is all done. False when more raycasts are required.</returns> private bool DoRaycast(Vector3 raycastToPosition, SightTargetInfo sightInfo, ref float hits, ref float hitFactor, int sampleCount) { RaycastHit hitInfo; bool hit = raycaster.Linecast(gameObject.transform.position, raycastToPosition, out hitInfo, config.raycastLayer); // If nothing was hit the object is visible. if (hit == false) { hitInfo.gameObject = sightInfo.target.gameObject; hitInfo.point = raycastToPosition; hitInfo.normal = Vector3.zero; } #if UNITY_EDITOR if (config.debug) { LosDebugUtility.DrawDebugLine(gameObject, hitInfo.gameObject, sightInfo.target.gameObject, gameObject.transform.position, hitInfo.point, raycastToPosition, config.updateInterval); } #endif // If we did hit something, is it the target? if (LosUtility.IsValidTarget(sightInfo.target.gameObject, hitInfo.gameObject) || hit == false) { hits++; hitFactor = hits / sampleCount; // If the sight is already detected we can bail early if (hitFactor >= GetMinVisibilityFactor(sightInfo.target) && sightInfo.isDetected) { return(true); // break; // Object is already visible no need to keep casting } } return(false); }