CapersProject/Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Save System/PersistentPositionData.cs

145 lines
6.4 KiB
C#
Raw Normal View History

// 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(".", "_");
}
}
}