summaryrefslogtreecommitdiff
path: root/Assets/MaterializeFX/MaterializationFX/Scripts/MfxController.cs
blob: bcdbe868d60cbabb51204074cfd2dd20a4ba112c (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
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
using System;
using UnityEngine;

namespace MaterializationFX.Scripts
{
    internal sealed class MfxController : MonoBehaviour
    {
        private const string PositionPropertyName = "_Position";
        private const string DirectionPropertyName = "_Direction";
        private const string PositionTypePropertyName = "_PositionType";

        public MfxType MfxShaderType;
        public MfxDirection MfxDirection;
        public PositionType PositionType;
        public AnimationCurve Position;
        public AnimationCurve PositionX;
        public AnimationCurve PositionY;
        public AnimationCurve PositionZ;
        public float ScaleTime = 1;
        public float ScalePosition = 1;
        public bool MofidyChildren;

        public GameObject TargetObject;
        public bool ByDistance;
        public Vector3 WorldPositionOffset;

        private float _startTime;
        private bool _isEnabled;
        private string _shaderName;
        private ShaderParameterSetter _shaderParameterSetter;

        private void Start()
        {
            var shaderName = MfxShaderType.GetFullShaderName();

            GameObject go;

            if (TargetObject != null && ByDistance)
                go = gameObject;
            else if (TargetObject != null)
                go = TargetObject;
            else
                go = gameObject;
            
            _shaderParameterSetter = new ShaderParameterSetter();
            _shaderParameterSetter.Init(go, shaderName, modifyChildren: MofidyChildren);

            var dissolveDirection = MfxDirection.ToVector3();
            _shaderParameterSetter.SetVector(DirectionPropertyName, dissolveDirection);
            _shaderParameterSetter.SetInt(PositionTypePropertyName, (int) PositionType);

            _startTime = Time.time;
        }

        private void Update()
        {
            if (!_isEnabled)
                return;

            if (TargetObject != null)
            {
                Vector3 worldPos;

                if (ByDistance)
                    worldPos = TargetObject.transform.position - transform.position + WorldPositionOffset;
                else
                    worldPos = transform.position + WorldPositionOffset;

                _shaderParameterSetter.SetVector(DirectionPropertyName, worldPos);

                return;
            }

            var time = Time.time - _startTime;
            
            switch (PositionType)
            {
                case PositionType.Local:
                    var position = Position.Evaluate(time / ScaleTime) * ScalePosition;
                    _shaderParameterSetter.SetFloat(PositionPropertyName, position);
                    break;
                case PositionType.World:
                    var posX = transform.position.x + PositionX.Evaluate(time / ScaleTime) * ScalePosition;
                    var posY = transform.position.y + PositionY.Evaluate(time / ScaleTime) * ScalePosition;
                    var posZ = transform.position.z + PositionZ.Evaluate(time / ScaleTime) * ScalePosition;
                    var vector3 = new Vector3(posX, posY, posZ);
                    _shaderParameterSetter.SetVector(DirectionPropertyName, vector3 + WorldPositionOffset);
                    break;
            }
        }

        private void OnEnable()
        {
            _isEnabled = true;
        }

        private void OnDisable()
        {
            _isEnabled = false;
        }
    }

    internal enum MfxType
    {
        SingleAlbedo,
        TwoAlbedo,
    }

    internal enum MfxDirection
    {
        None,
        Normal,
        XAxys,
        YAxis,
        ZAxis
    }

    internal enum PositionType
    {
        Local,
        World
    }

    internal static class MfxControllerExtensions
    {
        public static string GetFullShaderName(this MfxType mfxType)
        {
            switch (mfxType)
            {
                case MfxType.SingleAlbedo:
                    return "QFX/MFX/MfxSingleAlbedo";
                case MfxType.TwoAlbedo:
                    return "QFX/MFX/MfxTwoAlbedo";
                default:
                    throw new ArgumentOutOfRangeException("mfxType", mfxType, null);
            }
        }

        public static Vector3 ToVector3(this MfxDirection mfxDirection)
        {
            switch (mfxDirection)
            {
                case MfxDirection.None:
                case MfxDirection.Normal:
                    return new Vector3(0, 0, 0);
                case MfxDirection.XAxys:
                    return new Vector3(1, 0, 0);
                case MfxDirection.YAxis:
                    return new Vector3(0, 1, 0);
                case MfxDirection.ZAxis:
                    return new Vector3(0, 0, 1);
                default:
                    return Vector3.zero;
            }
        }
    }
}