145 lines
6.4 KiB
C#
145 lines
6.4 KiB
C#
|
// Copyright (c) Pixel Crushers. All rights reserved.
|
||
|
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace PixelCrushers.DialogueSystem
|
||
|
{
|
||
|
|
||
|
/// <summary>
|
||
|
/// The persistent position data component works with the PersistentDataManager to keep track
|
||
|
/// of a game object's position when saving and loading games or changing levels.
|
||
|
/// </summary>
|
||
|
[AddComponentMenu("")] // Use wrapper.
|
||
|
public class PersistentPositionData : MonoBehaviour
|
||
|
{
|
||
|
|
||
|
/// <summary>
|
||
|
/// (Optional) Normally, this component uses the game object's name as the name of the
|
||
|
/// actor in the Lua Actor[] table. If your actor is named differently in the Lua Actor[]
|
||
|
/// table (e.g., the actor has a different name in Chat Mapper or the DialogueDatabase),
|
||
|
/// then set this property to the Lua name.
|
||
|
/// </summary>
|
||
|
public string overrideActorName;
|
||
|
|
||
|
/// <summary>
|
||
|
/// If <c>true</c>, the object's current level is also recorded; and, on load, the
|
||
|
/// position is only applied if the current level matches the recorded level.
|
||
|
/// </summary>
|
||
|
public bool recordCurrentLevel = true;
|
||
|
|
||
|
[HideInInspector] // Deprecated.
|
||
|
public bool restoreCurrentLevelPosition = true;
|
||
|
|
||
|
private string actorName
|
||
|
{
|
||
|
get { return string.IsNullOrEmpty(overrideActorName) ? DialogueActor.GetPersistentDataName(gameObject.transform) : overrideActorName; }
|
||
|
}
|
||
|
|
||
|
protected virtual void OnEnable()
|
||
|
{
|
||
|
PersistentDataManager.RegisterPersistentData(gameObject);
|
||
|
}
|
||
|
|
||
|
protected virtual void OnDisable()
|
||
|
{
|
||
|
PersistentDataManager.UnregisterPersistentData(gameObject);
|
||
|
}
|
||
|
|
||
|
public void Start()
|
||
|
{
|
||
|
if (string.IsNullOrEmpty(overrideActorName))
|
||
|
{
|
||
|
overrideActorName = DialogueActor.GetPersistentDataName(transform);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Listens for the OnRecordPersistentData message and records the game object's position
|
||
|
/// and rotation into the Lua Actor[] table.
|
||
|
/// </summary>
|
||
|
public void OnRecordPersistentData()
|
||
|
{
|
||
|
string positionString = GetPositionString();
|
||
|
var fieldName = recordCurrentLevel ? "Position_" + SanitizeLevelName(Tools.loadedLevelName) : "Position";
|
||
|
if (DialogueDebug.logInfo) Debug.Log("Dialogue System: Persistent Position Data Actor[" + actorName + "]." + fieldName + "='" + positionString + "'", this);
|
||
|
DialogueLua.SetActorField(actorName, fieldName, positionString);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Listens for the OnApplyPersistentData message and retrieves the game object's position
|
||
|
/// and rotation from the Lua Actor[] table.
|
||
|
/// </summary>
|
||
|
public void OnApplyPersistentData()
|
||
|
{
|
||
|
string spawnpointName = DialogueLua.GetActorField(actorName, "Spawnpoint").asString;
|
||
|
if (!string.IsNullOrEmpty(spawnpointName))
|
||
|
{
|
||
|
var spawnpoint = Tools.GameObjectHardFind(spawnpointName);
|
||
|
if (spawnpoint == null)
|
||
|
{
|
||
|
if (DialogueDebug.logWarnings) Debug.LogWarning("Dialogue System: Persistent Position Data found Actor[" + actorName + "].Spawnpoint value '" + spawnpointName + "' but can't find a GameObject with this name in the scene. Moving actor to saved position instead.", this);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
transform.position = spawnpoint.transform.position;
|
||
|
transform.rotation = spawnpoint.transform.rotation;
|
||
|
if (DialogueDebug.logInfo) Debug.Log("Dialogue System: Persistent Position Data spawning " + actorName + " at spawnpoint " + spawnpoint, this);
|
||
|
}
|
||
|
DialogueLua.SetActorField(actorName, "Spawnpoint", string.Empty);
|
||
|
if (spawnpoint != null) return;
|
||
|
}
|
||
|
var fieldName = recordCurrentLevel ? "Position_" + SanitizeLevelName(Tools.loadedLevelName) : "Position";
|
||
|
var positionString = DialogueLua.GetActorField(actorName, fieldName).asString;
|
||
|
if (!string.IsNullOrEmpty(positionString))
|
||
|
{
|
||
|
if (DialogueDebug.logInfo) Debug.Log("Dialogue System: Persistent Position Data restoring " + actorName + " to position " + positionString, this);
|
||
|
ApplyPositionString(positionString);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (DialogueDebug.logInfo) Debug.Log("Dialogue System: Persistent Position Data Actor[" + actorName + "]." + fieldName + " is blank. Not moving " + actorName, this);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private string GetPositionString()
|
||
|
{
|
||
|
string optionalLevelName = recordCurrentLevel ? DialogueLua.DoubleQuotesToSingle("," + Tools.loadedLevelName) : string.Empty;
|
||
|
return string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0},{1},{2},{3},{4},{5},{6}{7}",
|
||
|
new System.Object[] { transform.position.x, transform.position.y, transform.position.z,
|
||
|
transform.rotation.x, transform.rotation.y, transform.rotation.z, transform.rotation.w,
|
||
|
optionalLevelName });
|
||
|
}
|
||
|
|
||
|
private void ApplyPositionString(string s)
|
||
|
{
|
||
|
if (string.IsNullOrEmpty(s) || s.Equals("nil")) return;
|
||
|
string[] tokens = s.Split(',');
|
||
|
if ((7 <= tokens.Length) && (tokens.Length <= 8))
|
||
|
{
|
||
|
if (recordCurrentLevel)
|
||
|
{
|
||
|
if ((tokens.Length == 8) && !string.Equals(tokens[7], Tools.loadedLevelName))
|
||
|
{
|
||
|
return; // This is not the recorded level. Don't apply position.
|
||
|
}
|
||
|
}
|
||
|
float[] values = new float[7];
|
||
|
for (int i = 0; i < 7; i++)
|
||
|
{
|
||
|
values[i] = 0;
|
||
|
float.TryParse(tokens[i], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out values[i]);
|
||
|
}
|
||
|
transform.position = new Vector3(values[0], values[1], values[2]);
|
||
|
transform.rotation = new Quaternion(values[3], values[4], values[5], values[6]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static string SanitizeLevelName(string levelName)
|
||
|
{
|
||
|
return DialogueLua.StringToTableIndex(levelName).Replace(".", "_");
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|