146 lines
6.3 KiB (Stored with Git LFS)
C#
146 lines
6.3 KiB (Stored with Git LFS)
C#
// Copyright (c) Pixel Crushers. All rights reserved.
|
|
|
|
using UnityEngine;
|
|
|
|
namespace PixelCrushers.DialogueSystem.SequencerCommands
|
|
{
|
|
|
|
/// <summary>
|
|
/// Implements sequencer command: Camera(angle[, gameobject|speaker|listener[, duration]])
|
|
///
|
|
/// Arguments:
|
|
/// -# Name of a camera angle (child transform) defined in cameraAngles. If the angle isn't
|
|
/// defined in Sequencer.CameraAngles, looks for a game object in the scene. Default: Closeup.
|
|
/// -# (Optional) The subject; can be speaker, listener, or the name of a game object. Default:
|
|
/// speaker.
|
|
/// -# (Optional) Duration over which to move the camera. Default: immediate.
|
|
/// </summary>
|
|
[AddComponentMenu("")] // Hide from menu.
|
|
public class SequencerCommandCamera : SequencerCommand
|
|
{
|
|
|
|
protected const float SmoothMoveCutoff = 0.05f;
|
|
|
|
protected Transform subject;
|
|
protected Transform angleTransform;
|
|
protected Transform cameraTransform;
|
|
protected bool isLocalTransform;
|
|
protected Quaternion targetRotation;
|
|
protected Vector3 targetPosition;
|
|
protected float duration;
|
|
protected float startTime;
|
|
protected float endTime;
|
|
protected Quaternion originalRotation;
|
|
protected Vector3 originalPosition;
|
|
|
|
protected virtual void Start()
|
|
{
|
|
// Get the values of the parameters:
|
|
string angle = GetParameter(0, "Closeup");
|
|
subject = GetSubject(1);
|
|
duration = GetParameterAsFloat(2, 0);
|
|
|
|
// Get angle:
|
|
bool isDefault = string.Equals(angle, "default");
|
|
if (isDefault) angle = SequencerTools.GetDefaultCameraAngle(subject);
|
|
bool isOriginal = string.Equals(angle, "original");
|
|
angleTransform = isOriginal
|
|
? ((Camera.main != null) ? Camera.main.transform : speaker)
|
|
: ((sequencer.cameraAngles != null) ? sequencer.cameraAngles.transform.Find(angle) : null);
|
|
isLocalTransform = true;
|
|
if (angleTransform == null)
|
|
{
|
|
isLocalTransform = false;
|
|
angleTransform = SequencerTools.GetSubject(angle, speaker, listener, null);
|
|
}
|
|
|
|
// Log:
|
|
if ((angleTransform == null) && DialogueDebug.logWarnings) Debug.LogWarning(string.Format("{0}: Sequencer: Camera({1}): Camera angle '{2}' wasn't found.", new System.Object[] { DialogueDebug.Prefix, GetParameters(), angle }));
|
|
else if ((subject == null && !isOriginal) && !(isLocalTransform && angleTransform != null) && DialogueDebug.logWarnings) Debug.LogWarning(string.Format("{0}: Sequencer: Camera({1}): Camera subject '{2}' or GameObject named '{3}' wasn't found.", new System.Object[] { DialogueDebug.Prefix, GetParameters(), GetParameter(1), GetParameter(0) }));
|
|
else if (DialogueDebug.logInfo) Debug.Log(string.Format("{0}: Sequencer: Camera({1}, {2}, {3}s)", new System.Object[] { DialogueDebug.Prefix, angle, Tools.GetGameObjectName(subject), duration }));
|
|
|
|
// If we have a camera angle and subject, move the camera to it:
|
|
sequencer.TakeCameraControl();
|
|
if (isOriginal || (angleTransform != null && (subject != null || isLocalTransform)))
|
|
{
|
|
cameraTransform = sequencer.sequencerCameraTransform;
|
|
if (isOriginal)
|
|
{
|
|
targetRotation = sequencer.originalCameraRotation;
|
|
targetPosition = sequencer.originalCameraPosition;
|
|
}
|
|
else if (isLocalTransform)
|
|
{
|
|
targetRotation = subject.rotation * angleTransform.localRotation;
|
|
targetPosition = subject.position + subject.rotation * angleTransform.localPosition;
|
|
}
|
|
else
|
|
{
|
|
targetRotation = angleTransform.rotation;
|
|
targetPosition = angleTransform.position;
|
|
}
|
|
|
|
// If duration is above the cutoff, smoothly move camera toward camera angle:
|
|
if (duration > SmoothMoveCutoff)
|
|
{
|
|
startTime = DialogueTime.time;
|
|
endTime = startTime + duration;
|
|
originalRotation = cameraTransform.rotation;
|
|
originalPosition = cameraTransform.position;
|
|
var useUnscaledTime = DialogueTime.mode != DialogueTime.TimeMode.Gameplay;
|
|
var easing = DialogueManager.displaySettings.cameraSettings.cameraEasing;
|
|
Tweener.Tween(originalPosition, targetPosition, duration, useUnscaledTime, easing,
|
|
onBegin: null,
|
|
onValue: (x) => cameraTransform.position = x,
|
|
onEnd: Stop);
|
|
Tweener.Tween(originalRotation, targetRotation, duration, useUnscaledTime, easing,
|
|
onBegin: null,
|
|
onValue: (x) => cameraTransform.rotation = x,
|
|
onEnd: Stop);
|
|
}
|
|
else
|
|
{
|
|
Stop();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Stop();
|
|
}
|
|
}
|
|
|
|
//--- We've switched to using the Tweener class to allow for more easing styles.
|
|
//--- This is just a safeguard now:
|
|
protected virtual void Update()
|
|
{
|
|
if (DialogueTime.time > endTime) Stop();
|
|
}
|
|
//public void Update()
|
|
//{
|
|
// // Keep smoothing for the specified duration:
|
|
// if (DialogueTime.time < endTime)
|
|
// {
|
|
// float elapsed = (DialogueTime.time - startTime) / duration;
|
|
// cameraTransform.rotation = Quaternion.Lerp(originalRotation, targetRotation, elapsed);
|
|
// cameraTransform.position = Vector3.Lerp(originalPosition, targetPosition, elapsed);
|
|
// }
|
|
// else
|
|
// {
|
|
// Stop();
|
|
// }
|
|
//}
|
|
|
|
protected virtual void OnDestroy()
|
|
{
|
|
// Final position:
|
|
if (angleTransform != null && subject != null)
|
|
{
|
|
cameraTransform.rotation = targetRotation;
|
|
cameraTransform.position = targetPosition;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|