110 lines
3.9 KiB
C#
110 lines
3.9 KiB
C#
|
// Copyright (c) Pixel Crushers. All rights reserved.
|
||
|
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace PixelCrushers.DialogueSystem.SequencerCommands
|
||
|
{
|
||
|
|
||
|
/// <summary>
|
||
|
/// Implements sequencer command: "MoveTo(target, [, subject[, duration]])", which matches the
|
||
|
/// subject to the target's position and rotation. If the subject has a rigidbody, uses
|
||
|
/// Rigidbody.MovePosition/Rotation; otherwise sets the transform directly.
|
||
|
///
|
||
|
/// Arguments:
|
||
|
/// -# The target.
|
||
|
/// -# (Optional) The subject; can be speaker, listener, or the name of a game object.
|
||
|
/// Default: speaker.
|
||
|
/// -# (Optional) Duration in seconds.
|
||
|
/// </summary>
|
||
|
[AddComponentMenu("")] // Hide from menu.
|
||
|
public class SequencerCommandMoveTo : SequencerCommand
|
||
|
{
|
||
|
|
||
|
private const float SmoothMoveCutoff = 0.05f;
|
||
|
|
||
|
private Transform target;
|
||
|
private Transform subject;
|
||
|
private Rigidbody subjectRigidbody;
|
||
|
private float duration;
|
||
|
float startTime;
|
||
|
float endTime;
|
||
|
Vector3 originalPosition;
|
||
|
Quaternion originalRotation;
|
||
|
|
||
|
public void Start()
|
||
|
{
|
||
|
// Get the values of the parameters:
|
||
|
target = GetSubject(0);
|
||
|
subject = GetSubject(1);
|
||
|
duration = GetParameterAsFloat(2, 0);
|
||
|
if (DialogueDebug.logInfo) Debug.Log(string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}: Sequencer: MoveTo({1}, {2}, {3})", new System.Object[] { DialogueDebug.Prefix, target, subject, duration }));
|
||
|
if ((target == null) && DialogueDebug.logWarnings) Debug.LogWarning(string.Format("{0}: Sequencer: MoveTo() target '{1}' wasn't found.", new System.Object[] { DialogueDebug.Prefix, GetParameter(0) }));
|
||
|
if ((subject == null) && DialogueDebug.logWarnings) Debug.LogWarning(string.Format("{0}: Sequencer: MoveTo() subject '{1}' wasn't found.", new System.Object[] { DialogueDebug.Prefix, GetParameter(1) }));
|
||
|
|
||
|
// Set up the move:
|
||
|
if ((subject != null) && (target != null) && (subject != target))
|
||
|
{
|
||
|
subjectRigidbody = subject.GetComponent<Rigidbody>();
|
||
|
|
||
|
// If duration is above the cutoff, smoothly move toward target:
|
||
|
if (duration > SmoothMoveCutoff)
|
||
|
{
|
||
|
startTime = DialogueTime.time;
|
||
|
endTime = startTime + duration;
|
||
|
originalPosition = subject.position;
|
||
|
originalRotation = subject.rotation;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Stop();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Stop();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void SetPosition(Vector3 newPosition, Quaternion newRotation)
|
||
|
{
|
||
|
// For efficiency, doesn't warp NavMeshAgent.
|
||
|
if (subjectRigidbody != null && !subjectRigidbody.isKinematic)
|
||
|
{
|
||
|
subjectRigidbody.MoveRotation(newRotation);
|
||
|
subjectRigidbody.MovePosition(newPosition);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
subject.rotation = newRotation;
|
||
|
subject.position = newPosition;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void Update()
|
||
|
{
|
||
|
// Keep smoothing for the specified duration:
|
||
|
if (DialogueTime.time < endTime)
|
||
|
{
|
||
|
float elapsed = (DialogueTime.time - startTime) / duration;
|
||
|
SetPosition(Vector3.Lerp(originalPosition, target.position, elapsed), Quaternion.Lerp(originalRotation, target.rotation, elapsed));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Stop();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void OnDestroy()
|
||
|
{
|
||
|
// Final position:
|
||
|
if ((subject != null) && (target != null) && (subject != target))
|
||
|
{
|
||
|
SetPosition(target.position, target.rotation);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|