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