// Don't need to do this every frame. Should make it a coroutine like above private void Update() { var random = Random.Range(0, 10000); var chance = voiceIdleOdds * Time.deltaTime; if (random < chance) { var audioClip = DialogRecord.GetDialogInfo(DialogType.Voice, GetComponent <Character>(), null, VoiceType.Idle.ToString()); if (audioClip != null && audio != null) { audio.PlayOneShot(audioClip.AudioClip); } } }
void IActivatable.Activate(GameObject target) { // Get the dialog component of the listener, so we can use it's NpcRecord player = target.GetComponent <Character>(); // Get the npc greeting, as if there is no greeting, the Npc can't be talked to. var greeting = DialogRecord.GetDialogInfo(DialogType.Greeting, Npc, player); if (greeting == null) { return; } // Check if the listener knows the current topic, otherwise it will not be available // This could be done within the same loop as getting the dialog topic topics = DialogRecord.GetDialog(Npc, player); var knownTopics = new List <DialogRecord>(); foreach (var topic in topics) { // Only show topics that the player knows if (player.Journal.Topics.ContainsKey(topic.name)) { knownTopics.Add(topic); } } // Display services var services = GetComponents <CharacterService>(); // Load the dialog and instantiate dialogView = DialogView.Create(this, record.FullName, knownTopics, services, Npc.GetDisposition(player)); // Process the greeting after getting topics, or there will be no topics to check against DisplayInfo(null, greeting); // Set this last, so it isn't true the first time the player talks to an Npc. GetComponent <Character>().HasTalkedToPlayer = true; }
private IEnumerator Start() { // Do an intial overlap sphere so that any Npc's already in range of others don't greet eachother var colliders = Physics.OverlapSphere(transform.position, GreetDistance * greetDistanceMultiplier, LayerMask.GetMask("Npc")); foreach (var collider in colliders) { // Do a raycast to make sure the NPC is actually visible var direction = collider.bounds.center - headTransform.position; RaycastHit hit; if (!Physics.Raycast(headTransform.position, direction, out hit, GreetDistance * greetDistanceMultiplier, LayerMask.GetMask("Default", "Npc", "Raycast Only")) || hit.collider != collider) { continue; } greetedNpcs.Add(collider); } while (isActiveAndEnabled) { yield return(new WaitForSeconds(GreetUpdateInterval)); // First, check if any of the previously-greeted Npc's have moved far enough away that they should be re-greeted if they get close. Add the greet distance to the rest ddistance, so that npcs with a long greet range don't re-greet players early greetedNpcs.RemoveWhere(col => Vector3.Distance(transform.position, col.transform.position) >= greetDistanceReset + GreetDistance * greetDistanceMultiplier); // Now periodically check for new Npcs, and if so, greet them colliders = Physics.OverlapSphere(headTransform.position, GreetDistance * greetDistanceMultiplier, LayerMask.GetMask("Npc")); foreach (var collider in colliders) { if (greetedNpcs.Contains(collider)) { continue; } // Raycast to the NPC first, to make sure there's nothing in the way. (This may not work, as it will probably raycast from the foot position var direction = collider.bounds.center - headTransform.position; RaycastHit hit; if (!Physics.Raycast(headTransform.position, direction, out hit, GreetDistance * greetDistanceMultiplier, LayerMask.GetMask("Default", "Npc", "Raycast Only")) || hit.collider != collider) { continue; } // Record this npc so we don't forget them greetedNpcs.Add(collider); // Get the Npc's NpcRecord var listener = collider.GetComponentInParent <DialogController>(); if (listener == null) { continue; } // Play greeting for any new Npc's detected var audioClip = DialogRecord.GetDialogInfo(DialogType.Voice, GetComponent <Character>(), listener.GetComponent <Character>(), VoiceType.Hello.ToString()); if (audio != null) { audio.PlayOneShot(audioClip.AudioClip); } } } }