DecalObject.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. #if UNITY_EDITOR
  5. public class DecalObject : MonoBehaviour
  6. {
  7. [SerializeField] private SpriteRenderer decalRenderer;
  8. [SerializeField] private Paper _paper;
  9. [SerializeField] private Texture2D paperTexture;
  10. private MeshRenderer targetObjectRenderer;
  11. private Texture2D newTargetObjectTexture;
  12. private void OnValidate()
  13. {
  14. if (_paper == null)
  15. _paper = GetComponentInChildren<Paper>(true);
  16. }
  17. private void Start()
  18. {
  19. _paper.GetFrontRenderer().material.mainTexture = paperTexture;
  20. }
  21. public IEnumerator Project()
  22. {
  23. targetObjectRenderer = _paper.GetFrontRenderer();
  24. Texture2D decalTexture = decalRenderer.sprite.texture;
  25. newTargetObjectTexture = new Texture2D(targetObjectRenderer.material.mainTexture.width, targetObjectRenderer.material.mainTexture.height, TextureFormat.RGBA32, false);
  26. Graphics.CopyTexture(targetObjectRenderer.material.mainTexture, newTargetObjectTexture);
  27. targetObjectRenderer.material.mainTexture = newTargetObjectTexture;
  28. int width = decalTexture.width;
  29. int height = decalTexture.height;
  30. var pixels = decalTexture.GetPixels32();
  31. for (int x = 0; x < width; x++)
  32. {
  33. for (int y = 0; y < height; y++)
  34. {
  35. if (decalTexture.GetPixel(x, y).a <= 0.1f)
  36. {
  37. continue;
  38. }
  39. ProjectPixel(x, y, decalTexture);
  40. }
  41. Debug.Log("Pixel printed");
  42. yield return null;
  43. }
  44. newTargetObjectTexture.Apply();
  45. SaveTexture();
  46. yield return new WaitForSeconds(10f);
  47. yield return null;
  48. yield break;
  49. }
  50. private void ProjectPixel(int x, int y, Texture2D decalTexture)
  51. {
  52. RaycastHit hit;
  53. Vector3 rayOrigin = GetRayOrigin(x, y, decalTexture);
  54. Vector3 rayDirection = decalRenderer.transform.forward;
  55. Ray ray = new Ray(rayOrigin, rayDirection);
  56. if (!Physics.Raycast(ray, out hit))
  57. return;
  58. Renderer rend = hit.transform.GetComponent<Renderer>();
  59. MeshCollider meshCollider = hit.collider as MeshCollider;
  60. if (rend == null || rend.sharedMaterial == null || rend.sharedMaterial.mainTexture == null || meshCollider == null)
  61. return;
  62. if (rend != targetObjectRenderer)
  63. return;
  64. Texture2D tex = rend.material.mainTexture as Texture2D;
  65. Vector2 pixelUV = hit.textureCoord;
  66. pixelUV.x *= tex.width;
  67. pixelUV.y *= tex.height;
  68. tex.SetPixel((int)pixelUV.x, (int)pixelUV.y, decalTexture.GetPixel(x, y));
  69. tex.Apply();
  70. }
  71. private Vector3 GetRayOrigin(int x, int y, Texture2D decalTexture)
  72. {
  73. float rightPercent = (float)x / decalTexture.width;
  74. float upPercent = (float)y / decalTexture.height;
  75. Vector3 startPosition = decalRenderer.transform.position;
  76. startPosition += decalRenderer.transform.right * (rightPercent - 0.5f) * decalRenderer.transform.localScale.x;
  77. startPosition += decalRenderer.transform.up * (upPercent - 0.5f) * decalRenderer.transform.localScale.y;
  78. return startPosition;
  79. }
  80. private void SaveTexture()
  81. {
  82. JTSystems.Utils.SaveTexture(newTargetObjectTexture, "/DecalToTexture/Created Textures2/");
  83. }
  84. }
  85. public struct Pixel
  86. {
  87. public int x;
  88. public int y;
  89. }
  90. #endif