private bool GetAllEntitySelectedByVirtualCamera(ref List <SpacecraftEntity> targetList)
    {
        MainCameraComponent mainCam = CameraManager.GetInstance().GetMainCamereComponent();

        SkillSystemGrow skillGrow = m_PlayerSkillProxy.GetCurrentWeaponSkill().GetSkillGrow();
        float           range     = skillGrow.Range * SceneController.SPACE_ACCURACY_TO_CLIENT;

        // 粗略的拾取.
        // 拾取锥体视为一个相机, 把技能射程视为远裁剪面. 根据FOV取远裁剪面的大小, 投射这个大小的Box, 获取所有拾取到的Entity
        {
            // 所有粗略裁剪的物体 = Physics.BoxCastAll(投射开始点, 盒子边长, 相机方向, SkillLayer)

            float halfBoxVerticalSideLength   = range * Mathf.Tan(m_ReticleHorizontalFOVParam / m_ReticleAspect * 0.5f * Mathf.Deg2Rad);
            float halfBoxHorizontalSideLength = halfBoxVerticalSideLength * m_ReticleAspect;

            // 投射开始的点 = 相机近裁剪面的中心点 + 相机方向 * 盒子边长的一半
            Vector3      startPoint = mainCam.transform.position + (mainCam.GetCamera().nearClipPlane + halfBoxVerticalSideLength) * mainCam.GetForward();
            RaycastHit[] hitInfos   = Physics.BoxCastAll(startPoint,
                                                         new Vector3(halfBoxHorizontalSideLength, halfBoxVerticalSideLength, halfBoxVerticalSideLength),
                                                         mainCam.GetForward(),
                                                         Quaternion.identity, range,
                                                         LayerUtil.GetLayersIntersectWithSkillProjectile(true));

            for (int iHit = 0; iHit < hitInfos.Length; iHit++)
            {
                Rigidbody rigidBody = hitInfos[iHit].rigidbody;
                if (rigidBody == null)
                {
                    continue;
                }

                SpacecraftEntity entity = rigidBody.GetComponent <SpacecraftEntity>();
                if (entity != null)
                {
                    targetList.Add(entity);
                }
            }
        }

        if (m_VirtualCameraForReticleSelection != null)
        {
            // 更新虚拟相机的方向和位置
            m_VirtualCameraForReticleSelection.transform.position = mainCam.transform.position;
            m_VirtualCameraForReticleSelection.transform.rotation = mainCam.transform.rotation;

            // 更精细的判断. 当前版本仅计算目标中心点是不是在 虚拟相机 里面
            for (int iTarget = 0; iTarget < targetList.Count; iTarget++)
            {
                Vector3 viewportPos = m_VirtualCameraForReticleSelection.WorldToViewportPoint(targetList[iTarget].transform.position);
                if (viewportPos.x < 0 || viewportPos.y < 0 || viewportPos.x > 1 || viewportPos.y > 1)
                {
                    targetList.RemoveAt(iTarget);
                    iTarget--;
                }
            }
        }
        return(targetList.Count > 0);
    }
예제 #2
0
    /// <summary>
    /// 正前方中心点射线选中的目标
    /// </summary>
    /// <returns></returns>
    private BaseEntity GetForwardEntity()
    {
        MainCameraComponent mainCam = CameraManager.GetInstance().GetMainCamereComponent();
        Ray        ray     = new Ray(mainCam.GetPosition(), mainCam.GetForward());
        RaycastHit hitInfo = new RaycastHit();

        if (Physics.Raycast(ray, out hitInfo, m_SkillMaxDistance, LayerUtil.GetLayersIntersectWithSkillProjectile(true)))
        {
            return(hitInfo.collider.attachedRigidbody?.GetComponent <BaseEntity>());
        }
        else
        {
            return(null);
        }
    }
