2D-Platformer/Assets/Plugins/Light2D/Scripts/LightObstacleMesh.cs
2022-02-12 12:53:50 +02:00

114 lines
4.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Light2D
{
/// <summary>
/// Automatically updating mesh, material and main texture of light obstacle.
/// Class is copying all data used for rendering from parent.
/// </summary>
public class LightObstacleMesh : MonoBehaviour
{
public Color32 MultiplicativeColor;
public Color AdditiveColor;
public Material Material;
private MeshRenderer _parentMeshRenderer;
private MeshFilter _parentMeshFilter;
private MeshRenderer _meshRenderer;
private MeshFilter _meshFilter;
private Mesh _oldParentMesh;
private Color32 _oldMulColor;
private Color _oldAddColor;
private Material _oldMaterial;
private CustomSprite.MaterialKey _materialKey;
void Awake()
{
_parentMeshRenderer = transform.parent.GetComponent<MeshRenderer>();
_parentMeshFilter = transform.parent.GetComponent<MeshFilter>();
_meshRenderer = GetComponent<MeshRenderer>();
if (_meshRenderer == null) _meshRenderer = gameObject.AddComponent<MeshRenderer>();
_meshFilter = GetComponent<MeshFilter>();
if (_meshFilter == null) _meshFilter = gameObject.AddComponent<MeshFilter>();
}
void Update()
{
Refresh();
}
void Refresh()
{
if (_parentMeshFilter == null || _parentMeshFilter == null || _meshRenderer == null || _meshFilter == null ||
_parentMeshFilter.sharedMesh == null || _parentMeshRenderer.sharedMaterial == null)
{
if (_meshRenderer != null)
_meshRenderer.enabled = false;
return;
}
bool dirty = false;
if (_parentMeshFilter.mesh != _oldParentMesh)
{
if (_meshFilter.mesh != null)
Destroy(_meshFilter.mesh);
_meshFilter.mesh = (Mesh) Instantiate(_parentMeshFilter.sharedMesh);
_meshFilter.mesh.MarkDynamic();
if (_meshFilter.mesh.tangents == null)
{
var tangents = new Vector4[_meshFilter.mesh.vertexCount];
for (int i = 0; i < tangents.Length; i++)
tangents[i] = new Vector4(1, 0);
_meshFilter.mesh.tangents = tangents;
}
_oldParentMesh = _parentMeshFilter.sharedMesh;
dirty = true;
}
if (_oldMaterial != _parentMeshRenderer.sharedMaterial ||
(_oldMaterial != null && _parentMeshRenderer.sharedMaterial != null &&
_oldMaterial.mainTexture != _parentMeshRenderer.sharedMaterial.mainTexture))
{
if (_meshRenderer.sharedMaterial != null && _materialKey != null)
{
CustomSprite.ReleaseMaterial(_materialKey);
}
var baseMat = Material == null ? _parentMeshRenderer.sharedMaterial : Material;
var tex = _parentMeshRenderer.sharedMaterial.mainTexture as Texture2D;
_meshRenderer.sharedMaterial = CustomSprite.GetOrCreateMaterial(baseMat, tex, out _materialKey);
_oldMaterial = _parentMeshRenderer.sharedMaterial;
}
if (!MultiplicativeColor.Equals(_oldMulColor) || AdditiveColor != _oldAddColor || dirty)
{
var colors = _meshFilter.mesh.colors32;
if (colors == null || colors.Length != _meshFilter.mesh.vertexCount)
colors = new Color32[_meshFilter.mesh.vertexCount];
for (int i = 0; i < colors.Length; i++)
colors[i] = MultiplicativeColor;
_meshFilter.mesh.colors32 = colors;
var uv1 = new Vector2(
Util.DecodeFloatRGBA((Vector4) AdditiveColor),
Util.DecodeFloatRGBA(new Vector4(AdditiveColor.a, 0, 0)));
var uv1Arr = _meshFilter.mesh.uv2;
if (uv1Arr == null || uv1Arr.Length != colors.Length)
uv1Arr = new Vector2[colors.Length];
for (int i = 0; i < uv1Arr.Length; i++)
{
uv1Arr[i] = uv1;
}
_meshFilter.mesh.uv2 = uv1Arr;
_oldMulColor = MultiplicativeColor;
_oldAddColor = AdditiveColor;
}
}
}
}