Cannot AddForce Simultaneously

hello,

i am having an issue with my game, in which i cannot apply two AddForces Simultaneously…

the codes in the game are the same for both objects so i would not know why this is happeneing. i have trakced them all to their routs and they are different gameobjects with different rigidbodies, and all is fine up untill i addforce…

Is this Normal Or should i look more into my Coding?

Post your code. Most likely you have a wrong reference (maybe both AddForce’s are being applied to the same ball).

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

public class LagShotCueManagerPlayerTwo : MonoBehaviour
{
    [SerializeField] private GameObject GAME_MANAGER;
    [SerializeField] private GameObject CUE_INSTANTIATOR;
    [SerializeField] private Slider SLIDER;
    [SerializeField] private GameObject CUE_BALL_GUI;
    [SerializeField] private float MOUSE_SENSITIVITY = 0;
    [SerializeField] private float CUEBALL_RADIUS = 0;
    [SerializeField] private float CUE_HALF_LENGTH = 0;
    [SerializeField] private Vector3 CUE_OFFSET = new Vector3(0, 0, 0);
    [SerializeField] private float MAX_DRAWBACK = 0;
    [SerializeField] private float MAX_CUE_FORCE = 0;
    [SerializeField] private float CUE_DISTANCE_FROM_CUEBALL = 0;

    [SerializeField] private Rigidbody cueBallPlayerTwo = null;
    [SerializeField] private GameObject cueBallReferencePlayerTwo = null;
    [SerializeField] private GameObject pointOfRotationPlayerTwo = null;
    [SerializeField] private GameObject cueStickPlayerTwo = null;

    //for physics Scene
    [SerializeField] private Rigidbody cueBallPhysics = null;
    [SerializeField] private GameObject cueBallReferencePhysics = null;
    [SerializeField] private GameObject pointOfRotationPhysics = null;

    GameManager gameManager;
    BallInstantiator ballInstantiator;
    CueInstantiator cueInstantiator;
    CueBallGUI cueBallGUI;
    GameRules gameRules;

    private Quaternion pointOfRotationTarget;
    private Quaternion cueStickTarget;

    private Vector3 initialMousePosition = new Vector3(0, 0, 0);
    private Vector3 differenceMousePositions = new Vector3(0, 0, 0);
    private Vector3 unitVector = new Vector3(0, 0, 0);
    private Vector3 unitVectorUp = new Vector3(0, 0, 0);
    private Vector3 cuePosition = new Vector3(0, 0, 0);
    private Vector3 cuePositionDraw = new Vector3(0, 0, 0);
    private Vector3 positionToHit = new Vector3(0, 0, 0);
    private Vector3 force = new Vector3(0, 0, 0);

    private float cueDistanceFromPOR = 0;
    private float cueStrength = 0;
    private float drawBackSave = 0;

    private bool mouseButtonUp = true;
    private bool mouseButtonDown = false;
    private bool cueManagerActive = false;
    private bool strike = false;
    private bool firstMouseClick = false;
    private bool setInitialPosition = false;
    private bool gotNeededData = false;


    public bool getGotDataNeeded()
    {
        return gotNeededData;
    }
    public Vector3 getCuePosition()
    {
        return cuePosition;
    }
     public Quaternion getCueStickTarget()
     {
         return cueStickTarget;
     }

    void Awake()
    {
        GAME_MANAGER = GameObject.Find("GameManager");
        gameManager = GAME_MANAGER.GetComponent<GameManager>();
        ballInstantiator = GAME_MANAGER.GetComponent<BallInstantiator>();
        gameRules = GAME_MANAGER.GetComponent<GameRules>();
    }