예제 #3
0
    /// <summary>
    /// 打出一条射线, 检测碰到得一个可攻击的目标
    /// </summary>
    /// <param name="targetPoint"></param>
    /// <param name="maxDistance"></param>
    /// <param name="hitInfo"></param>
    /// <returns>是否拾取到了技能目标</returns>
    public static bool PickSkillTargetEntityByRaycast(Vector3 targetPoint, float maxDistance, out RaycastHit hitInfo)
    {
        Vector3 mainCamPos = CameraManager.GetInstance().GetMainCamereComponent().GetPosition();
        Vector3 dir        = CameraManager.GetInstance().GetMainCamereComponent().GetForward();

        Ray ray = new Ray(mainCamPos, dir);

        if (Physics.Raycast(ray, out hitInfo, maxDistance, LayerUtil.GetLayersIntersectWithSkillProjectile(true)))
        {
            return(true);
        }
        else
        {
            return(false);
        }
    }
    /// <summary>
    /// 中心点射线选中的目标
    /// </summary>
    /// <returns></returns>
    private SpacecraftEntity GetTargetSelectedByCenterRay()
    {
        PlayerSkillVO       skillVO     = m_PlayerSkillProxy.GetCurrentWeaponSkill();
        SkillSystemGrow     skillGrow   = skillVO.GetSkillGrow();
        float               maxDistance = skillGrow.Range * SceneController.SPACE_ACCURACY_TO_CLIENT;
        MainCameraComponent mainCam     = CameraManager.GetInstance().GetMainCamereComponent();
        Ray        ray     = new Ray(mainCam.GetPosition(), mainCam.GetForward());
        RaycastHit hitInfo = new RaycastHit();

        if (Physics.Raycast(ray, out hitInfo, maxDistance, LayerUtil.GetLayersIntersectWithSkillProjectile(true)))
        {
            return(hitInfo.collider.attachedRigidbody?.GetComponent <SpacecraftEntity>());
        }
        else
        {
            return(null);
        }
    }
예제 #5
0
    /// <summary>
    /// 根据这次射击的弹道方向, 计算命中的目标Entity和目标点
    /// </summary>
    /// <param name="camDirAffectedByRecoil"></param>
    /// <returns></returns>
    protected SkillTarget CalulateTargetDataByShootingDirection(Vector3 camDirAffectedByRecoil)
    {
        // 计算射线碰到的目标点, 并重新计算从Launcher到目标点的方向
        PlayerSkillVO   skillVO     = m_PlayerSkillProxy.GetCurrentWeaponSkill();
        SkillSystemGrow skillGrow   = skillVO.GetSkillGrow();
        float           maxDistance = skillGrow.Range * SceneController.SPACE_ACCURACY_TO_CLIENT;
        Ray             ray         = new Ray(CameraManager.GetInstance().GetMainCamereComponent().GetPosition(), camDirAffectedByRecoil);
        RaycastHit      hitInfo     = new RaycastHit();

        if (Physics.Raycast(ray, out hitInfo, maxDistance, LayerUtil.GetLayersIntersectWithSkillProjectile(true)))
        {
            return(new SkillTarget(hitInfo.collider.attachedRigidbody?.GetComponent <SpacecraftEntity>(), hitInfo.point));
        }
        else
        {
            Vector3 skillReleasingDir = (ray.GetPoint(maxDistance) - m_MainPlayer.GetRootTransform().position).normalized;
            return(new SkillTarget(null, m_MainPlayer.GetRootTransform().position + skillReleasingDir * maxDistance));
        }
    }
예제 #6
0
    /// <summary>
    /// 改善的,获取目标列表
    /// </summary>
    /// <returns></returns>
    protected override List <Target> ImproveGetTarget()
    {
        List <Target> targets = base.ImproveGetTarget();

        Vector3 pos       = CameraManager.GetInstance().GetMainCamereComponent().GetPosition();
        Vector3 direction = IsChangCheckDirection ? m_CheckDirection : CameraManager.GetInstance().GetMainCamereComponent().GetForward();

        Collider[] colliders = Physics.OverlapSphere(pos, m_crosssightinfo.m_MaxRayDistance, LayerUtil.GetLayersIntersectWithSkillProjectile(true) /*LayerMask.GetMask("Enemy")*/);
        for (int i = 0; i < colliders.Length; i++)
        {
            Vector3 colliderPos = colliders[i].transform.position;                                       //检测单位位置
            if (Vector3.Angle(direction, colliderPos - pos) <= m_crosssightinfo.m_ConeInfo.angle * 0.5f) //单位跟摄像机正方向夹角是否在 1/2角度内
            {
                RaycastHit hit = new RaycastHit();

                int layermask = LayerUtil.GetLayersIntersectWithSkillProjectile(true);                          // LayerMask.GetMask("Enemy"/*, "Obstacles"*/); //指定射线碰撞的对象
                Physics.Raycast(pos, colliderPos - pos, out hit, m_crosssightinfo.m_MaxRayDistance, layermask); //检测障碍
                if (hit.collider == colliders[i])                                                               //如果途中无其他障碍物,那么射线就会碰撞到敌人
                {
                    if (hit.rigidbody != null)
                    {
                        BaseEntity entity = hit.rigidbody?.GetComponent <BaseEntity>();
                        if (entity != null && CCrossSightLoic.IsAdd(targets, entity.EntityId()))
                        {
                            Target target = new Target();
                            target.target_entityId = entity.EntityId();
                            target.target_pos      = hit.point;
                            targets.Add(target);

                            GizmosHelper.GetInstance().DrawLine(pos, hit.point, Color.red);
                        }
                    }
                }
            }
        }
        return(targets);
    }
