public abstract class WorldShifter : MonoBehaviour
Rather than duplicate the world when a world Origin Cell change occurs, you can shift
the world instead.
To do so, you can
use one of the provided World Shifter classes or create your own custom class by deriving
from this class.
The main component of your custom World Shifter class will be the ShiftWorld implementation,
which is a Unity coroutine. Here, you
can do whatever you want, however to function correctly, you need to ensure that your
world is shifted by the appropriate amount
(found via the CurrentShiftAmount property).
What you shift to accomplish this is entirely up to you. You can shift a root world
object that contains all of your world's objects,
the objects themselves (recommended), or something else. A custom class gives you
full control over your implementation details.
The class contains four events by default: PreWorldShift, PostWorldShift, PreTransformShift
and PostTransformShift. These events
will be available in the Unity editor for custom scripts in your scene to subscribe
to, or you can subscribe to them via code by
using one of the Subscribe methods (usually in OnEnable) and its corresponding Unsubscribe
method (usually in OnDisbale).
The PreWorldShift and PostWorldShift are fired under two scenarios. When the FireWorldShiftingEventAutomatically
and FireWorldShiftedEventAutomatically properties on your custom World Shifter are
configured to return true,
or when you manually call the FirePreWorldShiftEvent or
FirePreWorldShiftEvent methods (do so at the appropriate time of course!). The latter
can be done for more fine tuned control
over when the events fire. If you choose the first option, the pre event is fired
immediately before the WorldShift coroutine starts
executing, and the post event fires immediately after it finishes executing.
The PreTransformShift and PostTransformShift events will only fire if you utilize
the TransformShift method from within your
ShiftWorld implementation, which is highly recommended. In addition to firing the
events at the appropriate time, the method will
also add the CurrentShiftAmount to the transform's position, ensuring that everything
is done correctly.
However, because this class should offer maximum flexibility, it is not required that
you use this method, however keep in mind that if
you don't use the method, the PreTransformShift and PostTransformShift events will
not fire automatically. You can still fire them
manually using the FirePreTransformShiftEvent and FirePostTransformShiftEvent methods
(at the appropriate time of course).
It is possible to use the same WorldShifter object with multiple Worlds, however special
care must be taken in regards to subscribers of
the events, to ensure that they can handle the events being fired for different Worlds.
Name | Type | Default Value | Description |
---|---|---|---|
TransformShifted | TransformShiftedEvent |
An event that can be subscribed to in order to receive notifications just after each
Transform is shifted during the World shift.
|
|
TransformShifting | TransformShiftedEvent |
An event that can be subscribed to in order to receive notifications just before each
Transform is shifted during the World shift.
|
|
WorldShifted | WorldShiftEvent |
An event that can be subscribed to in order to receive notifications just after a
World shift is completed.
|
|
WorldShifting | WorldShiftEvent |
An event that can be subscribed to in order to receive notifications just before a
World shift starts.
|
Name | Type | Description |
---|---|---|
CurrentShiftAmount | Vector3Double |
The amount to add to the current position of objects in the world. Will be zero when a shift is not in progress |
CurrentWorldToBeShifted | World |
The current world that is to be shifted. Will be null when a shift is not in progress. |
FireWorldShiftedEventAutomatically | bool |
When overriden, tells the base World Shifter class whether the WorldShifted event
should be
fired automatically just after the ShiftWorld coroutine finishes running. This will
call the
FireWorldShiftedEvent method if true.
|
FireWorldShiftingEventAutomatically | bool |
When overriden, tells the base World Shifter class whether the WorldShifting event
should be fired automatically just prior to the ShiftWorld coroutine being run. This
will call
the FireWorldShiftingEvent method if true.
|
PerformShiftInSingleFrame | bool |
Gets the value of the performShiftInSingleFrame field in the inspector. |
TotalTransformsToBeShifted | int |
The number of transforms that will be shifted during the current world shift. Will be 0 when a shift is not in progress. |
protected void Awake()
The World Shifter's Awake method, called by Unity. You cannot utilize Awake in your derived class, if you need to perform some sort of awake related logic, override the AwakeExtended method, which will be called by this classes Awake method. Also note that you do not need to call base.AwakeExtended(); from your AwakeExtended method, as this is a virtual empty method that does nothing unless you override it. Also note that this method is protected simply so that if you derive from this class, you will see an error when trying to add the Awake method.
protected virtual void AwakeExtended()
Can be overriden to perform logic that would normally go in Awake (which is used by the base class). Use this instead of implementing Awake! You do not need to call base.AwakeExtended if you override this, as the base method is empty.
protected abstract int CalculateNumberOfTransformsToBeShifted()
A method which should be overriden to return the total number of transforms that will
be shifted by your
implementation of the ShiftWorld coroutine. This is basically the number of times
you will call
the ShiftTransformAndFireEvents method, or the total transforms you will
shift manually if you elect not to use that method. This is for use with
the PreTransformShift and PostTransformShift events, so that the TotalTransformsInShiftCycle
property
in the event args can be set properly. If you don't intend to use these events, you
don't need to
worry about this method (just return 0).
Please note that this is not necessarily a count of the total number of transforms
in your World, and some transforms may be
children of other transforms, which are shifted automatically when their parents are
shifted. Rather, this is a count of the total
number of transforms that are shifted either manually by you (transform.position =
transform.position + CurrentShiftAmount), or the
total number of transforms shifted via the ShiftTransformAndFireEvents method.
Also note that the CurrentWorldToBeShifted and CurrentShiftAmount properties will
be set prior to this method being called,
so you can access them if you need to in order to determine the value returned.
int
The number of transforms that will be shifted.
public void FireTransformShiftedEvent(Transform transform, int transformNumberInShiftCycle)
Manually fire the TransformShifted event. You need to track and set the transformNumberInShiftCycle
value, as automatic tracking
is only available when using the ShiftTransformAndFireEvents method. If you use this
method, you cannot use the ShiftTransformAndFireEvents method, as the
two are mutually exclusive. You must also make sure to call the FirePreShiftTransformEvent
method.
Ideally you would call this method immediately after manually shifting the transform's
position.
Name | Type | Description |
---|---|---|
transform | Transform |
The transformt that has just been shifted. |
transformNumberInShiftCycle | int |
The transformt that is about to be shifted. |
public void FireTransformShiftingEvent(Transform transform, int transformNumberInShiftCycle)
Manually fire the TransformShifting event. You need to track and set the transformNumberInShiftCycle
value, as automatic tracking
is only available when using the ShiftTransformAndFireEvents method. If you use this
method, you cannot use the ShiftTransformAndFireEvents method, as the
two are mutually exclusive. You must also make sure to call the FirePostShiftTransformEvent
method.
Ideally you would call this method immediately before manually shifting the transform's
position.
Name | Type | Description |
---|---|---|
transform | Transform |
The transformt that is about to be shifted. |
transformNumberInShiftCycle | int |
The transformt that is about to be shifted. |
protected void FireWorldShiftedEvent()
Fires the WorldShifted Event. You only need to call this if you've configured FireWorldShiftedEventAutomatically to return false in your custom World Shifter class.
protected void FireWorldShiftingEvent()
Fires the WorldShifting Event. You only need to call this if you've configured FireWorldShiftingEventAutomatically to return false in your custom World Shifter class.
public abstract bool IsConfiguredToMovePlayerFromActiveGrid(ActiveGrid activeGrid)
When overriden, executes a query to determine if the World Shifter has been configured to move the Player associated with the Active Grid. This is used by the Active Grid in certain situations to avoid double movements.
Name | Type | Description |
---|---|---|
activeGrid | ActiveGrid |
The active grid with the Player. |
bool
True if the World Shifter has been configured to move the player, false otherwise.
protected void OnDestroy()
The World Shifter's OnDestroy method, called by Unity. You cannot utilize OnDestroy in your derived class, if you need to perform some sort of OnDestroy related logic, override the OnDestroyExtended method, which will be called by this classes OnDestroy method. Also note that you do not need to call base.OnDestroyExtended(); from your OnDestroyExtended method, as this is a virtual empty method that does nothing unless you override it. Also note that this method is protected simply so that if you derive from this class, you will see an error when trying to add the OnDestroy method.
protected virtual void OnDestroyExtended()
Can be overriden to perform logic that would normally go in OnDestroy (which is used by the base class). Use this instead of implementing OnDestroy! You do not need to call base.OnDestroyExtended if you override this, as the base method is empty.
protected void ShiftTransformAndFireEvents(Transform transform)
First, it fires the TransformShifting event if there are any subscribers. Then, it
shifts the position of the input transform by the
value of CurrentShiftAmount. Finally, it fires the TransformShifted event if there
are any subscribers.
This method should be called for each Transform that you wish to shift. You can elect
to not use the method and shift the transforms
yourself, however the TransformShifting and TransformShifted methods will not be fired
automatically.
In that case, you can manually call FireTransformShiftingEvent before you shift the
transform and then FireTransformShiftedEvent
after you shift the transform, or elect not to use the Transform Shift events at all.
The method automatically increments the
TransformShiftEventArgs.TransformNumberInShiftCycle so you don't need to worry about
it.
If you utilize this method, you should not utilize the FireTransformShiftingEvent
and FireTransformShiftedEvent methods, as they
are mutually exclusive.
Name | Type | Description |
---|---|---|
transform | Transform |
The transform to shift. |
public abstract IEnumerator<YieldInstruction> ShiftWorld()
When overridden by a derived class, shifts the world.
You'll notice that this method is not passed any arguments. The World and shift amount
are set prior to this method
being called, and can be retrieved via the CurrentWorldToBeShifted and CurrentShiftAmount
properties.
What transforms you shift in order to complete a 'World Shift' is entirely up to you.
IEnumerator<YieldInstruction>
An IEnumerator<YieldInstruction> that can be iterated over or used as a coroutine.
See the
YieldInstruction page for more info.
public void SubscribeToTransformShiftedEvent(UnityAction<System.Object, TransformShiftEventArgs> subscriber)
Subcribe to the TransformShifted event via code. Typically you would do this in the OnEnable method, and then call the UnsubscribeFromTransformShiftedEvent method in your OnDisable method.
Name | Type | Description |
---|---|---|
subscriber | UnityAction<System.Object, TransformShiftEventArgs> |
The subscriber, which must be a void method with System.Object and TransformShiftEventArgs parameters. |
public void SubscribeToTransformShiftingEvent(UnityAction<System.Object, TransformShiftEventArgs> subscriber)
Subcribe to the TransformShifting event via code. Typically you would do this in the OnEnable method, and then call the UnsubscribeFromTransformShiftingEvent method in your OnDisable method.
Name | Type | Description |
---|---|---|
subscriber | UnityAction<System.Object, TransformShiftEventArgs> |
The subscriber, which must be a void method with System.Object and TransformShiftEventArgs parameters. |
public void SubscribeToWorldShiftedEvent(UnityAction<System.Object, WorldShiftEventArgs> subscriber)
Subcribe to the WorldShifted event via code. Typically you would do this in the OnEnable method, and then call the UnsubscribeFromWorldShiftedEvent method in your OnDisable method.
Name | Type | Description |
---|---|---|
subscriber | UnityAction<System.Object, WorldShiftEventArgs> |
The subscriber, which must be a void method with System.Object and WorldShiftEventArgs parameters. |
public void SubscribeToWorldShiftingEvent(UnityAction<System.Object, WorldShiftEventArgs> subscriber)
Subcribe to the WorldShifting event via code. Typically you would do this in the OnEnable method, and then call the UnsubscribeFromWorldShiftingEvent method in your OnDisable method.
Name | Type | Description |
---|---|---|
subscriber | UnityAction<System.Object, WorldShiftEventArgs> |
The subscriber, which must be a void method with System.Object and WorldShiftEventArgs parameters. |
public void UnsubscribeFromTransformShiftedEvent(UnityAction<System.Object, TransformShiftEventArgs> subscriber)
Unsubcribe from the TransformShifted event via code. Typically you would subscribe in the OnEnable method of your script, and then unsubscribe in the OnDisable method.
Name | Type | Description |
---|---|---|
subscriber | UnityAction<System.Object, TransformShiftEventArgs> |
The subscriber, which must be a void method with System.Object and TransformShiftEventArgs parameters, and be the same method you subscribed with. |
public void UnsubscribeFromTransformShiftingEvent(UnityAction<System.Object, TransformShiftEventArgs> subscriber)
Unsubcribe from the TransformShifting event via code. Typically you would subscribe in the OnEnable method of your script, and then unsubscribe in the OnDisable method.
Name | Type | Description |
---|---|---|
subscriber | UnityAction<System.Object, TransformShiftEventArgs> |
The subscriber, which must be a void method with System.Object and TransformShiftEventArgs parameters, and be the same method you subscribed with. |
public void UnsubscribeFromWorldShiftedEvent(UnityAction<System.Object, WorldShiftEventArgs> subscriber)
Unsubcribe from the WorldShifted event via code. Typically you would subscribe in the OnEnable method of your script, and then unsubscribe in the OnDisable method.
Name | Type | Description |
---|---|---|
subscriber | UnityAction<System.Object, WorldShiftEventArgs> |
The subscriber, which must be a void method with System.Object and WorldShiftEventArgs parameters, and be the same method you subscribed with. |
public void UnsubscribeFromWorldShiftingEvent(UnityAction<System.Object, WorldShiftEventArgs> subscriber)
Unsubcribe from the WorldShifting event via code. Typically you would subscribe in the OnEnable method of your script, and then unsubscribe in the OnDisable method.
Name | Type | Description |
---|---|---|
subscriber | UnityAction<System.Object, WorldShiftEventArgs> |
The subscriber, which must be a void method with System.Object and WorldShiftEventArgs parameters, and be the same method you subscribed with. |