using System; using UnityEngine; using NUnit.Framework; using Framework.Support; namespace Framework.Actors.Shooter { /// Unit tests for the mouse-look head controller [TestFixture] internal class MouseLookHeadControllerTest { /// Runs before each unit test to set up the test environment [SetUp] public void Setup() { var rootGameObject = new GameObject(); this.root = rootGameObject.transform; var chestGameObject = new GameObject(); this.chest = chestGameObject.transform; this.chest.localPosition = new Vector3(0.0f, 0.1340575f, 0.0f); GameObjectHelper.SetAsChild(rootGameObject, chestGameObject); var neckGameObject = new GameObject(); this.neck = neckGameObject.transform; this.neck.localPosition = new Vector3(0.0f, 0.2578747f, 0.0f); GameObjectHelper.SetAsChild(chestGameObject, neckGameObject); var headGameObject = new GameObject(); this.head = headGameObject.transform; this.head.localPosition = new Vector3(0.0f, 0.104514f, 0.0f); GameObjectHelper.SetAsChild(neckGameObject, headGameObject); HeadPoser headPoser = rootGameObject.AddComponent(); headPoser.Chest = this.chest; headPoser.Neck = this.neck; headPoser.Head = this.head; MouseLookHeadController headController = rootGameObject.AddComponent< MouseLookHeadController >(); this.controller = headController; MethodInvoker.CallAwake(headPoser); MethodInvoker.CallAwake(headController); } /// Verifies that the base orientation is the parent of the chest bone [Test] public void BaseOrientationIsParentOfChest() { this.chest.parent.Rotate(Vector3.up, 45.0f); Quaternion rootOrientation = this.chest.parent.rotation; Quaternion headBaseOrientation = this.controller.HeadBaseOrientation; Assert.That(headBaseOrientation, Is.EqualTo(rootOrientation)); } /// Verifies that the base orientation is identical to the head poser [Test] public void BaseOrientationIsSameAsHeadPosers() { this.chest.parent.Rotate(Vector3.right, 45.0f); HeadPoser headPoser = this.chest.parent.gameObject.GetComponent(); Assert.That( this.controller.HeadBaseOrientation, Is.EqualTo(headPoser.GetBaseOrientation()) ); } /// /// Verifies that the virtual reality camera root transform is null for the mouse /// look controller /// /// /// If it was anything else, other components such as the ShooterActorController /// would assume that they have to counter-rotate the camera root transform when /// they rotate the actor in response to excess head rotation - which is not /// wanted in case of the mouse look controller. /// [Test] public void VirtualRealityCameraRootIsNull() { Assert.That(this.controller.VirtualRealityCameraRoot, Is.Null); } // Verifies that the 2D rectangle class can provide a describing string [Test] public void OrientationCanBeAssigned() { float yaw = 45.0f * Mathf.Deg2Rad; float pitch = 22.5f * Mathf.Deg2Rad; // Make sure the head starts out looking straight ahead Quaternion initialHeadOrientation = this.controller.LocalHeadOrientation; Assert.That(initialHeadOrientation, Is.EqualTo(Quaternion.identity)); // Assign a different head orientation. The mouse look controller will // convert the quaternion back into pitch and yaw internally. Quaternion newHeadOrientation = Quaternion.AngleAxis(yaw, Vector3.up) * Quaternion.AngleAxis(pitch, Vector3.right); this.controller.LocalHeadOrientation = newHeadOrientation; // Now retrieve the orientation again. The mouse look controller will // reconstruct the quaternion this time, and it should be identical. Assert.That( this.controller.LocalHeadOrientation, Is.EqualTo(newHeadOrientation) ); } // Bullshit test to stop compiler warnings about unused 'root' [Test] public void ChestMustBeChildOfActor() { Assert.That(this.chest.IsChildOf(this.root)); } /// /// Verifies that the IsActive property can be used without /// the controllables framework being used /// [Test, Ignore("Needs dependency injector to function in editor mode")] public void IsActiveWorksWithoutControllable() { Assert.That( () => this.controller.IsActive, Throws.Nothing ); } /// Bones the head controller will update private Transform root, chest, neck, head; /// Head controller being tested private IHeadController controller; } } // namespace Framework.Geometry.Areas