You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
7.4 KiB
C#
199 lines
7.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Unity.BossRoom.Gameplay.GameplayObjects.AnimationCallbacks;
|
|
using UnityEngine;
|
|
|
|
namespace Unity.BossRoom.Gameplay.GameplayObjects.Character
|
|
{
|
|
/// <summary>
|
|
/// Responsible for storing of all of the pieces of a character, and swapping the pieces out en masse when asked to.
|
|
/// </summary>
|
|
public class CharacterSwap : MonoBehaviour
|
|
{
|
|
[System.Serializable]
|
|
public class CharacterModelSet
|
|
{
|
|
public GameObject ears;
|
|
public GameObject head;
|
|
public GameObject mouth;
|
|
public GameObject hair;
|
|
public GameObject eyes;
|
|
public GameObject torso;
|
|
public GameObject gearRightHand;
|
|
public GameObject gearLeftHand;
|
|
public GameObject handRight;
|
|
public GameObject handLeft;
|
|
public GameObject shoulderRight;
|
|
public GameObject shoulderLeft;
|
|
public GameObject handSocket;
|
|
public AnimatorTriggeredSpecialFX specialFx;
|
|
public AnimatorOverrideController animatorOverrides; // references a separate stand-alone object in the project
|
|
private List<Renderer> m_CachedRenderers;
|
|
|
|
public void SetFullActive(bool isActive)
|
|
{
|
|
ears.SetActive(isActive);
|
|
head.SetActive(isActive);
|
|
mouth.SetActive(isActive);
|
|
hair.SetActive(isActive);
|
|
eyes.SetActive(isActive);
|
|
torso.SetActive(isActive);
|
|
gearLeftHand.SetActive(isActive);
|
|
gearRightHand.SetActive(isActive);
|
|
handRight.SetActive(isActive);
|
|
handLeft.SetActive(isActive);
|
|
shoulderRight.SetActive(isActive);
|
|
shoulderLeft.SetActive(isActive);
|
|
}
|
|
|
|
public List<Renderer> GetAllBodyParts()
|
|
{
|
|
if (m_CachedRenderers == null)
|
|
{
|
|
m_CachedRenderers = new List<Renderer>();
|
|
AddRenderer(ref m_CachedRenderers, ears);
|
|
AddRenderer(ref m_CachedRenderers, head);
|
|
AddRenderer(ref m_CachedRenderers, mouth);
|
|
AddRenderer(ref m_CachedRenderers, hair);
|
|
AddRenderer(ref m_CachedRenderers, torso);
|
|
AddRenderer(ref m_CachedRenderers, gearRightHand);
|
|
AddRenderer(ref m_CachedRenderers, gearLeftHand);
|
|
AddRenderer(ref m_CachedRenderers, handRight);
|
|
AddRenderer(ref m_CachedRenderers, handLeft);
|
|
AddRenderer(ref m_CachedRenderers, shoulderRight);
|
|
AddRenderer(ref m_CachedRenderers, shoulderLeft);
|
|
}
|
|
return m_CachedRenderers;
|
|
}
|
|
|
|
private void AddRenderer(ref List<Renderer> rendererList, GameObject bodypartGO)
|
|
{
|
|
if (!bodypartGO) { return; }
|
|
var bodyPartRenderer = bodypartGO.GetComponent<Renderer>();
|
|
if (!bodyPartRenderer) { return; }
|
|
rendererList.Add(bodyPartRenderer);
|
|
}
|
|
|
|
}
|
|
|
|
[SerializeField]
|
|
CharacterModelSet m_CharacterModel;
|
|
|
|
public CharacterModelSet CharacterModel => m_CharacterModel;
|
|
|
|
/// <summary>
|
|
/// Reference to our shared-characters' animator.
|
|
/// Can be null, but if so, animator overrides are not supported!
|
|
/// </summary>
|
|
[SerializeField]
|
|
private Animator m_Animator;
|
|
|
|
/// <summary>
|
|
/// Reference to the original controller in our Animator.
|
|
/// We switch back to this whenever we don't have an Override.
|
|
/// </summary>
|
|
private RuntimeAnimatorController m_OriginalController;
|
|
|
|
[SerializeField]
|
|
[Tooltip("Special Material we plug in when the local player is \"stealthy\"")]
|
|
private Material m_StealthySelfMaterial;
|
|
|
|
[SerializeField]
|
|
[Tooltip("Special Material we plug in when another player is \"stealthy\"")]
|
|
private Material m_StealthyOtherMaterial;
|
|
|
|
public enum SpecialMaterialMode
|
|
{
|
|
None,
|
|
StealthySelf,
|
|
StealthyOther,
|
|
}
|
|
|
|
/// <summary>
|
|
/// When we swap all our Materials out for a special material,
|
|
/// we keep the old references here, so we can swap them back.
|
|
/// </summary>
|
|
private Dictionary<Renderer, Material> m_OriginalMaterials = new Dictionary<Renderer, Material>();
|
|
|
|
ClientCharacter m_ClientCharacter;
|
|
|
|
void Awake()
|
|
{
|
|
m_ClientCharacter = GetComponentInParent<ClientCharacter>();
|
|
m_Animator = m_ClientCharacter.OurAnimator;
|
|
m_OriginalController = m_Animator.runtimeAnimatorController;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
// It's important that the original Materials that we pulled out of the renderers are put back.
|
|
// Otherwise nothing will Destroy() them and they will leak! (Alternatively we could manually
|
|
// Destroy() these in our OnDestroy(), but in this case it makes more sense just to put them back.)
|
|
ClearOverrideMaterial();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Swap the visuals of the character to the index passed in.
|
|
/// </summary>
|
|
/// <param name="specialMaterialMode">Special Material to apply to all body parts</param>
|
|
public void SwapToModel(SpecialMaterialMode specialMaterialMode = SpecialMaterialMode.None)
|
|
{
|
|
ClearOverrideMaterial();
|
|
|
|
if (m_CharacterModel.specialFx)
|
|
{
|
|
m_CharacterModel.specialFx.enabled = true;
|
|
}
|
|
|
|
if (m_Animator)
|
|
{
|
|
// plug in the correct animator override... or plug the original non - overridden version back in!
|
|
if (m_CharacterModel.animatorOverrides)
|
|
{
|
|
m_Animator.runtimeAnimatorController = m_CharacterModel.animatorOverrides;
|
|
}
|
|
else
|
|
{
|
|
m_Animator.runtimeAnimatorController = m_OriginalController;
|
|
}
|
|
}
|
|
|
|
// lastly, now that we're all assembled, apply any override material.
|
|
switch (specialMaterialMode)
|
|
{
|
|
case SpecialMaterialMode.StealthySelf:
|
|
SetOverrideMaterial(m_StealthySelfMaterial);
|
|
break;
|
|
case SpecialMaterialMode.StealthyOther:
|
|
SetOverrideMaterial(m_StealthyOtherMaterial);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void ClearOverrideMaterial()
|
|
{
|
|
foreach (var entry in m_OriginalMaterials)
|
|
{
|
|
if (entry.Key)
|
|
{
|
|
entry.Key.material = entry.Value;
|
|
}
|
|
}
|
|
m_OriginalMaterials.Clear();
|
|
}
|
|
|
|
private void SetOverrideMaterial(Material overrideMaterial)
|
|
{
|
|
ClearOverrideMaterial(); // just sanity-checking; this should already have been called!
|
|
foreach (var bodyPart in m_CharacterModel.GetAllBodyParts())
|
|
{
|
|
if (bodyPart)
|
|
{
|
|
m_OriginalMaterials[bodyPart] = bodyPart.material;
|
|
bodyPart.material = overrideMaterial;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|