using UnityEngine;
namespace Passer.Humanoid {
/// Manage avatar meshes for a humanoid
/// The avatar manger can be used to manage multiple avatar meshes for a single humanoid.
/// It is supported single player and networking setups.
///
/// Setup
/// =====
/// The Avatar Manager script can be found should be attached to an GameObject with the
/// HumanoidControl component script.
///
/// Single User
/// ===========
/// \image html AvatarManagerInspectorSingle.png
///
/// The Avatar Manger script shows the list of available avatars to use.
/// Every avatar needs to have a Animator component attached and only avatars from the
/// Project Window (prefabs, models) are supported, so you cannot use avatar in you scene.
/// New avatars can be added to the list by clicking Add Avatar while empty slots will be
/// cleaned up automatically.
/// The Current Avatar Index shows the index number of the avatar which is currently used.
/// At startup, this value will determine which avatar is used when the scene is started.
/// *Note: this will override the avatar which is attached to the HumanoidControl component!*
///
/// Networking
/// ==========
/// When Networking Support is enabled additional entries for the third person avatar will be shown.
/// \image html AvatarManagerInspectorMulti.png
/// These values match the behaviour of the Remote Avatar in the Humanoid Control script:
/// at the local client, the first person avatar is used, while the third person avatar is used on
/// remote clients. This will enable you to optimize the avatars for each case.
/// If the Third Person avatar is left to None, like for Robot Kyle in the example above,
/// the First Person avatar will also be used for remote clients.
///
/// Changing Avatars
/// ================
/// The avatar can be set using on of the scripting functions like PreviousAvastar, NextAvatar
/// and SetAvatar. These functions can also be used in combination with \ref Script "Scripts"
/// or ControllerInput:
///
/// \image AvatarManagerControllerInput.png
///
[HelpURLAttribute("https://passervr.com/documentation/humanoid-control/avatar-manager/")]
public class AvatarManager : MonoBehaviour {
/// The index of the current avatar in the list
public int currentAvatarIndex = 0;
/// The list of avatars for the humanoid
/// For networked avatars this avatar will be used for the local client.
public Animator[] fpAvatars = new Animator[0];
/// The list of third person avatar for networked humanoids
/// This is the avatar which will be used to show a player of remote clients.
/// When no third person avatar is specified, the first person avatar will be used
/// as the third person avatar.
public Animator[] tpAvatars = new Animator[0];
private HumanoidControl humanoid;
protected virtual void Start() {
humanoid = GetComponent();
SetAvatar(currentAvatarIndex);
}
/// Replaces the current avatar by the next avatar in the list.
/// This will wrap around when the last avatar is the current avatar.
public void NextAvatar() {
currentAvatarIndex = mod(currentAvatarIndex + 1, fpAvatars.Length);
SetAvatar(currentAvatarIndex);
}
/// Replaces the current avatar by the previous avatar in the list.
/// This will wrap around when the first avatar is the current avatar.
public void PreviousAvatar() {
currentAvatarIndex = mod(currentAvatarIndex - 1, fpAvatars.Length);
SetAvatar(currentAvatarIndex);
}
/// This will replace the current avatar with the avatar indicated by the avatarIndex.
/// The index of the avatar in the list of avatars
public void SetAvatar(int avatarIndex) {
if (humanoid == null)
return;
if (avatarIndex < 0 || avatarIndex > fpAvatars.Length)
return;
if (fpAvatars[avatarIndex] != null) {
#if hNW_UNET || hNW_PHOTON
if (avatarIndex < tpAvatars.Length && tpAvatars[avatarIndex] != null)
humanoid.ChangeAvatar(fpAvatars[avatarIndex].gameObject, tpAvatars[avatarIndex].gameObject);
else
#endif
humanoid.ChangeAvatar(fpAvatars[avatarIndex].gameObject);
}
}
public static int mod(int k, int n) {
k %= n;
return (k < 0) ? k + n : k;
}
}
}