当前位置:   article > 正文

Unity--刮卡效果并附带百分比判断功能_rendertexture getpixel

rendertexture getpixel

先上成品效果

功能介绍:

1.笔刷形状(在预制体里面可以更改)

2.笔刷压力

3.百分判断

 进度1代表区域1 1代表100%   进度2代表区域2,依次类推!

shader代码如下:

  1. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
  2. Shader "Custom/MaskShader" {
  3. Properties{
  4. _Color("Color", Color) = (1,1,1,1)
  5. //_MainTex ("Albedo (RGB)", 2D) = "white" {}
  6. _MainTex("Mask Texture",2D) = "white"{}
  7. _Mask("Mask",2D) = "white"{}
  8. }
  9. SubShader{
  10. Tags{"RenderType" = "Transparent" "Queue" = "Transparent"}
  11. pass
  12. {
  13. Blend SrcAlpha OneMinusSrcAlpha
  14. CGPROGRAM
  15. #pragma vertex vert
  16. #pragma fragment frag
  17. #include "unitycg.cginc"
  18. struct v2f
  19. {
  20. float4 pos:POSITION;
  21. float2 uv:TEXCOORD1;
  22. };
  23. //sampler2D _MainTex;
  24. sampler2D _MainTex;
  25. sampler2D _Mask;
  26. v2f vert(appdata_base v)
  27. {
  28. v2f o;
  29. o.pos = UnityObjectToClipPos(v.vertex);
  30. o.uv = v.texcoord;
  31. return o;
  32. }
  33. float4 frag(v2f i) :COLOR
  34. {
  35. float4 maskTexColor = tex2D(_MainTex,i.uv);
  36. float4 maskColor = tex2D(_Mask,i.uv);
  37. maskTexColor.a = 1 - maskColor.a;
  38. return maskTexColor;
  39. }
  40. ENDCG
  41. }
  42. }
  43. FallBack "Diffuse"
  44. SubShader
  45. {
  46. LOD 100
  47. Tags
  48. {
  49. "Queue" = "Transparent"
  50. "IgnoreProjector" = "True"
  51. "RenderType" = "Transparent"
  52. }
  53. Pass
  54. {
  55. Cull Off
  56. Lighting Off
  57. ZWrite Off
  58. Fog { Mode Off }
  59. ColorMask RGB
  60. Blend SrcAlpha OneMinusSrcAlpha
  61. ColorMaterial AmbientAndDiffuse
  62. SetTexture[_MainTex]
  63. {
  64. Combine Texture * Primary
  65. }
  66. }
  67. }
  68. }

