How do I trigger a game object to move a desired distance at a desired speed?
I have a ball that when it rolls over a tile it will cause the tile to move upwards pushing the ball up with it. My script is below. The parent object is a tile that moves up when the ball rolls over it and collides with the nested trigger object. The tile moves up but does not push the ball up with it. I assume it is because the tile moves too quickly as the ball does have a Rigidbody component attached to it. How can I trigger the movement of the tile and define the distance and speed that the tile should move up?
public class Spring : MonoBehaviour
{
private void OnTriggerEnter(Collider other)
{
transform.parent.Translate(Vector3.up );
}
}
Answer by lgarczyn · Oct 12, 2019 at 03:25 PM
You assumed correctly. The tile needs to be a kinematic Rigidbody, and you need to use the MovePosition function. The tile collider cannot be a trigger.
You need to use two colliders if you want a trigger in the center of the platform. You could do something like this:
this is the script on the trigger collider in the center of the tile, that is a child of tile:
public class TriggerDispatcher : MonoBehaviour { public GameObject target; private void OnTriggerEnter(Collider other) { if (other.CompareTag("Player")) { target.SendMessage("OnPlayerEnter", other); } }
this is the script of the tile
public class TriggerDispatcher : MonoBehaviour { public float speed = 1f; public Vector3 target; private Vector3 startPos; public bool movingToTarget; private void Start() { startPos = transform.position; } private void OnPlayerEnter(Collider other) { movingToTarget = !movingToTarget; } private void FixedUpdate() { Vector3 destination; if (movingToTarget) destination = startPos + target; else destination = startPos; Vector3 movement = destination - transform.position; float distance = speed * Time.fixedDeltaTime; if (movement.magnitude > distance) movement = movement.normalized * distance; GetComponent<Rigidbody>().MovePosition(transform.position + movement); } }
Now this can be simplified if you add start and end position markers for your platform, and use the SmoothDamp function:
public class TriggerDispatcher : MonoBehaviour
{
public float speed = 1f;
public float timeToEnd = 1f;
public Transform startPos;
public Transform endPos;
public bool movingToTarget;
private Vector3 velocity;
private void Start() {
startPos = transform.position;
}
private void OnPlayerEnter(Collider other) {
movingToTarget = !movingToTarget;
}
private void FixedUpdate() {
Vector3 destination;
if (movingToTarget)
destination = endPos.position;
else
destination = startPos.position;
Vector3 newPos = SmoothDamp(
transform.position,
destination,
ref velocity,
timeToEnd,
speed);
GetComponent<Rigidbody>().MovePosition(newPos);
}
}
Your answer
Follow this Question
Related Questions
Vector3.Lerp not working properly, making the player bounce around 2 Answers
Error `UnityEngine.Component' does not contain a definition 1 Answer
Animation triggered by other animation, script, c# 1 Answer
Can’t keep the position 0 Answers
A way to make the player get punished when standing still? 0 Answers