0

I'm trying to program AI for a pong game and i'm trying to make the paddle game object follow the y co-ordinate movement of the ball game object.

The problem is that the paddle ends up just moving up and down and not actually following the ball.

This is the script i used to make it follow.

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

public class AIMove : MonoBehaviour {

    public int speed;
    public bool validUp = true;
    public bool validDown = true;


    void Awake()
    {

    }
    void Update()
    {

        GameObject sphere = GameObject.Find("Sphere");

        Transform spherePosition = sphere.GetComponent<Transform>();

        float spherePos = spherePosition.position.y; 

        if (spherePos < (0) && validUp == (true))
        {
            transform.Translate(Vector3.up * speed * Time.deltaTime);
        }
        else if (spherePos > (0) && validDown == (true))
        {
            transform.Translate(Vector3.down * speed * Time.deltaTime);
        }
        if (transform.position.y >= (2.3F))
        {
            validUp = false;
        }
        else if (transform.position.y <= (-2.3F))
        {
            validDown = false;
        }
        else
        {
            validUp = true;
            validDown = true;
        }








    }



}
user8077453
  • 15
  • 1
  • 3

1 Answers1

0

I think you do not fully understand how your code works. Let's take a look inside your Update method.

if (spherePos < (0) && validUp == (true))
{
    transform.Translate(Vector3.up * speed * Time.deltaTime);
}

What you are saying here is that if the position of the sphere on the Y axis is below 0, the AI paddle should move up. This contains no condition on whether the sphere is moving upwards or downwards. So, the sphere could be moving downwards, and you would still be moving the AI paddle upwards.

else if (spherePos > (0) && validDown == (true))
{
    transform.Translate(Vector3.down * speed * Time.deltaTime);
}

This contains the same kind of problems.

Instead, you could do something like this.

[SerializeField]
private float speed;
private Transform sphere;

private void Start()
{
    // In general, I'd recommend avoiding
    // GameObject.Find, but we'll use it for now.
    sphere = GameObject.Find("Sphere").transform;
}

private void Update()
{
    if(sphere.position.y >= transform.position.y)
    {
        transform.Translate(Vector.up * speed * Time.deltaTime);
    }
    else if(sphere.position.y <= transform.position.y)
    {
        transform.Translate(Vector.down * speed * Time.deltatime);
    }
}

This would basically compare the paddle's position on the Y axis to the sphere's position on the Y axis and move the paddle accordingly, to the correct direction. Then you just have to adjust the speed value as you want.

Note that this only moves the paddle based on the sphere's position on the Y axis alone. It does not take into account how the sphere is going to bounce off the walls or anything like that.

Kasperi
  • 93
  • 1
  • 12
  • Wow thank you, after looking at your code, i don't know why i thought mine would work, thank you. Just for curiosities sake, why did you make the variables private? Did that effect the functionality of the script? – user8077453 May 31 '17 at 12:47
  • It does not affect anything inside this script at all. It is just generally considered good practice to do so unless you need to access them outside of the class, more on that [here](https://softwareengineering.stackexchange.com/questions/143736/why-do-we-need-private-variables). Even then, you should rather use properties, more on that [here](https://stackoverflow.com/questions/295104/what-is-the-difference-between-a-field-and-a-property-in-c). – Kasperi May 31 '17 at 12:59
  • Thank you for explaining, i really appreciate it – user8077453 May 31 '17 at 23:39
  • Remember to accept the answer if it answered you question and solved your problem. – Kasperi Jun 04 '17 at 23:41