Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Character controller + ship moving physics question!

Discussion in 'Scripting' started by Palimon, Sep 19, 2014.

  1. Palimon

    Palimon

    Joined:
    Apr 18, 2013
    Posts:
    225
    Hey, so I'm making a game where you can walk around inside a spaceship with multiple other players, walk up to a console, take control of the spaceship, gun, etc. Right now I build my own rigidbody character controller, and have the spaceship pilotable and everything. I could really use some help brainstorming a good solution to when the ship moves, the character flies around. My only current idea that I know would work is to go to a non-rigidbody controller. Obviously the easiest, but I really want a rigidbody so I can affect the player with forces such as ship impacts, rotation-based "gravity", etc. I'm new to Unity, so there's probably some tools or architectures that are a great solution that I'm just not aware of. Thanks!
     
  2. spec7or

    spec7or

    Joined:
    Jan 11, 2014
    Posts:
    4
    Have you tried adding the ships velocity to the character controller manually? The other approach would be to seperate the interior and exterior of the ship and use multiple camera's or render targets to make it seem like they are one object this allows you to have specific control over the effects on the inside of the ship without having to artificialy modify the exterior ships velocity.
     
  3. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    does the player have to be inside the actual ship?

    as in, could you separate them so that the insides are actually another model somewhere in the scene... you move around inside this.. guess it depends if you have windows etc. Wouldnt be a problem if you have pro, because you could use render textures for your windows.

    otherwise, you could make your player a child of the ship.
     
  4. Palimon

    Palimon

    Joined:
    Apr 18, 2013
    Posts:
    225
    Great suggestions, thanks! I was hoping to not have to try using a ship interior somewhere else - I'll first try manually adding the velocity of the ship to the player. The player is currently a child of the ship, but that didn't seem to have any effect physics-wise. The child/player still behaves as if it wasn't.
     
  5. BmxGrilled

    BmxGrilled

    Joined:
    Jan 27, 2014
    Posts:
    238
    Easy fix, make the characters inside the ship, parented to the ship transform. then when the ship moves, the transform alteration will affect the characters. One thing to note, if the ship is at an angle from the defauly gravity direction (Vector3(0, -1, 0)), you'll want to turn off gravity and apply your own based on the ship. e.g. Vector3 gravity = -shipTransform.up; //negative up = down
    If you want the players to go through the airlock and become detached from the ship, use a trigger collider to determine if they are entering or leaving the ship. Hope this makes sense! :)
     
  6. Palimon

    Palimon

    Joined:
    Apr 18, 2013
    Posts:
    225
    @TwixEmma - I do have the character parented (Gameobject under Gameobject in the hierarchy). I was surprised when that didn't seem to do anything. Do you mean anything different from what I did by "parented to the ship transform"?
     
  7. BmxGrilled

    BmxGrilled

    Joined:
    Jan 27, 2014
    Posts:
    238
    Well theres the gravity thing I suggested. You can do:

    turn off gravity for your character rigidbodies, then add these lines to something on your characters

    //these should go into a FixedUpdate event.
    Vector3 artificialGravity = (shipTransform.rotation * Physics.gravity);
    characterRigidbody.MovePosition(characterRigidbody.position + (artificialGravity * Time.fixedDeltaTime));

    That would fix any gravity shearing. Also if the ship is a rigidbody, you could add it's velocity to your characters, e.g.

    characterRigidbody.MovePosition(characterRigidbody.position + shipRigidbody.velocity); //not sure if this needs to be scaled by fixedDeltaTime, please experiment if you use this solution.

    Hope this helps! :)
     
  8. Palimon

    Palimon

    Joined:
    Apr 18, 2013
    Posts:
    225
    Hey, thanks so much for the replies!! I've been busy, so finally able to get back to this. I played around with it a bunch more, and what I am currently doing is:

    In my ship controller script:
    Code (CSharp):
    1. float shipMass = rigidbody.mass;
    2.  
    3.             // Add Force and Torque to all rigidbodies inside of the ship
    4.             Rigidbody[] rbs = topOfShip.GetComponentsInChildren<Rigidbody>();
    5.             foreach (Rigidbody childRB in rbs)
    6.             {
    7.                 Debug.Log("Child Rigidbody (===== " + childRB.gameObject.name + " =====)");
    8.              
    9.                 // Scale force by each child's mass
    10.                 Vector3 modifiedTorque = new Vector3(relativeTorque.x, relativeTorque.y, relativeTorque.z);
    11.                 Vector3 modifiedForce = new Vector3(relativeForce.x, relativeForce.y, relativeForce.z);
    12.  
    13.                 float relativeMass = childRB.mass / shipMass;
    14.                 Debug.Log("modifiedForce (" + modifiedForce * relativeMass + ")");
    15.  
    16.                 childRB.AddRelativeTorque(modifiedTorque * relativeMass, ForceMode.Force);
    17.                 childRB.AddRelativeForce(modifiedForce * relativeMass, ForceMode.Force);
    18.              
    19.                 Debug.Log("velocity (" + childRB.velocity + ")");
    20.             }
    And in my character controller script for moving:
    Code (CSharp):
    1. Vector3 velocityChange = CalculateVelocityChange(inputVector);
    2.             rigidbody.AddForce(velocityChange);
    Both are within their respective FixedUpdate method. Basically, I'm applying a force relative to the mass of each object inside the ship when the ship thrusts. I'd have thought this would work, but it doesn't quite. If I comment out "rigidbody.AddForce(velocityChange);" for the character controller, everything works perfectly (except that I can't move, of course) from the ship's perspective. All items within the ship, and the character, move perfectly with the ship. If I uncomment the line, the character controller works perfectly, but even if I never input anything into the character controller for movement, the character model lags from the ship - it moves to slow and is left behind. Any ideas why this would be?