using FlaxEngine; using Cabrito; using System.Diagnostics; using System.IO; namespace Game { public class CameraMovement : Script { [Limit(0, 9000), Tooltip("Camera speed")] public float MoveSpeed { get; set; } = 400; private float viewPitch; private float viewYaw; private float viewRoll; 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; viewPitch = initialEulerAngles.X; viewYaw = initialEulerAngles.Y; viewRoll = initialEulerAngles.Z; } public override void OnUpdate() { var camTrans = Actor.Transform; var rootActor = Actor.GetChild(0); var camera = rootActor.GetChild(); float xAxis = InputManager.GetAxisRaw("Mouse X"); float yAxis = InputManager.GetAxisRaw("Mouse Y"); if (xAxis != 0.0f || yAxis != 0.0f) { viewPitch += yAxis; viewYaw += xAxis; viewPitch = Mathf.Clamp(viewPitch, -90.0f, 90.0f); // root orientation must be set first rootActor.Orientation = Quaternion.Euler(0, viewYaw, 0); camera.Orientation = Quaternion.Euler(viewPitch, viewYaw, viewRoll); } float inputH = InputManager.GetAxis("Horizontal"); float inputV = InputManager.GetAxis("Vertical"); var move = new Vector3(inputH, 0.0f, inputV); if (!move.IsZero) { move.Normalize(); move = camera.Transform.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; } } }