// Copyright (C) 2023 Nicholas Maltbie // // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and // associated documentation files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, publish, distribute, // sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all copies or // substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. using System.Collections; using nickmaltbie.OpenKCC.CameraControls; using nickmaltbie.OpenKCC.Character; using nickmaltbie.TestUtilsUnity; using nickmaltbie.TestUtilsUnity.Tests.TestCommon; using NUnit.Framework; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.TestTools; namespace nickmaltbie.OpenKCC.Tests.EditMode.Character { /// /// Basic tests for in edit mode. /// [TestFixture] public class CameraControlsTests : TestBase { private MockUnityService unityServiceMock; private CameraController cameraController; private Gamepad gamepad; private InputAction lookInputAction; private InputAction zoomInputAction; private StickControl lookAction; private StickControl zoomAction; private GameObject box; [SetUp] public override void Setup() { base.Setup(); GameObject go = CreateGameObject(); cameraController = go.AddComponent(); unityServiceMock = new MockUnityService(); cameraController.config.cameraTransform = cameraController.transform; cameraController.unityService = unityServiceMock; unityServiceMock.deltaTime = 0.1f; InputActionMap actionMap; (gamepad, _, actionMap) = base.SetupInputDevice(); zoomAction = gamepad.rightStick; lookAction = gamepad.leftStick; zoomInputAction = actionMap.AddAction("zoomAction", InputActionType.Value, zoomAction.path); lookInputAction = actionMap.AddAction("lookAction", InputActionType.Value, lookAction.path); cameraController.config.ZoomAction = InputActionReference.Create(zoomInputAction); cameraController.config.LookAction = InputActionReference.Create(lookInputAction); lookInputAction.Enable(); zoomInputAction.Enable(); cameraController.Start(); PlayerInputUtils.playerMovementState = PlayerInputState.Allow; cameraController.config.minCameraDistance = 0.0f; cameraController.config.maxCameraDistance = 10.0f; } [UnitySetUp] public IEnumerator UnitySetUp() { box = CreateGameObject(); box.AddComponent(); yield return null; } [TearDown] public override void TearDown() { base.TearDown(); PlayerInputUtils.playerMovementState = PlayerInputState.Allow; } [Test] public void Validate_CaemraController_CameraBase() { Assert.AreEqual(cameraController.config.cameraTransform, cameraController.CameraBase); } [Test] public void Validate_CameraController_DisallowMovement() { PlayerInputUtils.playerMovementState = PlayerInputState.Deny; Assert.AreEqual(0, cameraController.Pitch); Assert.AreEqual(0, cameraController.Yaw); Assert.AreEqual(0, cameraController.PlayerHeading.eulerAngles.y); Set(lookAction, Vector3.up); cameraController.Update(); Assert.AreEqual(0, cameraController.Pitch); Assert.AreEqual(0, cameraController.Yaw); Assert.AreEqual(0, cameraController.PlayerHeading.eulerAngles.y); Set(lookAction, Vector3.left); cameraController.Update(); Assert.AreEqual(0, cameraController.Pitch); Assert.AreEqual(0, cameraController.Yaw); Assert.AreEqual(0, cameraController.PlayerHeading.eulerAngles.y); } [Test] public void Validate_CameraController_BasicMovement([Values] bool rotatePlayer) { cameraController.config.rotatePlayer = rotatePlayer; Assert.AreEqual(0, cameraController.Pitch); Assert.AreEqual(0, cameraController.Yaw); Assert.AreEqual(0, cameraController.PlayerHeading.eulerAngles.y); Set(lookAction, Vector3.up); cameraController.Update(); Assert.AreEqual(-cameraController.config.rotationRate * 0.1f * 0.25f, cameraController.Pitch); Assert.AreEqual(0, cameraController.Yaw); Assert.AreEqual(0, cameraController.PlayerHeading.eulerAngles.y); Set(lookAction, Vector3.left); cameraController.Update(); Assert.AreEqual(-cameraController.config.rotationRate * 0.1f * 0.25f, cameraController.Pitch); Assert.AreEqual(-cameraController.config.rotationRate * 0.1f * 0.25f, cameraController.Yaw); Assert.AreEqual((-cameraController.config.rotationRate * 0.1f * 0.25f + 360) % 360, (cameraController.PlayerHeading.eulerAngles.y + 360) % 360); } [Test] public void Validate_CameraController_IgnoreObjects( [NUnit.Framework.Range(2, 10, 4)] float dist ) { cameraController.transform.position = Vector3.forward * dist; cameraController.config.currentDistance = dist; cameraController.config.AddIgnoreObject(box); cameraController.Update(); TestUtils.AssertInBounds(cameraController.config.CameraDistance, dist); cameraController.config.RemoveIgnoreObject(box); } [Test] public void Validate_CameraController_SphereCast( [NUnit.Framework.Range(2, 10, 4)] float dist ) { cameraController.transform.position = Vector3.forward * dist; cameraController.config.currentDistance = dist; Debug.DrawRay(cameraController.transform.position, -cameraController.transform.forward * cameraController.config.currentDistance); cameraController.Update(); TestUtils.AssertInBounds(cameraController.config.CameraDistance, dist - 0.5f, 0.25f); } [Test] public void Validate_CameraController_ThirdPerson( [NUnit.Framework.Range(2, 10, 4)] float dist ) { cameraController.transform.position = Vector3.forward * dist; cameraController.config.currentDistance = dist; cameraController.config.thirdPersonCharacterBase = cameraController.gameObject; cameraController.Update(); } [Test] public void Validate_CameraController_ThirdPerson_Dither( [NUnit.Framework.Range(0, 1, 0.1f)] float dist ) { cameraController.transform.position = Vector3.forward * (0.5f + dist); cameraController.config.currentDistance = 2.0f; cameraController.config.thirdPersonCharacterBase = cameraController.gameObject; cameraController.Update(); } } }