0
\$\begingroup\$

I need add force to object that has 2 different rigid bodies and someone said that the best way of this is using fixed joint. The case is this ; I have player object and it has a pusher object that while playing if I raise my finger, pusher object will move forward and backward so that push to enemies. The player object is like on the attacted photo below. enter image description here

So I added Fixed Joint to movingPusher. But the problem is this; When I want to add force to movingPusher, for break force = 50, it breaks the joint and so movingPusher move forward. So far so good, but I need this joint right after this push mechanic. So in here, someone suggest to point its connected body to null. ok well said. But even if I point it to null before I add force to movingPusher, the movingPusher object doesnt not affected by AddForce and not moving forward. So I couldnt figure out how to use fixed joint. If you could give some suggestions/ideas, I really will be appreciated:))

Here this is the code part also;

private void MovePlayer(Rigidbody PlayerRigid)
    {
        if (Input.GetMouseButtonDown(0))
        {
            firstTouchPos = Input.mousePosition;
            _gameStarted = true;
        }

        if (Input.GetMouseButton(0))
        {
            //MovingPusherTransform.position = StablePusherTransform.position;
            MovingPusherTransform.rotation = StablePusherTransform.rotation;

            if(fixedJoint.connectedBody == null)
            {
                fixedJoint.connectedBody = PlayerRigid;
            }

            _pushing = false;
            deltaTouchPos = Input.mousePosition - firstTouchPos;
            direction = new Vector3(deltaTouchPos.x, 0f, deltaTouchPos.y);
            PlayerRigid.velocity = direction.normalized * Speed;

            if (PlayerRigid.velocity != Vector3.zero)
            {
                PlayerRigid.rotation = Quaternion.LookRotation(PlayerRigid.velocity);
            }
        }
        
        else
        {
            if (_gameStarted)
            {
                PlayerRigid.velocity = Vector3.zero;
                fixedJoint.connectedBody = null;
                StartCoroutine("Push", 0.8f);
            }
        }
    }

    private IEnumerator Push(float duration)
    {
        if (!_pushing)
        {
            Debug.Log("forward!");
            PusherRigid.AddForce(StablePusherTransform.forward * PusherSpeed);
            PusherRigid.velocity = transform.TransformDirection(0, 0, 5);
            yield return (new WaitForSeconds(duration));
            _returning = true;
            _pushing = true;
        }

        else if (_returning)
        {
            Debug.Log("backward!");
            MovingPusherTransform.position = Vector3.MoveTowards(MovingPusherTransform.position, StablePusherTransform.position, 0.1f);
            yield return (new WaitForSeconds(duration));
            _returning = false;
        }

        else
        {
            //MovingPusherTransform.position = StablePusherTransform.position; 
            fixedJoint.connectedBody = PlayerRigid;
            yield break;
        }
    }

Edit for extra explanation: I try to code clone of "Push'em all" mobile game. I want my movingPusher object to follow the main object, "Player", while I am moving the Player object ( in if(Input.GetMouseButton(0)) statement ) . And when I raise my finger, I want to add force on movingPusher so that enemies will be pushed.

\$\endgroup\$
5
  • \$\begingroup\$ It's not clear to me what your desired outcome is. How do you want these two objects to move in relation to each other / to the world? Under what circumstances do you want that relationship to break or change? \$\endgroup\$ – DMGregory May 31 at 13:29
  • \$\begingroup\$ @DMGregory I try to code clone of "Push'em all" mobile game. I want my movingPusher object to follow the main object, "Player", while I am moving the Player object ( in if(Input.GetMouseButton(0)) statement ) . And when I raise my finger, I want to add force on movingPusher so that enemies will be pushed. Is it clear now? \$\endgroup\$ – anónimo May 31 at 13:55
  • \$\begingroup\$ No, I've never played that game. Edit your question to explain the behaviour in detail. From what you've described so far, it's not clear to me why these are two separate rigidbodies - could they not be just two colliders controlled by a single rigidbody? \$\endgroup\$ – DMGregory May 31 at 14:04
  • \$\begingroup\$ @DMGregory actually I am so new at unity. To move a game object or change its transform, shouldnt it have a rigidbody? If movingPusher wouldnt have a separate rigidbody, then how could it have physics actions and move? I am so confused now :( \$\endgroup\$ – anónimo May 31 at 14:47
  • \$\begingroup\$ You want it to move when the player moves, right? If they're both under the same player rigidbody, then that is what happens. If that is not what you want, then you need to explain what you do want in more detail. Consider including a video or animated gif of the behaviour from the game you're cloning, so you can show the behaviour if you find it too difficult to express clearly in words. \$\endgroup\$ – DMGregory May 31 at 14:54
1
\$\begingroup\$

EDITED

In Unity you have 2 ways of moving objects - either 'manually' move it little by little, or let Unity physics move it for you - add rigidbody, and give rigidbody force or velocity. Both methods are 'legal'.

To push things you will need rigidbody (but you still can move it little by little).

This should work:

  • Use separate rigidbody for pusher, make it a child, but give it big mass, also give big mass to player object as compared to pushed objects, then go to pusher rigidbody panel>constraints and mark FreezeRotation for all axes (alternatively checking the box isKinematic also works in my case). Here is gif of working pusher: pusher

Here I used move little by little method:

public IEnumerator doThePush()
{
    for (int i = 0; i < 58; i++)
    {
        transform.Translate(Vector3.forward * 2.2f * Time.deltaTime);
        yield return null;   //wait one frame
    }
    StartCoroutine(doGoback());
}

This works because pusher object already is moving according to parent, and on top of that I add its own movement.

In your code you are using move-by-velocities method, that is OK, however you set new velocity with this line:

PusherRigid.velocity = transform.TransformDirection(0, 0, 5);

basically you are saying "ignore any previous forces, ignore its parent velocity, just take this new velocity". So your previous line where you added the force is meaningless. You can avoid this by adding new velocity to existing one, not setting it. (For example just adding force, or combine your new velocity with existin one, then setting it). Or just use move-little-by-little method.

\$\endgroup\$
9
  • \$\begingroup\$ I am already using your second advice. there is 2 pusher object but one of them is not moving. The main reason that push me to use 2 seperate rigidbodies is; the player object will get damage by enemies ( which requires rigidbody ? ) , and my moving pusher object will push enemies forward which also requires rigidbody for box collider. I am confused now, to push enemies, moving pusher needs rigidbody, is it true? \$\endgroup\$ – anónimo Jun 1 at 8:10
  • \$\begingroup\$ it is so obvious that I am totally lost :D I dont know why I thought that to push enemies pusher object need rigidbody.. but thanks I removed it :) \$\endgroup\$ – anónimo Jun 1 at 8:38
  • \$\begingroup\$ but, then how can I set velocity for pusher object. because when I use your code part, for example if I increase stepCount, it doesnt push enemies and just pass through them? \$\endgroup\$ – anónimo Jun 1 at 8:44
  • \$\begingroup\$ exactly. it goes through. it seems it does need rigidbody. live and learn. I will update my answer \$\endgroup\$ – ShoulO Jun 1 at 8:45
  • \$\begingroup\$ hahah, ok thanks in anyway :) \$\endgroup\$ – anónimo Jun 1 at 8:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.