-

   rss_rss_hh_new

 - e-mail

 

 -

 LiveInternet.ru:
: 17.03.2011
:
:
: 51

:


[] Prince of Persia

, 19 2017 . 09:44 +
image

, . Unity, . , .

-, , . , .




Unity . , .

? !

?


Prince of Persia: The Sands of Time . , , , , , .


Prince of Persia: The Forgotten Sands. Sands Of Time . .

, , .

Braid, . Overwatch , , , , . GRID : , , . , .


GRID


. .


. SUPERHOT, Worms .

, : , . , , . Worms : .

SUPERHOT . , .

Super Meat Boy. , , .


Super Meat Boy. , .


, , . , . , .

, , . , Need for Speed Diddy Kong Racing.


Trackmania Nations. , , , . , , .


. , , . , , .

Trackmania, . , , .


. Team Fortress 2 , .


Team Fortress 2. , .

. , , , . , , , .


. !


, . C# Player.cs Update() :

void Update()
{
    transform.Translate (Vector3.forward * 3.0f * Time.deltaTime * Input.GetAxis ("Vertical"));
    transform.Rotate (Vector3.up * 200.0f * Time.deltaTime * Input.GetAxis ("Horizontal"));
}

. . Play . , . , , . - :



WSAD

TimeController


C# TimeController.cs GameObject. .

, . . , :

public GameObject player;

TimeController, .



:

public ArrayList playerPositions;

void Start()
{
    playerPositions = new ArrayList();
}

. , 6 , 8 ( ). , , .

:

void FixedUpdate()
{
    playerPositions.Add (player.transform.position);
}

FixedUpdate() . FixedUpdate(), 50 ( ), . Update() , , .

. !

. :

public bool isReversing = false;

Update():

void Update()
{
    if(Input.GetKey(KeyCode.Space))
    {
        isReversing = true;
    }
    else
    {
        isReversing = false;
    }
}

, . :

void FixedUpdate()
{
    if(!isReversing)
    {
        playerPositions.Add (player.transform.position);
    }
    else
    {
        player.transform.position = (Vector3) playerPositions[playerPositions.Count - 1];
        playerPositions.RemoveAt(playerPositions.Count - 1);
    }
}

TimeController :

using UnityEngine;
using System.Collections;

public class TimeController: MonoBehaviour
{
    public GameObject player;
    public ArrayList playerPositions;
    public bool isReversing = false;

    void Start()
    {
        playerPositions = new ArrayList();
    }

    void Update()
    {
        if(Input.GetKey(KeyCode.Space))
        {
            isReversing = true;
        }
        else
        {
            isReversing = false;
        }
    }
	
    void FixedUpdate()
    {
        if(!isReversing)
        {
            playerPositions.Add (player.transform.position);
        }
        else
        {
            player.transform.position = (Vector3) playerPositions[playerPositions.Count - 1];
            playerPositions.RemoveAt(playerPositions.Count - 1);
        }
    }
}

, player , TimeController , . :

using UnityEngine;
using System.Collections;

public class Player: MonoBehaviour
{
    private TimeController timeController;

    void Start()
    {
        timeController = FindObjectOfType(typeof(TimeController)) as TimeController;
    }
    
    void Update()
    {
        if(!timeController.isReversing)
        {
    	    transform.Translate (Vector3.forward * 3.0f * Time.deltaTime * Input.GetAxis ("Vertical"));
    	    transform.Rotate (Vector3.up * 200.0f * Time.deltaTime * Input.GetAxis ("Horizontal"));
        }
    }
}

TimeController . , .

. TimeRewindingFunctionality01, !

, - , ? !

, .

using UnityEngine;
using System.Collections;

public class TimeController: MonoBehaviour
{
    public GameObject player;
    public ArrayList playerPositions;
    public ArrayList playerRotations;
    public bool isReversing = false;
    
    void Start()
    {
        playerPositions = new ArrayList();
        playerRotations = new ArrayList();
    }
    
    void Update()
    {
        if(Input.GetKey(KeyCode.Space))
        {
            isReversing = true;
        }
        else
        {
            isReversing = false;
        }
    }
    
