summaryrefslogtreecommitdiff
path: root/Assets/Scripts/Effects/FxClear.cs
blob: 1edf2b97727a6cd40f049e77249cf5f4dce6118d (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
158
159
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
using System.Collections.Generic;

public enum EffectPlayTypes
{
    None = 0,
    Oneshot,
    Loop,
}

public static class TransformEx
{

    public static void DoRecursively(this Transform root, System.Action<Transform> action, bool containMe = true)
    {
        if (containMe)
            action(root);
        foreach (Transform child in root)
            child.DoRecursively(action);
    }

}

public struct PlayEffectInfo
{
    public string path { get; set; }
    public Transform rootTr { get; set; }
    public bool bAttached { get; set; }
    public Vector3 posOffset { get; set; }
    public Vector3 rot { get; set; }
    public Vector3 scale { get; set; }
    public EffectPlayTypes playEffectType { get; set; }
}

public class FxClear : MonoBehaviour
{
    [SerializeField]
    public float ClearTime = 2f;

    private EffectPlayTypes m_EffectPlayType = EffectPlayTypes.None;

    private Transform m_Root = null; //根节点,可以是角色或者某个骨骼,如果是空,代表是世界空间
    private bool m_Attached = false; // 跟随根节点运动

    private Vector3 m_Offset = Vector3.zero;
    private Vector3 m_Rotation = Vector3.zero;
    private Vector3 m_Scale = Vector3.one;

    private Quaternion m_RootRot = Quaternion.identity;
    private Vector3 m_RootPos = Vector3.zero;

#if UNITY_EDITOR
    private double m_PrevTime = 0.0f;
    private float m_RemoveWaitTime = 0.0f;
    private bool m_DestroyRequested = false;
#endif

    private float m_CurTime = 0.0f;
    public float time { get { return m_CurTime; } }

    private void Awake()
    {
        if (ClearTime <= float.Epsilon)
            m_EffectPlayType = EffectPlayTypes.Loop;
    }

    private void Start()
    {
    }

    private void OnDestroy()
    {
        Release();
    }

    public void Initialize(PlayEffectInfo info)
    {
        m_EffectPlayType = info.playEffectType;
        m_Root = info.rootTr;
        m_CurTime = 0.0f;
        m_Offset = info.posOffset;
        m_Rotation = info.rot;
        m_Scale = info.scale;
        m_Attached = info.bAttached;

        if(info.rootTr != null)
        {
            m_RootPos = info.rootTr.transform.position;
            m_RootRot = info.rootTr.transform.rotation;
        }

        SyncTr();
        gameObject.SetActive(true);
    }

    public void Release()
    {
        m_Root = null;
        m_CurTime = 0.0f;
        m_Attached = false;
        m_Offset = Vector3.zero;
        m_Rotation = Vector3.zero;
        m_Scale = Vector3.zero;
    }

    // 同步特效的缩放、旋转和位置
    private void SyncTr()
    {
		if (transform == null || transform.gameObject == null)
			return;

        if (m_Scale != Vector3.zero)
        {
            transform.localScale = m_Scale;
        }

        if (m_Root == null) // 世界空间
        {
            transform.position = m_Offset;
            transform.rotation = Quaternion.Euler(m_Rotation);
        }
        else
        {
            if (m_Attached)
            {
                transform.rotation = m_Root.rotation * Quaternion.Euler(m_Rotation);
                transform.position = m_Root.TransformPoint(m_Offset);
            }
            else
            {
                transform.rotation = m_RootRot * Quaternion.Euler(m_Rotation);
                transform.position = m_RootPos + (m_Root.rotation * m_Offset);
            }
        }
    }

    public void Restore()
    {
        DestroyImmediate(this.gameObject);
    }

    public void UpdateFunc(float dt)
    {
        m_CurTime += dt;
        SyncTr();
        if (m_EffectPlayType != EffectPlayTypes.Loop && m_CurTime >= ClearTime)
        {
            Restore();
            return;
        }
    }

    private void Update()
    {
        UpdateFunc(Time.unscaledDeltaTime);
    }
}