Skip to main content

3D preview

Getting the model​

You need a model of your car where all the parts you want to animate are lose and movable. You don't need to rig anything on it in Blender.

Orbit camera​

To make the orbit camera I used Cinemachine with the CinemachineFreeLook.

To control the camera with the mouse or touch screen I used the old input system, but you can also use the new input system.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;

[RequireComponent(typeof(CinemachineFreeLook))]
public class FreeLookInput : MonoBehaviour
{
private CinemachineFreeLook freeLookCamera;

private string XAxisName = "Mouse X";
private string YAxisName = "Mouse Y";

public float resetDuration = 0.5f; // Duration for setting the rotation

private Coroutine resetCoroutine;

private void Start()
{
freeLookCamera = GetComponent<CinemachineFreeLook>();
freeLookCamera.m_XAxis.m_InputAxisName = "";
freeLookCamera.m_YAxis.m_InputAxisName = "";
}


private void Update()
{
if (Input.GetMouseButton(0) && !Utilities.IsOverUI())
{
freeLookCamera.m_XAxis.m_InputAxisValue = -Input.GetAxis(XAxisName);
freeLookCamera.m_YAxis.m_InputAxisValue = -Input.GetAxis(YAxisName);
}
else
{
freeLookCamera.m_XAxis.m_InputAxisValue = 0;
freeLookCamera.m_YAxis.m_InputAxisValue = 0;
}
}

public void FollowCamView()
{
SetRotation(new Vector2(180f, 0.67f));
}

public void SetRotation(Vector2 targetRotation)
{
if (resetCoroutine != null)
StopCoroutine(resetCoroutine);

resetCoroutine = StartCoroutine(SetRotationSmoothly(targetRotation));
}

IEnumerator SetRotationSmoothly(Vector2 targetRotation)
{
float elapsedTime = 0f;
Vector2 startRotation = new Vector2(freeLookCamera.m_XAxis.Value, freeLookCamera.m_YAxis.Value);

while (elapsedTime < resetDuration)
{
float t = elapsedTime / resetDuration;
freeLookCamera.m_XAxis.Value = Mathf.Lerp(startRotation.x, targetRotation.x, t);
freeLookCamera.m_YAxis.Value = Mathf.Lerp(startRotation.y, targetRotation.y, t);
elapsedTime += Time.deltaTime;
yield return null;
}

freeLookCamera.m_XAxis.Value = targetRotation.x;
freeLookCamera.m_YAxis.Value = targetRotation.y;
}
}

The Utilities class:

public static class Utilities
{
/// <summary>Check if Pointer is over UI</summary>
/// <returns><see cref="bool"/> <see langword="true"/> if Pointer is over UI</returns>
public static bool IsOverUI()
{
PointerEventData pointerEventData = new PointerEventData(EventSystem.current) { position = Input.mousePosition };
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(pointerEventData, results);
return results.Count > 0;
}
}