    void Start()
    {
        CUE_INSTANTIATOR = GameObject.Find("CueInstantiator(Clone)");
        cueInstantiator = CUE_INSTANTIATOR.GetComponent<CueInstantiator>();
        CUE_BALL_GUI = GameObject.Find("CueBall UI");
        cueBallGUI = CUE_BALL_GUI.GetComponent<CueBallGUI>();

        SLIDER = (Slider)FindObjectOfType(typeof(Slider));

        cueDistanceFromPOR = CUE_HALF_LENGTH + CUEBALL_RADIUS + CUE_DISTANCE_FROM_CUEBALL;

        pointOfRotationTarget = Quaternion.Euler(0, (transform.rotation.y), (transform.rotation.z));
        cueStickTarget = Quaternion.Euler(0, (transform.rotation.y), (transform.rotation.z + 25));

        cueStickPlayerTwo = cueInstantiator.getCuePlayerTwo();

        cuePositionDraw = unitVector * MAX_DRAWBACK * Mathf.Pow(0, 2f);

        Ray ray = new Ray(transform.position, transform.right);
        Ray rayOffset = new Ray(transform.position, transform.up);
        Vector3 rayAtPoint = ray.GetPoint(1);
        Vector3 rayAtPointup = rayOffset.GetPoint(1);
        Vector3 heading = transform.position - rayAtPoint;
        Vector3 headingUp = transform.position - rayAtPointup;
        float distance = heading.magnitude;
        float elevation = headingUp.magnitude;

        unitVector = heading / distance;
        unitVectorUp = headingUp / elevation;

        cuePosition = unitVector * cueDistanceFromPOR + cuePositionDraw - unitVectorUp * CUE_OFFSET.y;
    }

    void Update()
    {
        if(!gotNeededData)
        {
            GetData();
          
        }
      
        if (gameRules.getLagShotStillInProcess())
        {
            mouseCheck();
            PORSetter();
            CueSetterForLagShot();
            CueStriker();
        }
        else
        {
            return;
        }
    }

    void mouseCheck()
    {
        if (Input.GetMouseButtonDown(0))
        {
            mouseButtonDown = true;
            mouseButtonUp = false;
            SLIDER.onValueChanged.AddListener(CueSliderManager);
            initialMousePosition = Input.mousePosition * MOUSE_SENSITIVITY - differenceMousePositions;
        }
        else if (Input.GetMouseButtonUp(0))
        {
            mouseButtonDown = false;
            mouseButtonUp = true;
        }
    }

    void PORSetter()
    {
        if (gameObject.name == "CueBallPointOfRotationPlayerTwo(Clone)")
        {
            pointOfRotationPlayerTwo.transform.position = cueBallReferencePlayerTwo.transform.position;
        }
    }

    void CueSetterForLagShot()
    {
        if (gameObject.name == "CueBallPointOfRotationPlayerTwo(Clone)")
        {
            if (cueStickPlayerTwo == null && cueInstantiator.getCuePlayerTwoAvailable())
            {
                cueStickPlayerTwo = cueInstantiator.getCuePlayerTwo();
            }
            if (cueStickPlayerTwo == null)
            {
                return;
            }
            cueStickPlayerTwo.transform.rotation = cueStickTarget;

            Ray ray = new Ray(transform.position, transform.right);
            Ray rayOffset = new Ray(transform.position, transform.up);
            Vector3 rayAtPoint = ray.GetPoint(1);
            Vector3 rayAtPointup = rayOffset.GetPoint(1);
            Vector3 heading = transform.position - rayAtPoint;
            Vector3 headingUp = transform.position - rayAtPointup;
            float distance = heading.magnitude;
            float elevation = headingUp.magnitude;

            unitVector = heading / distance;
            unitVectorUp = headingUp / elevation;
          
            cuePosition = unitVector * cueDistanceFromPOR + cuePositionDraw - unitVectorUp * CUE_OFFSET.y;

            cueStickPlayerTwo.transform.position = pointOfRotationPlayerTwo.transform.position + cuePosition;
        }
    }

    public void CueSliderManager(float drawBack)
    {
        if (!mouseButtonUp)
        {
          
            cuePositionDraw = unitVector * MAX_DRAWBACK * Mathf.Pow(drawBack, 2f);

            cueStrength = (MAX_CUE_FORCE * Mathf.Pow(drawBack, 2f));
            print(cueBallPlayerTwo.name);
            force = new Vector3(cueStrength,0,0);

            cueManagerActive = true;
            strike = true;

            if (Input.GetMouseButtonUp(0) && drawBack != 0)
                CueStriker();

            if (drawBack == 0)
            {
                strike = false;
            }
        }
    }

