Пример #1
0
    protected void UpdateRemoveDeadSections()
    {
        int   lastDeadSectionIndex = -1;
        float minLiveBirthTime     = Time.time - LifeTime;

        for (int iSection = 0; iSection < m_Sections.Count; iSection++)
        {
            hwmTrailSection iterSection = m_Sections[iSection];
            if (iterSection.BirthTime > minLiveBirthTime)
            {
                lastDeadSectionIndex = iSection - 1;
                break;
            }
        }

        if (lastDeadSectionIndex > -1) // 说明有过期的Section
        {
            /* 断裂效果说明:例
             *                  下图第一行是Section Index 第二行中"*"是Section "----"是画出来的Trail
             *                  0    1    2    3    4
             *----*----*----*----*
             *                  当有2个Section过期时,如果移除两个Section,结果如下图
             *                       2    3    4
             *                        ----*----*----*
             *                           ↑这里断裂
             *                  为了避免断裂效果,我们只移除1个Section(iLastOutdateSection = 1)
             *                       1    2    3    4
             *----*----*----*
             */
            m_Sections.RemoveRange(0, lastDeadSectionIndex + 1 == m_Sections.Count
                ? m_Sections.Count       // 所有的都过期了,我们可以彻底移除了
                : lastDeadSectionIndex); // 只要不是全部过期了就保留一个过期的Section,避免断裂效果
        }
    }
Пример #2
0
    /// <summary>
    /// 用于更新条带段的属性。自定制的特殊动画、过渡等逻辑请写在这个方法的重载中。(见osPlaneTrail范例中如何实现的“自定制曲线的条带颜色变化”)
    /// </summary>
    protected void UpdateSections()
    {
        for (int iSection = 0; iSection < m_Sections.Count; iSection++)
        {
            hwmTrailSection currentSection = m_Sections[iSection];

            currentSection.NormalizedAge = Mathf.Clamp01((Time.time - currentSection.BirthTime) / LifeTime);
            currentSection.Color         = Color.Lerp(StartColor, EndColor, currentSection.NormalizedAge);
            currentSection.HalfWidth     = Mathf.Lerp(StartHalfWidth, EndHalfWidth, currentSection.NormalizedAge);
        }
    }
Пример #3
0
    /// <summary>
    /// 计算Trail世界空间的包围球
    /// 如果当前没有Section,则返回中心为发射器的位置,大小为0的Bounds
    /// TODO 优化计算方式,降低计算频率
    ///     这种计算方式更适合处理一直朝某方向飞的条带
    ///     遍历所有的Section计算Bounds太废了,又不可能实现通用且高效的算法
    ///     考虑让子类重载,根据不同情况去优化计算
    /// </summary>
    protected Bounds CaculateBounds()
    {
        Bounds bounds = new Bounds(transform.position, Vector3.zero);

        if (m_Sections.Count > 0)
        {
            hwmTrailSection centerSection = m_Sections[m_Sections.Count / 2];
            hwmTrailSection lastSection   = m_Sections[m_Sections.Count - 1];
            bounds.Encapsulate(centerSection.Position);
            bounds.Encapsulate(lastSection.Position);
        }
        return(bounds);
    }
