using FlaxEngine; using Cabrito; using System.Diagnostics; namespace Game { public class CameraMovement : Script { [Limit(0, 9000), Tooltip("Camera speed")] public float MoveSpeed { get; set; } = 400; private float _pitch; private float _yaw; private float xAxis; private float yAxis; private float inputH; private float inputV; private InputEvent onExit = new InputEvent("Exit"); public override void OnAwake() { base.OnAwake(); onExit.Triggered += () => { if (Console.IsSafeToQuit) Engine.RequestExit(); }; } public override void OnDestroy() { base.OnDestroy(); onExit.Dispose(); } public override void OnStart() { var initialEulerAngles = Actor.Orientation.EulerAngles; _pitch = initialEulerAngles.X; _yaw = initialEulerAngles.Y; } public override void OnUpdate() { var camTrans = Actor.Transform; xAxis = InputManager.GetAxis("Mouse X"); yAxis = InputManager.GetAxis("Mouse Y"); if (xAxis != 0.0f || yAxis != 0.0f) { _pitch += yAxis; _yaw += xAxis; camTrans.Orientation = Quaternion.Euler(_pitch, _yaw, 0); } inputH = InputManager.GetAxis("Horizontal"); inputV = InputManager.GetAxis("Vertical"); var move = new Vector3(inputH, 0.0f, inputV); if (!move.IsZero) { move.Normalize(); move = camTrans.TransformDirection(move) * MoveSpeed; { Vector3 delta = move * Time.UnscaledDeltaTime; float movementLeft = delta.Length; // TODO: check multiple times in case we get stuck in walls float sphereRadius = 10.0f; // TODO: use collider radius RayCastHit[] hitInfos; float moveDist = delta.Length; Physics.SphereCastAll(Actor.Transform.Translation, sphereRadius, move.Normalized, out hitInfos, moveDist); //bool nohit = true; float hitDistance = moveDist; Vector3 hitNormal = move.Normalized; foreach (RayCastHit hitInfo in hitInfos) { if (hitInfo.Collider.Parent == Parent) continue; if (hitInfo.Distance < hitDistance) { hitDistance = hitInfo.Distance; hitNormal = hitInfo.Normal; } //nohit = false; //break; } if (hitDistance != moveDist) { //camTrans.Translation = Vector3.Lerp(Actor.Transform.Translation, camTrans.Translation, hitDistance); //projected = normal * dot(direction, normal); //direction = direction - projected //camTrans.Translation += hitNormal * (moveDist - hitDistance); // correct? //camTrans.Translation = hitNormal * (move * hitNormal); // correct? //camTrans.Translation = Actor.Transform.Translation; delta += -Vector3.Dot(delta, hitNormal) * hitNormal; // correct? } camTrans.Translation += delta; } } Actor.Transform = camTrans; } } }