    void CueStriker()
    {
        if (!mouseButtonUp || !cueManagerActive || !strike)
        {
            return;
        }

        float randomAddForce = Random.Range(-0.5f, 0.5f); //just for demo
      
        SLIDER.value = 0;
        strike = false;

        //when add elevation will need to fix for Y component

        cueBallPlayerTwo.AddForce(drawBackSave + randomAddForce, force.y, force.z, ForceMode.Impulse);

        cuePositionDraw = Vector3.zero;
 
        cueManagerActive = false;
    }

    void Shoot()
    {
        float randomAddForce = Random.Range(-0.5f, 0.5f); //just for demo
        cueBallPlayerTwo.AddForce(drawBackSave + randomAddForce, force.y, force.z, ForceMode.Impulse);
    }

    void GetData()
    {
        if (gameObject.name == "CueBallPointOfRotationPlayerTwo(Clone)")
        {
          
            if(cueBallReferencePlayerTwo == null)
            cueBallReferencePlayerTwo = ballInstantiator.getPlayerTwoCueBall();
            if(cueBallPlayerTwo == null)
            cueBallPlayerTwo = cueBallReferencePlayerTwo.GetComponent<Rigidbody>();
            if(pointOfRotationPlayerTwo == null)
            pointOfRotationPlayerTwo = ballInstantiator.getPlayerTwoCueBallPointOfRotation();
         
        }
        if (gameObject.name == "CueBallPointOfRotationPlayerTwo(Clone)" && cueBallPlayerTwo != null)
        {
            gotNeededData = true;
        }

    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class LagShotCueManagerPlayerOne : MonoBehaviour
{
    [SerializeField] private GameObject GAME_MANAGER;
    [SerializeField] private GameObject CUE_INSTANTIATOR;
    [SerializeField] private Slider SLIDER;
    [SerializeField] private GameObject CUE_BALL_GUI;
    [SerializeField] private float MOUSE_SENSITIVITY = 0;
    [SerializeField] private float CUEBALL_RADIUS = 0;
    [SerializeField] private float CUE_HALF_LENGTH = 0;
    [SerializeField] private Vector3 CUE_OFFSET = new Vector3(0, 0, 0);
    [SerializeField] private float MAX_DRAWBACK = 0;
    [SerializeField] private float MAX_CUE_FORCE = 0;
    [SerializeField] private float CUE_DISTANCE_FROM_CUEBALL = 0;

    [SerializeField] private Rigidbody cueBallPlayerOne = null;
    [SerializeField] private GameObject cueBallReferencePlayerOne = null;
    [SerializeField] private GameObject pointOfRotationPlayerOne = null;
    [SerializeField] private GameObject cueStickPlayerOne = null;

    //for physics Scene
    [SerializeField] private Rigidbody cueBallPhysics = null;
    [SerializeField] private GameObject cueBallReferencePhysics = null;
    [SerializeField] private GameObject pointOfRotationPhysics = null;

    GameManager gameManager;
    BallInstantiator ballInstantiator;
    CueInstantiator cueInstantiator;
    CueBallGUI cueBallGUI;
    GameRules gameRules;

    private Quaternion pointOfRotationTarget;
    private Quaternion cueStickTarget;

    private Vector3 initialMousePosition = new Vector3(0, 0, 0);
    private Vector3 differenceMousePositions = new Vector3(0, 0, 0);
    private Vector3 unitVector = new Vector3(0, 0, 0);
    private Vector3 unitVectorUp = new Vector3(0, 0, 0);
    private Vector3 cuePosition = new Vector3(0, 0, 0);
    private Vector3 cuePositionDraw = new Vector3(0, 0, 0);
    private Vector3 positionToHit = new Vector3(0, 0, 0);
    private Vector3 force = new Vector3(0, 0, 0);

    private float cueDistanceFromPOR = 0;
    private float cueStrength = 0;

    private bool mouseButtonUp = true;
    private bool mouseButtonDown = false;
    private bool cueManagerActive = false;
    private bool strike = false;
    private bool firstMouseClick = false;
    private bool setInitialPosition = false;
    private bool gotNeededData = false;


    public bool getGotDataNeeded()
    {
        return gotNeededData;
    }
    public Vector3 getCuePosition()
    {
        return cuePosition;
    }
    public Quaternion getCueStickTarget()
    {
        return cueStickTarget;
    }

    void Awake()
    {
        GAME_MANAGER = GameObject.Find("GameManager");
        gameManager = GAME_MANAGER.GetComponent<GameManager>();
        ballInstantiator = GAME_MANAGER.GetComponent<BallInstantiator>();
        gameRules = GAME_MANAGER.GetComponent<GameRules>();
    }

    void Start()
    {
        CUE_INSTANTIATOR = GameObject.Find("CueInstantiator(Clone)");
        cueInstantiator = CUE_INSTANTIATOR.GetComponent<CueInstantiator>();
        CUE_BALL_GUI = GameObject.Find("CueBall UI");
        cueBallGUI = CUE_BALL_GUI.GetComponent<CueBallGUI>();

        SLIDER = (Slider)FindObjectOfType(typeof(Slider));

        cueDistanceFromPOR = CUE_HALF_LENGTH + CUEBALL_RADIUS + CUE_DISTANCE_FROM_CUEBALL;

        pointOfRotationTarget = Quaternion.Euler(0, (transform.rotation.y), (transform.rotation.z));
        cueStickTarget = Quaternion.Euler(0, (transform.rotation.y), (transform.rotation.z + 25));

        cueStickPlayerOne = cueInstantiator.getCuePlayerOne();

        cuePositionDraw = unitVector * MAX_DRAWBACK * Mathf.Pow(0, 2f);

        Ray ray = new Ray(transform.position, transform.right);
        Ray rayOffset = new Ray(transform.position, transform.up);
        Vector3 rayAtPoint = ray.GetPoint(1);
        Vector3 rayAtPointup = rayOffset.GetPoint(1);
        Vector3 heading = transform.position - rayAtPoint;
        Vector3 headingUp = transform.position - rayAtPointup;
        float distance = heading.magnitude;
        float elevation = headingUp.magnitude;

        unitVector = heading / distance;
        unitVectorUp = headingUp / elevation;

        cuePosition = unitVector * cueDistanceFromPOR + cuePositionDraw - unitVectorUp * CUE_OFFSET.y;
    }

    void Update()
    {
        if (!gotNeededData)
        {
            GetData();

        }

        if (gameRules.getLagShotStillInProcess())
        {
            mouseCheck();
            PORSetter();
            CueSetterForLagShot();
            CueStriker();
        }
        else
        {
            return;
        }
    }

    void mouseCheck()
    {
        if (Input.GetMouseButtonDown(0))
        {
            mouseButtonDown = true;
            mouseButtonUp = false;
            SLIDER.onValueChanged.AddListener(CueSliderManager);
            initialMousePosition = Input.mousePosition * MOUSE_SENSITIVITY - differenceMousePositions;
        }
        else if (Input.GetMouseButtonUp(0))
        {
            mouseButtonDown = false;
            mouseButtonUp = true;
        }
    }

    void PORSetter()
    {
        if (gameObject.name == "CueBallPointOfRotationPlayerOne(Clone)")
        {
            pointOfRotationPlayerOne.transform.position = cueBallReferencePlayerOne.transform.position;
        }
    }

    void CueSetterForLagShot()
    {
        if (gameObject.name == "CueBallPointOfRotationPlayerOne(Clone)")
        {
            if (cueStickPlayerOne == null && cueInstantiator.getCuePlayerOneAvailable())
            {
                cueStickPlayerOne = cueInstantiator.getCuePlayerOne();
            }
            if (cueStickPlayerOne == null)
            {
                return;
            }
            cueStickPlayerOne.transform.rotation = cueStickTarget;

            Ray ray = new Ray(transform.position, transform.right);
            Ray rayOffset = new Ray(transform.position, transform.up);
            Vector3 rayAtPoint = ray.GetPoint(1);
            Vector3 rayAtPointup = rayOffset.GetPoint(1);
            Vector3 heading = transform.position - rayAtPoint;
            Vector3 headingUp = transform.position - rayAtPointup;
            float distance = heading.magnitude;
            float elevation = headingUp.magnitude;

            unitVector = heading / distance;
            unitVectorUp = headingUp / elevation;

            cuePosition = unitVector * cueDistanceFromPOR + cuePositionDraw - unitVectorUp * CUE_OFFSET.y;

            cueStickPlayerOne.transform.position = pointOfRotationPlayerOne.transform.position + cuePosition;
        }
    }

    public void CueSliderManager(float drawBack)
    {
        if (!mouseButtonUp)
        {
            cuePositionDraw = unitVector * MAX_DRAWBACK * Mathf.Pow(drawBack, 2f);

            cueStrength = (MAX_CUE_FORCE * Mathf.Pow(drawBack, 2f));

            force = new Vector3(cueStrength, 0, 0);

            cueManagerActive = true;
            strike = true;

            if (drawBack == 0)
            {
                strike = false;
            }
        }
    }

    void CueStriker()
    {
        if (!mouseButtonUp || !cueManagerActive || !strike)
        {
            return;
        }

        print(cueBallPlayerOne.name);
        SLIDER.value = 0;
        strike = false;

        //when add elevation will need to fix for Y component

        cueBallPlayerOne.AddForce(force.x, force.y, force.z, ForceMode.Impulse);

        //cueBallPlayerTwo.AddForce(force.x, force.y, force.z, ForceMode.Impulse);

        cuePositionDraw = Vector3.zero;

        cueManagerActive = false;
    }


    void GetData()
    {
        if (gameObject.name == "CueBallPointOfRotationPlayerOne(Clone)")
        {
          
            if (cueBallReferencePlayerOne == null)
                cueBallReferencePlayerOne = ballInstantiator.getPlayerOneCueBall();
            if (cueBallPlayerOne == null)
                cueBallPlayerOne = cueBallReferencePlayerOne.GetComponent<Rigidbody>();
            if (pointOfRotationPlayerOne == null)
                pointOfRotationPlayerOne = ballInstantiator.getPlayerOneCueBallPointOfRotation();
        }
        if (gameObject.name == "CueBallPointOfRotationPlayerOne(Clone)" && cueBallPlayerOne != null)
        {
            gotNeededData = true;
        }

    }
}

the thing is that sometime when im coding the first cue ball doesnt get the cuestick intstantiated… in that case the second ball works!! its very odd… here is my code for the two balls… i seperated the scripts into player one and player two so that it can be more clear… anyways by your reply i can understand that addingForce Simulataneously should not make a difference?

Looks like misconfig in inspector. First of all, reproduce the error having console open and chec if any errors. If there are any, fix them and try to reproduce bug again. If it still there, then reload the game, press pause button and double check references in all your inspectors for players and balls. I believe they messed somehow and you will find what one object is referenced from some two scripts or some reference is null.

1 Like

First, I am assuming that you’ve found that it doesn’t work when line 226 ISN’T commented out? Because that being commented out would be a very simple explanation :slight_smile:

One trick you could use to find wrong assignments in the inspector: Whenever you do the problematic thing (in this case, AddForce), put a Debug.Log there:

Debug.Log($"Adding {force} to {cueBallPlayerOne.gameObject.name}", cueBallPlayerOne);
Debug.Log($"Adding {force} to {cueBallPlayerTwo.gameObject.name}", cueBallPlayerTwo);

After you’ve clicked to add the force, pause it and click on each debug line in the console. When you click on each, some object in the scene should be highlighted yellow. The second parameter there allows you to determine specifically which object a given variable points to. If both debugs point to the same object, there’s your answer.

1 Like

Thanks, Getting Closer…

It was the Slider.value = 0;