Пример #4
0
    protected void UpdateAutoEmitting()
    {
        if (!m_IsEmitting ||
            m_IsManualEmit)
        {
            return;
        }

        if (!(m_Me2CameraDistanceSqr < AutoEmittingWhenMe2CameraDistanceSqrIsLessThan &&
              (EnableAutoEmittingWhenMeOutOfCamera ||
               IsInRendererCamera(transform.position))))
        {
            return;
        }

        Vector3    emitterPosition_RendererSpace = Quaternion.Inverse(m_TrailRenderer.transform.rotation) * (transform.position - m_TrailRenderer.transform.position);
        Quaternion emitterRotation_RendererSpace = transform.rotation * Quaternion.Inverse(m_TrailRenderer.transform.rotation);

        if (m_Sections.Count == 0)
        {
            // 在发射器上一帧的位置添加一个Section
            TryAddSection(emitterPosition_RendererSpace, emitterRotation_RendererSpace);
            // 在发射器当前位置添加一个Section作为HeadSection,
            TryAddSection(emitterPosition_RendererSpace, emitterRotation_RendererSpace);
        }
        else
        {
            #region 判断是否需要新的Section
            // TDOO 如果FOV不经常变动,可以把这个结果Cache下来。或者把这个值放在相机的管理中每帧计算
            float cameraHalfTanFOV = Mathf.Tan(RendererCamera.fieldOfView * 0.5f * Mathf.Deg2Rad);
            // 把需要发射新Section的发射器在屏幕上移动的距离换算成世界空间的距离
            float minMeMoveDistanceSqr = cameraHalfTanFOV * AutoEmittingAddSectionWhenMeMoveDistanceInScreenSpaceGreaterThen;
            minMeMoveDistanceSqr *= minMeMoveDistanceSqr;
            minMeMoveDistanceSqr *= m_Me2CameraDistanceSqr;
            // 需要同时满足世界空间距离和屏幕空间距离
            minMeMoveDistanceSqr = Mathf.Max(AutoEmittingAddSectionWhenMeMoveDistanceSqrInWorldSpcaeGreaterThen, minMeMoveDistanceSqr);
            bool needAddSection = (transform.position - m_Sections[m_Sections.Count - 2].Position).sqrMagnitude > minMeMoveDistanceSqr;
            #endregion
            if (needAddSection)
            {
                TryAddSection(emitterPosition_RendererSpace, emitterRotation_RendererSpace);
            }
            else
            {
                // 将HeadSection挪到发射器的位置
                hwmTrailSection headSection = m_Sections[m_Sections.Count - 1];
                SetupSection(headSection, emitterPosition_RendererSpace, emitterRotation_RendererSpace, m_Sections.Count - 2);
            }
        }
    }
Пример #5
0
    /// <summary>
    /// 如果希望在发射新的条带段时,能够对这个新产生的段上的数据做一些特殊处理(例如随机颜色),或者对自己扩展的变量进行初始化赋值时,重载本方法
    /// </summary>
    protected void SetupSection(hwmTrailSection section, Vector3 position, Quaternion rotation, int previousSectionIndex)
    {
        bool isHeadSection = previousSectionIndex < 0;

        section.Position       = position;
        section.BirthTime      = Time.time;
        section.RightDirection = rotation * Vector3.right;
        section.NormalizedAge  = 0;
        section.HalfWidth      = StartHalfWidth;
        section.Color          = StartColor;
        section.TexcoordU      = isHeadSection
            ? 0
            : (position - m_Sections[previousSectionIndex].Position).magnitude * WorldToTexcoordU + m_Sections[previousSectionIndex].TexcoordU;
    }
Пример #6
0
    /// <summary>
    /// 当前Section数量超过<see cref="MaxSectionCount"/>时不会添加Section
    /// </summary>
    protected hwmTrailSection TryAddSection(Vector3 position, Quaternion rotation)
    {
        // TODO 不能添加Section会导致条带发射器终止发射,暂时的解决方法是把MaxSectionCount配的很大。预计以后顶点数可以动态改变
        if (m_Sections.Count == MaxSectionCount - 1)
        {
            return(null);
        }

        hwmTrailSection newSection = new hwmTrailSection();

        m_Sections.Add(newSection);
        SetupSection(newSection, position, rotation, m_Sections.Count - 2);

        return(newSection);
    }
Пример #7
0
    /// <summary>
    /// 用于将条带的Section转换为用于渲染的顶点、索引缓冲
    /// 可以重载这个方法实现特定的填充策略,例如:
    ///     可断裂的条带
    ///     更高性能的填充策略
    ///     定向Billboard
    /// </summary>
    protected void UpdateBuffers()
    {
        // UNDONE 这里有点蒙蔽啊。懒得看了,直接问祝锐把
        for (int iSection = 0; iSection < m_Sections.Count; iSection++)
        {
            hwmTrailSection iterSection = m_Sections[iSection];

            // Generate vertices
            Vector3 vHalfWidth = iterSection.RightDirection * iterSection.HalfWidth;

            m_PositionBuffer[iSection * 4 + 0] = iterSection.Position - vHalfWidth;
            m_PositionBuffer[iSection * 4 + 1] = iterSection.Position + vHalfWidth;
            // fade colors out over time
            m_ColorBuffer[iSection * 4 + 0] = iterSection.Color;
            m_ColorBuffer[iSection * 4 + 1] = iterSection.Color;

            m_UVBuffer[iSection * 4 + 0] = new Vector2(iterSection.TexcoordU, 0);
            m_UVBuffer[iSection * 4 + 1] = new Vector2(iterSection.TexcoordU, 1);
        }

        for (int iSection = 0; iSection < m_Sections.Count - 1; iSection++)
        {
            hwmTrailSection iterSection = m_Sections[iSection + 1];
            // TODO 就这里不懂,找祝锐
            m_PositionBuffer[iSection * 4 + 2] = m_PositionBuffer[iSection * 4 + Mathf.Min(iSection, 1) * 4];
            m_PositionBuffer[iSection * 4 + 3] = m_PositionBuffer[iSection * 4 + Mathf.Min(iSection, 1) * 5];
            // fade colors out over time
            m_ColorBuffer[iSection * 4 + 2] = m_ColorBuffer[iSection * 4 + 4];
            m_ColorBuffer[iSection * 4 + 3] = m_ColorBuffer[iSection * 4 + 5];

            m_UVBuffer[iSection * 4 + 2] = m_UVBuffer[iSection * 4 + 4];
            m_UVBuffer[iSection * 4 + 3] = m_UVBuffer[iSection * 4 + 5];
        }


        for (int iSection = (m_Sections.Count - 1) * 4; iSection < m_PositionBuffer.Length; ++iSection)
        {
            // TODO 这里也不懂。这样为什么不会渲染出从最后一个Section到这个位置的Trail?是被裁剪掉了么。不是会把一个三角形切开,然后渲染在屏幕中的部分么。为什么全裁掉了
            m_PositionBuffer[iSection] = new Vector3(0, -100000.0f, 0);
        }
    }
Пример #8
0
    protected void OnDrawGizmosSelected()
    {
        if (!Application.isPlaying || !DEBUG_DrawGizmos)
        {
            return;
        }

        GUIStyle guiStyle = new GUIStyle();

        guiStyle.fontSize         = 15;
        guiStyle.normal.textColor = Color.green;

        for (int iSection = 0; iSection < m_Sections.Count; ++iSection)
        {
            hwmTrailSection iterSection = m_Sections[iSection];
            Gizmos.color = iSection == 0
                ? new Color(1.0f, 0, 0, 0.5f)
                : new Color(1.0f, 1.0f, 1.0f, 0.5f);
            float radius = Mathf.Lerp(StartHalfWidth, EndHalfWidth, iterSection.NormalizedAge);
            Gizmos.DrawWireSphere(iterSection.Position, radius);
            UnityEditor.Handles.Label(iterSection.Position, (iSection).ToString(), guiStyle);
        }

        for (int i = 0; i < m_PositionBuffer.Length; i++)
        {
            if (i % 2 == 0)
            {
                Vector3 start = m_PositionBuffer[i];
                Vector3 end   = m_PositionBuffer[i + 1];

                Gizmos.color = Color.yellow;
                Gizmos.DrawLine(start, end);

                if (i % 4 == 0)
                {
                    Gizmos.color = Color.green;
                    guiStyle.normal.textColor = Color.green;
                    Gizmos.DrawSphere(start, 0.05f);
                    UnityEditor.Handles.Label(start + Vector3.right * .2f, i.ToString(), guiStyle);
                    Gizmos.color = Color.red;
                    guiStyle.normal.textColor = Color.red;
                    Gizmos.DrawSphere(end, 0.05f);
                    UnityEditor.Handles.Label(end - Vector3.right * .2f, (i + 1).ToString(), guiStyle);
                }
                else
                {
                    Gizmos.color = Color.green;
                    guiStyle.normal.textColor = Color.green;
                    Gizmos.DrawSphere(start, 0.05f);
                    UnityEditor.Handles.Label(start + Vector3.right * .2f + Vector3.forward * .2f, i.ToString(), guiStyle);
                    Gizmos.color = Color.red;
                    guiStyle.normal.textColor = Color.red;
                    Gizmos.DrawSphere(end, 0.05f);
                    UnityEditor.Handles.Label(end - Vector3.right * .2f + Vector3.forward * .2f, (i + 1).ToString(), guiStyle);
                }
            }
        }
        Bounds bounds = m_TrailRenderer._MeshRenderer.bounds;

        Gizmos.color = Color.white;
        Gizmos.DrawWireSphere(bounds.center, bounds.extents.magnitude);
    }