    void FixedUpdate()
    {
        if(!isReversing)
        {
            playerPositions.Add (player.transform.position);
            playerRotations.Add (player.transform.localEulerAngles);
        }
        else
        {
            player.transform.position = (Vector3) playerPositions[playerPositions.Count - 1];
            playerPositions.RemoveAt(playerPositions.Count - 1);
    
            player.transform.localEulerAngles = (Vector3) playerRotations[playerRotations.Count - 1];
            playerRotations.RemoveAt(playerRotations.Count - 1);
        }
    }
}

! TimeRewindingFunctionality02 . - , .


, . , .

:

  • 12- ,
  • 75 ,

, , , :

  • , ( VHS-)
  • ,

Unity



, , . .


50 . , , .

4 . 92% , 50 , .

x . :

public int keyframe = 5;
private int frameCounter = 0;

keyframe FixedUpdate, . 5, FixedUpdate. FixedUpdate 50 , 10 . frameCounter .

FixedUpdate, :

if(!isReversing)
{
    if(frameCounter < keyframe)
    {
        frameCounter += 1;
    }
    else
    {
        frameCounter = 0;
        playerPositions.Add (player.transform.position);
        playerRotations.Add (player.transform.localEulerAngles);
    }
}

, , . , , . .

frameCounter, , .

private int reverseCounter = 0;

, , , . FixedUpdate :

void FixedUpdate()
{
    if(!isReversing)
    {
        if(frameCounter < keyframe)
        {
            frameCounter += 1;
        }
        else
        {
            frameCounter = 0;
            playerPositions.Add (player.transform.position);
            playerRotations.Add (player.transform.localEulerAngles);
        }
    }
    else
    {
        if(reverseCounter > 0)
        {
            reverseCounter -= 1;
        }
        else
        {
            player.transform.position = (Vector3) playerPositions[playerPositions.Count - 1];
            playerPositions.RemoveAt(playerPositions.Count - 1);

            player.transform.localEulerAngles = (Vector3) playerRotations[playerRotations.Count - 1];
            playerRotations.RemoveAt(playerRotations.Count - 1);
            
            reverseCounter = keyframe;
        }
    }
}

!

. , . -, :

private Vector3 currentPosition;
private Vector3 previousPosition;
private Vector3 currentRotation;
private Vector3 previousRotation;

, .

:

void RestorePositions()
{
    int lastIndex = keyframes.Count - 1;
    int secondToLastIndex = keyframes.Count - 2;

    if(secondToLastIndex >= 0)
    { 
        currentPosition  = (Vector3) playerPositions[lastIndex];
        previousPosition = (Vector3) playerPositions[secondToLastIndex];
        playerPositions.RemoveAt(lastIndex);
        
        currentRotation  = (Vector3) playerRotations[lastIndex];
        previousRotation = (Vector3) playerRotations[secondToLastIndex];
        playerRotations.RemoveAt(lastIndex);
    }
}

, . , .

:

if(reverseCounter > 0)
{
    reverseCounter -= 1;
}
else
{
    reverseCounter = keyframe;
    RestorePositions();
}

if(firstRun)
{
    firstRun = false;
    RestorePositions();
}

float interpolation = (float) reverseCounter / (float) keyframe;
player.transform.position = Vector3.Lerp(previousPosition, currentPosition, interpolation);
player.transform.localEulerAngles = Vector3.Lerp(previousRotation, currentRotation, interpolation);

( 5), , . :

if(firstRun)
{
    firstRun = false;
    RestorePositions();
}

, firstRun:

private bool firstRun = true;

:

if(Input.GetKey(KeyCode.Space))
{
    isReversing = true;
}
else
{
    isReversing = false;
    firstRun = true;
}

: , , , . .

Lerp, ( ). , 0 1. , , 40% .

, , , .

.


, , .

, . , .

, , , . , , , , . Prince of Persia 15 , Braid .

if(playerPositions.Count > 128)
{
    playerPositions.RemoveAt(0);
    playerRotations.RemoveAt(0);
}

, . , , . FixedUpdate .


. , , , . , ( ).

, , :