예제 #7
0
    /// <summary>
    /// 选中一个新的目标
    /// 1. 与上一帧选中的目标不同
    /// 2. 上一帧选中的目标已经锁定完成, 进行下一轮锁定
    /// </summary>
    /// <returns>是否有新的目标</returns>
    private bool PickNewTarget(out SpacecraftEntity newTarget)
    {
        PlayerSkillVO       skillVO     = m_PlayerSkillProxy.GetCurrentWeaponSkill();
        SkillSystemGrow     skillGrow   = skillVO.GetSkillGrow();
        float               maxDistance = skillGrow.Range * SceneController.SPACE_ACCURACY_TO_CLIENT;
        MainCameraComponent mainCam     = CameraManager.GetInstance().GetMainCamereComponent();
        Ray        ray     = new Ray(mainCam.GetPosition(), mainCam.GetForward());
        RaycastHit hitInfo = new RaycastHit();

        // UNDONE
        // 第一版: 使用屏幕中心射线作为目标选取射线. NOW
        // 第二版: 使用 Physics.BoxCast
        if (Physics.Raycast(ray, out hitInfo, maxDistance, LayerUtil.GetLayersIntersectWithSkillProjectile(true)))
        {
            SpacecraftEntity pickedTarget = hitInfo.collider.attachedRigidbody?.GetComponent <SpacecraftEntity>();
            newTarget = pickedTarget;
            return(true);
        }
        else
        {
            newTarget = null;
            return(false);
        }
    }
예제 #8
0
    /// <summary>
    /// 改善的,获取目标列表
    /// </summary>
    /// <returns></returns>
    protected override List <Target> ImproveGetTarget()
    {
        List <Target> targets = base.ImproveGetTarget();

        Vector3 pos       = CameraManager.GetInstance().GetMainCamereComponent().GetPosition();
        Vector3 direction = IsChangCheckDirection ? m_CheckDirection : CameraManager.GetInstance().GetMainCamereComponent().GetForward();


        if (m_crosssightinfo.m_RoundInfo.detectionMode == DetectionMode.One)
        {
            RaycastHit hitInfo = new RaycastHit();
            if (Physics.SphereCast(pos,                                 //起始点
                                   m_crosssightinfo.m_RoundInfo.radius, //半径
                                   direction,                           //方向
                                   out hitInfo,
                                   m_crosssightinfo.m_MaxRayDistance,   //最大距离
                                                                        //LayerMask.GetMask("Enemy")))                        //层
                                   LayerUtil.GetLayersIntersectWithSkillProjectile(true)))
            {
                if (hitInfo.rigidbody != null)
                {
                    BaseEntity entity = hitInfo.rigidbody?.GetComponent <BaseEntity>();
                    if (entity != null && CCrossSightLoic.IsAdd(targets, entity.EntityId()))
                    {
                        Target target = new Target();
                        target.target_entityId = entity.EntityId();
                        target.target_pos      = hitInfo.point;
                        targets.Add(target);

                        GizmosHelper.GetInstance().DrawLine(pos, hitInfo.point, Color.red);
                        GizmosHelper.GetInstance().DrawSphere(hitInfo.point, m_crosssightinfo.m_RoundInfo.radius, Color.red);
                    }
                }
            }
        }
        else if (m_crosssightinfo.m_RoundInfo.detectionMode == DetectionMode.All)
        {
            RaycastHit[] hits = Physics.SphereCastAll(pos,                                 //起始点
                                                      m_crosssightinfo.m_RoundInfo.radius, //半径
                                                      direction,                           //方向
                                                      m_crosssightinfo.m_MaxRayDistance,   //最大距离
                                                                                           // LayerMask.GetMask("Enemy"));                       //层
                                                      LayerUtil.GetLayersIntersectWithSkillProjectile(true));


            for (int i = 0; i < hits.Length; i++)
            {
                RaycastHit hit = hits[i];
                if (hit.rigidbody != null)
                {
                    BaseEntity entity = hit.rigidbody?.GetComponent <BaseEntity>();
                    if (entity != null && CCrossSightLoic.IsAdd(targets, entity.EntityId()))
                    {
                        Target target = new Target();
                        target.target_entityId = entity.EntityId();
                        target.target_pos      = hit.point;
                        targets.Add(target);

                        GizmosHelper.GetInstance().DrawLine(pos, hit.point, Color.red);
                    }
                }
            }
        }

        return(targets);
    }
