简体   繁体   中英

Ball movement around 3D sphere

I'm using Unity and mainly Java for the code although C# can also be used.

In my game the player controls a ball (rigidbody), with ball physics applied and working complete with collisons and you have to guide yourself around a planet Mario Galaxy-esque.

The problem I'm having is that the control system seems to do the opposite of what I am pressing depending on where I am on the planet. Is there a way to constrain the control system so that no matter what the orientation of the planet or camera, up is always forward, left is always left etc.

I have found some documentation regarding spherical corodinate systems , but am unsure whether this would be the way to go and if I would be overcomplicating the matter.

Code used to keep player ball on planet:

    FauxGravityAttractor.js

// Set to true for mono-directional gravity
var useLocalUpVector : boolean = false;

// Force applied along gravity up-vector (negative = down)
var fauxGravity = -10.0;

function Attract ( body : FauxGravityBody ){

    var gravityUp : Vector3;
    var localUp: Vector3;
    var localForward : Vector3;

    var t : Transform = body.transform;
    var r : Rigidbody = body.rigidbody;


    // Figure out the body's up vector

    if(useLocalUpVector){
        gravityUp = transform.up;   

    } else {

        gravityUp = t.position - transform.position;
        gravityUp.Normalize();
    }



    // Accelerate the body along its up vector

    r.AddForce( gravityUp * fauxGravity * r.mass );
    r.drag = body.grounded ? 1 : 0.1;



    // If the object's freezerotation is set, we force the object upright

    if(r.freezeRotation){

        // Orient relatived to gravity

        localUp = t.up;
        var q = Quaternion.FromToRotation(localUp, gravityUp);
        q = q * t.rotation;
        t.rotation = Quaternion.Slerp(t.rotation, q, 0.1);
        localForward = t.forward;

    }

}

And ball movement script:

using UnityEngine;
using System.Collections;

public class MarbleControl : MonoBehaviour {

    public float movementSpeed = 6.0f;

    void Update () {

        Vector3 movement = (Input.GetAxis("Horizontal") * Vector3.left * movementSpeed) + (Input.GetAxis("Vertical") * -Vector3.forward *movementSpeed);

        rigidbody.AddForce(movement, ForceMode.Force);
    }

    void OnTriggerEnter  (Collider other  ) {

        if (other.tag == "Pickup")

        {

            MarbleGameManager.SP.FoundGem();

            Destroy(other.gameObject);

        }    

    }
}

Vector3.left and Vector3.forward are constants like [-1,0,0] and [0,0,-1] correct? In that case it looks like you need to replace them with vectors coordinated relative to the orinetation of the marble, so that eg Vector3.left is replaced with the world space coordinates of the vector pointing in the direction you want to be the left direction of the marble.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM