Exemple #1
0
    //public void RemoveListData<T>(int index, List<T> list) {
    //    lock (list) {
    //        list.RemoveAt(index);
    //    }
    //}
    //public void AddListData<T>(T value, List<T> list) {
    //    lock (list) {
    //        list.Add(value);
    //    }
    //}
    #endregion

    #region 视野体的增加和移除
    /// <summary>
    /// 移除视野体
    /// </summary>
    /// <param name="i"></param>
    public void RemoveFOVUnit(int i)
    {
        lock (LogicalLayerObjects){
            IFOVUnit fOVUnit = LogicalLayerObjects[i].characterModel;
            // 删除逻辑层物体
            LogicalLayerObjects.RemoveAt(i);
            // 同步删除表示层物体
            lock (PresentationLayerObjects) {
                PresentationLayerObjects.Remove(fOVUnit);
            }
        }
    }
Exemple #2
0
    /// <summary>
    /// 判断一个单位是否处于可见范围
    /// </summary>
    /// <param name="unit"></param>
    /// <returns></returns>
    private bool IsUnitVisible(IFOVUnit unit)
    {
        // 获得当前单位位置
        Vector3 position = unit.Position;

        // 将单位坐标转换到贴图坐标中
        position *= textureSize / worldSize;

        // 判断当前贴图坐标的r通道是否大于等于255,如果大于,那么当前单位是可见
        int z = Mathf.Clamp(Mathf.FloorToInt(position.z), 0, textureSize);
        int x = Mathf.Clamp(Mathf.FloorToInt(position.x), 0, textureSize);

        if (buffer0[z * textureSize + x].r >= 255)
        {
            return(true);
        }
        else
        {
            return(false);
        }
    }
Exemple #3
0
    /// <summary>
    /// 使用视野单位的fov(扇形)视野来更新可见区域
    /// </summary>
    /// <param name="fOVUnit"></param>
    public void RevealUsingFOVVision(IFOVUnit fOVUnit)
    {
        try {
            float fov      = 30;
            float distance = 25f;
            float halfFov  = fov / 2;
            float halfL    = Mathf.Abs(distance * Mathf.Sin(halfFov));
            float H        = Mathf.Abs(distance * Mathf.Cos(halfFov));

            Vector3 pos        = fOVUnit.Position;
            Vector3 leftPoint  = new Vector3(pos.x - halfL, pos.y, pos.z + H);
            Vector3 rightPoint = new Vector3(pos.x + halfL, pos.y, pos.z + H);

            Vector3 originToLeft  = (-pos + leftPoint);
            Vector3 originToRight = (-pos + rightPoint);

            // 左右两个向量在贴图上相距了多少个像素
            float textxelCount = (originToRight - originToLeft).magnitude;

            Matrix4x4 rMatrix = fOVUnit.Rotation == null ? Matrix4x4.identity : Matrix4x4.Rotate(fOVUnit.Rotation);
            originToLeft  = rMatrix * originToLeft;
            originToRight = rMatrix * originToRight;
            originToLeft.Normalize(); originToRight.Normalize();

            // delta表示在贴图上每个像素的长宽
            // 即贴图上1单位的像素的物体表现在世界坐标上的长宽
            float delta = textureSize / worldSize;

            // 则t的增量即为 delta / textxelCount
            float tDelta = delta / textxelCount / 2;

            float t = 0;
            for (; t <= 1; t += tDelta)
            {
                Vector3 direction = Vector3.Lerp(originToLeft, originToRight, t).normalized;

                for (float d = 0; d <= distance; d += delta / 2)
                {
                    // 当前射线所涉及的点
                    Vector3 endPoint = pos + direction * d;

                    bool hit = false;
                    // 碰撞体半径
                    float objR = 1f;

                    // 对每一个逻辑层物体进行碰撞检测,
                    // 如果视线碰撞到障碍物,那么该视线就断了
                    for (int i = 0; i < LogicalLayerObjects.Count; i++)
                    {
                        CharacterMono logicalObject = LogicalLayerObjects[i];
                        if (logicalObject == null)
                        {
                            continue;
                        }

                        Vector3 logicalObjectPos = logicalObject.characterModel.Position;
                        if (logicalObjectPos == pos || (logicalObjectPos - pos).magnitude <= distance / 20)
                        {
                            continue;
                        }

                        // 暂时以半径为1的球形碰撞体举例
                        // 判断点在球体内,公式为 (x-x1)2 + (y-y1)2 + (z-z1)2 <= r2
                        if (
                            (endPoint.x - logicalObjectPos.x) * (endPoint.x - logicalObjectPos.x) +
                            (endPoint.z - logicalObjectPos.z) * (endPoint.z - logicalObjectPos.z)
                            <
                            objR * objR
                            )
                        {
                            hit = true;
                            break;
                        }
                    }
                    if (hit)
                    {
                        break;
                    }

                    endPoint *= delta;
                    int zw = (int)(endPoint.z) * textureSize;
                    int x  = (int)(endPoint.x);
                    if (x + zw < 0 || x + zw >= textureSizeSqr || x >= textureSize || zw >= textureSizeSqr)
                    {
                        continue;
                    }
                    buffer0[x + zw].r = 255;
                }
            }
        } catch (Exception e) { Debug.LogError(e.Message); }
    }