예제 #9
0
    /// <summary>
    /// 改善的,获取目标列表
    /// </summary>
    /// <returns></returns>
    protected override List <Target> ImproveGetTarget()
    {
        List <Target> targets = base.ImproveGetTarget();

        Vector3 pos       = CameraManager.GetInstance().GetMainCamereComponent().GetPosition();
        Vector3 direction = IsChangCheckDirection ? m_CheckDirection : CameraManager.GetInstance().GetMainCamereComponent().GetForward();

        Collider[] colliders = Physics.OverlapSphere(pos, m_crosssightinfo.m_MaxRayDistance, LayerUtil.GetLayersIntersectWithSkillProjectile(true) /*LayerMask.GetMask("Enemy")*/);

        Plane[] planes = null;

        // 更新虚拟相机的方向和位置
        if (m_virtualCamera != null)
        {
            m_virtualCamera.transform.position = pos;
            m_virtualCamera.transform.rotation = CameraManager.GetInstance().GetMainCamereComponent().GetRotation();

            planes = GeometryUtility.CalculateFrustumPlanes(m_virtualCamera);
        }

        for (int i = 0; i < colliders.Length; i++)
        {
            if (planes == null)
            {
                break;
            }

            if (GeometryUtility.TestPlanesAABB(planes, colliders[i].bounds))
            {
                BaseEntity entity = colliders[i].attachedRigidbody?.GetComponent <BaseEntity>();
                if (entity != null && CCrossSightLoic.IsAdd(targets, entity.EntityId()))
                {
                    Target target = new Target();
                    target.target_entityId = entity.EntityId();
                    target.target_pos      = entity.transform.position;
                    targets.Add(target);

                    GizmosHelper.GetInstance().DrawLine(pos, target.target_pos, Color.red);
                }
            }
        }

        return(targets);
    }
예제 #10
0
    /// <summary>
    ///  获取弹道上的目标,并返回弹道方向
    /// </summary>
    public override void GetBallisticTargetAndOutDirection(out List <Target> targets, out Vector3 direction, params object[] args)
    {
        Vector3 CamerPos = CameraManager.GetInstance().GetMainCamereComponent().GetPosition();// Camera.main.transform.position;

        base.GetBallisticTargetAndOutDirection(out targets, out direction, args);

        if (m_virtualCamera != null)
        {
            float offx = 0.0f;  //范围 0--0.5
            float offy = 0.0f;
            m_ballisticOffsetFunc?.Invoke(out offx, out offy, m_ballisticOffsetFunc_args);

            float   offz     = 500;                           //到摄像机近视窗平面距离
            Vector3 viewPos  = new Vector3(offx, offy, offz); //(0.5f + offx, 0.5f + offy, offz);
            Vector3 worldPos = m_virtualCamera.ViewportToWorldPoint(viewPos);
            direction = (worldPos - CamerPos).normalized;

            //验证
            //             GameObject ga = new GameObject("ddddd");
            //             ga.transform.position = worldPos;
            //             ga.AddComponent<BoxCollider>().size = Vector3.one;

            if (m_crosssightinfo.m_ConeSquareInfo.detectionMode == DetectionMode.One)
            {
                //射线检测目标
                RaycastHit hit       = new RaycastHit();
                int        layermask = LayerUtil.GetLayersIntersectWithSkillProjectile(true); // LayerMask.GetMask("Enemy"/*, "Obstacles"*/); //指定射线碰撞的对象
                Physics.Raycast(CamerPos, worldPos - CamerPos, out hit, offz, layermask);     //检测障碍

                if (hit.rigidbody != null)
                {
                    BaseEntity entity = hit.rigidbody?.GetComponent <BaseEntity>();
                    if (entity != null && CCrossSightLoic.IsAdd(targets, entity.EntityId()))
                    {
                        Target target = new Target();
                        target.target_entityId = entity.EntityId();
                        target.target_pos      = hit.point;
                        targets.Add(target);
                    }
                }
            }
            else if (m_crosssightinfo.m_ConeSquareInfo.detectionMode == DetectionMode.All)
            {
                int          layermask = LayerUtil.GetLayersIntersectWithSkillProjectile(true); // LayerMask.GetMask("Enemy"/*, "Obstacles"*/); //指定射线碰撞的对象
                RaycastHit[] hits      = Physics.RaycastAll(CamerPos,                           //起始点
                                                            worldPos - CamerPos,                //方向
                                                            m_crosssightinfo.m_MaxRayDistance,  //最大距离
                                                            layermask);

                for (int tt = 0; tt < hits.Length; tt++)
                {
                    RaycastHit hitt = hits[tt];
                    if (hitt.rigidbody != null)
                    {
                        BaseEntity entity = hitt.rigidbody?.GetComponent <BaseEntity>();
                        if (entity != null && CCrossSightLoic.IsAdd(targets, entity.EntityId()))
                        {
                            Target target = new Target();
                            target.target_entityId = entity.EntityId();
                            target.target_pos      = hitt.point;
                            targets.Add(target);

                            GizmosHelper.GetInstance().DrawLine(CamerPos, hitt.point, Color.red);
                        }
                    }
                }
            }
        }
    }