How to add a speed cap to an object that follows another object on the x axis? (C#)

I have a code that makes a paddle follow a ball along the X-axis simply by knowing the ball’s position. I planned to use this as a sort of “practice mode” for a breakout-style game but all it does is act like a wall, naturally. By that I mean it, no matter what, will be in the exact position of the ball, thus doing absolutely nothing and making it impossible to win.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AI_Paddle : MonoBehaviour {

    public bool autoPlay = true;

    private Ball ball;

    void Start() 
    {
        ball = GameObject.FindObjectOfType<Ball>();
    }

    // Update is called once per frame
    void Update () 
    {
        AutoPlay();
    }

    void AutoPlay()
    {
        Vector3 paddlePos = new Vector3(0.5f, this.transform.position.y, -1f);
        Vector3 ballPos = ball.transform.position;
        paddlePos.x = Mathf.Clamp(ballPos.x, 0.5f, 15.5f);
        this.transform.position = paddlePos;
    }
}

I would like to make it possible to beat the practice mode using something along the lines of a speed cap so the “practice paddle” can’t be on the ball’s exact position at higher speeds (I am open to suggestions of other ways) but, being a complete beginner, I have no clue how. I’m assuming this would require the entire AutoPlay() function?

Use MoveTowards() instead of setting a position, 3rd argument takes speed into consideration. If u want to only move the paddle on x axis: Vector3.MoveTowards on y axis only (C#) - Questions & Answers - Unity Discussions

I made an attempt and I feel like this is a really good solution but I just can’t get it to work in my script. Are you able to?

You can do it like so:

public class AI_Paddle : MonoBehaviour
{
    public bool autoPlay = true;

    public float MaxSpeed = 5;
    private Ball ball;

    Vector3 targetPos;

    void Start()
    {
        ball = FindObjectOfType<Ball>();
        targetPos = new Vector3(0.5f, 0, -1f);
        transform.position = targetPos;
    }
   
    void Update()
    {
        AutoPlay();
    }

    void AutoPlay()
    {
        Vector3 ballPos = ball.transform.position;
        targetPos.x = Mathf.Clamp(ball.transform.position.x, 0.5f, 15.5f);
        var step = MaxSpeed * Time.deltaTime;
        transform.position = Vector3.MoveTowards(transform.position, targetPos, step);
    }
}

Well, this is an interesting problem. This is the result of my script:


And this is the result of that one:

What the heck?

Something’s gone wrong somewhere along the way. You can just use your original script in its entirety and change these lines:

paddlePos.x = Mathf.Clamp(ballPos.x, 0.5f, 15.5f);

to:

paddlePos.x = Mathf.Clamp(Mathf.MoveTowards(paddlePos.x, ballPos.x, 5.0f * Time.deltaTime), 0.5f, 15.5f);

Change 5.0f to whatever speed you want the paddle to move by.

EDIT: You’ll also need to set the x position of the paddle position instead of just the Y:

Vector3 paddlePos = new Vector3(this.transform.position.x, this.transform.position.y, -1f);
1 Like

Finally, it worked! Thanks for the help!