using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace Light2D { /// /// Automatically updating mesh, material and main texture of light obstacle. /// Class is copying all data used for rendering from parent. /// 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(); _parentMeshFilter = transform.parent.GetComponent(); _meshRenderer = GetComponent(); if (_meshRenderer == null) _meshRenderer = gameObject.AddComponent(); _meshFilter = GetComponent(); if (_meshFilter == null) _meshFilter = gameObject.AddComponent(); } 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; } } } }