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); }
private Ray GetViewRay() { MainCameraComponent mainCam = CameraManager.GetInstance().GetMainCamereComponent(); if (mainCam != null) { return(new Ray(mainCam.GetPosition(), mainCam.GetForward())); } else { return(new Ray()); } }
/// <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); } }
/// <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); } }
/// <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); } }