NWH Common
Search Results for

    Camera System

    NWH Common provides camera switching, an extensible vehicle-camera base class, mouse/gamepad orbit controls, and an interior-camera marker. The runtime types are in NWH.Common.Cameras.

    Dependency context: NWH.Common.Vehicles.Vehicle is abstract, and NWH Common does not ship a concrete vehicle component. CameraChanger and CameraInsideVehicle therefore require either a consuming NWH product with a concrete Vehicle subclass (such as Vehicle Physics VehicleController, Aerodynamics AircraftController, or DWP AdvancedShipController) or a project-defined Vehicle subclass. A Common-only project cannot add the abstract Vehicle type as a component.

    CameraChanger

    CameraChanger enables one camera GameObject at a time and disables the others, including any AudioListener on those same GameObjects.

    Required hierarchy

    CameraChanger must be on the Vehicle GameObject or one of its descendants. During Awake it calls GetComponentInParent<Vehicle>(); without that parent it logs an error and does not register for the vehicle lifecycle events.

    Vehicle (Vehicle-derived component)
    └── Cameras (CameraChanger)
        ├── Chase Camera
        └── Interior Camera
    

    With autoFindCameras enabled, the component collects every Camera on its own GameObject and on any descendant, including inactive ones, in hierarchy order. The implementation does not filter by tag. Disable autoFindCameras to maintain the cameras list manually.

    currentCameraIndex selects the first active entry. It is clamped to the list before a camera is activated, so an index left over from a shorter list no longer disables every camera.

    Input and lifecycle

    While the parent vehicle is enabled and locally owned, CameraChanger combines SceneInputProviderBase.ChangeCamera() from the scene's registered input providers. A true result calls NextCamera().

    The component also responds to the parent Vehicle:

    • vehicle enable: enable the current camera and disable the others;
    • vehicle disable: disable every camera; and
    • remote multiplayer status: disable every camera for a remote instance.

    Public methods

    NextCamera() and PreviousCamera() are the only public switching methods. Both wrap at the ends of the list and update camera and listener active states.

    using NWH.Common.Cameras;
    using UnityEngine;
    
    public sealed class CameraButtons : MonoBehaviour
    {
        [SerializeField] private CameraChanger cameraChanger;
    
        public void Next()
        {
            cameraChanger.NextCamera();
        }
    
        public void Previous()
        {
            cameraChanger.PreviousCamera();
        }
    }
    

    CameraChanger does not expose SetCamera, camera-change events, or a public enable/disable-all method.

    VehicleCamera

    VehicleCamera is the base class that ships for vehicle-following camera implementations. It contains a public Transform target and a virtual Awake() method.

    When target is unassigned, Awake() looks for a parent Rigidbody and uses its Transform. A custom camera can inherit the base and implement its own movement:

    using NWH.Common.Cameras;
    using UnityEngine;
    
    public sealed class FixedOffsetVehicleCamera : VehicleCamera
    {
        public Vector3 localOffset = new(0f, 2f, -6f);
    
        private void LateUpdate()
        {
            if (target == null)
            {
                return;
            }
    
            transform.position = target.TransformPoint(localOffset);
            transform.LookAt(target);
        }
    }
    

    Assign target explicitly when the camera is not below the target Rigidbody.

    CameraMouseDrag

    CameraMouseDrag derives from VehicleCamera and supports first-person or third-person operation. It reads the combined camera rotation, panning, modifiers, and zoom values from SceneInputProviderBase.

    Setup:

    1. Add a Camera and CameraMouseDrag to the camera GameObject.
    2. Place it below the target Rigidbody or assign target.
    3. Add an InputSystemSceneInputProvider, InputManagerSceneInputProvider, or custom SceneInputProviderBase implementation to the scene.
    4. Configure povType and rotation/panning settings. For third person, also configure distance and zoom.

    Third-person-only options include auto-centering, speed-based field of view/distance/height, and look-ahead. Camera shake is available in both modes.

    The scene provider controls whether rotation or panning requires its modifier button through requireCameraRotationModifier and requireCameraPanningModifier.

    CameraInsideVehicle

    Add CameraInsideVehicle to a camera that should update the owning vehicle's interior-camera state. This component also requires a Vehicle in its parent hierarchy.

    While enabled it writes isInsideVehicle to Vehicle.CameraInsideVehicle every frame.

    Whenever CameraChanger activates a camera - on vehicle enable, on a ChangeCamera() input, or through a direct NextCamera() / PreviousCamera() call - it inspects the newly selected camera on the following Update and treats a missing marker as outside. The marker on the active camera then keeps writing that state each frame.

    Because the flag is written every frame by whichever marker is active, add CameraInsideVehicle to every camera in the rig and set isInsideVehicle to false on the exterior views. A camera with no marker leaves the vehicle in the outside state.

    Typical Setup

    1. Put a CameraChanger below the vehicle root.
    2. Create each camera as its child.
    3. Add CameraMouseDrag to cameras that need interactive movement.
    4. Add CameraInsideVehicle to every camera. Set isInsideVehicle to false on the exterior views.
    5. Leave autoFindCameras enabled, or disable it and order the cameras list manually.
    6. Add one scene input provider for camera controls.

    Use one active AudioListener per view. When the listener is on the same GameObject as a listed camera, CameraChanger keeps its enabled state synchronized automatically.

    Troubleshooting

    CameraChanger reports that no parent Vehicle exists

    Move it below a concrete component derived from NWH.Common.Vehicles.Vehicle. If only NWH Common is installed, supply a project-defined subclass; the abstract Common Vehicle type cannot be added directly.

    No cameras were found

    With autoFindCameras enabled, cameras must be descendants of the CameraChanger GameObject. Otherwise disable automatic discovery and populate cameras.

    Orbit input does nothing

    Verify that a SceneInputProviderBase implementation is active and that its rotation modifier is held, unless requireCameraRotationModifier is disabled.

    A custom VehicleCamera has no target

    Assign target or parent the camera below a Rigidbody before Awake.

    In this article
    Back to top Copyright © NWH - Vehicle Physics, Aerodynamics, Dynamic Water Physics