384 lines
12 KiB
C#
384 lines
12 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Sirenix.OdinInspector;
|
|
using UnityEngine;
|
|
|
|
namespace Beyond
|
|
{
|
|
public class CharacterVisibilityController : MonoBehaviour
|
|
{
|
|
public enum State
|
|
{
|
|
NORMAL,
|
|
GHOST,
|
|
INVISIBLE,
|
|
UNINITIALIZED
|
|
};
|
|
|
|
[Serializable]
|
|
public struct ShaderValues
|
|
{
|
|
public float alpha;
|
|
public float invisibility;
|
|
public float fresnelPower;
|
|
|
|
[ColorUsageAttribute(true, true, 0f, 8f, 0.125f, 3f)]
|
|
public Color fresnelColor;
|
|
|
|
public ShaderValues(float alpha, float invisibility, float fresnelPower, Color c)
|
|
{
|
|
fresnelColor = c;
|
|
this.alpha = alpha;
|
|
this.invisibility = invisibility;
|
|
this.fresnelPower = 4f;
|
|
}
|
|
|
|
public ShaderValues Lerp(ShaderValues val, float t)
|
|
{
|
|
ShaderValues res;
|
|
res.alpha = Mathf.Lerp(alpha, val.alpha, t);
|
|
res.invisibility = Mathf.Lerp(invisibility, val.invisibility, t);
|
|
res.fresnelPower = Mathf.Lerp(fresnelPower, val.fresnelPower, t);
|
|
res.fresnelColor = Color.Lerp(fresnelColor, val.fresnelColor, t);
|
|
return res;
|
|
}
|
|
}
|
|
|
|
public bDamageModifierController m_damageModifierContoller;
|
|
private const string NormalDamageModifierName = "NormalDamage", GhostDamageModifierName = "GhostDamage";
|
|
private const int ghostDamagePercentage = 0, normalDamagePercentage = -100;
|
|
|
|
public ShaderValues m_NormalShaderValue = new ShaderValues(1f, 0f, 4f, Color.black);
|
|
public ShaderValues m_GhostShaderValue = new ShaderValues(0.5f, 0f, 4f, new Color(0f, 1.5f, 2f));
|
|
public ShaderValues m_InvisibleShaderValue = new ShaderValues(0.4f, 10f, 4f, new Color(0f, 0.15f, 0.2f));
|
|
|
|
public ShaderValues m_currentValues;
|
|
public ShaderValues m_previousValues;
|
|
public ShaderValues m_targetValues;
|
|
|
|
public State m_currentState = State.UNINITIALIZED;
|
|
private State m_targetState = State.NORMAL;
|
|
public State m_startingState = State.NORMAL;
|
|
public float m_transitionTime = 5f;
|
|
private float m_timer = 0f;
|
|
/*
|
|
public float m_targetAlpha = 0.5f;
|
|
[ColorUsageAttribute(true,true,0f,8f,0.125f,3f)]
|
|
public Color m_targetFresnelColor = new Color(0f, 1f, 2f);
|
|
|
|
public float m_targetFresnelPower = 4f;
|
|
public float m_targetInvisibility = 0f;
|
|
*/
|
|
|
|
public List<GameObject> gameObjectsToExclideFromChange;
|
|
private List<Renderer> renderersToExcludeFromChange = new List<Renderer>();
|
|
|
|
[OnValueChanged("SetAlpha")]
|
|
public float m_alpha = 0f;
|
|
|
|
[ColorUsageAttribute(true, true, 0f, 8f, 0.125f, 3f)]
|
|
[OnValueChanged("SetFresnelColor")]
|
|
public Color m_fresnelColor = new Color(0.5f, 0.5f, 2f);
|
|
|
|
[OnValueChanged("SetFresnelPower")]
|
|
public float m_fresnelPower = 4f;
|
|
|
|
[OnValueChanged("SetCutoffThreshold")]
|
|
public float m_dissolveTh = 0f;
|
|
|
|
[OnValueChanged("SetInvisibility")]
|
|
public float m_invisibility = 0f;
|
|
|
|
private bool m_inTransition = false;
|
|
private List<Material> m_materials;
|
|
private Shader m_transparent;
|
|
private Shader m_opaque;
|
|
private int m_thresholID = Shader.PropertyToID("_Threshold");
|
|
private int m_baseColorID = Shader.PropertyToID("_BaseColor");
|
|
private int m_FresnelColorID = Shader.PropertyToID("_FresnelColor");
|
|
private int m_FresnelPowerID = Shader.PropertyToID("FresnelPower");
|
|
private int m_InvisibilityID = Shader.PropertyToID("_Invisibility");
|
|
|
|
private bool m_usesTransparent = false;
|
|
|
|
private void InitMaterials()
|
|
{
|
|
if (m_materials != null && m_materials.Count > 0)
|
|
return;
|
|
|
|
var renderers = GetComponentsInChildren<Renderer>().ToList();
|
|
if (gameObjectsToExclideFromChange.Count > 0)
|
|
{
|
|
gameObjectsToExclideFromChange.ForEach(gameObject => renderersToExcludeFromChange.AddRange(gameObject.GetComponentsInChildren<Renderer>().ToList()));
|
|
renderers.RemoveAll(item => renderersToExcludeFromChange.Contains(item));
|
|
}
|
|
m_materials = new List<Material>();
|
|
foreach (var r in renderers)
|
|
{
|
|
foreach (var m in r.materials)
|
|
m_materials.Add(m);
|
|
}
|
|
|
|
var rdr = GetComponent<Renderer>();
|
|
if (rdr)
|
|
{
|
|
foreach (var m in rdr.materials)
|
|
m_materials.Add(m);
|
|
}
|
|
|
|
m_transparent = Shader.Find("Shader Graphs/BeyondLitTransparent");
|
|
//m_transparent
|
|
if (m_transparent == null)
|
|
{
|
|
Debug.LogError("Transparent shader not found!");
|
|
}
|
|
m_opaque = Shader.Find("Shader Graphs/BeyondLit");
|
|
if (m_opaque == null)
|
|
{
|
|
Debug.LogError("Opaque shader not found!");
|
|
}
|
|
}
|
|
|
|
private ShaderValues GetValuesForState(State s)
|
|
{
|
|
ShaderValues v = m_NormalShaderValue;
|
|
switch (s)
|
|
{
|
|
case State.NORMAL:
|
|
v = m_NormalShaderValue;
|
|
break;
|
|
|
|
case State.GHOST:
|
|
v = m_GhostShaderValue;
|
|
break;
|
|
|
|
case State.INVISIBLE:
|
|
v = m_InvisibleShaderValue;
|
|
break;
|
|
}
|
|
|
|
return v;
|
|
}
|
|
|
|
private void SetValues(ShaderValues val)
|
|
{
|
|
foreach (var m in m_materials)
|
|
{
|
|
Color c = m.GetColor(m_baseColorID);
|
|
c.a = val.alpha;
|
|
m.SetColor(m_baseColorID, c);
|
|
m.SetColor(m_FresnelColorID, val.fresnelColor);
|
|
m.SetFloat(m_FresnelPowerID, val.fresnelPower);
|
|
m.SetFloat(m_InvisibilityID, val.invisibility);
|
|
}
|
|
}
|
|
|
|
private void SetAlpha()
|
|
{
|
|
#if UNITY_EDITOR
|
|
InitMaterials();
|
|
#endif
|
|
foreach (var m in m_materials)
|
|
{
|
|
Color c = m.GetColor(m_baseColorID);
|
|
c.a = m_alpha;
|
|
m.SetColor(m_baseColorID, c);
|
|
}
|
|
}
|
|
|
|
private void SetFresnelColor()
|
|
{
|
|
#if UNITY_EDITOR
|
|
InitMaterials();
|
|
#endif
|
|
foreach (var m in m_materials)
|
|
{
|
|
m.SetColor(m_FresnelColorID, m_fresnelColor);
|
|
}
|
|
}
|
|
|
|
private void SetFresnelPower()
|
|
{
|
|
#if UNITY_EDITOR
|
|
InitMaterials();
|
|
#endif
|
|
foreach (var m in m_materials)
|
|
{
|
|
m.SetFloat(m_FresnelPowerID, m_fresnelPower);
|
|
}
|
|
}
|
|
|
|
private void SetCutoffThreshold()
|
|
{
|
|
#if UNITY_EDITOR
|
|
InitMaterials();
|
|
#endif
|
|
foreach (var m in m_materials)
|
|
{
|
|
m.SetFloat(m_thresholID, m_dissolveTh);
|
|
}
|
|
}
|
|
|
|
private void SetInvisibility()
|
|
{
|
|
#if UNITY_EDITOR
|
|
InitMaterials();
|
|
#endif
|
|
foreach (var m in m_materials)
|
|
{
|
|
m.SetFloat(m_InvisibilityID, m_invisibility);
|
|
}
|
|
}
|
|
|
|
[Button]
|
|
public void SetNormalState()
|
|
{
|
|
SetState(State.NORMAL);
|
|
}
|
|
|
|
[Button]
|
|
public void SetGhostState()
|
|
{
|
|
SetState(State.GHOST);
|
|
}
|
|
|
|
[Button]
|
|
public void SetInvisibleState()
|
|
{
|
|
SetState(State.INVISIBLE);
|
|
}
|
|
|
|
[Button]
|
|
public void SetTransparentShader()
|
|
{
|
|
if (m_usesTransparent)
|
|
return;
|
|
#if UNITY_EDITOR
|
|
InitMaterials();
|
|
#endif
|
|
foreach (var m in m_materials)
|
|
{
|
|
m.shader = m_transparent;
|
|
}
|
|
|
|
m_usesTransparent = true;
|
|
}
|
|
|
|
[Button]
|
|
public void SetOpaqueShader()
|
|
{
|
|
if (!m_usesTransparent)
|
|
return;
|
|
#if UNITY_EDITOR
|
|
InitMaterials();
|
|
#endif
|
|
foreach (var m in m_materials)
|
|
{
|
|
m.shader = m_opaque;
|
|
}
|
|
|
|
m_usesTransparent = false;
|
|
}
|
|
|
|
public void SetState(State state)
|
|
{
|
|
if (state == m_currentState)
|
|
{
|
|
return;
|
|
}
|
|
if (m_currentState == State.UNINITIALIZED)
|
|
{
|
|
m_previousValues = m_currentValues = GetValuesForState(state);
|
|
SetValues(m_currentValues);
|
|
m_currentState = m_targetState = state;
|
|
ManageStatesBehaviour(state);
|
|
return;
|
|
}
|
|
//m_targetValues
|
|
m_targetState = state;
|
|
m_previousValues = m_targetValues;
|
|
m_timer = 0f;
|
|
m_targetValues = GetValuesForState(state);
|
|
ManageStatesBehaviour(state);
|
|
}
|
|
|
|
private void ManageStatesBehaviour(State state)
|
|
{
|
|
switch (state)
|
|
{
|
|
case State.NORMAL:
|
|
EnableAllDamage();
|
|
break;
|
|
|
|
case State.GHOST:
|
|
DisableAllDamageExceptGhost();
|
|
SetTransparentShader();
|
|
break;
|
|
|
|
case State.INVISIBLE:
|
|
SetTransparentShader();
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void EnableAllDamage()
|
|
{
|
|
if (!m_damageModifierContoller)
|
|
{
|
|
return;
|
|
}
|
|
m_damageModifierContoller.SetModifierPercentageDamage(NormalDamageModifierName, 0);
|
|
m_damageModifierContoller.SetModifierPercentageDamage(GhostDamageModifierName, 0);
|
|
}
|
|
|
|
private void DisableAllDamageExceptGhost()
|
|
{
|
|
if (!m_damageModifierContoller)
|
|
{
|
|
return;
|
|
}
|
|
m_damageModifierContoller.SetModifierPercentageDamage(NormalDamageModifierName, normalDamagePercentage);
|
|
m_damageModifierContoller.SetModifierPercentageDamage(GhostDamageModifierName, ghostDamagePercentage);
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (m_currentState != m_targetState)
|
|
{
|
|
if (m_timer > m_transitionTime)
|
|
{
|
|
m_currentState = m_targetState;
|
|
m_currentValues = m_targetValues;
|
|
switch (m_targetState)
|
|
{
|
|
case State.NORMAL:
|
|
SetOpaqueShader();
|
|
break;
|
|
|
|
case State.GHOST:
|
|
break;
|
|
|
|
case State.INVISIBLE:
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_previousValues = GetValuesForState(m_currentState);
|
|
m_currentValues = m_previousValues.Lerp(m_targetValues, m_timer / m_transitionTime);
|
|
m_timer += Time.deltaTime;
|
|
}
|
|
SetValues(m_currentValues);
|
|
}
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
m_currentState = State.UNINITIALIZED;
|
|
InitMaterials();
|
|
SetState(m_startingState);
|
|
}
|
|
}
|
|
} |