Im trying to copy a master object position and rotation in another object with delay.
I would like to realize the delay of the timing to start move and rotation instead of the speed of move and rotation itself.
It can be imagined that writing the master position and rotation in the array for each frame and reading the array by offsetting the array by the delayed seconds.
No, Coroutine and Invoke methods should be used in the Awake or Start method, which is not appropriate in this case.
I need to manipulate the positions and rotations that are updated in the Update method.
A shifting register, where you PUSH transformations of master object and POP transformation to slave object, could solve this.
However you need to use it in fixed update and use target framerate to get consistent results (independant of default framerate (which is “as many as possible”)).
Then the only thing you’ll need to look out for is the size of the register.
create a custom class container that holds a Vector3 (for position) a Quaternion (for rotation) and a float (for timestamp) and use a Queue of this class.
Unless the Transforms interact with physics they don’t need to be in FixedUpdate. Pooling and skipping to the youngest register thats older than the delay will handle it just fine.
and yes the size of the register will need to be cared for. this is largely dependent on how large you set the delay.
TranformState
public class TransformState
{
public Vector3 position;
public Quaternion rotation;
public float timeStamp;
public TransformState(Vector3 position, Quaternion rotation, float timeStamp)
{
this.position = position;
this.rotation = rotation;
this.timeStamp = timeStamp;
}
public TransformState(Transform transform)
{
SetState(transform);
}
public SetState(Transform transform)
{
this.position = transform.position;
this.rotation = transform.rotation;
this.timeStamp = Time.time;
}
}
Queue Code (with pooling)
private Queue<TransformState> frameStates = new Queue<TransformState>();
private List<TransformState> pooledStates = new List<TransformState>();
private void Update()
{
TransformState state = null;
if(pooledStates.Count>1)
{
state = pooledStates[0];
pooledStates.Remove(state);
state.SetState(transform);
}
else
{
state = new TransformState(transform);
}
frameState.Enqueue(state);
TransformState delayState = null;
while(frameState.Count>0)
{
var peekState = frameState.Peek();
if(peekState == null || (state.timeStamp - peekState.timeStamp) < delay) break;
delayState = frameState.Dequeue();
pooledStates.Add(delayState);
}
if(delayState != null)
{
var slaveTransform = slaveObject.transform;
slaveTransform.position = delayState.position;
slaveTransform.rotation = delayState.rotation;
}
}
I applied it to the scene based on your code.
Both position and rotation will move to follow the master object, but the slave object flickers.
Since the error occurs when writing the SetState() in the constructor of the TransformState script and declaring the delayState in the Queue script, I am assigning an instance of TransformState, but is this a problem?
oh, that was a lazy copy/paste… i fixed line 16 in TransformState and line 21 in the Queue Code. I wrote all this directly in the post so I didn’t have a compiler proof-read it.
Similar to TransformState, write a custom class that holds a single Slave’s transform and its delay. Your script will hold a list of these objects. populate the list via the inspector. then in either Awake, Start, or preferably OnEnable, sort the list by delay in descending order (you can use Linq for this). then take the Queue code I wrote and wrap lines 22-39 in a for loop that iterates through your sorted slaves. change a couple lines withing the code i posted so that they are using the each slaves delay and transform instead of the values I wrote to.
I tried but it does not work.
I could grasp the atmosphere what Queue code is doing but I do not know how to modify it.
I created a TransformState class for Slave, attached it to SlaveObject, put them together in a list. I have not tried descending order yet.
How to combine the SlaveObject stored in the List with the TransformState of the existing Master in the Queue code?
In the TransformState of Master that already exists in the Queue code, the comparison target is Master itself, but does Slave need to be processed in the same way?
Or is there a need to compare between Master’s transform and Slave’s transform?
Sorry, I could not think simply and it got confused.