using Prism; namespace FPSExample { public class FPSPlayer : Entity { public float WalkingSpeed = 10.0F; public float RunSpeed = 20.0F; public float JumpForce = 50.0F; public float MouseSensitivity = 10.0F; public float Distance = 5.0F; private bool m_Colliding = false; private float m_CurrentSpeed; private RigidBodyComponent m_RigidBody; private TransformComponent m_Transform; private TransformComponent m_CameraTransform; private Entity m_CameraEntity; private Vec2 m_LastMousePosition; private float m_CameraRotationX = 0.0f; private float m_RotationY = 0.0f; void OnCreate() { m_Transform = GetComponent(); m_RigidBody = GetComponent(); m_CurrentSpeed = WalkingSpeed; AddCollisionBeginCallback((n) => { m_Colliding = true; }); AddCollisionEndCallback((n) => { m_Colliding = false; }); m_CameraEntity = FindEntityByTag("Camera"); m_CameraTransform = m_CameraEntity.GetComponent(); m_LastMousePosition = Input.GetMousePosition(); Input.SetCursorMode(Input.CursorMode.Locked); } void OnUpdate(float ts) { if (Input.IsKeyPressed(KeyCode.Escape) && Input.GetCursorMode() == Input.CursorMode.Locked) Input.SetCursorMode(Input.CursorMode.Normal); if(Input.IsMouseButtonPressed(Input.MouseButton.Left) && Input.GetCursorMode() == Input.CursorMode.Normal) Input.SetCursorMode(Input.CursorMode.Locked); m_CurrentSpeed = Input.IsKeyPressed(KeyCode.LeftControl) ? RunSpeed : WalkingSpeed; UpdateRotation(ts); UpdateMovement(); UpdateCameraTransform(); } private void UpdateRotation(float ts) { Vec2 currentMousePosition = Input.GetMousePosition(); Vec2 delta = m_LastMousePosition - currentMousePosition; if (delta.X != 0) { m_RotationY += delta.X * MouseSensitivity * ts; } m_RigidBody.Rotate(new Vec3(0.0F, delta.X * MouseSensitivity, 0.0f) * ts); if (delta.Y != 0.0F) { m_CameraRotationX += delta.Y * MouseSensitivity * ts; m_CameraRotationX = Mathf.Clamp(m_CameraRotationX, -80.0f, 80.0f); } m_LastMousePosition = currentMousePosition; } Collider[] colliders = new Collider[10]; private void UpdateMovement() { RaycastHit hitInfo; if (Input.IsKeyPressed(KeyCode.H) && Physics.Raycast(m_CameraTransform.Transform.Translation + (m_CameraTransform.Forward * 5.0f), m_CameraTransform.Forward, 20.0f, out hitInfo)) { FindEntityByID(hitInfo.EntityID).GetComponent().Mesh.GetMaterial(0).Set("u_AlbedoColor", new Vec3(1.0f ,0.0f, 0.0f)); } if (Input.IsKeyPressed(KeyCode.I)) { // NOTE: The NonAlloc version of Overlap functions should be used when possible since it doesn't allocate a new array // whenever you call it. The normal versions allocates a brand new array every time. int numColliders = Physics.OverlapBoxNonAlloc(m_Transform.Transform.Translation, new Vec3(1.0F), colliders); Console.WriteLine("Colliders: {0}", numColliders); // When using NonAlloc it's not safe to use a foreach loop since some of the colliders may not exist for (int i = 0; i < numColliders; i++) { Console.WriteLine(colliders[i]); } } if (Input.IsKeyPressed(KeyCode.W)) m_RigidBody.AddForce(m_Transform.Forward * m_CurrentSpeed); else if (Input.IsKeyPressed(KeyCode.S)) m_RigidBody.AddForce(m_Transform.Forward * -m_CurrentSpeed); if (Input.IsKeyPressed(KeyCode.A)) m_RigidBody.AddForce(m_Transform.Right * -m_CurrentSpeed); else if (Input.IsKeyPressed(KeyCode.D)) m_RigidBody.AddForce(m_Transform.Right * m_CurrentSpeed); if (Input.IsKeyPressed(KeyCode.Space) && m_Colliding) m_RigidBody.AddForce(Vec3.Up * JumpForce); } private void UpdateCameraTransform(){ // TODO: This workflow needs to be improved. (Will be fixed by object parenting) Mat4 cameraTransform = m_CameraTransform.Transform; Vec3 cameraTranslation = cameraTransform.Translation; Vec3 translation = m_Transform.Transform.Translation; cameraTranslation.XZ = translation.XZ; cameraTranslation.Y = translation.Y + 1.5F; cameraTransform.Translation = cameraTranslation + m_CameraTransform.Forward * -Mathf.Clamp(Distance, 0, 10); m_CameraTransform.Transform = cameraTransform; m_CameraTransform.Rotation = new Vec3(m_CameraRotationX, m_RotationY, 0.0f); } } }