/// <summary> /// 获取最远点 /// </summary> /// <param name="context"></param> /// <param name="selectionData"></param> /// <returns></returns> private static void GetFarthestPostionActionTarget(ref ActionTarget actionTarget, IContext context, Vector3 calculateDirection) { IBaseActionProperty baseActionProperty = context.GetObject <IBaseActionProperty>(); if (baseActionProperty.IsMain()) { SkillData skillData = context.GetObject <SkillData>(); MainCameraComponent mainCamComponent = context.GetObject <MainCameraComponent>(); if (mainCamComponent == null) { actionTarget = null; return; } //最远点 Vector3 distantPoint = Vector3.zero; Vector3 playerPosition = baseActionProperty.GetRootTransform().position; //玩家位置 Vector3 CamPosition = mainCamComponent.GetPosition(); //摄像机位置 Vector3 cameDir = calculateDirection; /*mainCamComponent.GetForward()*/ //摄像机方向向量 Vector3 camera2Player = playerPosition - CamPosition; //摄像机到玩家的向量 Vector3 verticalPos = CamPosition + Vector3.Dot(camera2Player, cameDir) * cameDir; //垂线坐标 = 摄像机坐标+ camera2Player在cameDir投影距离 * cameDir向量 Vector3 Play2VerticaN = (verticalPos - playerPosition).normalized; //玩家到垂线点 的单位向量 float Play2VerticaD = Vector3.Distance(verticalPos, playerPosition); //玩家跟垂线点的距离 float MaxDis = skillData.BaseData.Value.MaxDistance; if (MaxDis > Play2VerticaD) { distantPoint = Mathf.Sqrt(MaxDis * MaxDis - Play2VerticaD * Play2VerticaD) * cameDir + verticalPos; //最远点 = 三角函数求得垂线点到最远点向量+ 垂线点坐标 } else { distantPoint = playerPosition + Play2VerticaN * MaxDis;//垂线上找到距离是 MaxDis 的坐标 } actionTarget.TargetType = ActionTargetType.Position; actionTarget.TargetPosition = distantPoint; } else { SkillData skillData = context.GetObject <SkillData>(); Vector3 playerPosition = baseActionProperty.GetRootTransform().position; float d = skillData.BaseData.Value.MaxDistance; Vector3 distantPoint = playerPosition + calculateDirection * d; actionTarget.TargetType = ActionTargetType.Position; actionTarget.TargetPosition = distantPoint; //Leyoutech.Utility.DebugUtility.LogError("第三方最远点方向", string.Format("计算最远点 ---->self = {0} , calculateDirection = {1}, PlayPos = {2} , distantPoint = {3}", // baseActionProperty.EntityId(), // calculateDirection, // playerPosition, // distantPoint // )); } }
private Ray GetViewRay() { MainCameraComponent mainCam = CameraManager.GetInstance().GetMainCamereComponent(); if (mainCam != null) { return(new Ray(mainCam.GetPosition(), mainCam.GetForward())); } else { return(new Ray()); } }
/// <summary> /// 获取当前主摄像机注视,所选技能最远处的,四元数旋转值 /// </summary> /// <param name="mainCamComponent">主摄像机组件</param> /// <param name="d">最远距离</param> /// <returns></returns> private Crucis.Protocol.Vec4 GetCameraQuaternion(MainCameraComponent mainCamComponent, Vector3 direction, float d) { if (mainCamComponent == null) { Leyoutech.Utility.DebugUtility.LogError("目标方向", " 上下文没有摄像机数据"); return(null); } //最远点 Vector3 distantPoint = Vector3.zero; Vector3 playerPosition = m_ISpacecraftSkillProperty.GetRootTransform().position; //玩家位置 Vector3 CamPosition = mainCamComponent.GetPosition(); //摄像机位置 Vector3 cameDir = direction; /*mainCamComponent.GetForward()*/ //摄像机方向向量 Vector3 camera2Player = playerPosition - CamPosition; //摄像机到玩家的向量 Vector3 verticalPos = CamPosition + Vector3.Dot(camera2Player, cameDir) * cameDir; //垂线坐标 = 摄像机坐标+ camera2Player在cameDir投影距离 * cameDir向量 Vector3 Play2VerticaN = (verticalPos - playerPosition).normalized; //玩家到垂线点 的单位向量 float Play2VerticaD = Vector3.Distance(verticalPos, playerPosition); //玩家跟垂线点的距离 float MaxDis = d; if (MaxDis > Play2VerticaD) { distantPoint = Mathf.Sqrt(MaxDis * MaxDis - Play2VerticaD * Play2VerticaD) * cameDir + verticalPos; //最远点 = 三角函数求得垂线点到最远点向量+ 垂线点坐标 } else { distantPoint = playerPosition + Play2VerticaN * MaxDis;//垂线上找到距离是 MaxDis 的坐标 } Vector3 Spheredirection = (distantPoint - m_ISpacecraftSkillProperty.GetRootTransform().position).normalized; //船到最远处单位方向向量 Quaternion cameraQuaternion = Quaternion.Euler(Quaternion.FromToRotation(Vector3.forward, Spheredirection).eulerAngles); //欧拉角-->四元数 Crucis.Protocol.Vec4 vec4 = new Crucis.Protocol.Vec4(); vec4.X = cameraQuaternion.x; vec4.Y = cameraQuaternion.y; vec4.Z = cameraQuaternion.z; vec4.W = cameraQuaternion.w; Vector3 tt = playerPosition + cameraQuaternion * Vector3.forward * d; Leyoutech.Utility.DebugUtility.LogWarning("目标方向", string.Format(" 摄像机注视方向射程最远点计算-----> 玩家自己entity = {0}, 玩家坐标:{1} , 计算得到方向 欧拉角 : {2} , 最大射程点坐标:{3}", m_ISpacecraftSkillProperty.EntityId(), playerPosition, cameraQuaternion, distantPoint)); return(vec4); }
/// <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); } }
private void DrawGizmo() { MainCameraComponent mainCam = CameraManager.GetInstance().GetMainCamereComponent(); if (mainCam == null) { return; } // 根据当前瞄准方向更新主区域的目标信息 m_MainAimArea.UpdateBaseRay(GetViewRay().direction); Vector3 baseRayPos = mainCam.GetPosition() + m_MainAimArea.GetBaseRay(); GizmosHelper.GetInstance().DrawCircle(baseRayPos, 0.05f); m_MainAimArea.UpdateRayList(false); m_MainAimArea.GetRayList(ref m_AimDirectionsCache); for (int iRay = 0; iRay < m_AimDirectionsCache.Count; iRay++) { Vector3 pos = mainCam.GetPosition() + m_AimDirectionsCache[iRay]; GizmosHelper.GetInstance().DrawCircle(pos, 0.005f); GizmosHelper.GetInstance().DrawLine(mainCam.GetPosition(), mainCam.GetPosition() + m_AimDirectionsCache[iRay] * 5); } // 根据当前瞄准方向更新主区域的目标信息 for (int iAim = 0; iAim < m_SubAimAreas.Count; iAim++) { m_SubAimAreas[iAim].UpdateBaseRay(GetViewRay().direction); baseRayPos = mainCam.GetPosition() + m_SubAimAreas[iAim].GetBaseRay(); GizmosHelper.GetInstance().DrawCircle(baseRayPos, 0.05f); m_SubAimAreas[iAim].UpdateRayList(false); m_SubAimAreas[iAim].GetRayList(ref m_AimDirectionsCache); for (int iRay = 0; iRay < m_AimDirectionsCache.Count; iRay++) { Vector3 pos = mainCam.GetPosition() + m_AimDirectionsCache[iRay]; GizmosHelper.GetInstance().DrawCircle(pos, 0.005f); GizmosHelper.GetInstance().DrawLine(mainCam.GetPosition(), mainCam.GetPosition() + m_AimDirectionsCache[iRay] * 5); } } }
private void DrawBoxOnGUI() { MainCameraComponent mainCam = CameraManager.GetInstance().GetMainCamereComponent(); if (mainCam == null) { return; } for (int iAim = 0; iAim < m_SubAimAreas.Count; iAim++) { AimArea aimArea = m_SubAimAreas[iAim]; m_SubAimAreas[iAim].UpdateBaseRay(GetViewRay().direction); Vector3 aimDir = m_SubAimAreas[iAim].GetBaseRay(); Vector3 pos = mainCam.GetPosition() + aimDir; Vector3 screenPos = mainCam.GetCamera().WorldToScreenPoint(pos); GizmosHelper.GetInstance().DrawGUIBox(screenPos, 100); } }
/// <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); } }