Hi everybody,
what I want to do is gradually decrease the speed of my Player (a moving disc) as it moves on a Path, and gradually increase it when the Player exits the Path.
This is a mobile app and I’m using the acceleremeter to move the Player.
I tried using the Math.Smoothstep function but the result is that the speed decrease or increase without smoothing.
Here is the script of my Player object:
using UnityEngine;
using System.Collections;
public class MovePlayer : MonoBehaviour {
// Speed multiplier
public float speed;
// FixedUpdate for physical objects
void FixedUpdate () {
transform.Translate (
Input.acceleration.x * Time.deltaTime * speed,
Input.acceleration.y * Time.deltaTime * speed,
0);
}
// Collision control (requires RigidBody)
void OnCollisionEnter2D(Collision2D obj){
if (obj.gameObject.CompareTag ("Wall")) {
Debug.Log ("Collision: Wall");
}
}
// Player enters path
void OnTriggerEnter2D(Collider2D obj){
if (obj.gameObject.CompareTag ("Path")) {
Debug.Log ("Trigger Enter: Path");
speed = Mathf.SmoothStep (speed, speed / 2, 2);
}
}
// Player exits path
void OnTriggerExit2D(Collider2D obj){
if (obj.gameObject.CompareTag ("Path")) {
Debug.Log ("Trigger Exit: Path");
speed = Mathf.SmoothStep (speed, speed * 2, 2);
}
}
}
That’s because you’re using SmoothStep erroneously. The calculation is done a single time on the trigger events and it doesn’t consider the time, thus the instant change.
The correct usage is at FixedUpdate, and it should be something like this:
Thus, you would set targetSpeed at the triggers, then calculate and apply the new currentSpeed value. The “2” value defines how fast the transition is. You may want to expose it as public property as well for experimenting with the value.
using UnityEngine;
using System.Collections;
public class MovePlayer : MonoBehaviour {
public float maxSpeed; // Maximum speed reachable
public float minSpeed; // Minimum speed reachable
public float duration; // Duration of the speed transition
private float targetSpeed;
private float currentSpeed;
void Start(){
// Setting the starting speed parameters
currentSpeed = targetSpeed = maxSpeed;
}
void FixedUpdate () {
transform.Translate (
Input.acceleration.x * Time.deltaTime * currentSpeed,
Input.acceleration.y * Time.deltaTime * currentSpeed,
0);
// Smooting the currentSpeed to the targetSpeed
currentSpeed = Mathf.SmoothStep (currentSpeed, targetSpeed, duration * Time.deltaTime);
Debug.Log ("Speed: " + currentSpeed);
}
// Player enters path
void OnTriggerEnter2D(Collider2D other) {
if (other.gameObject.CompareTag ("Path")) {
Debug.Log ("Trigger Enter: Path");
targetSpeed = minSpeed; // Setting the new speed to the minimum
}
}
// Player exits path
void OnTriggerExit2D(Collider2D other){
if (other.gameObject.CompareTag ("Path")) {
Debug.Log ("Trigger Exit: Path");
targetSpeed = maxSpeed; // Setting the new speed to the maximum
}
}
// Collision control (requires RigidBody)
void OnCollisionEnter2D(Collision2D obj){
if (obj.gameObject.CompareTag ("Wall")) {
Debug.Log ("Collision: Wall");
}
}
}
It is not the most efficient way to do that because the Mathf.SmoothStep function is called even when it is not needed, but I think a simple check could solve the problem.