C#代码:

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using UnityEngine.UI;
  6. public class DrawMask : MonoBehaviour
  7. {
  8. public float radius = 0.5f;
  9. public GameObject brush;
  10. bool startDraw = false;
  11. bool twoPoints = false;
  12. Vector2 lastPos;
  13. Vector2 penultPos;
  14. List<GameObject> brushesPool = new List<GameObject>(), activeBrushes = new List<GameObject>();
  15. public Rect[] rect;
  16. float total1;
  17. float total2;
  18. float total3;
  19. float total4;
  20. float precess1;
  21. float precess2;
  22. float precess3;
  23. float precess4;
  24. Texture2D t2d;
  25. void Start()
  26. {
  27. for (int i = 0; i < Camera.allCameras.Length; i++)
  28. {
  29. if (Camera.allCameras[i].name == "Post-Camera")
  30. {
  31. RenderTexture rt = Camera.allCameras[i].targetTexture;
  32. t2d = this.RenderTexture2Texture2D(rt);
  33. this.total1 = (Convert.ToInt32(t2d.width / 10) * Convert.ToInt32(t2d.height / 10)) / 4;
  34. this.total4 = this.total3 = this.total2 = this.total1;
  35. }
  36. }
  37. Debug.Log("数组长度:" + Convert.ToInt32(t2d.width / 10) * Convert.ToInt32(t2d.height / 10));
  38. }
  39. // Update is called once per frame
  40. void Update()
  41. {
  42. GetInput();
  43. }
  44. void GetInput()
  45. {
  46. if (Input.GetMouseButtonDown(0))
  47. {
  48. startDraw = true;
  49. penultPos = Input.mousePosition;
  50. }
  51. else if (Input.GetMouseButton(0))
  52. {
  53. if (twoPoints && Vector2.Distance(Input.mousePosition, lastPos) > 0.5f)
  54. {
  55. Vector2 pos = Input.mousePosition;
  56. float dis = Vector2.Distance(lastPos, pos);
  57. int segments = (int)(dis / radius);
  58. segments = segments < 1 ? 1 : segments;
  59. Vector2[] points = GetPoint(penultPos, lastPos, pos, segments);
  60. for (int i = 0; i < points.Length; i++) InstanceBrush(ScreenToWorldPoint(points[i]));
  61. lastPos = pos;
  62. penultPos = points[points.Length - 2];
  63. precess4 = precess3 = precess2 = precess1 = 0;
  64. for (int i = 0; i < Camera.allCameras.Length; i++)
  65. {
  66. if (Camera.allCameras[i].name == "Post-Camera")
  67. {
  68. RenderTexture rt = Camera.allCameras[i].targetTexture;
  69. t2d = this.RenderTexture2Texture2D(rt);
  70. for (int x = 0; x < this.t2d.width; x += 10)
  71. {
  72. for (int y = 0; y < this.t2d.height; y += 10)
  73. {
  74. if (this.t2d.GetPixel(x, y).a > 0.1)
  75. {
  76. for (int ii = 0; ii < this.rect.Length; ii++)
  77. {
  78. if (this.rect[ii].Contains(new Vector2(x, y)))
  79. {
  80. if (ii == 0) this.precess1++;
  81. else if (ii == 1) this.precess2++;
  82. else if (ii == 2) this.precess3++;
  83. else if (ii == 3) this.precess4++;
  84. }
  85. }
  86. }
  87. }
  88. }
  89. //Debug.Log("鼠标位置:" + Input.mousePosition);
  90. Debug.Log("当前进度1:" + (this.precess1 / this.total1) + " 进度2:" + (this.precess2 / this.total2) + " " +
  91. " 进度3:" + (this.precess3 / this.total3) + " 进度4:" + (this.precess4 / this.total4));
  92. }
  93. }
  94. }
  95. else
  96. {
  97. twoPoints = true;
  98. lastPos = Input.mousePosition;
  99. }
  100. }
  101. else if (Input.GetMouseButtonUp(0))
  102. {
  103. startDraw = false;
  104. twoPoints = false;
  105. }
  106. }
  107. private void OnPostRender()
  108. {
  109. InitBrushes();
  110. }
  111. void InitBrushes()
  112. {
  113. for (int i = 0; i < activeBrushes.Count; i++)
  114. {
  115. activeBrushes[i].SetActive(false);
  116. brushesPool.Add(activeBrushes[i]);
  117. }
  118. activeBrushes.Clear();
  119. }
  120. void InstanceBrush(Vector2 pos)
  121. {
  122. GameObject brushClone;
  123. if (brushesPool.Count > 0)
  124. {
  125. brushClone = brushesPool[brushesPool.Count - 1];
  126. brushesPool.RemoveAt(brushesPool.Count - 1);
  127. }
  128. else brushClone = Instantiate(brush, pos, Quaternion.identity);
  129. brushClone.transform.position = pos;
  130. brushClone.transform.localScale = Vector3.one * radius;
  131. brushClone.SetActive(true);
  132. activeBrushes.Add(brushClone);
  133. }
  134. public Vector2[] GetPoint(Vector2 start, Vector2 mid, Vector2 end, int segments)
  135. {
  136. float d = 1f / segments;
  137. Vector2[] points = new Vector2[segments - 1];
  138. for (int i = 0; i < points.Length; i++)
  139. {
  140. float t = d * (i + 1);
  141. points[i] = (1 - t) * (1 - t) * mid + 2 * t * (1 - t) * start + t * t * end;
  142. }
  143. List<Vector2> rps = new List<Vector2>();
  144. rps.Add(mid);
  145. rps.AddRange(points);
  146. rps.Add(end);
  147. return rps.ToArray();
  148. }
  149. Vector2 ScreenToWorldPoint(Vector2 point)
  150. {
  151. return Camera.allCameras[0].ScreenToWorldPoint(new Vector3(point.x, point.y, 0));
  152. }
  153. public Texture2D RenderTexture2Texture2D(RenderTexture rt)
  154. {
  155. RenderTexture preRT = RenderTexture.active;
  156. RenderTexture.active = rt;
  157. Texture2D tex = null;
  158. if (!this.t2d)
  159. tex = new Texture2D(rt.width, rt.height, TextureFormat.ARGB32, false);
  160. else
  161. tex = this.t2d;
  162. tex.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
  163. tex.Apply();
  164. RenderTexture.active = preRT;
  165. return tex;
  166. }
  167. }

如果笔刷出现不连续情况,调整下面这个值可以解决.

 如果有不明白可以下载下来包自己学习(工程使用Unity2020.3.9f1版本)

https://download.csdn.net/download/haseef520s/22070358

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/111753
推荐阅读
相关标签
  

闽ICP备14008679号