BFX_DecalSettings.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. 
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using UnityEngine;
  6. public class BFX_DecalSettings : MonoBehaviour
  7. {
  8. public BFX_BloodSettings BloodSettings;
  9. public Transform parent;
  10. public float TimeHeightMax = 3.1f;
  11. public float TimeHeightMin = -0.1f;
  12. [Space]
  13. public Vector3 TimeScaleMax = Vector3.one;
  14. public Vector3 TimeScaleMin = Vector3.one;
  15. [Space]
  16. public Vector3 TimeOffsetMax = Vector3.zero;
  17. public Vector3 TimeOffsetMin = Vector3.zero;
  18. [Space]
  19. public AnimationCurve TimeByHeight = AnimationCurve.Linear(0, 0, 1, 1);
  20. private Vector3 startOffset;
  21. private Vector3 startScale;
  22. private float timeDelay;
  23. Transform t, tParent;
  24. BFX_ShaderProperies shaderProperies;
  25. Vector3 averageRay;
  26. bool isPositionInitialized;
  27. private Vector3 initializedPosition;
  28. private void Awake()
  29. {
  30. startOffset = transform.localPosition;
  31. startScale = transform.localScale;
  32. t = transform;
  33. tParent = parent.transform;
  34. shaderProperies = GetComponent<BFX_ShaderProperies>();
  35. shaderProperies.OnAnimationFinished += ShaderCurve_OnAnimationFinished;
  36. }
  37. private void ShaderCurve_OnAnimationFinished()
  38. {
  39. GetComponent<Renderer>().enabled = false;
  40. }
  41. private void Update()
  42. {
  43. if (!isPositionInitialized) InitializePosition();
  44. if (shaderProperies.enabled && initializedPosition.x < float.PositiveInfinity) transform.position = initializedPosition;
  45. }
  46. void InitializePosition()
  47. {
  48. GetComponent<Renderer>().enabled = false;
  49. var currentHeight = parent.position.y;
  50. var ground = BloodSettings.GroundHeight;
  51. var currentScale = parent.localScale.y;
  52. var scaledTimeHeightMax = TimeHeightMax * currentScale;
  53. var scaledTimeHeightMin = TimeHeightMin * currentScale;
  54. if (currentHeight - ground >= scaledTimeHeightMax || currentHeight - ground <= scaledTimeHeightMin)
  55. {
  56. GetComponent<MeshRenderer>().enabled = false;
  57. }
  58. else
  59. {
  60. GetComponent<MeshRenderer>().enabled = true;
  61. }
  62. float diff = (tParent.position.y - ground) / scaledTimeHeightMax;
  63. diff = Mathf.Abs(diff);
  64. var scaleMul = Vector3.Lerp(TimeScaleMin, TimeScaleMax, diff);
  65. t.localScale = new Vector3(scaleMul.x * startScale.x, startScale.y, scaleMul.z * startScale.z);
  66. var lastOffset = Vector3.Lerp(TimeOffsetMin, TimeOffsetMax, diff);
  67. t.localPosition = startOffset + lastOffset;
  68. t.position = new Vector3(t.position.x, ground + 0.05f, t.position.z);
  69. timeDelay = TimeByHeight.Evaluate(diff);
  70. shaderProperies.enabled = false;
  71. Invoke("EnableDecalAnimation", Mathf.Max(0, timeDelay / BloodSettings.AnimationSpeed));
  72. if (BloodSettings.DecalRenderinMode == BFX_BloodSettings._DecalRenderinMode.AverageRayBetwenForwardAndFloor)
  73. {
  74. averageRay = GetAverageRay(tParent.position + tParent.right * 0.05f, tParent.right);
  75. float decalAngle = Vector3.Angle(Vector3.up, averageRay);
  76. var zRotation = Mathf.Clamp(decalAngle, -90, 90);
  77. var decalRotation = t.localRotation.eulerAngles;
  78. t.localRotation = Quaternion.Euler(decalRotation.x, decalRotation.y, -(zRotation) * 0.5f);
  79. var scaleRelativeToAngle = Mathf.Abs(zRotation) / 90f;
  80. var decalScale = t.localScale;
  81. decalScale.y = Mathf.Lerp(decalScale.y, decalScale.x * 1.5f, scaleRelativeToAngle);
  82. t.localScale = decalScale;
  83. }
  84. if (BloodSettings.ClampDecalSideSurface) Shader.EnableKeyword("CLAMP_SIDE_SURFACE");
  85. isPositionInitialized = true;
  86. }
  87. private void OnDisable()
  88. {
  89. if (BloodSettings.ClampDecalSideSurface) Shader.DisableKeyword("CLAMP_SIDE_SURFACE");
  90. isPositionInitialized = false;
  91. initializedPosition = Vector3.positiveInfinity;
  92. }
  93. Vector3 GetAverageRay(Vector3 start, Vector3 forward)
  94. {
  95. if (Physics.Raycast(start, -forward, out RaycastHit bulletRay))
  96. {
  97. return (bulletRay.normal + Vector3.up).normalized;
  98. }
  99. return Vector3.up;
  100. }
  101. void EnableDecalAnimation()
  102. {
  103. shaderProperies.enabled = true;
  104. initializedPosition = transform.position;
  105. }
  106. private void OnDrawGizmos()
  107. {
  108. if (t == null) t = transform;
  109. Gizmos.color = new Color(49 / 255.0f, 136 / 255.0f, 1, 0.03f);
  110. Gizmos.matrix = Matrix4x4.TRS(t.position, t.rotation, t.lossyScale);
  111. Gizmos.DrawCube(Vector3.zero, Vector3.one);
  112. Gizmos.color = new Color(49 / 255.0f, 136 / 255.0f, 1, 0.85f);
  113. Gizmos.DrawWireCube(Vector3.zero, Vector3.one);
  114. }
  115. }