-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAliveAction.cs
162 lines (134 loc) · 6.09 KB
/
AliveAction.cs
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
using System.Collections.Generic;
using UnityEngine;
namespace Unity.LEGO.Behaviours.Actions
{
public class AliveAction : Action
{
public enum Type
{
Creature,
Robot
}
[SerializeField, Tooltip("Move like a creature.\nor\nMove like a robot.")]
protected Type m_Type;
enum State
{
WaitingToMove,
Moving
}
State m_State;
float m_CurrentTime;
AliveMovement m_CurrentMovement;
float m_Pause;
Vector3 m_Offset;
Vector3 m_RotationOffset;
Vector3 m_Pivot;
List<AliveMovement> m_Movements = new List<AliveMovement> { new Breathe(), new Jump(), new Look(), new Shake(), new Wobble() };
const float k_MaxPauseTime = 1.0f;
List<Shader> m_OriginalShaders = new List<Shader>();
List<Material> m_Materials = new List<Material>();
static readonly int s_DeformMatrix1ID = Shader.PropertyToID("_DeformMatrix1");
static readonly int s_DeformMatrix2ID = Shader.PropertyToID("_DeformMatrix2");
static readonly int s_DeformMatrix3ID = Shader.PropertyToID("_DeformMatrix3");
protected override void Reset()
{
base.Reset();
m_IconPath = "Assets/LEGO/Gizmos/LEGO Behaviour Icons/Alive Action.png";
}
protected override void Start()
{
base.Start();
if (IsPlacedOnBrick())
{
// Change the shader of all scoped part renderers if not already changed.
foreach(var partRenderer in m_ScopedPartRenderers)
{
if (partRenderer.sharedMaterial.shader.name != "Deformed")
{
m_OriginalShaders.Add(partRenderer.sharedMaterial.shader);
// The renderQueue value is reset when changing the shader, so transfer it.
var renderQueue = partRenderer.material.renderQueue;
partRenderer.material.shader = Shader.Find("Deformed");
partRenderer.material.renderQueue = renderQueue;
}
m_Materials.Add(partRenderer.material);
}
m_Pivot = transform.InverseTransformVector(new Vector3(m_ScopedBounds.center.x, m_ScopedBounds.min.y, m_ScopedBounds.center.z) - transform.position);
m_Pause = Random.Range(0.0f, k_MaxPauseTime);
}
}
protected void Update()
{
if (m_Active)
{
// Update time.
m_CurrentTime += Time.deltaTime;
// Move.
if (m_State == State.Moving)
{
m_CurrentMovement.UpdateMovement(m_CurrentTime);
// Move and rotate bricks.
var offsetDelta = m_CurrentMovement.GetOffset() - m_Offset;
var rotationDelta = m_CurrentMovement.GetRotation() - m_RotationOffset;
var worldPivot = transform.position + transform.TransformVector(m_Pivot);
foreach (var brick in m_ScopedBricks)
{
brick.transform.RotateAround(worldPivot, rotationDelta, rotationDelta.magnitude);
brick.transform.position += offsetDelta;
}
m_Offset += offsetDelta;
m_RotationOffset += rotationDelta;
var deformMatrix = Matrix4x4.Translate(worldPivot) * Matrix4x4.Scale(m_CurrentMovement.GetScale()) * Matrix4x4.Translate(-worldPivot);
foreach (var material in m_Materials)
{
material.SetVector(s_DeformMatrix1ID, deformMatrix.GetRow(0));
material.SetVector(s_DeformMatrix2ID, deformMatrix.GetRow(1));
material.SetVector(s_DeformMatrix3ID, deformMatrix.GetRow(2));
}
if (m_CurrentTime >= m_CurrentMovement.Time)
{
m_CurrentTime -= m_CurrentMovement.Time;
m_Pause = Random.Range(0.0f, k_MaxPauseTime);
m_State = State.WaitingToMove;
}
}
// Waiting to move.
if (m_State == State.WaitingToMove)
{
if (m_CurrentTime >= m_Pause)
{
m_CurrentTime -= m_Pause;
m_CurrentMovement = m_Movements[Random.Range(0, m_Movements.Count)];
m_CurrentMovement.Initialise(m_ScopedBounds, m_Type);
if (m_CurrentMovement.GetType() != typeof(Breathe) && m_CurrentMovement.GetType() != typeof(Shake))
{
PlayAudio();
}
m_State = State.Moving;
}
}
}
}
protected override void OnDestroy()
{
base.OnDestroy();
// Check if the original materials have been stored for all scoped part renderers.
if (m_ScopedPartRenderers.Count > m_OriginalShaders.Count)
{
return;
}
// Change the material back to original for all scoped part renderers.
for (var i = 0; i < m_ScopedPartRenderers.Count; ++i)
{
if (m_ScopedPartRenderers[i])
{
var partRenderer = m_ScopedPartRenderers[i];
// The renderQueue value is reset when changing the shader, so transfer it.
var renderQueue = partRenderer.material.renderQueue;
partRenderer.material.shader = m_OriginalShaders[i];
partRenderer.material.renderQueue = renderQueue;
}
}
}
}
}