0
\$\begingroup\$

I'm recording the velocity of a Rigidbody2D using Animation Curves and I need to reproduce the same "movement" on an instantiated prefab (we really need "stuck like glue" movement matching between these two objects).

Sample

enter image description here

I've already achieved reproducing the stored movements, but I need to make the "Player" able to "piggyback" on top of the instantiated prefab (and able to move while on the prefab top). I've tried to pass the "velocity" to the "Player" movement script, but I get some "delay" in execution.

PlaybackBahaviour.cs

using System.Linq;
using UnityEngine;
 
public class PlaybackBahaviour : MonoBehaviour
{
    private AnimationCurves _animationCurves;
 
    private float _lastKeyframeTimeX;
    private float _lastKeyframeTimeY;
    private float _reproduceSmoothedTime = 0f;
 
    private Rigidbody2D _rigidBody2D;
    private PlayerMovement _playerMovement;
 
    private void Start()
    {
        _rigidBody2D = GetComponent<Rigidbody2D>();
        _lastKeyframeTimeX = _animationCurves.XPosition.keys.Last().time;
        _lastKeyframeTimeY = _animationCurves.YPosition.keys.Last().time;
 
        _rigidBody2D.position = new Vector2
        (
           x: _animationCurves.XPositionRB.Evaluate(_reproduceSmoothedTime),
           y: _animationCurves.YPositionRB.Evaluate(_reproduceSmoothedTime)
        );
    }
 
    private void FixedUpdate()
    {
        _reproduceSmoothedTime += Time.smoothDeltaTime;
 
        ReproduceMyAnimationCurves();
    }
 
    private void ReproduceMyAnimationCurves()
    {
        // Applies recorded rigidbody velocity...
        _rigidBody2D.velocity = new Vector2
        (
            x: _animationCurves.XVelocity.Evaluate(_reproduceSmoothedTime),
            y: _animationCurves.YVelocity.Evaluate(_reproduceSmoothedTime)
        );
 
        if (_playerMovement != null)
        {
            // Pass the current rigidbody velocity to the player movement script...
            _playerMovement.SetExternalVelocity(_rigidBody2D.velocity);
        }
 
        var allXKeyframesReproduced = _reproduceSmoothedTime >= _lastKeyframeTimeX;
        var allYKeyframesReproduced = _reproduceSmoothedTime >= _lastKeyframeTimeY;
 
        if (allXKeyframesReproduced && allYKeyframesReproduced)
            _reproduceSmoothedTime = 0;
    }
 
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.CompareTag("Player"))
        {
            _playerMovement = collision.gameObject.GetComponent<PlayerMovement>();
        }
    }
 
    private void OnTriggerExit2D(Collider2D collision)
    {
        _playerMovement = null;
    }
}

PlayerMovement.cs

private Vector2 _externalVelocity;
 
//Omitted for brevity...
 
public virtual void SetExternalVelocity(Vector2 velocity)
{
     _externalVelocity = velocity;
}
 
//Omitted for brevity...
 
private void FixedUpdate()
{
    //Omitted for brevity...
    Move(1);
}
 
private void Move(float lerpAmount)
{
        //Omitted for brevity...
 
        //Calculate the direction we want to move in and our desired velocity
        float targetSpeed = _moveInput.x * Data.runMaxSpeed;
 
        //We can reduce are control using Lerp() this smooths changes to are direction and speed
        targetSpeed = Mathf.Lerp(RB.velocity.x, targetSpeed, lerpAmount);
 
        float speedDiff;
 
        if (_externalVelocity.x != 0)
            speedDiff = targetSpeed - (RB.velocity.x - _externalVelocity.x);
        else
            speedDiff = targetSpeed - RB.velocity.x;
 
        //Calculate force along x-axis to apply to thr player
        float movement = speedDif * accelRate;
 
        //Convert this to a vector and apply to rigidbody
        RB.AddForce(movement * Vector2.right, ForceMode2D.Force);
 
        //Omitted for brevity...
}

Simulation result: enter image description here

Youtube Demo

Player = Cyan cube.

Clone = Orange cube.

Result: Clone cube goes first and then the Cyan cube follows the movement.

I've already tried modifying the script execution order, without success.

I've already tried Rigidbody.MovePosition(...) without success.

How can I solve this?

\$\endgroup\$
3
  • \$\begingroup\$ We have previous Q&A about moving platforms that might help you solve this \$\endgroup\$
    – DMGregory
    Commented Feb 15, 2023 at 15:56
  • \$\begingroup\$ Moving platforms with Rigidbody causes problems with "high velocity"... mostly vertically. The most common is "parent" to another "GameObject", but that is not a solution for this project. \$\endgroup\$
    – Igor
    Commented Feb 15, 2023 at 16:02
  • \$\begingroup\$ For true "stuck like glue" the second body needs to be kinematic and not rigid body. However... \$\endgroup\$
    – user122973
    Commented Feb 17, 2023 at 8:36

0

You must log in to answer this question.

Browse other questions tagged .