public void RegisterOwnerPlayer(IOwnerPlayer ownerPlayer) { Leyoutech.Utility.DebugUtility.Log(LOG_TAG, "Register Owner Player: " + (ownerPlayer == null ? "None" : ownerPlayer.GetDisplay())); m_OwnerPlayer = ownerPlayer; }
public void UnregisterOwnerPlayer(IOwnerPlayer ownerPlayer) { if (m_OwnerPlayer == ownerPlayer) { Leyoutech.Utility.DebugUtility.Log(LOG_TAG , "Unregister Owner Player: " + ownerPlayer.GetDisplay()); m_OwnerPlayer = null; } }
protected void LateUpdate() { if (m_OwnerPlayer == null || !m_OwnerPlayer.IsAlive()) { if (m_OwnerPlayer != null) { Leyoutech.Utility.DebugUtility.Log(LOG_TAG , "Unregister Owner Player because not alive"); } m_OwnerPlayer = null; m_LastFocusInteractable = null; return; } // fill camera state if (GameFacade._IsGaming) { MainCameraComponent cameraComponent = CameraManager.GetInstance().GetMainCamereComponent(); m_CameraState.HalfTanFov = cameraComponent.GetHalfTanFov(); m_CameraState.AspectRatio = CameraManager.GetInstance().GetAspectRatio(); } else { m_CameraState.HalfTanFov = Leyoutech.Utility.RendererUtility.CaculateHalfTanCameraFov(m_CameraState.Camera.fieldOfView); m_CameraState.AspectRatio = (float)Screen.width / Screen.height; } m_CameraState.WorldPosition = m_CameraState.Camera.transform.position; // foreach interactable Interactable focusInteractable = null; float maxWeight = float.MinValue; for (int iInteractable = 0; iInteractable < m_Interactables.Count; iInteractable++) { Interactable iterInteractable = m_Interactables[iInteractable]; IInteractable iterInteractableInstance = iterInteractable.Instance; Interactable.ForDebug forDebug = Interactable.EMPTY_FORDEBUG; if (!iterInteractableInstance.IsAlive()) { Leyoutech.Utility.DebugUtility.Log(LOG_TAG , "Unregister Interactable because not alive"); m_Interactables.RemoveAt(iInteractable); iInteractable--; continue; } #if UNITY_EDITOR if (m_EnableGizmos) { EditorExtend.GizmosHelper.GetInstance().DrawSphere(iterInteractableInstance.GetWorldPosition() , iterInteractableInstance.GetInteractableRadius() , Color.gray); } #endif // 判断距离能否交互 float interactableToOwnerPlayerDistanceSquare = (iterInteractableInstance.GetWorldPosition() - m_OwnerPlayer.GetWorldPosition()).sqrMagnitude; forDebug.ToPlayerDistanceSquare = interactableToOwnerPlayerDistanceSquare; if (interactableToOwnerPlayerDistanceSquare > iterInteractableInstance.GetInteractableDistanceSquare()) { m_Interactables[iInteractable]._ForDebug = forDebug; continue; } forDebug.MyAllowStep = Interactable.ForDebug.AllowStep.DistanceToPlayer; // 判断是否在屏幕内 Vector3 viewportPoint = m_CameraState.Camera.WorldToViewportPoint(iterInteractableInstance.GetWorldPosition()); forDebug.ViewportPoint = viewportPoint; // 到 以相机朝向为法线的平面 的距离 float interactableToCameraPlaneDistance = viewportPoint.z; // 在相机后方 if (interactableToCameraPlaneDistance < 0) { m_Interactables[iInteractable]._ForDebug = forDebug; continue; } forDebug.MyAllowStep = Interactable.ForDebug.AllowStep.InCameraForward; // 到相机的距离 Vector3 cameraToInteractableDirection = iterInteractableInstance.GetWorldPosition() - m_CameraState.WorldPosition; float interactableToCameraDistance = cameraToInteractableDirection.magnitude; float interactableRelativeHeight = Leyoutech.Utility.RendererUtility.CaculateRelativeHeightInScreen(iterInteractableInstance.GetInteractableRadius() * 0.5f , interactableToCameraDistance , m_CameraState.HalfTanFov); float interactableRelativeWidth = interactableRelativeHeight * m_CameraState.AspectRatio; bool inScreen = viewportPoint.x > SAFE_AREA_X - interactableRelativeWidth && viewportPoint.x <(1.0f + interactableRelativeWidth - SAFE_AREA_X) && viewportPoint.y> SAFE_AREA_Y - interactableRelativeHeight && viewportPoint.y < (1.0f + interactableRelativeHeight - SAFE_AREA_Y); forDebug.RelativeSize = new Vector2(interactableRelativeWidth, interactableRelativeHeight); if (!inScreen) { m_Interactables[iInteractable]._ForDebug = forDebug; continue; } forDebug.MyAllowStep = Interactable.ForDebug.AllowStep.InScreen; // 到屏幕中心距离 float interactableToScreenCenterWidth = (viewportPoint.x - 0.5f) * m_CameraState.AspectRatio; float interactableToScreenCenterHeight = (viewportPoint.y - 0.5f); // 单位是屏幕高度的平方(0表示在正中心,0.25表示距离中心半个屏幕高度) float interactableToScreenCenterDistanceSquare = interactableToScreenCenterWidth * interactableToScreenCenterWidth + interactableToScreenCenterHeight * interactableToScreenCenterHeight; forDebug.ToScreenCenterDistanceSquare = interactableToScreenCenterDistanceSquare; // 计算权重 float weight = 1.0f / interactableToScreenCenterDistanceSquare * interactableRelativeWidth * interactableRelativeWidth / interactableToOwnerPlayerDistanceSquare * iterInteractableInstance.GetInteractableDistanceSquare(); forDebug.Weight = weight; if (weight < maxWeight) { m_Interactables[iInteractable]._ForDebug = forDebug; continue; } forDebug.MyAllowStep = Interactable.ForDebug.AllowStep.Weight; // 检测目标是否被碰撞体遮挡 bool isRaycast = Physics.Raycast(m_CameraState.WorldPosition , cameraToInteractableDirection , interactableToCameraDistance - iterInteractableInstance.GetInteractableRadius() , m_PhysicsLayerMask); #if UNITY_EDITOR if (m_EnableGizmos) { EditorExtend.GizmosHelper.GetInstance().DrawLine(m_CameraState.WorldPosition , m_CameraState.WorldPosition + cameraToInteractableDirection * (interactableToCameraDistance - iterInteractableInstance.GetInteractableRadius()) / interactableToCameraDistance , isRaycast ? Color.red : Color.green); } #endif if (isRaycast) { m_Interactables[iInteractable]._ForDebug = forDebug; continue; } forDebug.MyAllowStep = Interactable.ForDebug.AllowStep.Raycast; maxWeight = weight; focusInteractable = iterInteractable; m_Interactables[iInteractable]._ForDebug = forDebug; } // change focus bool changedFocus = m_LastFocusInteractable == null ? focusInteractable != null : focusInteractable == null || focusInteractable.Instance != m_LastFocusInteractable; if (changedFocus) { Leyoutech.Utility.DebugUtility.Log(LOG_TAG , string.Format("ChangedFocus from ({0}) to ({1}): " , m_LastFocusInteractable == null || !m_LastFocusInteractable.IsAlive() ? "None" : m_LastFocusInteractable.GetDisplay() , focusInteractable == null || !focusInteractable.Instance.IsAlive() ? "None" : focusInteractable.Instance.GetDisplay())); if (m_LastFocusInteractable != null && m_LastFocusInteractable.IsAlive()) { m_LastFocusInteractable.SetFocus(false); } if (focusInteractable == null) { m_LastFocusInteractable = null; } else if (focusInteractable.Instance.GetIsActive()) { m_LastFocusInteractable = focusInteractable.Instance; m_LastFocusInteractable.SetFocus(true); } } if (m_LastFocusInteractable != null) { focusInteractable._ForDebug.MyAllowStep = Interactable.ForDebug.AllowStep.Pass; } }