Hello we would like some help with a problem we are having. Our player gets a extra speed powerup and “appears” to moving very fast though the game. However the NPCs speed is unaffected so it seems that they are moving just as fast as the player. This is because the scrolling speed of the background speeds up while everyone thing else doesn’t (Like the game jetpack joyride). We would like to slow down the speed of the animators of the other sprites when the powerup is active. But I can’t find anything in the docs that talk about how to access multiple animators at once. There has to be a better way then to have to reference all the animations indivaully in code.
Using root motion? Or are you using some sort of character/motor script to move your characters?
With root motion you just have to duplicate the animation and change the speed value. Then set some variable when the power up is enabled–the variable will then trigger the slower animations. Look up BlendTrees, you can blend between the slow and fast animations.
Either use Time.timeScale or have a global float timeScale in a GameManager somewhere and update the speed of the animations via code with the Animator component.
No, I’m not using a character controller/motor.
how wold I go about this? I’m a noob with code. So this project has been a big learning experience for me.
I added on to a script thats controlling the velocity of the spawned NPCs, will this work?
using UnityEngine;
using System.Collections;
public class InstantVelocity : MonoBehaviour {
public PlayerManager playerManager;
public Vector2 velocity = Vector2.zero;
private Rigidbody2D body2d;
void Awake()
{
body2d = GetComponent<Rigidbody2D> ();
}
void FixedUpdate()
{
body2d.velocity = velocity;
}
void Slowdown ()
{
playerManager.ActivateExtraSpeed ();
Time.timeScale = 0.7F;
Invoke ("SpeedIsNormal", 10);
}
void SpeedIsNormal ()
{
playerManager.DisableExtraSpeed ();
Time.timeScale = 1.0F;
}
}
So when you have a situation where you want 1 thing to appear different from everything else. It’s easier to alter the 1 thing, rather than alter the everything except the one thing.
Of course though, from the sounds of it, you want the players animations to appear normal speed… and everything else to appear slower.
So, we need to globally turn down the speed, and custom keep the players speed at normal.
OK
Well, I personally didn’t like the way that Unity gave you the time… it’s ONLY global. So I spun my own object identity for time in the game.
First I defined the interface for it called ‘TimeSupplier’, as well as an ‘IScalableTimeSupplier’ (because things like real time aren’t scalable):
And I implemented it for the standards times that exist out there: normal, real, and smooth (Normal returns fixed time when in FixedUpdate… just like Time.deltaTime). As well as a factory for creating custom time objects:
Now with this what I would do is create a custom time for the player. Name it something like “PlayerTime”. And use the global for the everything.
When the player gets the powerup, slow the global down, and make sure that the player updates at the normal speed.
Something like this:
public class PlayerScript : MonoBehaviour
{
private IScalableTimeSupplier _playerTime;
private Animator _anim;
private bool _inSlowMo;
private void Awake()
{
_playerTime = SPTime.CreateCustomTime("PlayerTime");
_anim = this.GetComponent<Animator>();
}
private void Update()
{
//instead of using things like Time.deltaTime, use _playerTime.Delta
//simple example code, player is always moving right at a speed of 5 units per second:
var pos = this.transform.position;
pos.x += 5f * _playerTime.Delta; //will always be at 1x realTime
this.transform.position = pos;
}
public void StartSpeedBoost()
{
//slow down the global time to
SPTime.Normal.SetScale("PlayerSpeedBoost", 0.5f);
_anim.speed = SPTime.GetInverseScale(_playerTime); //gets the speed the animator should be to reflect the speed defined by _playerTime
}
public void EndSpeedBoost()
{
//return speed to normal
SPTime.Normal.SetScale("PlayerSpeedBoost", 1f);
_anim.speed = 1f;
}
}
In this example, all that’s really happening is we’re saying:
slow everything down to 0.5 speed
player updates on its own timeScale defined in ‘PlayerTime’ time supplier, it’s always at 1x speed
during speedboost, we have to set the player’s animator speed to 2 (1f / 0.5f) so that it still appears to animate at ‘normal’ speed since the global timeScale has been halved.
Now we don’t have to update every animator in the scene, and instead only the player.
Well, I did get a few errors. Cleaned some of them up my self but I can’t quite solve these. Can you help ?
It appears you brought the SPTime class into your project.
That class is part of a larger framework, so it has dependencies you’d have to purge. It’s not a copy paste a single class option. Sorry… I should have pointed that out earlier. I was merely showing you the design of how I approach it. To directly adopt it, you’d need to fork my Spacepuppy Framework… OR grab its dependencies, which there are many.
-
I linked to both SPTime and the interfaces that SPTime uses. ITimeSupplier, and IScalableTimeSupplier:
spacepuppy-unity-framework/SpacepuppyBase/ITimeSupplier.cs at master · lordofduct/spacepuppy-unity-framework · GitHub -
CustomTimeSupplier for your custom times:
spacepuppy-unity-framework/SpacepuppyBase/CustomTimeSupplier.cs at master · lordofduct/spacepuppy-unity-framework · GitHub -
At line 300 it uses this extension method:
public static float Product(this IEnumerable<float> coll)
{
if (coll == null) return float.NaN;
float result = 1f;
foreach(float value in coll)
{
result *= value;
}
return result;
}
Which is found in MathUtil:
- And GameLoopEntry which has its own bag of dependencies:
spacepuppy-unity-framework/SpacepuppyBase/GameLoopEntry.cs at master · lordofduct/spacepuppy-unity-framework · GitHub
Got more errors, I assume that it’s more missing connections from other scripts ? I would hate to use all your scripts for this game just because of missing connections. I’m awaiting for your reply.
Yeah, there’s several. As I pointed out, the 4 dependencies above. Of which GameLoopEntry has even more dependencies. I don’t like rewriting certain bits of code, so I have a framework of code to depend on.
It’s all part of a larger framework.
There is a built version of the framework on there already for easy use in a project. But it adds a dll dependency to your project as well.
Or you could just spin your own… that doesn’t have the dependencies I have. Creating an object identity for time for yourself. Without the need for my framework… which would come with a lot of things you may not need (like a tweener, event system, coroutine extensions, and other things).
Also, note, you can just use the Time.timeScale and Time.realDeltaTime for a similar effect. It just lacks the object identity I set up. And if you have any other scaling of time in the code, it could disjoint things.
public class PlayerScript : MonoBehaviour
{
private Animator _anim;
private void Awake()
{
_anim = this.GetComponent<Animator>();
}
private void Update()
{
//instead of using things like Time.deltaTime, use _playerTime.Delta
//simple example code, player is always moving right at a speed of 5 units per second:
var pos = this.transform.position;
pos.x += 5f * Time.realDeltaTime; //will always be at 1x realTime
this.transform.position = pos;
}
public void StartSpeedBoost()
{
//slow down the global time to
Time.timeScale = 0.5f;
_anim.speed = 1f / Time.timeScale; //gets the speed the animator should be to reflect the speed defined by _playerTime
}
public void EndSpeedBoost()
{
//return speed to normal
Time.timeScale = 1f;
_anim.speed = 1f;
}
}

