summaryrefslogtreecommitdiff
path: root/Runtime/Graphs/UnityEngine.Graphs/LogicNodeLibrary/Material/MaterialNodes.cs
blob: 734968b605e49e2c22b2d101080e358bc91a4768 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
using UnityEngine;
using System.Collections;

namespace UnityEngine.Graphs.LogicGraph
{
	public class MaterialNodes
	{
		#if REIMPLEMENT_USING_CLASS_NODES
		[Logic(typeof(Renderer), typeof(NodeLibrary.StartStopEvents))]
		public static IEnumerator UVScroll (Renderer self, ByRef<NodeLibrary.StartStopEvents> evt, string property, Vector2 magnitude, float frequency, int mode)
		{
			Material mat = self.material;
			if (property == null || property == "")
				property = "_MainTex";
			
			if (mode == 0)
			{
				while (true)
				{
					// scroll uv
					Vector2 uv = mat.GetTextureOffset(property);
					uv += magnitude * Time.deltaTime;
					mat.SetTextureOffset(property, uv);
					
					// Handle Stop event
					if (evt.Value == NodeLibrary.StartStopEvents.Stop)
						break;
					yield return 0;
				}
			}
			else
			{
				// Elapsed time, measured in cycles.
				float elapsed = 0;
				
				Vector2 lastUV = mat.GetTextureOffset(property);
				
				float stopElapsed = 0f;
				bool exit = false;
				
				while (true)
				{
					// Handle Stop event
					if (evt.Value == NodeLibrary.StartStopEvents.Stop)
					{
						// When stopping, complete the current cycle before really stopping
						// Update: Actually we only need to complete the current half-cycle
						// because the cycle always has the same value in the middle as in the beginning and end.
						if (stopElapsed == 0)
							stopElapsed = Mathf.Ceil(elapsed * 2) * 0.5f;
						
						// When we reach the end of the cycle, stop at the exact time
						else if (elapsed >= stopElapsed)
						{
							elapsed = stopElapsed;
							exit = true;
						}
					}
					
					Vector2 uv = Vector2.zero;
					// Triangle wave (centered around 0)
					if (mode == 1)
						uv += magnitude * (Mathf.PingPong(elapsed * 2f + 0.5f, 1) - 0.5f);
					// Sine wave (centered around 0)
					if (mode == 2)
						uv += magnitude * 0.5f * Mathf.Sin(elapsed * 2f * Mathf.PI);
					
					mat.SetTextureOffset(property, mat.GetTextureOffset(property) + (uv - lastUV));
					lastUV = uv;
					
					if (exit)
						break;
					
					elapsed += Time.deltaTime * frequency;
					
					yield return 0;
				}
			}
			
		}
		
		[Logic(typeof(Renderer), typeof(NodeLibrary.StartStopEvents))]
		public static IEnumerator UVCycler (Renderer self, ByRef<NodeLibrary.StartStopEvents> evt, string property, int xTiles, int yTiles, float speed)
		{
			Material mat = self.material;
			if (property == null || property == "")
				property = "_MainTex";
			
			// TODO: find out what initial frame is based on uv offset in the beginning?
			
			float elapsed = 0;
			while (true)
			{
				int frame = Mathf.FloorToInt(elapsed);
				
				float xOffset = frame % xTiles;
				float yOffset = yTiles - 1 - (frame / xTiles) % yTiles;
				
				Vector2 uv = new Vector2(xOffset / xTiles, yOffset / yTiles);
				mat.SetTextureOffset(property, uv);
				
				// Handle Stop event
				if (evt.Value == NodeLibrary.StartStopEvents.Stop)
					break;
				
				elapsed += Time.deltaTime * speed;
				
				yield return 0;
			}
		}
		#endif
	}
}