liuzhiwei
2020-12-21 1fbd60b81ef4a93df75c32e7d9aa285d8fa533d1
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
163
164
165
166
167
168
169
using Core.Health;
using Core.Utilities;
using System.Collections;
using System.Collections.Generic;
using TowerDefense.Agents;
using UnityEngine;
 
/// <summary>
/// 游戏内的电弧效果处理,这个主要是显示从A点电击到B点的电弧特效
/// </summary>
public class LightBoltEffect : AgentEffect
{
 
    /// <summary>
    /// 电弧的播放特效
    /// </summary>
    protected GameObject m_LightBoltFx;
 
    /// <summary>
    /// 电弧击中的效果
    /// </summary>
    protected GameObject m_LightHitFx;
 
    /// <summary>
    /// 删除Timer.
    /// </summary>
    protected Timer m_DestroyTimer;
 
    /// <summary>
    /// 用于备份粒子系统的默认Scale,在设置完Parent之后,会有对自己Scale的设置,从而导致还回内存池之后,
    /// LocalScale会缩小的情况发生。
    /// </summary>
    protected Vector3 m_BackScale;
    protected Vector3 m_BackScale1;
 
    /// <summary>
    /// 在srcAgent和dstAgent之间播放一个闪电弧。
    /// </summary>
    /// <param name="maxPlaySec"></param>
    /// <param name="lightBoltPrefab"></param>
    /// <param name="lightHit"></param>
    /// <param name="srcAgent"></param>
    /// <param name="dstAgent"></param>
    public void Initialize(float maxPlaySec, GameObject lightBoltPrefab ,GameObject lightHit, Agent srcAgent,Agent dstAgent )
    {
 
        m_LightBoltFx = Poolable.TryGetPoolable(lightBoltPrefab);
        if (!m_LightBoltFx) return;
 
        m_BackScale = m_LightBoltFx.transform.localScale;
        m_LightBoltFx.transform.SetParent(transform, true);
 
        // 获取位置和放置方向,播放当前的特效
        Vector3 offsetPos = dstAgent.position - srcAgent.position;
        m_LightBoltFx.transform.localPosition = Vector3.zero;
 
        float xScale = offsetPos.magnitude / 10.0f;
        if (xScale < 1) xScale = 1;
        xScale *= 0.5f;
        m_LightBoltFx.transform.localScale = new Vector3(xScale, 1.0f, 1.0f);
 
        //  解决 Look rotation viewing vector is zero 这个异常的Bug.
        if (offsetPos.magnitude < 0.0001f)
        {
            offsetPos.y = 1;
        }
 
        // 旋转方向的处理:
        Quaternion look = Quaternion.LookRotation(offsetPos, Vector3.up);
        m_LightBoltFx.transform.rotation = look;
 
        // 处理其它相关的内容.
        var particle = m_LightBoltFx.GetComponent<ParticleSystem>();
        if (particle)
        {
            particle.Simulate(0.0f);
            particle.Play();
        }
 
        // 处理LightHitEffect.
        m_LightHitFx = Poolable.TryGetPoolable(lightHit);
        m_BackScale1 = m_LightHitFx.transform.localScale;
        m_LightHitFx.transform.SetParent(transform, true);
        m_LightHitFx.transform.localPosition = Vector3.zero;
        m_LightHitFx.transform.localScale = new Vector3(2.0f, 2.0f, 2.0f);
        particle = m_LightHitFx.GetComponent<ParticleSystem>();
        if (particle)
        {
            particle.Simulate(0.0f);
            particle.Play();
        }
 
        // 死亡后直接去除.
        m_Agent.removed += OnRemoved;
 
 
        m_DestroyTimer = new Timer(maxPlaySec, RemoveEffect);
    }
 
    /// <summary>
    /// A simply function to convert an angle to a -180/180 wrap
    /// </summary>
    static float Wrap180(float angle)
    {
        angle %= 360;
        if (angle < -180)
        {
            angle += 360;
        }
        else if (angle > 180)
        {
            angle -= 360;
        }
        return angle;
    }
 
    /// <summary>
    /// 获取新的Vec相对于(0,0,1)绕Y轴的旋转角度.
    /// </summary>
    /// <param name="vec3rot"></param>
    /// <returns></returns>
    protected float getYRotAngle( Vector3 vec3rot)
    {
        return 0;
    }
 
    // Update is called once per frame
    void Update()
    {
        if( m_DestroyTimer != null )
            m_DestroyTimer.Tick( Time.deltaTime );
    }
 
    protected void RemoveEffect()
    {
        m_Agent.removed -= OnRemoved;
        ResetAgent();
    }
 
    void OnRemoved(DamageableBehaviour targetable)
    {
        m_Agent.removed -= OnRemoved;
        ResetAgent();
    }
 
    void ResetAgent()
    {
        m_Agent.navMeshNavMeshAgent.speed = m_Agent.originalMovementSpeed;
        if (m_LightBoltFx != null)
        {
            var particle = m_LightBoltFx.GetComponent<ParticleSystem>();
            if (particle)
                particle.Stop();
            Poolable.TryPool(m_LightBoltFx);
            m_LightBoltFx.transform.localScale = m_BackScale;
            m_LightBoltFx = null;
        }
        if( m_LightHitFx != null)
        {
            var particle = m_LightHitFx.GetComponent<ParticleSystem>();
            if (particle)
                particle.Stop();
            Poolable.TryPool(m_LightHitFx);
            m_LightHitFx.transform.localScale = m_BackScale1;
            m_LightHitFx = null;
        }
        Destroy(this);
    }
}