public class Keyframe
{
    public Vector3 position;
    public Vector3 rotation;

    public Keyframe(Vector3 position, Vector3 rotation)
    {
        this.position = position;
        this.rotation = rotation;
    }
}

TimeController.cs file . . .

. Start :

keyframes = new ArrayList();

:

playerPositions.Add (player.transform.position);
playerRotations.Add (player.transform.localEulerAngles);

Keyframe:

keyframes.Add(new Keyframe(player.transform.position, player.transform.localEulerAngles));

, , .

,


- , , . , . , , (, ), ( ).

- Prince of Persia .


Prince of Persia: The Forgotten Sands

Unity , , .

. Assets > Import Package > Effects , .



. Components > Image Effects Blur Bloom. , .



. .

, .



. TimeController . :

using UnityStandardAssets.ImageEffects;

TimeController, :

private Camera camera;

Start:

camera = Camera.main;

:

void Update()
{
    if(Input.GetKey(KeyCode.Space))
    {
        isReversing = true;
        camera.GetComponent().enabled = true;
        camera.GetComponent().enabled = true;
    }
    else
    {
        isReversing = false;
        firstRun = true;
        camera.GetComponent().enabled = false;
        camera.GetComponent().enabled = false;
    }
}

, , .

TimeController :

using UnityEngine;
using System.Collections;
using UnityStandardAssets.ImageEffects;

public class Keyframe
{
    public Vector3 position;
    public Vector3 rotation;

    public Keyframe(Vector3 position, Vector3 rotation)
    {
        this.position = position;
        this.rotation = rotation;
    }
}

public class TimeController: MonoBehaviour
{
    public GameObject player;
    public ArrayList keyframes;
    public bool isReversing = false;
    
    public int keyframe = 5;
    private int frameCounter = 0;
    private int reverseCounter = 0;
    
    private Vector3 currentPosition;
    private Vector3 previousPosition;
    private Vector3 currentRotation;
    private Vector3 previousRotation;
    
    private Camera camera;
    
    private bool firstRun = true;
    
    void Start()
    {
        keyframes = new ArrayList();
        camera = Camera.main;
    }
    
    void Update()
    {
        if(Input.GetKey(KeyCode.Space))
        {
            isReversing = true;
            camera.GetComponent().enabled = true;
            camera.GetComponent().enabled = true;
        }
        else
        {
            isReversing = false;
            firstRun = true;
            camera.GetComponent().enabled = false;
            camera.GetComponent().enabled = false;
        }
    }
    
    void FixedUpdate()
    {
        if(!isReversing)
        {
            if(frameCounter < keyframe)
            {
                frameCounter += 1;
            }
            else
            {
                frameCounter = 0;
                keyframes.Add(new Keyframe(player.transform.position, player.transform.localEulerAngles));
            }
        }
        else
        {
            if(reverseCounter > 0)
            {
                reverseCounter -= 1;
            }
            else
            {
                reverseCounter = keyframe;
                RestorePositions();
            }
    
            if(firstRun)
            {
                firstRun = false;
                RestorePositions();
            }
    
            float interpolation = (float) reverseCounter / (float) keyframe;
            player.transform.position = Vector3.Lerp(previousPosition, currentPosition, interpolation);
            player.transform.localEulerAngles = Vector3.Lerp(previousRotation, currentRotation, interpolation);
        }
    
        if(keyframes.Count > 128)
        {
            keyframes.RemoveAt(0);
        }
    }
    
    void RestorePositions()
    {
        int lastIndex = keyframes.Count - 1;
        int secondToLastIndex = keyframes.Count - 2;
    
        if(secondToLastIndex >= 0)
        {
            currentPosition  = (keyframes[lastIndex] as Keyframe).position;
            previousPosition = (keyframes[secondToLastIndex] as Keyframe).position;
    
            currentRotation  = (keyframes[lastIndex] as Keyframe).rotation;
            previousRotation = (keyframes[secondToLastIndex] as Keyframe).rotation;
    
            keyframes.RemoveAt(lastIndex);
        }
    }
}

.


. , 90% . , , .

!
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/333594/

:  

: [1] []
 

:
: 

: ( )

:

  URL