0
Answered

Occurrence + SpawnPool

Tin Kei Wong (Canis) 7 months ago • updated by Lazlo Bonin (Lead Developer) 6 days ago 4

Hi, I'm trying to implement the plugin with SpawnPool from "PathologicalGames",
so yes the spawned GameObject are reusable and might not be same token.
I read the tutorial of Occurrence and create the following class.

I hope it's not very hard to understand the workflow.
so I keep it short,

  1. Fire bullet by using m_TimeLine.Do(true, new SpawnBulletOccurrence(info));
  2. Timeout despawn by using, m_TimeoutDespawn = m_TimeLine.Plan(m_DespawnTime, true, new DespawnBulletOccurrence(info));
  3. when hit something despawn by using, m_TimeLine.Do(true, new DespawnBulletOccurrence(m_Info));
    ALSO, cancel the (2) m_TimeLine.Cancel(m_TimeoutDespawn);



public struct BulletLifeInfo{
    public Transform m_BulletSpawnPoint;
    public bool m_HandleAmmoAmount;
    public CAmmo m_Ammo;


    // Time control
    public TimelineMode m_ClockMode;
    public string m_ClockName;
    
    // SpawnPool reference.
    public SpawnPool m_Pool;
    public CBullet m_BulletInstance;
    public Vector3 m_DespawnPosition;
    public Quaternion m_DespawnQuaternion;
}


public class SpawnBulletOccurrence : Occurrence
{
    BulletLifeInfo m_Info;
    public SpawnBulletOccurrence(BulletLifeInfo info)
    {
        m_Info = info;
    }


    public override void Backward()
    {
        if (m_Info.m_HandleAmmoAmount)
            m_Info.m_Ammo.quantity++;
        m_Info.m_Pool.Despawn(m_Info.m_BulletInstance.transform);
    }


    public override void Forward()
    {
        if (!m_Info.m_HandleAmmoAmount)
            m_Info.m_Ammo.quantity--;
        Transform obj = m_Info.m_Pool.Spawn(m_Info.m_Ammo.GetBulletPrefab(), m_Info.m_BulletSpawnPoint.position, m_Info.m_BulletSpawnPoint.rotation);
        m_Info.m_BulletInstance = obj.GetComponent<CBullet>();
        m_Info.m_BulletInstance.Launch(m_Info);
    }
}


public class DespawnBulletOccurrence : Occurrence
{
    BulletLifeInfo m_Info;
    public DespawnBulletOccurrence(BulletLifeInfo info)
    {
        m_Info = info;
    }


    public override void Forward()
    {
        m_Info.m_DespawnPosition = m_Info.m_BulletInstance.transform.position;
        m_Info.m_DespawnQuaternion = m_Info.m_BulletInstance.transform.rotation;
        m_Info.m_Pool.Despawn(m_Info.m_BulletInstance.transform);
    }


    public override void Backward()
    {
        Transform obj = m_Info.m_Pool.Spawn(m_Info.m_Ammo.GetBulletPrefab(), m_Info.m_DespawnPosition, m_Info.m_DespawnQuaternion);
        m_Info.m_BulletInstance = obj.GetComponent<CBullet>();
        m_Info.m_BulletInstance.Launch(m_Info);
    }
}


The problem is, when I rewind time, seem like Timeline are trying to Despawn another instance. after few cycle.

of cause because SpawnPool not returning the same instance, which mean another timeline will be active.

so I guess so many people should already have the solution to make it work with pooling system, anyone can tell me the solution ?

or may be it just I did something wrong in coding ?

Chronos Version:
2.4.8
Unity Version:
5.5.1f1

I think I start understand the structure, the Occurrence information are stored in Timeline.cs
and the Timeline.cs component attached on bullet token, when spawnpool sent another bullet instance,
the information just not right.

so I change the structure like this.

  • BulletSpawnPool (SpawnPool + TimeLine)
    • Bullet (TimeLineChild)
    • Bullet (TimeLineChild)

and then start working on re-route all the Occurrence to the TimeLine parent..

but I still don't fully understand the "Despawn" issue...
only reason I can think of. are the TimeLine.Plan().... but I'm not 100% sure the root cause.

=======

I randomly clicked Fire button, and map the timeScale = -1 during the avatar crouch action.
and timeScale = 1 during standing.

as you can see the bullet will return to their start point.
but after some point it start fail.

Under Review

Hi Tin Kei,

Thank you for your patience.

Your spawn pool should not have a Timeline component attached. 

Each bullet prefab (or spawnable instance) should have a Timeline component, not a TimelineChild.

The bullets' timeline should point to the same global clock, if you want them to be synchronized.

When despawning, I suggest you use:

GetComponent<Timeline>().recorder.Reset();

Tell me if this helps with your issue.

I'll add a more robust reset in the next version:

GetComponent<Timeline>().ResetComponents();

Cheers,

Lazlo

my first attempt , was using Timeline on bullet, and without using Timeline on spawnpool.

doing exactly same thing as you suggest, except the Timeline.recorder.Reset();

but I afraid it's not good enough for my use case.


I haven't really run test on Reset(), but remove the record should only remove the glitch cause by reuse that gameobject, it can't provide the correct information for rewind. (correct me if I'm wrong, perhaps I missunderstand something?!)

What I'm trying to do, was using the plugin to revert the whole game state,

include the destroy bullet(s), enemy's health by doing time rewind, I wish I can redeem the damage I done on target, at the same time the bullet should pull out (re-spawn and fly backward) from the enemy, this part I used "Occurrence", and it work..

however if there is no way to use spawn pool yet. I guess we need to suspension this solution.

(just because instantiate are too expensive), however Chronos still a good plugin for pause & time effect.

looking forward for you guys suggestion.


PS: don't worry, we got a backup plan for this feature. different presentation...etc