Created
May 4, 2020 20:11
-
-
Save janhohenheim/dc3358ec7483e4a999379badd86408fb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using Player; | |
| using Unity.Collections; | |
| using Unity.Entities; | |
| using Unity.Mathematics; | |
| using Unity.Physics; | |
| using Unity.Physics.Systems; | |
| using Unity.Transforms; | |
| using UnityEngine; | |
| namespace Camera | |
| { | |
| [UpdateAfter(typeof(MovementSystem))] | |
| public class FollowPlayerSystem : ComponentSystem | |
| { | |
| private const float MaxCameraDistance = 10f; | |
| private InputManager _inputManager; | |
| private BuildPhysicsWorld _buildPhysicsWorld; | |
| protected override void OnStartRunning() | |
| { | |
| base.OnStartRunning(); | |
| _buildPhysicsWorld = World.GetOrCreateSystem<BuildPhysicsWorld>(); | |
| } | |
| protected override void OnCreate() | |
| { | |
| base.OnCreate(); | |
| _inputManager = new InputManager(); | |
| _inputManager.Enable(); | |
| } | |
| protected override void OnUpdate() | |
| { | |
| Entities | |
| .WithAll<CameraTag>() | |
| .ForEach(( | |
| ref Translation cameraTranslation, | |
| ref LocalToWorld localToWorld, | |
| ref Rotation cameraRotation) => | |
| { | |
| var playerTranslation = GetPlayerTranslation(); | |
| var vectorFromPlayerToNewCameraPosition = CalculateVectorFromPlayerToNewCameraPosition(cameraTranslation, playerTranslation); | |
| var newCameraPosition = playerTranslation.Value + vectorFromPlayerToNewCameraPosition; | |
| var adjustedCameraPosition = MovePositionBeforeWalls(newCameraPosition, playerTranslation.Value); | |
| cameraTranslation.Value = adjustedCameraPosition; | |
| cameraRotation.Value = quaternion.LookRotationSafe(-vectorFromPlayerToNewCameraPosition, new float3(0f, 1f, 0f)); | |
| }); | |
| } | |
| private float3 CalculateVectorFromPlayerToNewCameraPosition(Translation cameraTranslation, Translation playerTranslation) | |
| { | |
| const float cameraSensitivity = 2f; | |
| var vectorFromPlayerToCamera = cameraTranslation.Value - playerTranslation.Value; | |
| var input = _inputManager.Player.MoveCamera.ReadValue<Vector2>(); | |
| var inputAsEulerAngles = new float3(input.y * 0.01f * cameraSensitivity, input.x * 0.01f * cameraSensitivity, 0f); | |
| var rotatedVectorFromPlayerToCamera = math.mul(quaternion.Euler(inputAsEulerAngles), vectorFromPlayerToCamera); | |
| var normalizedVectorFromPlayerToCamera = math.normalizesafe(rotatedVectorFromPlayerToCamera); | |
| return normalizedVectorFromPlayerToCamera * MaxCameraDistance; | |
| } | |
| private float3 MovePositionBeforeWalls(float3 cameraPosition, float3 playerPosition) | |
| { | |
| var rayCastInput = new RaycastInput | |
| { | |
| Start = playerPosition, | |
| End = cameraPosition, | |
| Filter = new CollisionFilter | |
| { | |
| BelongsTo = 1u << PhysicsLayerBits.Player, | |
| CollidesWith = 1u << PhysicsLayerBits.Terrain | |
| } | |
| }; | |
| if (!_buildPhysicsWorld.PhysicsWorld.CollisionWorld.CastRay(rayCastInput, out var hit)) | |
| { | |
| return cameraPosition; | |
| } | |
| var distanceToWall = MaxCameraDistance * hit.Fraction; | |
| var vectorFromPlayerToCamera = cameraPosition - playerPosition; | |
| var normalizedVectorFromPlayerToCamera = math.normalizesafe(vectorFromPlayerToCamera); | |
| var adjustedVectorFromPlayerToCamera = normalizedVectorFromPlayerToCamera * distanceToWall; | |
| return playerPosition + adjustedVectorFromPlayerToCamera; | |
| } | |
| private Translation GetPlayerTranslation() | |
| { | |
| var playerTranslation = new Translation(); | |
| Entities | |
| .WithAll<PlayerTag>() | |
| .ForEach((ref Translation innerPlayerTranslation) => | |
| { | |
| playerTranslation = innerPlayerTranslation; | |
| }); | |
| return playerTranslation; | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment