add camera rig, click-to-move locomotion, and click interaction
Camera: Cinemachine-based rig with an anchor, a state director, point-of- interest framing, pan input, and dialogue framing volumes. Player: click-to-move over the NavMesh, a pointer input layer, and a motion arbiter that reconciles direct stick input with navigation-driven movement. The pure math is isolated in NightclubArcadia.Locomotion.Math with an EditMode suite, so the arbitration rules are testable without a scene. Interaction: IClickInteractable plus a bridge that routes pointer clicks to it. Supporting project settings: adds the Cinemachine package, the Interactable and Ground tags the raycasts depend on, and NavMesh agent dimensions matched to the player capsule (radius 0.3, height 1.8, climb 0.25). Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
using NightclubArcadia.Player.Math;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NightclubArcadia.Locomotion.Math.Tests
|
||||
{
|
||||
public class MotionInputMathTests
|
||||
{
|
||||
[Test]
|
||||
public void WorldToCameraRelativeInput_ZeroVelocity_ReturnsZero()
|
||||
{
|
||||
var result = MotionInputMath.WorldToCameraRelativeInput(Vector3.zero, 2f, 0f);
|
||||
Assert.AreEqual(Vector2.zero, result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WorldToCameraRelativeInput_YawZero_PreservesForward()
|
||||
{
|
||||
var world = new Vector3(0f, 0f, 2f);
|
||||
var result = MotionInputMath.WorldToCameraRelativeInput(world, 2f, 0f);
|
||||
Assert.AreEqual(new Vector2(0f, 1f), result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WorldToCameraRelativeInput_Yaw90_RotatesCorrectly()
|
||||
{
|
||||
var world = new Vector3(0f, 0f, 2f);
|
||||
var result = MotionInputMath.WorldToCameraRelativeInput(world, 2f, 90f);
|
||||
Assert.That(result.x, Is.EqualTo(1f).Within(0.001f));
|
||||
Assert.That(result.y, Is.EqualTo(0f).Within(0.001f));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WorldToCameraRelativeInput_ClampFractionToOne()
|
||||
{
|
||||
var world = new Vector3(0f, 0f, 10f);
|
||||
var result = MotionInputMath.WorldToCameraRelativeInput(world, 2f, 0f);
|
||||
Assert.That(result.magnitude, Is.EqualTo(1f).Within(0.001f));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WorldToCameraRelativeInput_RoundTripsThroughAtan2()
|
||||
{
|
||||
var world = new Vector3(1f, 0f, 2f).normalized;
|
||||
var cameraYaw = 15f;
|
||||
var input = MotionInputMath.WorldToCameraRelativeInput(world, 1f, cameraYaw);
|
||||
var targetRotation = Mathf.Atan2(input.x, input.y) * Mathf.Rad2Deg + cameraYaw;
|
||||
var reconstructed = Quaternion.Euler(0f, targetRotation, 0f) * Vector3.forward;
|
||||
var flatWorld = new Vector3(world.x, 0f, world.z).normalized;
|
||||
|
||||
Assert.That(Vector3.Dot(reconstructed, flatWorld), Is.EqualTo(1f).Within(0.001f));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ScreenDeltaToWorldPan_UsesCameraBasis()
|
||||
{
|
||||
var right = Vector3.right;
|
||||
var forward = Vector3.forward;
|
||||
var delta = new Vector2(10f, 0f);
|
||||
var result = MotionInputMath.ScreenDeltaToWorldPan(delta, right, forward, 0.02f);
|
||||
Assert.AreEqual(new Vector3(-0.2f, 0f, 0f), result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3e10736152304d63ab3fc46cfdb2873
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "NightclubArcadia.Locomotion.Math.Tests",
|
||||
"rootNamespace": "NightclubArcadia.Locomotion.Math.Tests",
|
||||
"references": [
|
||||
"NightclubArcadia.Locomotion.Math",
|
||||
"UnityEngine.TestRunner",
|
||||
"UnityEditor.TestRunner"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": true,
|
||||
"precompiledReferences": [
|
||||
"nunit.framework.dll"
|
||||
],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [
|
||||
"UNITY_INCLUDE_TESTS"
|
||||
],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: caa98c93c07f34ac6aedf23ee4f45c2a
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user