You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
290 lines
8.6 KiB
290 lines
8.6 KiB
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
|
|
[CreateAssetMenu(fileName = "VisualStyle", menuName = "UniQuake/Visual Style", order = 1)]
|
|
public class VisualStyle : ScriptableObject
|
|
{
|
|
[SerializeField]
|
|
protected Material entityMaterial;
|
|
|
|
[SerializeField]
|
|
protected Material worldMaterial; // TODO: split into wall, liquid, sky, etc
|
|
|
|
[SerializeField]
|
|
protected Material liquidMaterial;
|
|
|
|
[SerializeField]
|
|
protected bool pointSampling;
|
|
|
|
[SerializeField]
|
|
protected bool affineTexturing;
|
|
|
|
[SerializeField]
|
|
protected LiquidProperties liquidProperties = new LiquidProperties();
|
|
|
|
[SerializeField]
|
|
protected ParticleSystems particles = new ParticleSystems();
|
|
public ParticleSystems Particles => particles;
|
|
|
|
public virtual void Activate()
|
|
{
|
|
particles.Init();
|
|
|
|
if (pointSampling)
|
|
Shader.EnableKeyword("_POINT_SAMPLING");
|
|
else
|
|
Shader.DisableKeyword("_POINT_SAMPLING");
|
|
}
|
|
|
|
public virtual Material CreateEntityMaterial(bool aliasModel)
|
|
{
|
|
var material = new Material(entityMaterial);
|
|
|
|
if (aliasModel && affineTexturing)
|
|
material.EnableKeyword("_AFFINE_ON");
|
|
else
|
|
material.DisableKeyword("_AFFINE_ON");
|
|
|
|
return material;
|
|
}
|
|
|
|
public virtual Material CreateWorldMaterial(QSurfaceFlags surfaceFlags)
|
|
{
|
|
Material material;
|
|
|
|
if (surfaceFlags.HasFlag(QSurfaceFlags.DrawTurbulence) && liquidMaterial != null)
|
|
{
|
|
float alpha = 1f;
|
|
if (surfaceFlags.HasFlag(QSurfaceFlags.DrawWater))
|
|
alpha = liquidProperties.waterAlpha;
|
|
else if (surfaceFlags.HasFlag(QSurfaceFlags.DrawSlime))
|
|
alpha = liquidProperties.slimeAlpha;
|
|
else if (surfaceFlags.HasFlag(QSurfaceFlags.DrawLava))
|
|
alpha = liquidProperties.lavaAlpha;
|
|
else if (surfaceFlags.HasFlag(QSurfaceFlags.DrawTeleporter))
|
|
alpha = liquidProperties.teleAlpha;
|
|
|
|
material = new Material(liquidMaterial);
|
|
material.SetColor("_BaseColor", new Color(1, 1, 1, alpha));
|
|
}
|
|
else
|
|
{
|
|
material = new Material(worldMaterial);
|
|
}
|
|
|
|
if (surfaceFlags.HasFlag(QSurfaceFlags.DrawFence))
|
|
{
|
|
material.EnableKeyword("_ALPHATEST_ON");
|
|
}
|
|
|
|
return material;
|
|
}
|
|
|
|
public virtual void SetupEntityRenderer(MeshRenderer meshRenderer)
|
|
{
|
|
meshRenderer.shadowCastingMode = ShadowCastingMode.Off;
|
|
meshRenderer.receiveShadows = false;
|
|
meshRenderer.lightProbeUsage = LightProbeUsage.Off;
|
|
meshRenderer.reflectionProbeUsage = ReflectionProbeUsage.Off;
|
|
}
|
|
|
|
public virtual void SetupEntityRenderer(SkinnedMeshRenderer skinnedMeshRenderer)
|
|
{
|
|
skinnedMeshRenderer.shadowCastingMode = ShadowCastingMode.Off;
|
|
skinnedMeshRenderer.receiveShadows = false;
|
|
skinnedMeshRenderer.lightProbeUsage = LightProbeUsage.Off;
|
|
skinnedMeshRenderer.reflectionProbeUsage = ReflectionProbeUsage.Off;
|
|
}
|
|
|
|
public virtual void SetupWorldRenderer(MeshRenderer meshRenderer)
|
|
{
|
|
meshRenderer.shadowCastingMode = ShadowCastingMode.Off;
|
|
meshRenderer.receiveShadows = false;
|
|
meshRenderer.lightProbeUsage = LightProbeUsage.Off;
|
|
meshRenderer.reflectionProbeUsage = ReflectionProbeUsage.Off;
|
|
}
|
|
|
|
public virtual void SetEntityTextures(Material material, Texture2D mainTexture, Texture2D fullBright)
|
|
{
|
|
material.mainTexture = mainTexture;
|
|
|
|
material.SetTexture("_EmissionMap", fullBright);
|
|
material.SetColor("_EmissionColor", Color.white);
|
|
|
|
if (fullBright != null)
|
|
material.EnableKeyword("_EMISSION");
|
|
else
|
|
material.DisableKeyword("_EMISSION");
|
|
}
|
|
|
|
public virtual void SetWorldTextures(Material material, Texture2D mainTexture, Texture2D fullBright, Texture2D lightmap)
|
|
{
|
|
material.mainTexture = mainTexture;
|
|
|
|
material.SetTexture("_EmissionMap", fullBright);
|
|
material.SetColor("_EmissionColor", Color.white);
|
|
|
|
if (fullBright != null)
|
|
material.EnableKeyword("_EMISSION");
|
|
else
|
|
material.DisableKeyword("_EMISSION");
|
|
|
|
material.SetTexture("_LightMap", lightmap);
|
|
|
|
if (lightmap != null)
|
|
material.EnableKeyword("_QLIGHTMAP_ON");
|
|
else
|
|
material.DisableKeyword("_QLIGHTMAP_ON");
|
|
}
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class LiquidProperties
|
|
{
|
|
[Range(0, 1)]
|
|
public float
|
|
waterAlpha = 0.85f,
|
|
slimeAlpha = 0.9f,
|
|
lavaAlpha = 0.95f,
|
|
teleAlpha = 1.0f;
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class ParticleSystems
|
|
{
|
|
[SerializeField]
|
|
protected Material particleMaterial;
|
|
|
|
[SerializeField]
|
|
protected float particleSize = 1.0f;
|
|
|
|
[SerializeField]
|
|
protected ParticleSystem particleEffect;
|
|
|
|
[SerializeField]
|
|
protected ParticleSystem explosion;
|
|
|
|
[SerializeField]
|
|
protected ParticleSystem rogueExplosion;
|
|
|
|
[SerializeField]
|
|
protected ParticleSystem blobExplosion;
|
|
|
|
[SerializeField]
|
|
protected ParticleSystem teleportSplash;
|
|
|
|
[SerializeField]
|
|
protected ParticleSystem lavaSplash;
|
|
|
|
public virtual void Init()
|
|
{
|
|
InitTemplate(particleEffect);
|
|
InitTemplate(explosion);
|
|
InitTemplate(rogueExplosion);
|
|
InitTemplate(blobExplosion);
|
|
InitTemplate(teleportSplash);
|
|
InitTemplate(lavaSplash);
|
|
}
|
|
|
|
protected virtual void InitTemplate(ParticleSystem template)
|
|
{
|
|
if (template == null)
|
|
return;
|
|
|
|
var main = template.main;
|
|
main.startSize = particleSize;
|
|
|
|
if (particleMaterial != null)
|
|
{
|
|
var renderer = template.GetComponent<ParticleSystemRenderer>();
|
|
renderer.sharedMaterial = particleMaterial;
|
|
}
|
|
|
|
int childCount = template.transform.childCount;
|
|
for (int i = 0; i < childCount; ++i)
|
|
{
|
|
var child = template.transform.GetChild(i);
|
|
InitTemplate(child.GetComponent<ParticleSystem>());
|
|
}
|
|
}
|
|
|
|
public virtual void RunParticleEffect(Vector3 position, Vector3 direction, Color colorMin, Color colorMax, int count, Layers layer)
|
|
{
|
|
var effect = InstantiateEffect(particleEffect, position, layer);
|
|
if (effect == null)
|
|
return;
|
|
|
|
var main = effect.main;
|
|
main.maxParticles = count;
|
|
SetColorGradient(main, colorMin, colorMax);
|
|
|
|
var velocity = effect.velocityOverLifetime;
|
|
velocity.x = direction.x * 15f;
|
|
velocity.y = direction.y * 15f;
|
|
velocity.z = direction.z * 15f;
|
|
}
|
|
|
|
public virtual void CreateExplosion(Vector3 position, Layers layer)
|
|
{
|
|
InstantiateEffect(explosion, position, layer);
|
|
}
|
|
|
|
public virtual void CreateRogueExplosion(Vector3 position, Color colorMin, Color colorMax, Layers layer)
|
|
{
|
|
var effect = InstantiateEffect(rogueExplosion, position, layer);
|
|
if (effect == null)
|
|
return;
|
|
|
|
SetColorGradient(effect.main, colorMin, colorMax);
|
|
}
|
|
|
|
public virtual void CreateBlobExplosion(Vector3 position, Layers layer)
|
|
{
|
|
InstantiateEffect(blobExplosion, position, layer);
|
|
}
|
|
|
|
public virtual void CreateTeleportSplash(Vector3 position, Layers layer)
|
|
{
|
|
InstantiateEffect(teleportSplash, position, layer);
|
|
}
|
|
|
|
public virtual void CreateLavaSplash(Vector3 position, Layers layer)
|
|
{
|
|
InstantiateEffect(lavaSplash, position, layer);
|
|
}
|
|
|
|
protected virtual ParticleSystem InstantiateEffect(ParticleSystem template, Vector3 position, Layers layer)
|
|
{
|
|
if (template == null)
|
|
return null;
|
|
|
|
var effect = Object.Instantiate(template);
|
|
SetLayer(effect.gameObject, layer);
|
|
effect.transform.position = position;
|
|
return effect;
|
|
}
|
|
|
|
protected static void SetLayer(GameObject go, Layers layer)
|
|
{
|
|
go.layer = (int)layer;
|
|
|
|
int childCount = go.transform.childCount;
|
|
for (int i = 0; i < childCount; ++i)
|
|
{
|
|
go.transform.GetChild(i).gameObject.layer = (int)layer;
|
|
}
|
|
}
|
|
|
|
protected static void SetColorGradient(ParticleSystem.MainModule main, Color colorMin, Color colorMax)
|
|
{
|
|
var startColor = main.startColor;
|
|
startColor.gradient.colorKeys = new[]
|
|
{
|
|
new GradientColorKey(colorMin, 0f),
|
|
new GradientColorKey(colorMax, 1f),
|
|
};
|
|
main.startColor = startColor;
|
|
}
|
|
}
|