| | 1 | | using DCL.Configuration; |
| | 2 | | using DCL.Controllers; |
| | 3 | | using DCL.ECSRuntime; |
| | 4 | | using DCL.Models; |
| | 5 | | using DCL.Components; |
| | 6 | | using UnityEngine; |
| | 7 | |
|
| | 8 | | namespace DCL.ECSComponents |
| | 9 | | { |
| | 10 | | public class CameraModeAreaComponentHandler : IECSComponentHandler<PBCameraModeArea> |
| | 11 | | { |
| | 12 | | private readonly DataStore_Player dataStore; |
| | 13 | | internal readonly IUpdateEventHandler updateEventHandler; |
| | 14 | |
|
| | 15 | | internal CameraModeRepresentantion cameraModeRepresentantion; |
| | 16 | | private UnityEngine.Vector3 area; |
| | 17 | | private IDCLEntity entity; |
| | 18 | | private IParcelScene scene; |
| | 19 | | internal PBCameraModeArea lastModel; |
| | 20 | |
|
| 5 | 21 | | internal ICameraModeAreasController areasController = new CameraModeAreasController(); |
| | 22 | | private Collider playerCollider; |
| | 23 | | internal bool isPlayerInside = false; |
| | 24 | |
|
| 5 | 25 | | public CameraModeAreaComponentHandler(IUpdateEventHandler updateEventHandler, DataStore_Player dataStore) |
| | 26 | | { |
| 5 | 27 | | this.updateEventHandler = updateEventHandler; |
| 5 | 28 | | this.dataStore = dataStore; |
| 5 | 29 | | } |
| | 30 | |
|
| | 31 | | public void OnComponentCreated(IParcelScene scene, IDCLEntity entity) |
| | 32 | | { |
| 5 | 33 | | Initialize(scene, entity, dataStore.ownPlayer.Get()?.collider); |
| 5 | 34 | | dataStore.ownPlayer.OnChange += OnOwnPlayerChange; |
| 5 | 35 | | } |
| | 36 | |
|
| | 37 | | public void OnComponentRemoved(IParcelScene scene, IDCLEntity entity) |
| | 38 | | { |
| 6 | 39 | | Dispose(); |
| 6 | 40 | | dataStore.ownPlayer.OnChange -= OnOwnPlayerChange; |
| 6 | 41 | | } |
| | 42 | |
|
| | 43 | | public void OnComponentModelUpdated(IParcelScene scene, IDCLEntity entity, PBCameraModeArea model) |
| | 44 | | { |
| | 45 | | // We check if the mode should change, and adjust the area for the new model |
| 4 | 46 | | bool cameraModeChanged = lastModel != null || model.Mode != lastModel?.Mode; |
| | 47 | |
|
| 4 | 48 | | area = ProtoConvertUtils.PBVectorToUnityVector(model.Area); |
| 4 | 49 | | lastModel = model; |
| | 50 | |
|
| | 51 | | // If the camera mode hasn't changed we skip the model |
| 4 | 52 | | if (!cameraModeChanged) |
| 0 | 53 | | return; |
| | 54 | |
|
| | 55 | | // We set the new mode |
| 4 | 56 | | cameraModeRepresentantion.SetCameraMode(ProtoConvertUtils.PBCameraEnumToUnityEnum(model.Mode)); |
| | 57 | |
|
| | 58 | | // If the mode must change and the player is inside, we change the mode here |
| 4 | 59 | | if (isPlayerInside) |
| 2 | 60 | | areasController.ChangeAreaMode(cameraModeRepresentantion); |
| 4 | 61 | | } |
| | 62 | |
|
| | 63 | | internal void Initialize(in IParcelScene scene, in IDCLEntity entity, in Collider playerCollider) |
| | 64 | | { |
| 5 | 65 | | this.playerCollider = playerCollider; |
| 5 | 66 | | this.scene = scene; |
| 5 | 67 | | this.entity = entity; |
| | 68 | |
|
| 5 | 69 | | updateEventHandler.AddListener(IUpdateEventHandler.EventType.Update, Update); |
| 5 | 70 | | cameraModeRepresentantion = new CameraModeRepresentantion(); |
| 5 | 71 | | } |
| | 72 | |
|
| | 73 | | internal void Update() |
| | 74 | | { |
| 1 | 75 | | if (lastModel == null) |
| 0 | 76 | | return; |
| | 77 | |
|
| 1 | 78 | | bool playerInside = IsPlayerInsideArea(); |
| | 79 | |
|
| | 80 | | switch (playerInside) |
| | 81 | | { |
| 0 | 82 | | case true when !isPlayerInside: |
| 0 | 83 | | areasController.AddInsideArea(cameraModeRepresentantion); |
| 0 | 84 | | break; |
| 1 | 85 | | case false when isPlayerInside: |
| 1 | 86 | | areasController.RemoveInsideArea(cameraModeRepresentantion); |
| | 87 | | break; |
| | 88 | | } |
| | 89 | |
|
| 1 | 90 | | isPlayerInside = playerInside; |
| 1 | 91 | | } |
| | 92 | |
|
| | 93 | | internal void Dispose() |
| | 94 | | { |
| 6 | 95 | | OnAreaDisabled(); |
| 6 | 96 | | updateEventHandler.RemoveListener(IUpdateEventHandler.EventType.Update, Update); |
| 6 | 97 | | } |
| | 98 | |
|
| | 99 | | private bool IsPlayerInsideArea() |
| | 100 | | { |
| 1 | 101 | | if (entity == null || scene == null || |
| | 102 | | scene.sceneData.id != CommonScriptableObjects.sceneID.Get()) |
| 1 | 103 | | return false; |
| | 104 | |
|
| 0 | 105 | | UnityEngine.Vector3 center = entity.gameObject.transform.position; |
| 0 | 106 | | Quaternion rotation = entity.gameObject.transform.rotation; |
| | 107 | |
|
| 0 | 108 | | Collider[] colliders = Physics.OverlapBox(center, area * 0.5f, rotation, |
| | 109 | | PhysicsLayers.avatarTriggerMask, QueryTriggerInteraction.Collide); |
| | 110 | |
|
| 0 | 111 | | if (colliders.Length == 0) |
| 0 | 112 | | return false; |
| | 113 | |
|
| 0 | 114 | | for (int i = 0; i < colliders.Length; i++) |
| | 115 | | { |
| 0 | 116 | | if (colliders[i] == playerCollider) |
| 0 | 117 | | return true; |
| | 118 | | } |
| 0 | 119 | | return false; |
| | 120 | | } |
| | 121 | |
|
| | 122 | | private void OnAreaDisabled() |
| | 123 | | { |
| 6 | 124 | | if (!isPlayerInside) |
| 4 | 125 | | return; |
| | 126 | |
|
| 2 | 127 | | areasController.RemoveInsideArea(cameraModeRepresentantion); |
| 2 | 128 | | isPlayerInside = false; |
| 2 | 129 | | } |
| | 130 | |
|
| | 131 | | private void OnOwnPlayerChange(Player current, Player previous) |
| | 132 | | { |
| 0 | 133 | | playerCollider = current.collider; |
| 0 | 134 | | } |
| | 135 | | } |
| | 136 | | } |