164 lines
6.6 KiB
C#
164 lines
6.6 KiB
C#
using UnityEngine;
|
|
|
|
// Sci-Fi Ship Controller. Copyright (c) 2018-2023 SCSM Pty Ltd. All rights reserved.
|
|
namespace SciFiShipController
|
|
{
|
|
/// <summary>
|
|
/// Sample to create a new Path in the scene at runtime and then teleport the ship and path.
|
|
/// This works a bit like a floating point error manager.
|
|
/// Setup:
|
|
/// 1. Attach this to an empty gameobject in the scene
|
|
/// 2. Add an NPC ship to the scene
|
|
/// 3. Add a Ship AI Input Module to the NPC ship
|
|
/// 4. Add the PlayerCamera prefab to the scene
|
|
/// 5. Add the PlayerCamera to the shipCameraModule slot
|
|
/// 6. Place other non-ship environment-type objects in a separate root-level gameobject
|
|
/// 7. Add the environment gameobject to the slot in this component.
|
|
/// 8. Play the scene
|
|
/// This is only a sample to demonstrate how API calls could be used in
|
|
/// your own code. You should write your own version of this in your own
|
|
/// namespace.
|
|
/// </summary>
|
|
[AddComponentMenu("Sci-Fi Ship Controller/Samples/TelePort World")]
|
|
[HelpURL("http://scsmmedia.com/ssc-documentation")]
|
|
public class SampleTelePortWorld : MonoBehaviour
|
|
{
|
|
#region Public Variables
|
|
public ShipControlModule shipNPC = null;
|
|
public ShipCameraModule shipCameraModule = null;
|
|
public float moveOriginDistance = 200f;
|
|
public GameObject worldEnvironment = null;
|
|
#endregion
|
|
|
|
#region Private Variables
|
|
private ShipAIInputModule shipAIInputModule = null;
|
|
private SSCManager sscManager = null;
|
|
private PathData myPath = null;
|
|
private bool isInitialised = false;
|
|
//private Vector3 initialPosition = Vector3.zero;
|
|
#endregion
|
|
|
|
#region Initialisation Methods
|
|
// Start is called before the first frame update
|
|
void Start()
|
|
{
|
|
sscManager = SSCManager.GetOrCreateManager();
|
|
if (shipCameraModule == null)
|
|
{
|
|
#if UNITY_EDITOR
|
|
Debug.LogWarning("ERROR: SampleTelePortWorld shipCameraModule is null. Did you forget to add it to the slot provided on this component?");
|
|
#endif
|
|
}
|
|
else if (shipNPC == null)
|
|
{
|
|
#if UNITY_EDITOR
|
|
Debug.LogWarning("ERROR: SampleTelePortWorld shipNPC is null. Did you forget to add it to the slot provided on this component?");
|
|
#endif
|
|
}
|
|
else if (shipNPC.GetShipAIInputModule(true) == null)
|
|
{
|
|
#if UNITY_EDITOR
|
|
Debug.LogWarning("ERROR: SampleTelePortWorld shipNPC does not seem to have a ShipAIInputModule component.");
|
|
#endif
|
|
}
|
|
else if (sscManager != null)
|
|
{
|
|
shipCameraModule.SetTarget(shipNPC);
|
|
|
|
#region Create the new path
|
|
myPath = new PathData();
|
|
|
|
sscManager.pathDataList.Add(myPath);
|
|
|
|
bool autoGenerateLocationNames = false;
|
|
|
|
#if UNITY_EDITOR
|
|
myPath.name = "MyMovingPath";
|
|
myPath.showLocationsInEditor = true;
|
|
autoGenerateLocationNames = true;
|
|
#endif
|
|
|
|
sscManager.AppendLocation(myPath, new Vector3(100f,100f, 0f), autoGenerateLocationNames, false);
|
|
sscManager.AppendLocation(myPath, new Vector3(300f,100f, 0f), autoGenerateLocationNames, false);
|
|
sscManager.AppendLocation(myPath, new Vector3(600f,100f, 50f), autoGenerateLocationNames, false);
|
|
sscManager.AppendLocation(myPath, new Vector3(1000f,200f, 50f), autoGenerateLocationNames, false);
|
|
sscManager.AppendLocation(myPath, new Vector3(800f,200f, 300f), autoGenerateLocationNames, false);
|
|
sscManager.AppendLocation(myPath, new Vector3(500f,150f, 500f), autoGenerateLocationNames, false);
|
|
sscManager.AppendLocation(myPath, new Vector3(300f,150f, 300f), autoGenerateLocationNames, false);
|
|
sscManager.AppendLocation(myPath, new Vector3(200f,150f, 350f), autoGenerateLocationNames, false);
|
|
sscManager.AppendLocation(myPath, new Vector3(100f,100f, 200f), autoGenerateLocationNames, false);
|
|
|
|
myPath.isClosedCircuit = true;
|
|
|
|
sscManager.RefreshPathDistances(myPath);
|
|
|
|
sscManager.InitialiseLocations(myPath, transform.position, Vector3.zero, Quaternion.identity, Vector3.zero, Vector3.zero);
|
|
#endregion
|
|
|
|
#region Assign Path to Ship
|
|
|
|
// Check for an AI module
|
|
shipAIInputModule = shipNPC.GetShipAIInputModule(true);
|
|
if (shipAIInputModule != null)
|
|
{
|
|
shipAIInputModule.Initialise();
|
|
|
|
//initialPosition = shipNPC.shipInstance.TransformPosition;
|
|
|
|
// Tell the AI ship to follow the path
|
|
shipAIInputModule.AssignTargetPath(myPath);
|
|
shipAIInputModule.SetState(AIState.moveToStateID);
|
|
|
|
isInitialised = true;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Update Methods
|
|
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
if (isInitialised)
|
|
{
|
|
// Keep the ship near the origin (0,0,0)
|
|
Vector3 _shipPosDelta = -shipNPC.shipInstance.TransformPosition;
|
|
Vector3 _absPosDelta = SSCMath.Abs(_shipPosDelta);
|
|
|
|
if ((_absPosDelta.x > _absPosDelta.z && _absPosDelta.x > moveOriginDistance) || (_absPosDelta.z > moveOriginDistance && _absPosDelta.z > _absPosDelta.x))
|
|
{
|
|
// Teleport - ignore Y axis
|
|
TelePortWorld(new Vector3(_shipPosDelta.x, 0f, _shipPosDelta.z));
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private Methods
|
|
|
|
private void TelePortWorld(Vector3 deltaTP)
|
|
{
|
|
if (isInitialised)
|
|
{
|
|
// Move Path. As the path is not part of a ShipDockingStation on large mothership, we can use
|
|
// a simplified MoveLocations method.
|
|
sscManager.MoveLocations(myPath, Time.deltaTime, deltaTP, Quaternion.identity);
|
|
|
|
// Teleport the ShipAIInputModule rather than the ShipControlModule
|
|
shipAIInputModule.TelePort(deltaTP, false);
|
|
|
|
shipCameraModule.TelePort(deltaTP);
|
|
|
|
sscManager.TelePortProjectiles(deltaTP);
|
|
|
|
if (worldEnvironment != null) { worldEnvironment.transform.position += deltaTP; }
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |